From 652abbacf7b913ef87474df4bcce4fe90aec24a1 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 19 Jun 2013 21:34:51 +0200 Subject: [PATCH] SI-7596 Curtail overloaded symbols during unpickling In code like: object O { val x = A; def x(a: Any) = ... } object P extends O.x.A The unpickler was using an overloaded symbol for `x` in the parent type of `P`. This led to compilation failures under separate compilation. The code that leads to this is in `Unpicklers`: def fromName(name: Name) = name.toTermName match { case nme.ROOT => loadingMirror.RootClass case nme.ROOTPKG => loadingMirror.RootPackage case _ => adjust(owner.info.decl(name)) } This commit filters the overloaded symbol based its stability unpickling a singleton type. That seemed a slightly safer place than in `fromName`. --- .../reflect/internal/pickling/UnPickler.scala | 2 +- test/files/pos/t7596/A_1.scala | 10 ++++++++++ test/files/pos/t7596/B_2.scala | 19 +++++++++++++++++++ test/files/pos/t7596b/A.scala | 10 ++++++++++ test/files/pos/t7596b/B.scala | 6 ++++++ test/files/pos/t7596c/A_1.scala | 11 +++++++++++ test/files/pos/t7596c/B_2.scala | 9 +++++++++ 7 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 test/files/pos/t7596/A_1.scala create mode 100644 test/files/pos/t7596/B_2.scala create mode 100644 test/files/pos/t7596b/A.scala create mode 100644 test/files/pos/t7596b/B.scala create mode 100644 test/files/pos/t7596c/A_1.scala create mode 100644 test/files/pos/t7596c/B_2.scala diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala index 5433bfad6031..a35620a99424 100644 --- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala +++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala @@ -396,7 +396,7 @@ abstract class UnPickler { case NOtpe => NoType case NOPREFIXtpe => NoPrefix case THIStpe => ThisType(readSymbolRef()) - case SINGLEtpe => SingleType(readTypeRef(), readSymbolRef()) + case SINGLEtpe => SingleType(readTypeRef(), readSymbolRef().filter(_.isStable)) // SI-7596 account for overloading case SUPERtpe => SuperType(readTypeRef(), readTypeRef()) case CONSTANTtpe => ConstantType(readConstantRef()) case TYPEREFtpe => TypeRef(readTypeRef(), readSymbolRef(), readTypes()) diff --git a/test/files/pos/t7596/A_1.scala b/test/files/pos/t7596/A_1.scala new file mode 100644 index 000000000000..6303c6d132ce --- /dev/null +++ b/test/files/pos/t7596/A_1.scala @@ -0,0 +1,10 @@ +trait Driver { + abstract class Table +} + +object Config { + val driver : Driver = ??? + def driver(a: Any) = ??? +} + +object Sites extends Config.driver.Table diff --git a/test/files/pos/t7596/B_2.scala b/test/files/pos/t7596/B_2.scala new file mode 100644 index 000000000000..977e5c8bd1e5 --- /dev/null +++ b/test/files/pos/t7596/B_2.scala @@ -0,0 +1,19 @@ +object Test { + locally { + Sites: Config.driver.Table + } +} + +// Under separate compilation, the pickler is foiled by the +// overloaded term `Config.driver`, and results in: + +// qbin/scalac test/files/pos/t7596/A_1.scala && qbin/scalac -explaintypes test/files/pos/t7596/B_2.scala +// test/files/pos/t7596/B_2.scala:3: error: type mismatch; +// found : Sites.type +// required: Config.driver.Table +// Sites: Config.driver.Table +// ^ +// Sites.type <: Config.driver.Table? +// Driver.this.type = Config.driver.type? +// false +// false \ No newline at end of file diff --git a/test/files/pos/t7596b/A.scala b/test/files/pos/t7596b/A.scala new file mode 100644 index 000000000000..65c1bc56efb3 --- /dev/null +++ b/test/files/pos/t7596b/A.scala @@ -0,0 +1,10 @@ +trait H2Driver{ + abstract class Table[T] +} + +object Config { + val driver : H2Driver = ??? + def driver(app: Any): H2Driver = ??? +} + +class Sites extends Config.driver.Table[String] diff --git a/test/files/pos/t7596b/B.scala b/test/files/pos/t7596b/B.scala new file mode 100644 index 000000000000..cbcf149c2398 --- /dev/null +++ b/test/files/pos/t7596b/B.scala @@ -0,0 +1,6 @@ +class DAOBase[E]{ + type TableType <: Config.driver.Table[E] +} +class SitesDAO extends DAOBase[String]{ + type TableType = Sites +} diff --git a/test/files/pos/t7596c/A_1.scala b/test/files/pos/t7596c/A_1.scala new file mode 100644 index 000000000000..3e366df477d5 --- /dev/null +++ b/test/files/pos/t7596c/A_1.scala @@ -0,0 +1,11 @@ +trait Driver { + abstract class Table +} + +object Config { + val driver : Driver = ??? + val driverUniqueName: driver.type = driver + def driver(a: Any) = ??? +} + +object Sites extends Config.driver.Table diff --git a/test/files/pos/t7596c/B_2.scala b/test/files/pos/t7596c/B_2.scala new file mode 100644 index 000000000000..33da68c1ff11 --- /dev/null +++ b/test/files/pos/t7596c/B_2.scala @@ -0,0 +1,9 @@ +object Test { + locally { + Sites: Config.driver.Table + } +} + +// This variation worked by avoiding referring to the +// overloaded term `Config.driver` in the parent type of +// Sites \ No newline at end of file