diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 66845e343f7f..b49418661261 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -833,12 +833,18 @@ class Typer extends Namer case _: WildcardType => untpd.TypeTree() case _ => untpd.TypeTree(tp) } + def interpolateWildcards = new TypeMap { + def apply(t: Type): Type = t match + case WildcardType(bounds: TypeBounds) => + newTypeVar(apply(bounds.orElse(TypeBounds.empty)).bounds) + case _ => mapOver(t) + } pt.stripTypeVar.dealias match { case pt1 if defn.isNonRefinedFunction(pt1) => // if expected parameter type(s) are wildcards, approximate from below. // if expected result type is a wildcard, approximate from above. // this can type the greatest set of admissible closures. - (pt1.argTypesLo.init, typeTree(pt1.argTypesHi.last)) + (pt1.argTypesLo.init, typeTree(interpolateWildcards(pt1.argTypesHi.last))) case SAMType(sam @ MethodTpe(_, formals, restpe)) => (formals, if (sam.isResultDependent) @@ -1900,7 +1906,6 @@ class Typer extends Namer else tree1 } - def typedAsFunction(tree: untpd.PostfixOp, pt: Type)(implicit ctx: Context): Tree = { val untpd.PostfixOp(qual, Ident(nme.WILDCARD)) = tree val pt1 = if (defn.isFunctionType(pt)) pt else AnyFunctionProto diff --git a/tests/pos/i7392.scala b/tests/pos/i7392.scala new file mode 100644 index 000000000000..579e4422d2f7 --- /dev/null +++ b/tests/pos/i7392.scala @@ -0,0 +1,16 @@ +object Test { + + trait ZStream[-R, +E, +A] + + object ZStream { + def empty: ZStream[Any, Nothing, Nothing] = + ??? + } + + trait Gen[-R, +A](sample: ZStream[R, Nothing, A]) + + def fromIterable[R, A]( + as: Iterable[A], + shrinker: (A => ZStream[R, Nothing, A]) = (_: A) => ZStream.empty + ): Gen[R, A] = ??? +} \ No newline at end of file