diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index ab9fa26bac4f..6cbddf296f8d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -1446,9 +1446,7 @@ trait Infer extends Checkable { log(s"Attaching AntiPolyType-carrying overloaded type to $sym") // Multiple alternatives which are within bounds; spin up an // overloaded type which carries an "AntiPolyType" as a prefix. - val tparams = newAsSeenFromMap(pre, hd.owner) mapOver hd.typeParams - val bounds = tparams map (_.tpeHK) // see e.g., #1236 - val tpe = PolyType(tparams, OverloadedType(AntiPolyType(pre, bounds), alts)) + val tpe = typeFunAnonSeenFrom(pre, hd, hd.typeParams, (bounds: List[Type]) => OverloadedType(AntiPolyType(pre, bounds), alts)) finish(sym setInfo tpe, tpe) } matchingLength.alternatives match { diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index adc2362e88a5..009909047c7d 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -2181,7 +2181,9 @@ trait Types // must initialise symbol, see test/files/pos/ticket0137.scala val tpars = initializedTypeParams if (tpars.isEmpty) this - else typeFunAnon(tpars, copyTypeRef(this, pre, sym, tpars map (_.tpeHK))) // todo: also beta-reduce? + else { + typeFunAnonSeenFrom(pre, sym, tpars, bounds => copyTypeRef(this, pre, sym, bounds)) + } // todo: also beta-reduce? } // only need to rebind type aliases, as typeRef already handles abstract types @@ -3610,6 +3612,15 @@ trait Types /** A creator for a type functions, assuming the type parameters tps already have the right owner. */ def typeFun(tps: List[Symbol], body: Type): Type = PolyType(tps, body) + def typeFunAnonSeenFrom(pre: Type, sym: Symbol, tpars: List[Symbol], body: List[Type] => Type): Type = { + val map = newAsSeenFromMap(pre, sym.owner) + val tpars1 = map.mapOver(tpars) + if (tpars eq tpars1) + typeFunAnon(tpars, body(tpars map (_.tpeHK))) + else + typeFunAnon(tpars1, body(tpars map (_.tpeHK.substSym(tpars, tpars1)))) + } + /** A creator for existential types. This generates: * * tpe1 where { tparams } diff --git a/test/files/pos/t4043.scala b/test/files/pos/t4043.scala new file mode 100644 index 000000000000..56f6daa064be --- /dev/null +++ b/test/files/pos/t4043.scala @@ -0,0 +1,13 @@ +object TypeParam { + trait GC[K[_ <: H0], H0] + + trait PA[H1] { + type Apply[A <: H1] = Any + } + + // error: + // kinds of the type arguments ([A <: H1]Any,Int) do not conform to the expected kinds of the type parameters (type K,type H0) in trait GC. + // [A <: H1]Any's type parameters do not match type K's expected parameters: + // type A's bounds >: Nothing <: H1 are stricter than type _'s declared bounds >: Nothing <: H0 + type a = GC[PA[Int]#Apply, Int] +}