Skip to content

Commit 97c072a

Browse files
authored
Merge pull request #265 from scala/backport-lts-3.3-21744
Backport "Make overload pruning based on result types less aggressive" to 3.3 LTS
2 parents 25ce043 + a1d6be0 commit 97c072a

File tree

6 files changed

+54
-6
lines changed

6 files changed

+54
-6
lines changed

compiler/src/dotty/tools/dotc/core/NamerOps.scala

+5-2
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,11 @@ object NamerOps:
113113
var flags = ApplyProxyFlags | (constr.flagsUNSAFE & AccessFlags)
114114
if cls.is(Protected) && !modcls.is(Protected) then flags |= Protected
115115
newSymbol(
116-
modcls, nme.apply, flags,
117-
ApplyProxyCompleter(constr), coord = constr.coord)
116+
modcls, nme.apply,
117+
flags,
118+
ApplyProxyCompleter(constr),
119+
cls.privateWithin,
120+
constr.coord)
118121
for dcl <- cls.info.decls do
119122
if dcl.isConstructor then scope.enter(proxy(dcl))
120123
scope

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

+15-3
Original file line numberDiff line numberDiff line change
@@ -1949,16 +1949,27 @@ trait Applications extends Compatibility {
19491949
def resolveOverloaded(alts: List[TermRef], pt: Type)(using Context): List[TermRef] =
19501950
record("resolveOverloaded")
19511951

1952-
/** Is `alt` a method or polytype whose result type after the first value parameter
1952+
/** Is `alt` a method or polytype whose approximated result type after the first value parameter
19531953
* section conforms to the expected type `resultType`? If `resultType`
19541954
* is a `IgnoredProto`, pick the underlying type instead.
1955+
*
1956+
* Using an approximated result type is necessary to avoid false negatives
1957+
* due to incomplete type inference such as in tests/pos/i21410.scala and tests/pos/i21410b.scala.
19551958
*/
19561959
def resultConforms(altSym: Symbol, altType: Type, resultType: Type)(using Context): Boolean =
19571960
resultType.revealIgnored match {
19581961
case resultType: ValueType =>
19591962
altType.widen match {
1960-
case tp: PolyType => resultConforms(altSym, instantiateWithTypeVars(tp), resultType)
1961-
case tp: MethodType => constrainResult(altSym, tp.resultType, resultType)
1963+
case tp: PolyType => resultConforms(altSym, tp.resultType, resultType)
1964+
case tp: MethodType =>
1965+
val wildRes = wildApprox(tp.resultType)
1966+
1967+
class ResultApprox extends AvoidWildcardsMap:
1968+
// Avoid false negatives by approximating to a lower bound
1969+
variance = -1
1970+
1971+
val approx = ResultApprox()(wildRes)
1972+
constrainResult(altSym, approx, resultType)
19621973
case _ => true
19631974
}
19641975
case _ => true
@@ -2304,6 +2315,7 @@ trait Applications extends Compatibility {
23042315
if t.exists && alt.symbol.exists then
23052316
val (trimmed, skipped) = trimParamss(t.stripPoly, alt.symbol.rawParamss)
23062317
val mappedSym = alt.symbol.asTerm.copy(info = t)
2318+
mappedSym.annotations = alt.symbol.annotations
23072319
mappedSym.rawParamss = trimmed
23082320
val (pre, totalSkipped) = mappedAltInfo(alt.symbol) match
23092321
case Some((pre, prevSkipped)) =>

tests/pos/i21410.scala

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class A
2+
object Test:
3+
type F[X] <: Any = X match
4+
case A => Int
5+
6+
def foo[T](x: String): T = ???
7+
def foo[U](x: U): F[U] = ???
8+
9+
val x1 = foo(A())
10+
val y: Int = x1
11+
12+
val x2: Int = foo(A()) // error

tests/pos/i21410b.scala

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
object Test:
2+
def foo[T](x: Option[T]): T = ???
3+
def foo[T <: Tuple](x: T): Tuple.Map[T, List] = ???
4+
5+
val tup: (Int, String) = (1, "")
6+
7+
val x = foo(tup)
8+
val y: (List[Int], List[String]) = x
9+
10+
val x2: (List[Int], List[String]) = foo(tup) // error

tests/pos/i21410c.scala

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class AppliedPIso[A, B]()
2+
case class User(age: Int)
3+
4+
object Test:
5+
extension [From, To](from: From)
6+
def focus(): AppliedPIso[From, From] = ???
7+
transparent inline def focus(inline lambda: (From => To)): Any = ???
8+
9+
10+
val u = User(1)
11+
val ap: AppliedPIso[User, User] = u.focus(_.age) // error

tests/pos/i22560b/client_2.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ package companioned:
1414

1515
package p:
1616

17-
def f = internal.P(42)
17+
def f = new internal.P(42)

0 commit comments

Comments
 (0)