Skip to content

Commit 44d6dfa

Browse files
committed
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] scala/scala3#282
1 parent e6e5b14 commit 44d6dfa

File tree

7 files changed

+48
-23
lines changed

7 files changed

+48
-23
lines changed

src/compiler/scala/tools/nsc/typechecker/Contexts.scala

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -810,12 +810,7 @@ trait Contexts { self: Analyzer =>
810810
val qual = imp.qual
811811

812812
val qualSym = qual.tpe.typeSymbol
813-
val pre =
814-
if (qualSym.isPackageClass)
815-
// SI-6225 important if the imported symbol is inherited by the the package object.
816-
qualSym.packageObject.typeOfThis
817-
else
818-
qual.tpe
813+
val pre = qual.tpe
819814
def collect(sels: List[ImportSelector]): List[ImplicitInfo] = sels match {
820815
case List() =>
821816
List()

src/compiler/scala/tools/nsc/typechecker/Infer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1447,7 +1447,7 @@ trait Infer extends Checkable {
14471447
log(s"Attaching AntiPolyType-carrying overloaded type to $sym")
14481448
// Multiple alternatives which are within bounds; spin up an
14491449
// overloaded type which carries an "AntiPolyType" as a prefix.
1450-
val tparams = newAsSeenFromMap(pre, hd.owner) mapOver hd.typeParams
1450+
val tparams = new AsSeenFromMap(pre, hd.owner) mapOver hd.typeParams
14511451
val bounds = tparams map (_.tpeHK) // see e.g., #1236
14521452
val tpe = PolyType(tparams, OverloadedType(AntiPolyType(pre, bounds), alts))
14531453
finish(sym setInfo tpe, tpe)

src/interactive/scala/tools/nsc/interactive/Global.scala

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -159,18 +159,6 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
159159
override def forInteractive = true
160160
override protected def synchronizeNames = true
161161

162-
override def newAsSeenFromMap(pre: Type, clazz: Symbol): AsSeenFromMap =
163-
new InteractiveAsSeenFromMap(pre, clazz)
164-
165-
class InteractiveAsSeenFromMap(pre: Type, clazz: Symbol) extends AsSeenFromMap(pre, clazz) {
166-
/** The method formerly known as 'instParamsRelaxed' goes here if it's still necessary,
167-
* which it is currently supposed it is not.
168-
*
169-
* If it is, change AsSeenFromMap method correspondingTypeArgument to call an overridable
170-
* method rather than aborting in the failure case.
171-
*/
172-
}
173-
174162
/** A map of all loaded files to the rich compilation units that correspond to them.
175163
*/
176164
val unitOfFile = mapAsScalaMapConverter(new ConcurrentHashMap[AbstractFile, RichCompilationUnit] {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ trait Types
666666
)
667667
if (trivial) this
668668
else {
669-
val m = newAsSeenFromMap(pre.normalize, clazz)
669+
val m = new AsSeenFromMap(pre.normalize, clazz)
670670
val tp = m(this)
671671
val tp1 = existentialAbstraction(m.capturedParams, tp)
672672

src/reflect/scala/reflect/internal/tpe/TypeMaps.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -449,12 +449,15 @@ private[internal] trait TypeMaps {
449449
(pre eq NoType) || (pre eq NoPrefix) || !isPossiblePrefix(clazz)
450450
)
451451

452-
def newAsSeenFromMap(pre: Type, clazz: Symbol): AsSeenFromMap =
453-
new AsSeenFromMap(pre, clazz)
452+
@deprecated("Use new AsSeenFromMap instead", "2.12.0")
453+
final def newAsSeenFromMap(pre: Type, clazz: Symbol): AsSeenFromMap = new AsSeenFromMap(pre, clazz)
454454

455455
/** A map to compute the asSeenFrom method.
456456
*/
457-
class AsSeenFromMap(seenFromPrefix: Type, seenFromClass: Symbol) extends TypeMap with KeepOnlyTypeConstraints {
457+
class AsSeenFromMap(seenFromPrefix0: Type, seenFromClass: Symbol) extends TypeMap with KeepOnlyTypeConstraints {
458+
private val seenFromPrefix: Type = if (seenFromPrefix0.typeSymbolDirect.hasPackageFlag && !seenFromClass.hasPackageFlag)
459+
seenFromPrefix0.packageObject.typeOfThis
460+
else seenFromPrefix0
458461
// Some example source constructs relevant in asSeenFrom:
459462
//
460463
// object CaptureThis {

test/files/pos/t9074.scala

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package blam {
2+
3+
package foo {
4+
5+
trait F[T] {
6+
def f(d: Double, t: T): T = ???
7+
def f(d: Int, t: T): T = ???
8+
def f(d: String, t: T): T = ???
9+
10+
def g[A](a: T): T = ???
11+
def g(a: Int) = ???
12+
}
13+
}
14+
15+
package object foo extends foo.F[Double] {
16+
override def f(d: Double, t: Double): Double = ???
17+
}
18+
}
19+
20+
object Test {
21+
import blam._
22+
foo.f("3", 4.0)
23+
foo.g[Any](1d) : Double
24+
}

test/files/pos/t9074b.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
trait Echo [T] {
2+
def echo(t: T): Unit
3+
}
4+
5+
trait IntEcho extends Echo[Int] {
6+
def echo(t: Int) = println(t)
7+
}
8+
9+
object echo extends IntEcho
10+
package object echo1 extends IntEcho
11+
12+
object App extends App {
13+
echo.echo(1)
14+
echo1.echo(1)
15+
}

0 commit comments

Comments
 (0)