diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 69bdf0a89877..2e4d927b11e0 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -1957,7 +1957,7 @@ final class SearchRoot extends SearchHistory { // Substitute dictionary references into dictionary entry RHSs val rhsMap = new TreeTypeMap(treeMap = { case id: Ident if vsymMap.contains(id.symbol) => - tpd.ref(vsymMap(id.symbol)) + tpd.ref(vsymMap(id.symbol))(ctx.withSource(id.source)).withSpan(id.span) case tree => tree }) val nrhss = rhss.map(rhsMap(_)) @@ -1981,7 +1981,7 @@ final class SearchRoot extends SearchHistory { val res = resMap(tree) - val blk = Inliner.reposition(Block(classDef :: inst :: Nil, res), span) + val blk = Block(classDef :: inst :: Nil, res).withSpan(span) success.copy(tree = blk)(success.tstate, success.gstate) } diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index fe21741080cd..9a621f0c0177 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -152,10 +152,15 @@ object Inliner { /** Replace `Inlined` node by a block that contains its bindings and expansion */ def dropInlined(inlined: Inlined)(implicit ctx: Context): Tree = - if (enclosingInlineds.nonEmpty) inlined // Remove in the outer most inlined call - else reposition(inlined, inlined.call.span) + val tree1 = + if inlined.bindings.isEmpty then inlined.expansion + else cpy.Block(inlined)(inlined.bindings, inlined.expansion) + // Reposition in the outer most inlined call + if (enclosingInlineds.nonEmpty) tree1 else reposition(tree1, inlined.span) + + def reposition(tree: Tree, callSpan: Span)(implicit ctx: Context): Tree = { + // Reference test tests/run/i4947b - def reposition(tree: Tree, span: Span)(implicit ctx: Context): Tree = { val curSource = ctx.compilationUnit.source // Tree copier that changes the source of all trees to `curSource` @@ -169,39 +174,30 @@ object Inliner { /** Removes all Inlined trees, replacing them with blocks. * Repositions all trees directly inside an inlined expansion of a non empty call to the position of the call. * Any tree directly inside an empty call (inlined in the inlined code) retains their position. + * + * Until we implement JSR-45, we cannot represent in output positions in other source files. + * So, reposition inlined code from other files with the call position. */ class Reposition extends TreeMap(cpyWithNewSource) { - def finalize(tree: Tree, copied: untpd.Tree) = - copied.withSpan(tree.span).withAttachmentsFrom(tree).withTypeUnchecked(tree.tpe) - - def reposition(tree: Tree)(implicit ctx: Context): Tree = enclosingInlineds match { - case call :: _ if call.symbol.source != curSource => - tree match { - case _: EmptyTree[?] | _: EmptyValDef[?] => tree - case _ => - // Until we implement JSR-45, we cannot represent in output positions in other source files. - // So, reposition inlined code from other files with the call position: - tree.withSpan(span) - } - case _ => tree - } override def transform(tree: Tree)(implicit ctx: Context): Tree = { - val transformed = reposition(tree match { - case tree: Inlined => - tpd.seq(transformSub(tree.bindings), transform(tree.expansion)(inlineContext(tree.call)))(ctx.withSource(curSource)) : Tree - case tree: Ident => finalize(tree, untpd.Ident(tree.name)(curSource)) - case tree: Literal => finalize(tree, untpd.Literal(tree.const)(curSource)) - case tree: This => finalize(tree, untpd.This(tree.qual)(curSource)) - case tree: JavaSeqLiteral => finalize(tree, untpd.JavaSeqLiteral(transform(tree.elems), transform(tree.elemtpt))(curSource)) - case tree: SeqLiteral => finalize(tree, untpd.SeqLiteral(transform(tree.elems), transform(tree.elemtpt))(curSource)) - case tree: TypeTree => tpd.TypeTree(tree.tpe)(ctx.withSource(curSource)).withSpan(tree.span) - case tree: Bind => finalize(tree, untpd.Bind(tree.name, transform(tree.body))(curSource)) + def finalize(copied: untpd.Tree) = + val span = if tree.source == curSource then tree.span else callSpan + copied.withSpan(span).withAttachmentsFrom(tree).withTypeUnchecked(tree.tpe) + + given as Context = ctx.withSource(curSource) + + tree match { + case tree: Ident => finalize(untpd.Ident(tree.name)(curSource)) + case tree: Literal => finalize(untpd.Literal(tree.const)(curSource)) + case tree: This => finalize(untpd.This(tree.qual)(curSource)) + case tree: JavaSeqLiteral => finalize(untpd.JavaSeqLiteral(transform(tree.elems), transform(tree.elemtpt))(curSource)) + case tree: SeqLiteral => finalize(untpd.SeqLiteral(transform(tree.elems), transform(tree.elemtpt))(curSource)) + case tree: Bind => finalize(untpd.Bind(tree.name, transform(tree.body))(curSource)) + case tree: TypeTree => finalize(tpd.TypeTree(tree.tpe)) case tree: DefTree => super.transform(tree).setDefTree case _ => super.transform(tree) - }) - assert(transformed.isInstanceOf[EmptyTree[?]] || transformed.isInstanceOf[EmptyValDef[?]] || transformed.source == curSource) - transformed + } } } diff --git a/library/src/scala/internal/quoted/Matcher.scala b/library/src/scala/internal/quoted/Matcher.scala index b59382f12a82..ea16027cae93 100644 --- a/library/src/scala/internal/quoted/Matcher.scala +++ b/library/src/scala/internal/quoted/Matcher.scala @@ -24,7 +24,7 @@ private[quoted] object Matcher { */ private type Env = Map[Symbol, Symbol] - inline private def withEnv[T](env: Env)(body: => Env ?=> T): T = body(using env) + inline private def withEnv[T](env: Env)(inline body: Env ?=> T): T = body(using env) class SymBinding(val sym: Symbol, val fromAbove: Boolean)