From 678d4b1991f1f3d18a96d6052afea05661f87c2e Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Tue, 17 Oct 2017 21:42:42 +0200 Subject: [PATCH] Fix #3343: Make baseType work properly with type lambdas Previously, `C[Char]`.baseTypeOf(`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. This is fixed by always going through `AppliedType#superType` when the tycon is not a class. --- .../src/dotty/tools/dotc/core/SymDenotations.scala | 10 ++++------ tests/pos/i3343.scala | 5 +++++ 2 files changed, 9 insertions(+), 6 deletions(-) create mode 100644 tests/pos/i3343.scala diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index 2c3d2f9259a4..145913261053 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1646,13 +1646,11 @@ object SymDenotations { case tp @ AppliedType(tycon, args) => val subsym = tycon.typeSymbol if (subsym eq symbol) tp - else subsym.denot match { - case clsd: ClassDenotation => - val tparams = clsd.typeParams - if (tparams.hasSameLengthAs(args)) baseTypeOf(tycon).subst(tparams, args) - else NoType - case _ => + else tycon.typeParams match { + case LambdaParam(_, _) :: _ => baseTypeOf(tp.superType) + case tparams: List[Symbol @unchecked] => + baseTypeOf(tycon).subst(tparams, args) } case tp: TypeProxy => baseTypeOf(tp.superType) diff --git a/tests/pos/i3343.scala b/tests/pos/i3343.scala new file mode 100644 index 000000000000..15f1d88922ef --- /dev/null +++ b/tests/pos/i3343.scala @@ -0,0 +1,5 @@ +object Test { + def foo[C[_]](implicit t: C[Char] => Traversable[Char]): C[Char] = ??? + + val a: List[Char] = foo +}