Skip to content

Commit e46d751

Browse files
oderskyWojciechMazur
authored andcommitted
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 #23773 [Cherry-picked 30aa805]
1 parent 144b12f commit e46d751

File tree

6 files changed

+32
-5
lines changed

6 files changed

+32
-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
@@ -1954,6 +1954,11 @@ object Types extends TypeUtils {
19541954
/** If this is a proto type, WildcardType, otherwise the type itself */
19551955
def dropIfProto: Type = this
19561956

1957+
/** If this is a (possibly applied) selection proto type, ignore the
1958+
* selection part
1959+
*/
1960+
def ignoreSelectionProto(using Context): Type = this
1961+
19571962
/** If this is an AndType, the number of factors, 1 for all other types */
19581963
def andFactorCount: Int = 1
19591964

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,12 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
352352
~ "]"
353353
case IgnoredProto(ignored) =>
354354
"?" ~ ("(ignored: " ~ toText(ignored) ~ ")").provided(printDebug)
355-
case tp @ PolyProto(targs, resType) =>
356-
"[applied to [" ~ toTextGlobal(targs, ", ") ~ "] returning " ~ toText(resType)
355+
case tp @ PolyProto(targs, resultType) =>
356+
"[applied to ["
357+
~ toTextGlobal(targs, ", ")
358+
~ "] returning "
359+
~ toText(resultType)
360+
~ "]"
357361
case _ =>
358362
super.toText(tp)
359363
}

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,7 +1422,7 @@ trait Applications extends Compatibility {
14221422
val typedArgs = if (isNamed) typedNamedArgs(tree.args) else tree.args.mapconserve(typedType(_))
14231423
record("typedTypeApply")
14241424

1425-
typedExpr(tree.fun, PolyProto(typedArgs, pt)) match {
1425+
typedExpr(tree.fun, PolyProto(typedArgs, pt.ignoreSelectionProto)) match
14261426
case fun: TypeApply if !ctx.isAfterTyper =>
14271427
val function = fun.fun
14281428
val args = (fun.args ++ tree.args).map(_.show).mkString(", ")
@@ -1446,7 +1446,6 @@ trait Applications extends Compatibility {
14461446
}
14471447
if (typedFn.tpe eq TryDynamicCallType) tryDynamicTypeApply()
14481448
else assignType(cpy.TypeApply(tree)(typedFn, typedArgs), typedFn, typedArgs)
1449-
}
14501449
}
14511450

14521451
/** Rewrite `new Array[T](....)` if T is an unbounded generic to calls to newGenericArray.

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

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

289+
override def ignoreSelectionProto(using Context): IgnoredProto =
290+
IgnoredProto(this)
291+
289292
override def computeHash(bs: Hashable.Binders): Int = {
290293
val delta = (if (compat eq NoViewsAllowed) 1 else 0) | (if (privateOK) 2 else 0)
291294
addDelta(doHash(bs, name, memberProto), delta)
@@ -620,6 +623,9 @@ object ProtoTypes {
620623
override def deepenProtoTrans(using Context): FunProto =
621624
derivedFunProto(args, resultType.deepenProtoTrans, constrainResultDeep = true)
622625

626+
override def ignoreSelectionProto(using Context): FunProto =
627+
derivedFunProto(args, resultType.ignoreSelectionProto)
628+
623629
override def withContext(newCtx: Context): ProtoType =
624630
if newCtx `eq` protoCtx then this
625631
else new FunProto(args, resType)(typer, applyKind, state)(using newCtx)
@@ -734,6 +740,9 @@ object ProtoTypes {
734740

735741
override def deepenProtoTrans(using Context): PolyProto =
736742
derivedPolyProto(targs, resultType.deepenProtoTrans)
743+
744+
override def ignoreSelectionProto(using Context): PolyProto =
745+
derivedPolyProto(targs, resultType.ignoreSelectionProto)
737746
}
738747

739748
/** A prototype for expressions [] that are known to be functions:

tests/run/overloading-specifity-2.scala renamed to tests/neg/overloading-specifity-2.scala

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)