Skip to content

Commit 2710e2b

Browse files
committed
Allow user-defined error diagnostics when rewriting
So far, it's very rudimentary. There's a method `typelevel.error` which produces an error with a constant string argument. To make this more powerful we need a rewriting framework that interpolates strings and can report compiler trees and terms in such strings.
1 parent e881350 commit 2710e2b

File tree

3 files changed

+20
-0
lines changed

3 files changed

+20
-0
lines changed

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

+4
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,10 @@ class Definitions {
218218
lazy val Sys_errorR = SysPackage.moduleClass.requiredMethodRef(nme.error)
219219
def Sys_error(implicit ctx: Context) = Sys_errorR.symbol
220220

221+
lazy val TypelevelPackageObjectRef = ctx.requiredModuleRef("scala.typelevel.package")
222+
lazy val Typelevel_errorR = TypelevelPackageObjectRef.symbol.requiredMethodRef(nme.error)
223+
def Typelevel_error(implicit ctx: Context) = Typelevel_errorR.symbol
224+
221225
/** The `scalaShadowing` package is used to safely modify classes and
222226
* objects in scala so that they can be used from dotty. They will
223227
* be visible as members of the `scala` package, replacing any objects

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

+12
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,16 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
425425
expansion
426426
}
427427

428+
def issueError() = callValueArgss match {
429+
case (msgArg :: Nil) :: Nil =>
430+
msgArg.tpe match {
431+
case ConstantType(Constant(msg: String)) =>
432+
ctx.error(msg, call.pos)
433+
case _ =>
434+
}
435+
case _ =>
436+
}
437+
428438
trace(i"inlining $call", inlining, show = true) {
429439

430440
// The normalized bindings collected in `bindingsBuf`
@@ -444,6 +454,8 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
444454
val (finalBindings, finalExpansion) = dropUnusedDefs(bindingsBuf.toList ++ matchBindings, expansion1)
445455
val (finalMatchBindings, finalArgBindings) = finalBindings.partition(matchBindings.contains(_))
446456

457+
if (inlinedMethod == defn.Typelevel_error) issueError()
458+
447459
// Take care that only argument bindings go into `bindings`, since positions are
448460
// different for bindings from arguments and bindings from body.
449461
tpd.Inlined(call, finalArgBindings, seq(finalMatchBindings, finalExpansion))
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package scala
22

33
package object typelevel {
4+
45
erased def erasedValue[T]: T = ???
6+
57
case class Typed[T](val value: T) { type Type = T }
8+
9+
rewrite def error(transparent msg: String): Nothing = ???
610
}

0 commit comments

Comments
 (0)