diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index d73e9b29c492..2d99cf201375 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -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] } } diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala index a6dad7aa6ec3..f35acdfaaafe 100644 --- a/compiler/src/dotty/tools/dotc/ast/Trees.scala +++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala @@ -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 { diff --git a/compiler/src/dotty/tools/dotc/ast/untpd.scala b/compiler/src/dotty/tools/dotc/ast/untpd.scala index eb5ec1872ff5..08f3db4981ff 100644 --- a/compiler/src/dotty/tools/dotc/ast/untpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/untpd.scala @@ -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 diff --git a/tests/pos-custom-args/captures/i19751.scala b/tests/pos-custom-args/captures/i19751.scala new file mode 100644 index 000000000000..b6023cc0ff87 --- /dev/null +++ b/tests/pos-custom-args/captures/i19751.scala @@ -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 +