Skip to content

Commit 0ddafa7

Browse files
authored
Merge pull request #8436 from dotty-staging/fix-#6745
Fix #6745: Fix handling of `this` in dependent function types
2 parents bb52aa8 + dee65e2 commit 0ddafa7

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -951,11 +951,19 @@ class Typer extends Namer
951951
isContextual = funFlags.is(Given), isErased = funFlags.is(Erased))
952952

953953
/** Typechecks dependent function type with given parameters `params` */
954-
def typedDependent(params: List[ValDef])(implicit ctx: Context): Tree =
954+
def typedDependent(params: List[untpd.ValDef])(implicit ctx: Context): Tree =
955+
val fixThis = new untpd.UntypedTreeMap:
956+
// pretype all references of this in outer context,
957+
// so that they do not refer to the refined type being constructed
958+
override def transform(tree: untpd.Tree)(using Context): untpd.Tree = tree match
959+
case This(id) => untpd.TypedSplice(typedExpr(tree)(using ctx.outer))
960+
case _ => super.transform(tree)
961+
955962
val params1 =
956963
if funFlags.is(Given) then params.map(_.withAddedFlags(Given))
957964
else params
958-
val appDef0 = untpd.DefDef(nme.apply, Nil, List(params1), body, EmptyTree).withSpan(tree.span)
965+
val params2 = params1.map(fixThis.transformSub)
966+
val appDef0 = untpd.DefDef(nme.apply, Nil, List(params2), body, EmptyTree).withSpan(tree.span)
959967
index(appDef0 :: Nil)
960968
val appDef = typed(appDef0).asInstanceOf[DefDef]
961969
val mt = appDef.symbol.info.asInstanceOf[MethodType]
@@ -966,10 +974,11 @@ class Typer extends Namer
966974
val tycon = TypeTree(funCls.typeRef)
967975
val core = AppliedTypeTree(tycon, typeArgs)
968976
RefinedTypeTree(core, List(appDef), ctx.owner.asClass)
977+
end typedDependent
969978

970979
args match {
971980
case ValDef(_, _, _) :: _ =>
972-
typedDependent(args.asInstanceOf[List[ValDef]])(
981+
typedDependent(args.asInstanceOf[List[untpd.ValDef]])(
973982
ctx.fresh.setOwner(ctx.newRefinedClassSymbol(tree.span)).setNewScope)
974983
case _ =>
975984
typed(cpy.AppliedTypeTree(tree)(untpd.TypeTree(funCls.typeRef), args :+ body), pt)

tests/pos/i6745.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
trait Foo { self =>
2+
type M
3+
def apply(prog: (h: this.type) => h.M): M = prog(this)
4+
}

0 commit comments

Comments
 (0)