Skip to content

Commit 7f33bfb

Browse files
committed
Fix #3343: Make baseType work properly with type lambdas
Previously, `C[Char]`.baseType(`Traversable[Char]`) where C := `[X] => List|X]` returned `Traversable[ParamRef(A)]` instead of `Traversable[Char]`, because the substitution was done on the type parameters of the class symbol instead of the type parameters of the type, these are different when type lambdas are involved.
1 parent 28bf5b3 commit 7f33bfb

File tree

3 files changed

+12
-3
lines changed

3 files changed

+12
-3
lines changed

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,9 +1648,7 @@ object SymDenotations {
16481648
if (subsym eq symbol) tp
16491649
else subsym.denot match {
16501650
case clsd: ClassDenotation =>
1651-
val tparams = clsd.typeParams
1652-
if (tparams.hasSameLengthAs(args)) baseTypeOf(tycon).subst(tparams, args)
1653-
else NoType
1651+
baseTypeOf(tycon).substTypeParams(tycon, args)
16541652
case _ =>
16551653
baseTypeOf(tp.superType)
16561654
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,6 +1307,12 @@ object Types {
13071307
final def substParams(from: BindingType, to: List[Type])(implicit ctx: Context): Type =
13081308
ctx.substParams(this, from, to, null)
13091309

1310+
/** Substitute the type parameters of `from` by some other types */
1311+
final def substTypeParams(from: Type, to: List[Type])(implicit ctx: Context): Type = from.typeParams match {
1312+
case LambdaParam(lam, _) :: _ => this.substParams(lam, to)
1313+
case tparams: List[Symbol @unchecked] => this.subst(tparams, to)
1314+
}
1315+
13101316
/** Substitute all occurrences of symbols in `from` by references to corresponding symbols in `to`
13111317
*/
13121318
final def substSym(from: List[Symbol], to: List[Symbol])(implicit ctx: Context): Type =

tests/pos/i3343.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Test {
2+
def foo[C[_]](implicit t: C[Char] => Traversable[Char]): C[Char] = ???
3+
4+
val a: List[Char] = foo
5+
}

0 commit comments

Comments
 (0)