diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index ca2dd9b3c1dd..023617ef42d4 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -65,10 +65,14 @@ object Checking { * cannot handle those. */ def checkAppliedType(tree: AppliedTypeTree, boundsCheck: Boolean)(implicit ctx: Context) = { + def kind(tp: Type): Type = tp match { + case nTp: NamedType => nTp.info + case _ => tp + } val AppliedTypeTree(tycon, args) = tree // If `args` is a list of named arguments, return corresponding type parameters, // otherwise return type parameters unchanged - val tparams = tycon.tpe.typeParams + val tparams = kind(tycon.tpe).typeParams def argNamed(tparam: ParamInfo) = args.find { case NamedArg(name, _) => name == tparam.paramName case _ => false diff --git a/tests/pos/i4884.scala b/tests/pos/i4884.scala new file mode 100644 index 000000000000..8b17dc05e022 --- /dev/null +++ b/tests/pos/i4884.scala @@ -0,0 +1,41 @@ +object Test { + trait A + trait TestConstructor1 { type F[_ <: A] } + trait TestConstructor2[D] { + type F[_ <: D] + class G[X <: D] + trait TestConstructor3[E] { + type G[_ <: D & E] + class H[X <: D & E] + } + } + + val v1: TestConstructor1 => Unit = { f => + type P[a <: A] = f.F[a] // OK + } + + val v2: TestConstructor2[A] => Unit = { f => + type P[a <: A] = f.F[a] // Error! Type argument a does not conform to upper bound D + } + + def f2(f: TestConstructor2[A]): Unit = { + type P[a <: A] = f.F[a] // Error! Type argument a does not conform to upper bound D + } + + // val v3: (f: TestConstructor2[A]) => (g: f.TestConstructor3[A]) => Unit = { f => g => + // type P[a <: A] = f.F[a] // Error! Type argument a does not conform to upper bound D + // // type Q[a <: A] = g.G[a] + // // type R[a <: A] = (f.F & g.G)[a] + // // type R[a <: A] = ([X] => f.F[X] & g.G[X])[a] + // } + def f3(f: TestConstructor2[A], g: f.TestConstructor3[A]): Unit = { + type P[a <: A] = f.F[a] // Error! Type argument a does not conform to upper bound D + type Q[a <: A] = g.G[a] + // type R[a <: A] = (f.F & g.G)[a] // compiler error + type R[a <: A] = ([X <: A] => f.F[X] & g.G[X])[a] + type S[a <: A] = f.G[a] & g.H[a] + } + //val v4: (f: TestConstructor2[A]) => (g: f.TestConstructor3[A]) => Unit = {f => ???} // crash + //val v5: (f: TestConstructor2[A]) => (g: f.TestConstructor3[A]) => Unit = {(f: TestConstructor2[A]) => ???} // crash + //val v6: (f: TestConstructor2[A]) => (g: f.TestConstructor3[A]) => Unit = {(f: TestConstructor2[A]) => (g: f.TestConstructor3[A]) => ???} // crash +}