Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong linearization for super calls caused by unrelated trait mixins #20284

Open
SakulK opened this issue Apr 29, 2024 · 0 comments · May be fixed by #20400
Open

Wrong linearization for super calls caused by unrelated trait mixins #20284

SakulK opened this issue Apr 29, 2024 · 0 comments · May be fixed by #20400
Assignees
Labels
area:erasure itype:bug regression This worked in a previous version but doesn't anymore

Comments

@SakulK
Copy link

SakulK commented Apr 29, 2024

Sorry for slightly long minimization, didn't manage to make it any shorter.
Behavior changed in 3.3.3, used to work fine in 2.13.13 and 3.3.1 at least.
Test1 is the reproduction - D.print and B.print are not getting called
Test2 has no with Z, which shouldn't matter, and yet it "fixes" the problem
Test3 extends the X, Y and Z traits first instead of last like Test1, which also causes all prints to run

Compiler version

3.3.1, 3.4.1

Minimized code

scala-cli run test.sc -S 3.3.3

test.sc:

trait A {
  def print: Unit = println("A")
}

trait B extends A {
  override def print: Unit = {
    println("B")
    super.print
  }
}

trait C extends A {
  override def print: Unit = {
    println("C")
    super.print
  }
}

trait D extends B {
  override def print: Unit = {
    println("D")
    super.print
  }
}

trait BB extends B

trait X
trait Y
trait Z

class Test1 extends C with B with BB with D with X with Y with Z {
  override def print: Unit = {
    println("Test 1")
    super.print
  }
}
new Test1().print

class Test2 extends C with B with BB with D with X with Y {
  override def print: Unit = {
    println("Test 2")
    super.print
  }
}
new Test2().print

class Test3 extends X with Y with Z with C with B with BB with D {
  override def print: Unit = {
    println("Test 3")
    super.print
  }
}
new Test3().print

Output

In scala 3.3.3 and 3.4.1:

Test 1
C
A
Test 2
D
B
C
A
Test 3
D
B
C
A

In scala 2.13.13 and 3.3.1:

Test 1
D
B
C
A
Test 2
D
B
C
A
Test 3
D
B
C
A

Expectation

Which super method calls are executed is not affected by "extra" traits

@SakulK SakulK added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Apr 29, 2024
@Gedochao Gedochao added regression This worked in a previous version but doesn't anymore area:erasure and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels May 9, 2024
odersky added a commit to dotty-staging/dotty that referenced this issue May 13, 2024
scala#20284 started breaking since we now balance AndTypes to avoid performance drops.
But (re-)balancing an AndType interferes with the logic that determines which
symbol is referred by a super select. This is fixed by two changes:

 - Form types of super with `AndType` instead of `&`
 - Don't simplify types of super since that would rebalance the underlying AndTypes.

Fixes scala#20284
@odersky odersky linked a pull request May 13, 2024 that will close this issue
odersky added a commit to dotty-staging/dotty that referenced this issue May 13, 2024
scala#20284 started breaking since we now balance AndTypes to avoid performance drops.
But (re-)balancing an AndType interferes with the logic that determines which
symbol is referred by a super select. This is fixed by two changes:

 - Form types of super with `AndType` instead of `&`
 - Don't simplify types of super since that would rebalance the underlying AndTypes.

Fixes scala#20284
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:erasure itype:bug regression This worked in a previous version but doesn't anymore
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants