Skip to content

Commit 12eef6d

Browse files
authored
Merge pull request #5899 from dotty-staging/fix-#5844
Fix #5844: Use an approximating type map to substitute parent type params
2 parents 4c3e170 + cf5d20e commit 12eef6d

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

compiler/src/dotty/tools/dotc/core/Substituters.scala

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,4 +195,28 @@ trait Substituters { this: Context =>
195195
final class SubstParamsMap(from: BindingType, to: List[Type]) extends DeepTypeMap {
196196
def apply(tp: Type): Type = substParams(tp, from, to, this)
197197
}
198+
199+
/** An approximating substitution that can handle wildcards in the `to` list */
200+
final class SubstApproxMap(from: List[Symbol], to: List[Type])(implicit ctx: Context) extends ApproximatingTypeMap {
201+
def apply(tp: Type): Type = tp match {
202+
case tp: NamedType =>
203+
val sym = tp.symbol
204+
var fs = from
205+
var ts = to
206+
while (fs.nonEmpty) {
207+
if (fs.head eq sym)
208+
return ts.head match {
209+
case TypeBounds(lo, hi) => range(lo, hi)
210+
case tp1 => tp1
211+
}
212+
fs = fs.tail
213+
ts = ts.tail
214+
}
215+
if (tp.prefix `eq` NoPrefix) tp else derivedSelect(tp, apply(tp.prefix))
216+
case _: ThisType | _: BoundType =>
217+
tp
218+
case _ =>
219+
mapOver(tp)
220+
}
221+
}
198222
}

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1790,7 +1790,7 @@ object SymDenotations {
17901790
case LambdaParam(_, _) :: _ =>
17911791
recur(tp.superType)
17921792
case tparams: List[Symbol @unchecked] =>
1793-
recur(tycon).subst(tparams, args)
1793+
new ctx.SubstApproxMap(tparams, args).apply(recur(tycon))
17941794
}
17951795
record(tp, baseTp)
17961796
baseTp

tests/pos/i5844.scala

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package p1 {
2+
trait A
3+
trait B[X, Y]{
4+
def m(): X
5+
}
6+
trait C[X] extends B[X, X & A]
7+
8+
object O{
9+
def m(c: C[_]) = {
10+
val x = c.m()
11+
}
12+
}
13+
}
14+
package p2 {
15+
trait A
16+
trait B[X]{
17+
def m(): X
18+
}
19+
trait C[X] extends B[X with A]
20+
21+
object O{
22+
def m(c: C[_]) = {
23+
val x: A = c.m()
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)