Skip to content

Type inference on class member widened to abstract definition #17324

Closed
@ftucky

Description

@ftucky

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 A

Expectation

The issue is the type of the val objN in Y.

  • obj0: EXPECTED. Type is B as inferred from choose( ) return type.
  • obj1: UNEXPECTED. Type is A, widened to the abstract definition val obj1:A in X
  • obj2: EXPECTED. Type is B, from the type-ascription.
  • obj3: ???. Type is B. The final modifier has an impact on the member type (vs. obj1), and seems to restore expected type inference. On the other hand making the entire class Y final 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 final on the type of the member expected ?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions