Boo

No type safety at all if LHS or RHS of expression is an interface

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Not A Bug
  • Affects Version/s: 0.9.1
  • Fix Version/s: 0.8.2, 0.9, 0.9.3
  • Component/s: Compiler
  • Labels:
    None
  • Testcase included:
    yes
  • Number of attachments :
    0

Description

Funny one :

class Foo:
    pass

foo = Foo()
i as System.Collections.IEnumerable = Foo  #! typo type Foo not lowercase local foo
i = foo #oh but even without the typo this also compiles successfully since `i''s type is an interface

This obviously fail at run-time.

Activity

Hide
Cedric Vivier added a comment -

Hmm this seems to have been introduce by the TypeSystem refactoring.
As long as a left-hand or right-hand expression is an interface (not final) then anything goes

Two testcases using this have been added later:

tests/testcases/integration/operators/cast-6.boo
tests/testcases/integration/types/interfaces-20.boo

Is it intentional? am not sure to get what's the rationale/usecase about it?
Considering the dangers of such a kind of downcasting (I only detected this quite late at run-time because of a typo..) should we allow it only when an explicit cast to interface is present maybe?

Show
Cedric Vivier added a comment - Hmm this seems to have been introduce by the TypeSystem refactoring. As long as a left-hand or right-hand expression is an interface (not final) then anything goes Two testcases using this have been added later: tests/testcases/integration/operators/cast-6.boo tests/testcases/integration/types/interfaces-20.boo Is it intentional? am not sure to get what's the rationale/usecase about it? Considering the dangers of such a kind of downcasting (I only detected this quite late at run-time because of a typo..) should we allow it only when an explicit cast to interface is present maybe?
Hide
Cedric Vivier added a comment -

Fwiw culprits introduced in TSS refactoring are lines 640,641 of TypeSystemServices.cs in AreTypesRelated:

(lhs.IsInterface && !rhs.IsFinal)
(rhs.IsInterface && !lhs.IsFinal)
Show
Cedric Vivier added a comment - Fwiw culprits introduced in TSS refactoring are lines 640,641 of TypeSystemServices.cs in AreTypesRelated:
(lhs.IsInterface && !rhs.IsFinal)
(rhs.IsInterface && !lhs.IsFinal)
Hide
Cedric Vivier added a comment -

Proposal for type safety when using interfaces while still allowing interface downcasts when potentially available :

lass Fruit:
    pass
class Apple (Fruit, IFruit):
    pass
interface IFruit:
    pass
class Drink:
    pass


def Drop(a as Apple):
    pass
def Eat(f as IFruit):
    pass


fruit = Fruit()
drink = Drink()
odrink as object = Drink()

#object downcast (current behavior)
Drop(fruit)       #compiles
Drop(odrink)  #compiles
#Drop(drink)  #error since Drink is not in the hierarchy of Apple

#interface downcast
Eat(fruit)       #compiles
Eat(odrink)  #compiles
Eat(drink)    #current behavior: compiles though it will _always_ fail
                      #PROPOSAL: error since no type in Drink hierarchy implements IFruit
                      #                         if lhs or rhs is `object' any interface downcast is possible like today

This would keep interface downcast working for use cases as integration/operators/casts-6.boo and integration/types/interfaces-20.boo.

Show
Cedric Vivier added a comment - Proposal for type safety when using interfaces while still allowing interface downcasts when potentially available :
lass Fruit:
    pass
class Apple (Fruit, IFruit):
    pass
interface IFruit:
    pass
class Drink:
    pass


def Drop(a as Apple):
    pass
def Eat(f as IFruit):
    pass


fruit = Fruit()
drink = Drink()
odrink as object = Drink()

#object downcast (current behavior)
Drop(fruit)       #compiles
Drop(odrink)  #compiles
#Drop(drink)  #error since Drink is not in the hierarchy of Apple

#interface downcast
Eat(fruit)       #compiles
Eat(odrink)  #compiles
Eat(drink)    #current behavior: compiles though it will _always_ fail
                      #PROPOSAL: error since no type in Drink hierarchy implements IFruit
                      #                         if lhs or rhs is `object' any interface downcast is possible like today
This would keep interface downcast working for use cases as integration/operators/casts-6.boo and integration/types/interfaces-20.boo.
Hide
Rodrigo B. de Oliveira added a comment -

By design. Type safety in that case could only be guaranteed with closed world analysis.

Show
Rodrigo B. de Oliveira added a comment - By design. Type safety in that case could only be guaranteed with closed world analysis.

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: