From 3d9d1f6c99d2ee803402b02cccba72086af74b38 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sun, 11 Jan 2015 19:01:09 +1000 Subject: SI-9074 Fix generic substitution with package objects, overloading Takes a leaf out of dotty's book [1] and makes `asSeenFrom` transparently change the prefix from the package class to the package object when needed. This fixes generic subsitution during overload resolution, as reported in SI-9074. This subsumes the former fix for SI-6225, which is removed here. [1] https://github.com/lampepfl/dotty/pull/282 --- .../scala/tools/nsc/typechecker/Contexts.scala | 7 +------ .../scala/tools/nsc/typechecker/Infer.scala | 2 +- .../scala/tools/nsc/interactive/Global.scala | 12 ----------- src/reflect/scala/reflect/internal/Types.scala | 2 +- .../scala/reflect/internal/tpe/TypeMaps.scala | 9 +++++--- test/files/pos/t9074.scala | 24 ++++++++++++++++++++++ test/files/pos/t9074b.scala | 15 ++++++++++++++ 7 files changed, 48 insertions(+), 23 deletions(-) create mode 100644 test/files/pos/t9074.scala create mode 100644 test/files/pos/t9074b.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index b3e207b334..98289f6a3c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -810,12 +810,7 @@ trait Contexts { self: Analyzer => val qual = imp.qual val qualSym = qual.tpe.typeSymbol - val pre = - if (qualSym.isPackageClass) - // SI-6225 important if the imported symbol is inherited by the the package object. - qualSym.packageObject.typeOfThis - else - qual.tpe + val pre = qual.tpe def collect(sels: List[ImportSelector]): List[ImplicitInfo] = sels match { case List() => List() diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index cf97474d9a..b9ccf0977c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -1447,7 +1447,7 @@ trait Infer extends Checkable { log(s"Attaching AntiPolyType-carrying overloaded type to $sym") // Multiple alternatives which are within bounds; spin up an // overloaded type which carries an "AntiPolyType" as a prefix. - val tparams = newAsSeenFromMap(pre, hd.owner) mapOver hd.typeParams + val tparams = new AsSeenFromMap(pre, hd.owner) mapOver hd.typeParams val bounds = tparams map (_.tpeHK) // see e.g., #1236 val tpe = PolyType(tparams, OverloadedType(AntiPolyType(pre, bounds), alts)) finish(sym setInfo tpe, tpe) diff --git a/src/interactive/scala/tools/nsc/interactive/Global.scala b/src/interactive/scala/tools/nsc/interactive/Global.scala index a192dd3738..3f963730f1 100644 --- a/src/interactive/scala/tools/nsc/interactive/Global.scala +++ b/src/interactive/scala/tools/nsc/interactive/Global.scala @@ -159,18 +159,6 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") override def forInteractive = true override protected def synchronizeNames = true - override def newAsSeenFromMap(pre: Type, clazz: Symbol): AsSeenFromMap = - new InteractiveAsSeenFromMap(pre, clazz) - - class InteractiveAsSeenFromMap(pre: Type, clazz: Symbol) extends AsSeenFromMap(pre, clazz) { - /** The method formerly known as 'instParamsRelaxed' goes here if it's still necessary, - * which it is currently supposed it is not. - * - * If it is, change AsSeenFromMap method correspondingTypeArgument to call an overridable - * method rather than aborting in the failure case. - */ - } - /** A map of all loaded files to the rich compilation units that correspond to them. */ val unitOfFile = mapAsScalaMapConverter(new ConcurrentHashMap[AbstractFile, RichCompilationUnit] { diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 4d230cc1cc..a4269fcbc5 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -666,7 +666,7 @@ trait Types ) if (trivial) this else { - val m = newAsSeenFromMap(pre.normalize, clazz) + val m = new AsSeenFromMap(pre.normalize, clazz) val tp = m(this) val tp1 = existentialAbstraction(m.capturedParams, tp) diff --git a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala index c705ca7069..d6d2cf3383 100644 --- a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala +++ b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala @@ -449,12 +449,15 @@ private[internal] trait TypeMaps { (pre eq NoType) || (pre eq NoPrefix) || !isPossiblePrefix(clazz) ) - def newAsSeenFromMap(pre: Type, clazz: Symbol): AsSeenFromMap = - new AsSeenFromMap(pre, clazz) + @deprecated("Use new AsSeenFromMap instead", "2.12.0") + final def newAsSeenFromMap(pre: Type, clazz: Symbol): AsSeenFromMap = new AsSeenFromMap(pre, clazz) /** A map to compute the asSeenFrom method. */ - class AsSeenFromMap(seenFromPrefix: Type, seenFromClass: Symbol) extends TypeMap with KeepOnlyTypeConstraints { + class AsSeenFromMap(seenFromPrefix0: Type, seenFromClass: Symbol) extends TypeMap with KeepOnlyTypeConstraints { + private val seenFromPrefix: Type = if (seenFromPrefix0.typeSymbolDirect.hasPackageFlag && !seenFromClass.hasPackageFlag) + seenFromPrefix0.packageObject.typeOfThis + else seenFromPrefix0 // Some example source constructs relevant in asSeenFrom: // // object CaptureThis { diff --git a/test/files/pos/t9074.scala b/test/files/pos/t9074.scala new file mode 100644 index 0000000000..67db281f54 --- /dev/null +++ b/test/files/pos/t9074.scala @@ -0,0 +1,24 @@ +package blam { + + package foo { + + trait F[T] { + def f(d: Double, t: T): T = ??? + def f(d: Int, t: T): T = ??? + def f(d: String, t: T): T = ??? + + def g[A](a: T): T = ??? + def g(a: Int) = ??? + } + } + + package object foo extends foo.F[Double] { + override def f(d: Double, t: Double): Double = ??? + } +} + +object Test { + import blam._ + foo.f("3", 4.0) + foo.g[Any](1d) : Double +} diff --git a/test/files/pos/t9074b.scala b/test/files/pos/t9074b.scala new file mode 100644 index 0000000000..dadcebf399 --- /dev/null +++ b/test/files/pos/t9074b.scala @@ -0,0 +1,15 @@ +trait Echo [T] { + def echo(t: T): Unit +} + +trait IntEcho extends Echo[Int] { + def echo(t: Int) = println(t) +} + +object echo extends IntEcho +package object echo1 extends IntEcho + +object App extends App { + echo.echo(1) + echo1.echo(1) +} -- cgit v1.2.3