Skip to content

Commit 8076738

Browse files
committed
SI-7928 Favour module accessors symbols in rebind
The Refchecks tree transformer transforms a nested modules that overrides a method into a pair of symbols: the module itself, and an module accessor that matches the overridden symbol. [[syntax trees at end of typer]] // test1.scala package <empty> { abstract trait C2 extends scala.AnyRef { def O1: Any }; class C1 extends AnyRef with C2 { object O1 extends scala.AnyRef } } [[syntax trees at end of refchecks]] // test1.scala package <empty> { abstract trait C2 extends scala.AnyRef { def O1: Any }; class C1 extends AnyRef with C2 { object O1 extends scala.AnyRef @volatile <synthetic> private[this] var O1$module: C1.this.O1.type = _; <stable> def O1: C1.this.O1.type = { C1.this.O1$module = new C1.this.O1.type(); C1.this.O1$module } } } When constructing a TypeRef or SingleType with a prefix and and a symbol, the factory methods internally use `rebind` to see if the provided symbol should be replaced with an overriding symbol that is available in that prefix. Trying this out in the REPL is a bit misleading, because even if you change phase to `refchecks`, you won't get the desired results because the transform is not done in an InfoTransformer. scala> val O1 = typeOf[C1].decl(TermName("O1")) O1: $r.intp.global.Symbol = object O1 scala> typeRef(typeOf[C2], O1, Nil) res13: $r.intp.global.Type = C2#O1 scala> res13.asInstanceOf[TypeRef].sym.owner res14: $r.intp.global.Symbol = class C1 But debugging the test case, we get into `rebind` during an AsSeenFrom which is where we crashed when `suchThat` encountered the overloaded module and module accessor symbols: typeOf[OuterObject.Inner.type].memberType(symbolOf[InnerTrait.Collection]) ... singleTypeAsSeen(OuterTrait.this.Inner.type) val SingleType(pre, sym) = tp // pre = OuterTrait.this.type // sym = OuterTrait.Inner val pre1 = this(pre) // OuterObject.type singleType(pre1, sym) rebind(pre1, sym) // was crashing, now OuterObject.Inner } This commit excludes the module symbol from symbol lookup in the prefix in rebind.
1 parent 0c2d737 commit 8076738

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

src/reflect/scala/reflect/internal/Types.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3385,7 +3385,11 @@ trait Types
33853385
/** Rebind symbol `sym` to an overriding member in type `pre`. */
33863386
private def rebind(pre: Type, sym: Symbol): Symbol = {
33873387
if (!sym.isOverridableMember || sym.owner == pre.typeSymbol) sym
3388-
else pre.nonPrivateMember(sym.name).suchThat(sym => sym.isType || (sym.isStable && !sym.hasVolatileType)) orElse sym
3388+
else pre.nonPrivateMember(sym.name).suchThat(sym =>
3389+
// SI-7928 `isModuleNotMethod` is here to avoid crashing with overloaded module accessor and module symbols
3390+
// after refchecks eliminates a ModuleDef that implements and interface.
3391+
sym.isType || (!sym.isModuleNotMethod && sym.isStable && !sym.hasVolatileType)
3392+
) orElse sym
33893393
}
33903394

33913395
/** Convert a `super` prefix to a this-type if `sym` is abstract or final. */

test/files/pos/t7928.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
trait OuterTrait {
2+
trait InnerTrait {
3+
type Element
4+
type Collection <: Iterable[Inner.Element]
5+
}
6+
7+
val Inner: InnerTrait
8+
9+
}
10+
11+
object OuterObject extends OuterTrait {
12+
object Inner extends InnerTrait {
13+
type Element = String
14+
override type Collection = Seq[Inner.Element]
15+
}
16+
}

0 commit comments

Comments
 (0)