Skip to content

Commit a13d60f

Browse files
authored
Merge pull request #6901 from dotty-staging/fix-chained-ext
Fix #6900: Support chained polymorphic extension methods
2 parents 791bac2 + 35d425d commit a13d60f

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1837,13 +1837,23 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
18371837
* <methodRef>(<receiver>) or
18381838
* <methodRef>[<type-args>](<receiver>)
18391839
*
1840-
* where <type-args> comes from `pt` if it is a PolyProto.
1840+
* where <type-args> comes from `pt` if it is a (possibly ignored) PolyProto.
18411841
*/
18421842
def extMethodApply(methodRef: untpd.Tree, receiver: Tree, pt: Type)(implicit ctx: Context) = {
1843-
val (core, pt1) = pt.revealIgnored match {
1844-
case PolyProto(targs, restpe) => (untpd.TypeApply(methodRef, targs.map(untpd.TypedSplice(_))), restpe)
1845-
case _ => (methodRef, pt)
1843+
/** Integrate the type arguments from `currentPt` into `methodRef`, and produce
1844+
* a matching expected type.
1845+
* If `currentPt` is ignored, the new expected type will be ignored too.
1846+
*/
1847+
def integrateTypeArgs(currentPt: Type, wasIgnored: Boolean = false): (untpd.Tree, Type) = currentPt match {
1848+
case IgnoredProto(ignored) =>
1849+
integrateTypeArgs(ignored, wasIgnored = true)
1850+
case PolyProto(targs, restpe) =>
1851+
val core = untpd.TypeApply(methodRef, targs.map(untpd.TypedSplice(_)))
1852+
(core, if (wasIgnored) IgnoredProto(restpe) else restpe)
1853+
case _ =>
1854+
(methodRef, pt)
18461855
}
1856+
val (core, pt1) = integrateTypeArgs(pt)
18471857
val app =
18481858
typed(untpd.Apply(core, untpd.TypedSplice(receiver) :: Nil), pt1, ctx.typerState.ownedVars)(
18491859
ctx.addMode(Mode.SynthesizeExtMethodReceiver))

tests/pos/i6900.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
object Test {
2+
given bla[A] { def (a: A) foo[C]: C => A = _ => a }
3+
4+
1.foo.foo
5+
1.foo.foo[String]
6+
1.foo[String].foo
7+
1.foo[String].foo[String]
8+
}

0 commit comments

Comments
 (0)