Skip to content

Commit

Permalink
Fix Function tree copier (#19822)
Browse files Browse the repository at this point in the history
It did not copy correctly instances of the FunctionWithMods subclass.

Fixes #19751
  • Loading branch information
odersky authored Feb 29, 2024
2 parents 1191671 + cd68604 commit 6e8b355
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 9 deletions.
5 changes: 1 addition & 4 deletions compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1967,10 +1967,7 @@ object desugar {
val applyVParams = args.zipWithIndex.map {
case (p, n) => makeSyntheticParameter(n + 1, p)
}
tree match
case tree: FunctionWithMods =>
untpd.FunctionWithMods(applyVParams, result, tree.mods, tree.erasedParams)
case _ => untpd.Function(applyVParams, result)
cpy.Function(tree)(applyVParams, result).asInstanceOf[untpd.Function]
}
}

Expand Down
9 changes: 5 additions & 4 deletions compiler/src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1255,11 +1255,12 @@ object Trees {
case _ => finalize(tree, untpd.Ident(name)(sourceFile(tree)))
}
def Select(tree: Tree)(qualifier: Tree, name: Name)(using Context): Select = tree match {
case tree: SelectWithSig =>
if ((qualifier eq tree.qualifier) && (name == tree.name)) tree
else finalize(tree, SelectWithSig(qualifier, name, tree.sig)(sourceFile(tree)))
case tree: Select if (qualifier eq tree.qualifier) && (name == tree.name) => tree
case _ => finalize(tree, untpd.Select(qualifier, name)(sourceFile(tree)))
case _ =>
val tree1 = tree match
case tree: SelectWithSig => untpd.SelectWithSig(qualifier, name, tree.sig)(using sourceFile(tree))
case _ => untpd.Select(qualifier, name)(using sourceFile(tree))
finalize(tree, tree1)
}
/** Copy Ident or Select trees */
def Ref(tree: RefTree)(name: Name)(using Context): RefTree = tree match {
Expand Down
6 changes: 5 additions & 1 deletion compiler/src/dotty/tools/dotc/ast/untpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,11 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
}
def Function(tree: Tree)(args: List[Tree], body: Tree)(using Context): Tree = tree match {
case tree: Function if (args eq tree.args) && (body eq tree.body) => tree
case _ => finalize(tree, untpd.Function(args, body)(tree.source))
case _ =>
val tree1 = tree match
case tree: FunctionWithMods => untpd.FunctionWithMods(args, body, tree.mods, tree.erasedParams)(using tree.source)
case _ => untpd.Function(args, body)(using tree.source)
finalize(tree, tree1)
}
def PolyFunction(tree: Tree)(targs: List[Tree], body: Tree)(using Context): Tree = tree match {
case tree: PolyFunction if (targs eq tree.targs) && (body eq tree.body) => tree
Expand Down
22 changes: 22 additions & 0 deletions tests/pos-custom-args/captures/i19751.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import language.experimental.captureChecking
import annotation.capability
import caps.cap

trait Ptr[A]
@capability trait Scope:
def allocate(size: Int): Ptr[Unit]^{this}


object Scope:
def confined[A](fn: Scope ?->{cap} A): A =
val scope = new Scope:
def allocate(size: Int) = new Ptr[Unit] {}
fn(using scope)

def Test: Unit =
val s = Scope.confined:
val s2 = summon[Scope]
Scope.confined:
s2.allocate(5)
5

0 comments on commit 6e8b355

Please sign in to comment.