From 80767383fdc52a444295fdc2ab5f4b9fbfa1c352 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 23 Oct 2013 11:29:09 +0200 Subject: 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 { 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 { abstract trait C2 extends scala.AnyRef { def O1: Any }; class C1 extends AnyRef with C2 { object O1 extends scala.AnyRef @volatile private[this] var O1$module: C1.this.O1.type = _; 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. --- test/files/pos/t7928.scala | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 test/files/pos/t7928.scala (limited to 'test') diff --git a/test/files/pos/t7928.scala b/test/files/pos/t7928.scala new file mode 100644 index 0000000000..d9e29935b3 --- /dev/null +++ b/test/files/pos/t7928.scala @@ -0,0 +1,16 @@ +trait OuterTrait { + trait InnerTrait { + type Element + type Collection <: Iterable[Inner.Element] + } + + val Inner: InnerTrait + +} + +object OuterObject extends OuterTrait { + object Inner extends InnerTrait { + type Element = String + override type Collection = Seq[Inner.Element] + } +} -- cgit v1.2.3