diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 17be2acc7378..de9caf05b550 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -2076,16 +2076,20 @@ trait Applications extends Compatibility { def resolveOverloaded(alts: List[TermRef], pt: Type)(using Context): List[TermRef] = record("resolveOverloaded") - /** Is `alt` a method or polytype whose result type after the first value parameter + /** Is `alt` a method or polytype whose approximated result type after the first value parameter * section conforms to the expected type `resultType`? If `resultType` * is a `IgnoredProto`, pick the underlying type instead. + * + * Using approximated result types is necessary to avoid false negatives + * due to incomplete type inference such as in tests/pos/i21410.scala. */ def resultConforms(altSym: Symbol, altType: Type, resultType: Type)(using Context): Boolean = resultType.revealIgnored match { case resultType: ValueType => altType.widen match { - case tp: PolyType => resultConforms(altSym, instantiateWithTypeVars(tp), resultType) - case tp: MethodType => constrainResult(altSym, tp.resultType, resultType) + case tp: PolyType => resultConforms(altSym, tp.resultType, resultType) + case tp: MethodType => + constrainResult(altSym, wildApprox(tp.resultType), resultType) case _ => true } case _ => true diff --git a/tests/pos/i21410.scala b/tests/pos/i21410.scala new file mode 100644 index 000000000000..c3ba3ea862bc --- /dev/null +++ b/tests/pos/i21410.scala @@ -0,0 +1,12 @@ +class A +object Test: + type F[X] <: Any = X match + case A => Int + + def foo[T](x: String): T = ??? + def foo[U](x: U): F[U] = ??? + + val x1 = foo(A()) + val y: Int = x1 + + val x2: Int = foo(A()) // error diff --git a/tests/pos/i21410b.scala b/tests/pos/i21410b.scala new file mode 100644 index 000000000000..a17ad59bc59e --- /dev/null +++ b/tests/pos/i21410b.scala @@ -0,0 +1,10 @@ +object Test: + def foo[T](x: Option[T]): T = ??? + def foo[T <: Tuple](x: T): Tuple.Map[T, List] = ??? + + val tup: (Int, String) = (1, "") + + val x = foo(tup) + val y: (List[Int], List[String]) = x + + val x2: (List[Int], List[String]) = foo(tup) // error