Skip to content

Commit 3fffa25

Browse files
committed
Intrinsify scala.compiletime.code
1 parent 1180aba commit 3fffa25

File tree

8 files changed

+45
-30
lines changed

8 files changed

+45
-30
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ class Definitions {
224224
@tu lazy val ScalaXmlPackageClass: Symbol = getPackageClassIfDefined("scala.xml")
225225

226226
@tu lazy val CompiletimePackageObject: Symbol = requiredModule("scala.compiletime.package")
227+
@tu lazy val Compiletime_code: Symbol = CompiletimePackageObject.requiredMethod("code")
227228
@tu lazy val Compiletime_erasedValue : Symbol = CompiletimePackageObject.requiredMethod("erasedValue")
228229
@tu lazy val Compiletime_error : Symbol = CompiletimePackageObject.requiredMethod(nme.error)
229230
@tu lazy val Compiletime_requireConst: Symbol = CompiletimePackageObject.requiredMethod("requireConst")

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,28 @@ object Inliner {
332332
def typeCheckErrors(tree: Tree)(using Context): Tree =
333333
val errors = compileForErrors(tree, false)
334334
packErrors(errors)
335+
336+
def code(strCtx: Tree, argsTree: Tree, pos: SrcPos)(using Context): Tree =
337+
object Consts:
338+
def unapply(trees: List[Tree]): Option[List[String]] =
339+
trees match
340+
case Nil => Some(Nil)
341+
case Literal(Constant(part: String)) :: Consts(rest) => Some(part :: rest)
342+
case _ => None
343+
strCtx match
344+
case Apply(stringContextApply, List(Typed(SeqLiteral(Consts(parts), _), _)))
345+
if stringContextApply.symbol == defn.StringContextModule_apply =>
346+
argsTree match
347+
case Typed(SeqLiteral(args, _), _) =>
348+
val argStrs = args.map(_.show)
349+
val showed = StringContext(parts: _*).s(argStrs: _*)
350+
Literal(Constant(showed)).withSpan(pos.span)
351+
case _ =>
352+
report.error("Exprected explicit arguments to code", strCtx.srcPos)
353+
ref(defn.Predef_undefined)
354+
case _ =>
355+
report.error("Exprected StringContext.apply with explicit `parts` arguments", strCtx.srcPos)
356+
ref(defn.Predef_undefined)
335357
}
336358
}
337359

@@ -622,6 +644,8 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
622644
arg match
623645
case ConstantValue(_) | Inlined(_, Nil, Typed(ConstantValue(_), _)) => // ok
624646
case _ => report.error(em"expected a constant value but found: $arg", arg.srcPos)
647+
case (strCtx :: Nil) :: (args :: Nil) :: Nil if inlinedMethod == defn.Compiletime_code =>
648+
return Intrinsics.code(strCtx, args, call.srcPos)
625649
case _ =>
626650

627651
// Special handling of `constValue[T]` and `constValueOpt[T]`

library/src-bootstrapped/dotty/internal/CompileTimeMacros.scala

Lines changed: 0 additions & 11 deletions
This file was deleted.

library/src-non-bootstrapped/dotty/internal/CompileTimeMacros.scala

Lines changed: 0 additions & 7 deletions
This file was deleted.

library/src/scala/compiletime/package.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ package object compiletime {
3535
/** Returns the string representation of interpolated elaborated code:
3636
*
3737
* ```scala
38-
* inline def logged(p1: => Any) = {
38+
* inline def logged(inline p1: Any) = {
3939
* val c = code"code: $p1"
4040
* val res = p1
4141
* (c, p1)
@@ -45,11 +45,13 @@ package object compiletime {
4545
* // ("code: scala.Predef.identity("foo")", identity("foo"))
4646
* ```
4747
*
48-
* @note only by-name arguments will be displayed as "code".
48+
* The formatting of the code is not stable across version of the compiler.
49+
*
50+
* @note only `inline` arguments will be displayed as "code".
4951
* Other values may display unintutively.
5052
*/
51-
transparent inline def code (inline args: Any*): String =
52-
${ dotty.internal.CompileTimeMacros.codeExpr('self, 'args) }
53+
transparent inline def code (inline args: Any*): String = ???
54+
5355
end extension
5456

5557
/** Checks at compiletime that the provided values is a constant after

tests/run-macros/beta-reduce-inline-result.check

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
compile-time: (4: scala.Int)
1+
compile-time: 4:Int
22
run-time: 4
3-
compile-time: (1: scala.Int)
3+
compile-time: 1:Int
44
run-time: 1
55
run-time: 5
66
run-time: 7

tests/run-macros/i6622.check

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
abc println(34) ...
2+
abc println(34)
3+
println(34) ...
4+
println(34)
5+
...
6+

tests/run-macros/i6622.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import scala.compiletime._
33
object Test {
44

55
def main(args: Array[String]): Unit = {
6-
assert(code"abc ${println(34)} ..." == "abc scala.Predef.println(34) ...")
7-
assert(code"abc ${println(34)}" == "abc scala.Predef.println(34)")
8-
assert(code"${println(34)} ..." == "scala.Predef.println(34) ...")
9-
assert(code"${println(34)}" == "scala.Predef.println(34)")
10-
assert(code"..." == "...")
11-
assert(testConstant(code"") == "")
6+
println(code"abc ${println(34)} ...")
7+
println(code"abc ${println(34)}")
8+
println(code"${println(34)} ...")
9+
println(code"${println(34)}")
10+
println(code"...")
11+
println(testConstant(code""))
1212
}
1313

1414
inline def testConstant(inline msg: String): String = msg

0 commit comments

Comments
 (0)