diff --git a/compiler/src/dotty/tools/dotc/core/NamerOps.scala b/compiler/src/dotty/tools/dotc/core/NamerOps.scala index 2fffa1fed1e5..82ebb03b9662 100644 --- a/compiler/src/dotty/tools/dotc/core/NamerOps.scala +++ b/compiler/src/dotty/tools/dotc/core/NamerOps.scala @@ -113,8 +113,11 @@ object NamerOps: var flags = ApplyProxyFlags | (constr.flagsUNSAFE & AccessFlags) if cls.is(Protected) && !modcls.is(Protected) then flags |= Protected newSymbol( - modcls, nme.apply, flags, - ApplyProxyCompleter(constr), coord = constr.coord) + modcls, nme.apply, + flags, + ApplyProxyCompleter(constr), + cls.privateWithin, + constr.coord) for dcl <- cls.info.decls do if dcl.isConstructor then scope.enter(proxy(dcl)) scope diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 5254ec3712c1..8947a2941cc0 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -1949,16 +1949,27 @@ 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 an approximated result type is necessary to avoid false negatives + * due to incomplete type inference such as in tests/pos/i21410.scala and tests/pos/i21410b.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 => + val wildRes = wildApprox(tp.resultType) + + class ResultApprox extends AvoidWildcardsMap: + // Avoid false negatives by approximating to a lower bound + variance = -1 + + val approx = ResultApprox()(wildRes) + constrainResult(altSym, approx, resultType) case _ => true } case _ => true @@ -2304,6 +2315,7 @@ trait Applications extends Compatibility { if t.exists && alt.symbol.exists then val (trimmed, skipped) = trimParamss(t.stripPoly, alt.symbol.rawParamss) val mappedSym = alt.symbol.asTerm.copy(info = t) + mappedSym.annotations = alt.symbol.annotations mappedSym.rawParamss = trimmed val (pre, totalSkipped) = mappedAltInfo(alt.symbol) match case Some((pre, prevSkipped)) => 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 diff --git a/tests/pos/i21410c.scala b/tests/pos/i21410c.scala new file mode 100644 index 000000000000..21f69fec20fa --- /dev/null +++ b/tests/pos/i21410c.scala @@ -0,0 +1,11 @@ +class AppliedPIso[A, B]() +case class User(age: Int) + +object Test: + extension [From, To](from: From) + def focus(): AppliedPIso[From, From] = ??? + transparent inline def focus(inline lambda: (From => To)): Any = ??? + + + val u = User(1) + val ap: AppliedPIso[User, User] = u.focus(_.age) // error diff --git a/tests/pos/i22560b/client_2.scala b/tests/pos/i22560b/client_2.scala index bb57276c12c6..5376bcfa03cd 100644 --- a/tests/pos/i22560b/client_2.scala +++ b/tests/pos/i22560b/client_2.scala @@ -14,4 +14,4 @@ package companioned: package p: - def f = internal.P(42) + def f = new internal.P(42)