Skip to content

Commit 90b0c78

Browse files
committed
Handle SuperAccessorName
1 parent 67f11ff commit 90b0c78

File tree

3 files changed

+66
-17
lines changed

3 files changed

+66
-17
lines changed

compiler/src/dotty/tools/dotc/transform/init/Semantic.scala

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import Symbols.*
88
import Types.*
99
import StdNames.*
1010
import NameKinds.OuterSelectName
11+
import NameKinds.SuperAccessorName
12+
import NameOps.unexpandedName
1113

1214
import ast.tpd.*
1315
import config.Printers.init as printer
@@ -788,7 +790,9 @@ object Semantic:
788790
if !needResolve then
789791
meth
790792
else if superType.exists then
791-
resolveSuper(ref.klass, superType, meth)
793+
meth
794+
else if meth.name.is(SuperAccessorName) then
795+
ResolveSuper.rebindSuper(ref.klass, meth)
792796
else
793797
resolve(ref.klass, meth)
794798

@@ -829,7 +833,7 @@ object Semantic:
829833
value.select(target, receiver, needResolve = false)
830834
else
831835
if ref.klass.isSubClass(receiver.widenSingleton.classSymbol) then
832-
report.error("Unexpected resolution failure: ref.klass = " + ref.klass.show + ", meth = " + meth.show + Trace.show, Trace.position)
836+
report.error("[Internal error] Unexpected resolution failure: ref.klass = " + ref.klass.show + ", meth = " + meth.show + Trace.show, Trace.position)
833837
Hot
834838
else
835839
// This is possible due to incorrect type cast.
@@ -1175,9 +1179,8 @@ object Semantic:
11751179
// Note that a parameterized trait may only get parameters from the class that extends the trait.
11761180
// A trait may not supply constructor arguments to another trait.
11771181
if !klass.is(Flags.Trait) then
1178-
for parent <- klass.parentSyms if parent.hasSource do doPromote(parent.asClass, klass, isHotSegment)
1179-
// We still need to handle indirectly extended traits via traits, which are not in the parent list.
11801182
val superCls = klass.superClass
1183+
if superCls.hasSource then doPromote(superCls.asClass, klass, isHotSegment)
11811184
val mixins = klass.baseClasses.tail.takeWhile(_ != superCls)
11821185
for mixin <- mixins if mixin.hasSource do doPromote(mixin.asClass, klass, isHotSegment)
11831186
end doPromote
@@ -1768,16 +1771,3 @@ object Semantic:
17681771
if (sym.isEffectivelyFinal || sym.isConstructor) sym
17691772
else sym.matchingMember(cls.appliedRef)
17701773
}
1771-
1772-
def resolveSuper(cls: ClassSymbol, superType: Type, sym: Symbol)(using Context): Symbol =
1773-
import annotation.tailrec
1774-
@tailrec def loop(bcs: List[ClassSymbol]): Symbol = bcs match {
1775-
case bc :: bcs1 =>
1776-
val cand = sym.matchingDecl(bcs.head, cls.thisType)
1777-
.suchThat(alt => !alt.is(Flags.Deferred)).symbol
1778-
if (cand.exists) cand else loop(bcs.tail)
1779-
case _ =>
1780-
NoSymbol
1781-
}
1782-
loop(cls.info.baseClasses.dropWhile(sym.owner != _))
1783-

tests/init/neg/super-resolution.check

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
-- Error: tests/init/neg/super-resolution.scala:21:6 -------------------------------------------------------------------
2+
21 | val m = 30 // error
3+
| ^
4+
| Access non-initialized value m. Calling trace:
5+
| -> class C extends A with M with N: [ super-resolution.scala:17 ]
6+
| ^
7+
| -> foo() [ super-resolution.scala:18 ]
8+
| ^^^^^
9+
| -> override def foo(): Int = b * super.foo() [ super-resolution.scala:15 ]
10+
| ^^^^^^^^^^^
11+
| -> override def foo(): Int = a + super.foo() [ super-resolution.scala:11 ]
12+
| ^^^^^^^^^^^
13+
| -> def foo(): Int = m [ super-resolution.scala:7 ]
14+
| ^
15+
-- Error: tests/init/neg/super-resolution.scala:19:6 -------------------------------------------------------------------
16+
19 | val a = 10 // error
17+
| ^
18+
| Access non-initialized value a. Calling trace:
19+
| -> class C extends A with M with N: [ super-resolution.scala:17 ]
20+
| ^
21+
| -> foo() [ super-resolution.scala:18 ]
22+
| ^^^^^
23+
| -> override def foo(): Int = b * super.foo() [ super-resolution.scala:15 ]
24+
| ^^^^^^^^^^^
25+
| -> override def foo(): Int = a + super.foo() [ super-resolution.scala:11 ]
26+
| ^
27+
-- Error: tests/init/neg/super-resolution.scala:20:6 -------------------------------------------------------------------
28+
20 | val b = 20 // error
29+
| ^
30+
| Access non-initialized value b. Calling trace:
31+
| -> class C extends A with M with N: [ super-resolution.scala:17 ]
32+
| ^
33+
| -> foo() [ super-resolution.scala:18 ]
34+
| ^^^^^
35+
| -> override def foo(): Int = b * super.foo() [ super-resolution.scala:15 ]
36+
| ^

tests/init/neg/super-resolution.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
abstract class A:
2+
val n: Int
3+
def foo(): Int = n
4+
5+
trait B:
6+
val m: Int
7+
def foo(): Int = m
8+
9+
trait M extends A with B:
10+
val a: Int
11+
override def foo(): Int = a + super.foo()
12+
13+
trait N extends A with B:
14+
val b: Int
15+
override def foo(): Int = b * super.foo()
16+
17+
class C extends A with M with N:
18+
foo()
19+
val a = 10 // error
20+
val b = 20 // error
21+
val m = 30 // error
22+
val n = 40
23+

0 commit comments

Comments
 (0)