Skip to content

Commit 826ffb3

Browse files
committed
extMethodApply: refactor prototype handling
Previously, both `normPt` and `integrateTypeArgs` could tweak the expected type, this commit merges them together in one `normalizePt` method which should be slightly more general. Also updated i9509 to make the invariance of the leaf case explicit (since we might change the desugaring of enums to preserve the parent variance by default).
1 parent 234e59c commit 826ffb3

File tree

2 files changed

+16
-20
lines changed

2 files changed

+16
-20
lines changed

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

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2086,27 +2086,23 @@ trait Applications extends Compatibility {
20862086
* where <type-args> comes from `pt` if it is a (possibly ignored) PolyProto.
20872087
*/
20882088
def extMethodApply(methodRef: untpd.Tree, receiver: Tree, pt: Type)(using Context): Tree = {
2089-
// (1) always reveal further arguments in extension method applications,
2090-
// (2) but do not reveal anything else in a prototype.
2091-
// (1) is needed for i9509.scala (2) is needed for i6900.scala
2092-
val normPt = pt match
2093-
case IgnoredProto(ignored: FunProto) => ignored
2094-
case _ => pt
2095-
2096-
/** Integrate the type arguments from `currentPt` into `methodRef`, and produce
2097-
* a matching expected type.
2098-
* If `currentPt` is ignored, the new expected type will be ignored too.
2089+
/** Integrate the type arguments (if any) from `currentPt` into `tree`, and produce
2090+
* an expected type that hides the appropriate amount of information through IgnoreProto.
20992091
*/
2100-
def integrateTypeArgs(currentPt: Type, wasIgnored: Boolean = false): (untpd.Tree, Type) = currentPt match {
2101-
case IgnoredProto(ignored) =>
2102-
integrateTypeArgs(ignored, wasIgnored = true)
2092+
def normalizePt(tree: untpd.Tree, currentPt: Type): (untpd.Tree, Type) = currentPt match
2093+
// Always reveal expected arguments to guide inference (needed for i9509.scala)
2094+
case IgnoredProto(ignored: FunOrPolyProto) =>
2095+
normalizePt(tree, ignored)
2096+
// Always hide expected member to allow for chained extensions (needed for i6900.scala)
2097+
case _: SelectionProto =>
2098+
(tree, IgnoredProto(currentPt))
21032099
case PolyProto(targs, restpe) =>
2104-
val core = untpd.TypeApply(methodRef, targs.map(untpd.TypedSplice(_)))
2105-
(core, if (wasIgnored) IgnoredProto(restpe) else restpe)
2100+
val tree1 = untpd.TypeApply(tree, targs.map(untpd.TypedSplice(_)))
2101+
normalizePt(tree1, restpe)
21062102
case _ =>
2107-
(methodRef, normPt)
2108-
}
2109-
val (core, pt1) = integrateTypeArgs(normPt)
2103+
(tree, currentPt)
2104+
2105+
val (core, pt1) = normalizePt(methodRef, pt)
21102106
val app = withMode(Mode.SynthesizeExtMethodReceiver) {
21112107
typed(untpd.Apply(core, untpd.TypedSplice(receiver) :: Nil), pt1, ctx.typerState.ownedVars)
21122108
}

tests/pos/i9509.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
enum AList[+A] {
2-
case Cons(head: A, tail: AList[A])
2+
case Cons[X](head: X, tail: AList[X]) extends AList[X]
33
case Nil
44
}
55

@@ -8,4 +8,4 @@ object AList {
88
case Cons(x, xs) => numeric.plus(x, xs.sum(using numeric))
99
case Nil => numeric.zero
1010
}
11-
}
11+
}

0 commit comments

Comments
 (0)