Skip to content

Commit a1c1f74

Browse files
committed
Ignore selection prototypes when typing type applications
Ignore selection prototypes at first when typing type applications. If we need them later for overloading disambiguation, reveal the ignored type. The reason for doing this is that a selection might come from an extension method, and in this case we should not require the selected name as a member of the result. This change breaks one test (overloading-specifity-2.scala) that explicitly tested that we don't consult implicit arguments for disambiguation since the expected type was a selection that already determined the outcome. This is logic no longer holds. We have to see whether this change breaks any code in practice. Fixes scala#23773 [Cherry-picked 30aa805][modified]
1 parent 6b2f766 commit a1c1f74

File tree

6 files changed

+33
-5
lines changed

6 files changed

+33
-5
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,6 +1859,11 @@ object Types extends TypeUtils {
18591859
/** If this is a proto type, WildcardType, otherwise the type itself */
18601860
def dropIfProto: Type = this
18611861

1862+
/** If this is a (possibly applied) selection proto type, ignore the
1863+
* selection part
1864+
*/
1865+
def ignoreSelectionProto(using Context): Type = this
1866+
18621867
/** If this is an AndType, the number of factors, 1 for all other types */
18631868
def andFactorCount: Int = 1
18641869

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -306,9 +306,13 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
306306
~ toText(resultType)
307307
~ "]"
308308
case IgnoredProto(ignored) =>
309-
"?" ~ (("(ignored: " ~ toText(ignored) ~ ")") provided printDebug)
310-
case tp @ PolyProto(targs, resType) =>
311-
"[applied to [" ~ toTextGlobal(targs, ", ") ~ "] returning " ~ toText(resType)
309+
"?" ~ ("(ignored: " ~ toText(ignored) ~ ")").provided(printDebug)
310+
case tp @ PolyProto(targs, resultType) =>
311+
"[applied to ["
312+
~ toTextGlobal(targs, ", ")
313+
~ "] returning "
314+
~ toText(resultType)
315+
~ "]"
312316
case _ =>
313317
super.toText(tp)
314318
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1248,7 +1248,7 @@ trait Applications extends Compatibility {
12481248
val isNamed = hasNamedArg(tree.args)
12491249
val typedArgs = if (isNamed) typedNamedArgs(tree.args) else tree.args.mapconserve(typedType(_))
12501250
record("typedTypeApply")
1251-
typedExpr(tree.fun, PolyProto(typedArgs, pt)) match {
1251+
typedExpr(tree.fun, PolyProto(typedArgs, pt.ignoreSelectionProto)) match {
12521252
case fun: TypeApply if !ctx.isAfterTyper =>
12531253
val function = fun.fun
12541254
val args = (fun.args ++ tree.args).map(_.show).mkString(", ")

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,9 @@ object ProtoTypes {
252252
override def deepenProtoTrans(using Context): SelectionProto =
253253
derivedSelectionProto(name, memberProto.deepenProtoTrans, compat, nameSpan)
254254

255+
override def ignoreSelectionProto(using Context): IgnoredProto =
256+
IgnoredProto(this)
257+
255258
override def computeHash(bs: Hashable.Binders): Int = {
256259
val delta = (if (compat eq NoViewsAllowed) 1 else 0) | (if (privateOK) 2 else 0)
257260
addDelta(doHash(bs, name, memberProto), delta)
@@ -584,6 +587,9 @@ object ProtoTypes {
584587
override def deepenProtoTrans(using Context): FunProto =
585588
derivedFunProto(args, resultType.deepenProtoTrans, constrainResultDeep = true)
586589

590+
override def ignoreSelectionProto(using Context): FunProto =
591+
derivedFunProto(args, resultType.ignoreSelectionProto)
592+
587593
override def withContext(newCtx: Context): ProtoType =
588594
if newCtx `eq` protoCtx then this
589595
else new FunProto(args, resType)(typer, applyKind, state)(using newCtx)
@@ -694,6 +700,9 @@ object ProtoTypes {
694700

695701
override def deepenProtoTrans(using Context): PolyProto =
696702
derivedPolyProto(targs, resultType.deepenProtoTrans)
703+
704+
override def ignoreSelectionProto(using Context): PolyProto =
705+
derivedPolyProto(targs, resultType.ignoreSelectionProto)
697706
}
698707

699708
/** A prototype for expressions [] that are known to be functions:
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@ object Test extends App {
2323
def foo[T]: Show[T] = new Show[T](2)
2424
}
2525

26-
assert(a.foo[Int].i == 1) // error: no implicit argument of type Test.Context was found for parameter ctx
26+
assert(a.foo[Int].i == 1) // error: no implicit argument of type Test.Context was found for parameter ctx, was OK
2727
}

tests/pos/i23773.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
trait Foo[T]
2+
3+
def foo[A]: Int = ???
4+
def foo[A: Foo]: Int = ???
5+
6+
extension (x: Int)
7+
def succ: Int = x + 1
8+
9+
val a = foo[Int]
10+
val b = foo[Int].succ // error

0 commit comments

Comments
 (0)