diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/KernelImpl.scala b/compiler/src/dotty/tools/dotc/tastyreflect/KernelImpl.scala index 6fe0505f1db0..87d9791322fb 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/KernelImpl.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/KernelImpl.scala @@ -29,6 +29,16 @@ class KernelImpl(val rootContext: core.Contexts.Context, val rootPosition: util. def Context_source(self: Context): java.nio.file.Path = self.compilationUnit.source.file.jpath + // + // REPORTING + // + + def error(msg: => String, pos: Position)(implicit ctx: Context): Unit = + ctx.error(msg, pos) + + def warning(msg: => String, pos: Position)(implicit ctx: Context): Unit = + ctx.warning(msg, pos) + // // Settings // diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index 6105babde61c..8ffaf87d604f 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -441,6 +441,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { case tree: Ident => paramProxy.get(tree.tpe) match { case Some(t) if tree.isTerm && t.isSingleton => + // FIXME wrong span, this is the span inside the inline method singleton(t.dealias).withSpan(tree.span) case Some(t) if tree.isType => TypeTree(t).withSpan(tree.span) diff --git a/library/src/scala/tasty/Reflection.scala b/library/src/scala/tasty/Reflection.scala index d891eea6e73e..6ba6fe08f636 100644 --- a/library/src/scala/tasty/Reflection.scala +++ b/library/src/scala/tasty/Reflection.scala @@ -15,6 +15,7 @@ abstract class Reflection with PatternOps with PositionOps with Printers + with ReportingOps with RootPosition with SettingsOps with SignatureOps diff --git a/library/src/scala/tasty/reflect/Kernel.scala b/library/src/scala/tasty/reflect/Kernel.scala index 4d6a6d031bbf..00a1b5c4f94e 100644 --- a/library/src/scala/tasty/reflect/Kernel.scala +++ b/library/src/scala/tasty/reflect/Kernel.scala @@ -138,6 +138,16 @@ trait Kernel { /** Returns the source file being compiled. The path is relative to the current working directory. */ def Context_source(self: Context): java.nio.file.Path + // + // REPORTING + // + + /** Report a compilation error with the given message at the given position */ + def error(msg: => String, pos: Position)(implicit ctx: Context): Unit + + /** Report a compilation warning with the given message at the given position */ + def warning(msg: => String, pos: Position)(implicit ctx: Context): Unit + // // Settings // diff --git a/library/src/scala/tasty/reflect/ReportingOps.scala b/library/src/scala/tasty/reflect/ReportingOps.scala new file mode 100644 index 000000000000..947991278b7f --- /dev/null +++ b/library/src/scala/tasty/reflect/ReportingOps.scala @@ -0,0 +1,11 @@ +package scala.tasty.reflect + +trait ReportingOps extends Core { + + def error(msg: => String, pos: Position)(implicit ctx: Context): Unit = + kernel.error(msg, pos) + + def warning(msg: => String, pos: Position)(implicit ctx: Context): Unit = + kernel.warning(msg, pos) + +} diff --git a/tests/neg/tasty-macro-error.check b/tests/neg/tasty-macro-error.check new file mode 100644 index 000000000000..bd2bc791e85d --- /dev/null +++ b/tests/neg/tasty-macro-error.check @@ -0,0 +1,16 @@ +[486..500] in quoted_2.scala +here is the the argument is _root_.scala.StringContext.apply(("abc", "": scala.[scala#Predef.String])).s(("def": scala.[scala.Any])) +[453..466] in quoted_2.scala +here is the the argument is ("abc": scala.Predef.String) +[407..408] in quoted_2.scala +here is the the argument is d +[386..387] in quoted_2.scala +here is the the argument is c +[309..323] in quoted_2.scala +here is the the argument is _root_.scala.StringContext.apply(("abc", "": scala.[scala#Predef.String])).s(("def": scala.[scala.Any])) +[277..290] in quoted_2.scala +here is the the argument is ("abc": scala.Predef.String) +[233..234] in quoted_2.scala +here is the the argument is d +[213..214] in quoted_2.scala +here is the the argument is c diff --git a/tests/neg/tasty-macro-error/quoted_1.scala b/tests/neg/tasty-macro-error/quoted_1.scala new file mode 100644 index 000000000000..c51496d72ae7 --- /dev/null +++ b/tests/neg/tasty-macro-error/quoted_1.scala @@ -0,0 +1,25 @@ +import scala.quoted._ + +import scala.tasty._ + +object Macros { + + inline def fun(x: Any): Unit = ${ impl('x) } + + inline def fun2(x: =>Any): Unit = ${ impl('x) } + + inline def fun3[T]: Unit = ${ impl2('[T]) } + + def impl(x: Expr[Any])(implicit reflect: Reflection): Expr[Unit] = { + import reflect._ + error("here is the the argument is " + x.unseal.underlyingArgument.showCode, x.unseal.underlyingArgument.pos) + '{} + } + + def impl2[T](x: quoted.Type[T])(implicit reflect: Reflection): Expr[Unit] = { + import reflect._ + error("here is the the argument is " + x.unseal.showCode, x.unseal.pos) + '{} + } + +} diff --git a/tests/neg/tasty-macro-error/quoted_2.scala b/tests/neg/tasty-macro-error/quoted_2.scala new file mode 100644 index 000000000000..a8bbe3000783 --- /dev/null +++ b/tests/neg/tasty-macro-error/quoted_2.scala @@ -0,0 +1,38 @@ + +import Macros._ + +object Test { + def main(args: Array[String]): Unit = { + val a: String = "abc" + val b: 42 = 42 + def c: String = "abc" + def d: 42 = 42 + +// fun(a) // ERROR +// fun(b) // ERROR + fun(c) // error + fun(d) // error +// fun("abc") // ERROR + fun("abc": String) // error + fun(s"abc${"def"}") // error + +// fun2(a) // ERROR +// fun2(b) // ERROR + fun2(c) // error + fun2(d) // error +// fun2("abc") // ERROR + fun2("abc": String) // error + fun2(s"abc${"def"}") // error + +// type T +// type U = "abc" +// +// fun3[T] // ERROR +// fun3[String] // ERROR +// fun3["abc"] // ERROR +// fun3[U] // ERROR + } +// FIXME all the lines marked as ERROR have the wrong position on the three of the argument. +// they all have as source file this file but the span of `'x` in `fun` or `fun2`. +// see #6026 and #6027 +}