diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 5329c29ce0b3..511219a4f2df 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -2086,20 +2086,23 @@ trait Applications extends Compatibility { * where comes from `pt` if it is a (possibly ignored) PolyProto. */ def extMethodApply(methodRef: untpd.Tree, receiver: Tree, pt: Type)(using Context): Tree = { - /** Integrate the type arguments from `currentPt` into `methodRef`, and produce - * a matching expected type. - * If `currentPt` is ignored, the new expected type will be ignored too. + /** Integrate the type arguments (if any) from `currentPt` into `tree`, and produce + * an expected type that hides the appropriate amount of information through IgnoreProto. */ - def integrateTypeArgs(currentPt: Type, wasIgnored: Boolean = false): (untpd.Tree, Type) = currentPt match { - case IgnoredProto(ignored) => - integrateTypeArgs(ignored, wasIgnored = true) + def normalizePt(tree: untpd.Tree, currentPt: Type): (untpd.Tree, Type) = currentPt match + // Always reveal expected arguments to guide inference (needed for i9509.scala) + case IgnoredProto(ignored: FunOrPolyProto) => + normalizePt(tree, ignored) + // Always hide expected member to allow for chained extensions (needed for i6900.scala) + case _: SelectionProto => + (tree, IgnoredProto(currentPt)) case PolyProto(targs, restpe) => - val core = untpd.TypeApply(methodRef, targs.map(untpd.TypedSplice(_))) - (core, if (wasIgnored) IgnoredProto(restpe) else restpe) + val tree1 = untpd.TypeApply(tree, targs.map(untpd.TypedSplice(_))) + normalizePt(tree1, restpe) case _ => - (methodRef, pt) - } - val (core, pt1) = integrateTypeArgs(pt) + (tree, currentPt) + + val (core, pt1) = normalizePt(methodRef, pt) val app = withMode(Mode.SynthesizeExtMethodReceiver) { typed(untpd.Apply(core, untpd.TypedSplice(receiver) :: Nil), pt1, ctx.typerState.ownedVars) } diff --git a/tests/pos/i9509.scala b/tests/pos/i9509.scala new file mode 100644 index 000000000000..e713242244b6 --- /dev/null +++ b/tests/pos/i9509.scala @@ -0,0 +1,11 @@ +enum AList[+A] { + case Cons[X](head: X, tail: AList[X]) extends AList[X] + case Nil +} + +object AList { + extension [A](l: AList[A]) def sum(using numeric: Numeric[A]): A = l match { + case Cons(x, xs) => numeric.plus(x, xs.sum(using numeric)) + case Nil => numeric.zero + } +}