Skip to content

Commit 35b05c5

Browse files
committed
Fix #7392: Interpolate all wildcards in the result prototype of a closure
Make sure we interpolate all wildcards in the prototype before making it the result type of an anonymous function. This was done previously only for toplevel wildcards, but not for wildcards nested in some type.
1 parent 754fa51 commit 35b05c5

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -833,12 +833,18 @@ class Typer extends Namer
833833
case _: WildcardType => untpd.TypeTree()
834834
case _ => untpd.TypeTree(tp)
835835
}
836+
def interpolateWildcards = new ApproximatingTypeMap {
837+
def apply(t: Type) = t match
838+
case WildcardType => emptyRange
839+
case WildcardType(bounds: TypeBounds) => range(bounds.lo, bounds.hi)
840+
case _ => mapOver(t)
841+
}
836842
pt.stripTypeVar.dealias match {
837843
case pt1 if defn.isNonRefinedFunction(pt1) =>
838844
// if expected parameter type(s) are wildcards, approximate from below.
839845
// if expected result type is a wildcard, approximate from above.
840846
// this can type the greatest set of admissible closures.
841-
(pt1.argTypesLo.init, typeTree(pt1.argTypesHi.last))
847+
(pt1.argTypesLo.init, typeTree(interpolateWildcards(pt1.argTypesHi.last)))
842848
case SAMType(sam @ MethodTpe(_, formals, restpe)) =>
843849
(formals,
844850
if (sam.isResultDependent)
@@ -1900,7 +1906,6 @@ class Typer extends Namer
19001906
else tree1
19011907
}
19021908

1903-
19041909
def typedAsFunction(tree: untpd.PostfixOp, pt: Type)(implicit ctx: Context): Tree = {
19051910
val untpd.PostfixOp(qual, Ident(nme.WILDCARD)) = tree
19061911
val pt1 = if (defn.isFunctionType(pt)) pt else AnyFunctionProto

tests/pos/i7392.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
object Test {
2+
3+
trait ZStream[-R, +E, +A]
4+
5+
object ZStream {
6+
def empty: ZStream[Any, Nothing, Nothing] =
7+
???
8+
}
9+
10+
trait Gen[-R, +A](sample: ZStream[R, Nothing, A])
11+
12+
def fromIterable[R, A](
13+
as: Iterable[A],
14+
shrinker: (A => ZStream[R, Nothing, A]) = (_: A) => ZStream.empty
15+
): Gen[R, A] = ???
16+
}

0 commit comments

Comments
 (0)