@@ -472,7 +472,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
472472 val expansion = inliner.transform(rhsToInline)
473473
474474 def issueError () = callValueArgss match {
475- case (msgArg :: rest ) :: Nil =>
475+ case (msgArg :: Nil ) :: Nil =>
476476 msgArg.tpe match {
477477 case ConstantType (Constant (msg : String )) =>
478478 // Usually `error` is called from within a rewrite method. In this
@@ -482,23 +482,49 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
482482 val callToReport = if (enclosingInlineds.nonEmpty) enclosingInlineds.last else call
483483 val ctxToReport = ctx.outersIterator.dropWhile(enclosingInlineds(_).nonEmpty).next
484484 def issueInCtx (implicit ctx : Context ) = {
485- def decompose (arg : Tree ): String = arg match {
486- case Typed (arg, _) => decompose(arg)
487- case SeqLiteral (elems, _) => elems.map(decompose).mkString(" , " )
488- case arg =>
489- arg.tpe.widenTermRefExpr match {
490- case ConstantType (Constant (c)) => c.toString
491- case _ => arg.show
492- }
493- }
494- ctx.error(s " $msg${rest.map(decompose).mkString(" , " )}" , callToReport.sourcePos)
485+ ctx.error(msg, callToReport.sourcePos)
495486 }
496487 issueInCtx(ctxToReport)
497488 case _ =>
498489 }
499490 case _ =>
500491 }
501492
493+ def issueCode ()(implicit ctx : Context ): Literal = {
494+ def decompose (arg : Tree ): String = arg match {
495+ case Typed (arg, _) => decompose(arg)
496+ case SeqLiteral (elems, _) => elems.map(decompose).mkString(" , " )
497+ case Block (Nil , expr) => decompose(expr)
498+ case Inlined (_, Nil , expr) => decompose(expr)
499+ case arg =>
500+ arg.tpe.widenTermRefExpr match {
501+ case ConstantType (Constant (c)) => c.toString
502+ case _ => arg.show
503+ }
504+ }
505+
506+ def malformedString (): String = {
507+ ctx.error(" Malformed part `code` string interpolator" , call.sourcePos)
508+ " "
509+ }
510+
511+ callValueArgss match {
512+ case List (List (Apply (_,List (Typed (SeqLiteral (Literal (headConst) :: parts,_),_)))), List (Typed (SeqLiteral (interpolatedParts,_),_)))
513+ if parts.size == interpolatedParts.size =>
514+ val constantParts = parts.map {
515+ case Literal (const) => const.stringValue
516+ case _ => malformedString()
517+ }
518+ val decomposedInterpolations = interpolatedParts.map(decompose)
519+ val constantString = decomposedInterpolations.zip(constantParts)
520+ .foldLeft(headConst.stringValue) { case (acc, (p1, p2)) => acc + p1 + p2 }
521+
522+ Literal (Constant (constantString)).withSpan(call.span)
523+ case _ =>
524+ Literal (Constant (malformedString()))
525+ }
526+ }
527+
502528 trace(i " inlining $call" , inlining, show = true ) {
503529
504530 // The normalized bindings collected in `bindingsBuf`
@@ -522,9 +548,13 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
522548
523549 if (inlinedMethod == defn.Compiletime_error ) issueError()
524550
525- // Take care that only argument bindings go into `bindings`, since positions are
526- // different for bindings from arguments and bindings from body.
527- tpd.Inlined (call, finalBindings, finalExpansion)
551+ if (inlinedMethod == defn.Compiletime_code ) {
552+ issueCode()(ctx.fresh.setSetting(ctx.settings.color, " never" ))
553+ } else {
554+ // Take care that only argument bindings go into `bindings`, since positions are
555+ // different for bindings from arguments and bindings from body.
556+ tpd.Inlined (call, finalBindings, finalExpansion)
557+ }
528558 }
529559 }
530560
0 commit comments