-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Closed
Labels
Description
Compiler version
3.2.2 , 3.3.0-RC3
Minimized code
class A
class B extends A:
def m = true
//transparent inline def choose(b: Boolean): A =
// if b then new A else new B
def choose(b:Boolean):B = new B
class X:
val obj1 : A
val obj2 : A
val obj3 : A
class Y extends X:
val obj0 = choose(false) // type B ( from inference )
val obj1 = choose(false) // type A ( from X.this.obj1 )
val obj2 : B = choose(false) // type B ( from ascription )
final val obj3 = choose(false) // type B ( from inference )
val y = new Y
y.obj0.m // compiles EXPECTED
y.obj1.m // compile error UNEXPECTED
y.obj2.m // compiles EXPECTED
y.obj3.m // compiles EXPECTED // Why different from obj1 case ?Output
y.obj1.m ---- m is not a member of AExpectation
The issue is the type of the val objN in Y.
obj0: EXPECTED. Type isBas inferred fromchoose( )return type.obj1: UNEXPECTED. Type isA, widened to the abstract definitionval obj1:AinXobj2: EXPECTED. Type isB, from the type-ascription.obj3: ???. Type isB. Thefinalmodifier has an impact on the member type (vs.obj1), and seems to restore expected type inference. On the other hand making the entireclass Yfinal has no impact.
Observations
You may notice a pattern very close to the one described here. The bug is not caused bug transparent inline, but loses the on-purpose crafted type.
In scala2 the type was the expected one. scastie
class A { }
class B extends A { def m = true }
trait X { def obj : A }
class Y extends X { def obj = new B }
val y = new Y
y.obj.m // Compiles in scala2, does not compile in scala3.- Is the change of behavior between scala2 and scala3 intentional ?
- Is the impact of
finalon the type of the member expected ?
He-PinHe-Pin