diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-12-09 08:13:05 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-12-09 08:31:04 +0100 |
commit | 369f370b1e894893d315de3bd861c9292695f71d (patch) | |
tree | b79b6c10ef770d768372cf95c716e203963da82f | |
parent | 7d28c4966e5b32b46fda927f303aea4af20c4517 (diff) | |
download | scala-369f370b1e894893d315de3bd861c9292695f71d.tar.gz scala-369f370b1e894893d315de3bd861c9292695f71d.tar.bz2 scala-369f370b1e894893d315de3bd861c9292695f71d.zip |
SI-8054 Fix regression in TypeRef rebind with val overriding object
Regressed in 80767383fd / SI-7928
The condition added in that commit are necessary after refchecks but
poisonous before.
This still seems rather fragile: I wonder if `eliminateModuleDefs`
in `RefChecks` ought to flag the module symbol as `ARTIFACT` after
creating the accessor, so as to signal that it shouldn't be bound
anymore?
-rw-r--r-- | src/reflect/scala/reflect/internal/Types.scala | 13 | ||||
-rw-r--r-- | test/files/pos/t8054.scala | 31 |
2 files changed, 39 insertions, 5 deletions
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index e483fa6ba8..99e6ae633f 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -3392,11 +3392,14 @@ trait Types /** Rebind symbol `sym` to an overriding member in type `pre`. */ private def rebind(pre: Type, sym: Symbol): Symbol = { if (!sym.isOverridableMember || sym.owner == pre.typeSymbol) sym - else pre.nonPrivateMember(sym.name).suchThat(sym => - // SI-7928 `isModuleNotMethod` is here to avoid crashing with overloaded module accessor and module symbols - // after refchecks eliminates a ModuleDef that implements and interface. - sym.isType || (!sym.isModuleNotMethod && sym.isStable && !sym.hasVolatileType) - ) orElse sym + else pre.nonPrivateMember(sym.name).suchThat { sym => + // SI-7928 `isModuleNotMethod` is here to avoid crashing with spuriously "overloaded" module accessor and module symbols. + // These appear after refchecks eliminates ModuleDefs that implement an interface. + // Here, we exclude the module symbol, which allows us to bind to the accessor. + // SI-8054 We must only do this after refchecks, otherwise we exclude the module symbol which does not yet have an accessor! + val isModuleWithAccessor = phase.refChecked && sym.isModuleNotMethod + sym.isType || (!isModuleWithAccessor && sym.isStable && !sym.hasVolatileType) + } orElse sym } /** Convert a `super` prefix to a this-type if `sym` is abstract or final. */ diff --git a/test/files/pos/t8054.scala b/test/files/pos/t8054.scala new file mode 100644 index 0000000000..a7bb44b1ed --- /dev/null +++ b/test/files/pos/t8054.scala @@ -0,0 +1,31 @@ +trait D { + trait Manifest { + class Entry + } + + val M: Manifest + + def m: M.Entry = ??? +} + +object D1 extends D { + object M extends Manifest +} + +object D2 extends D { + val M: Manifest = ??? +} + +object Hello { + + def main(args: Array[String]) { + // 2.10.3 - ok + // 2.11.0-M7 - type mismatch; found : Seq[DB1.MANIFEST.Entry] + // required: Seq[DB1.MANIFEST.Entry] + val t1: D1.M.Entry = D1.m + + // 2.10.3 - ok + // 2.11.0-M7 - ok + val t2: D2.M.Entry = D2.m + } +} |