Skip to content

Add macro error reporting #6024

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions compiler/src/dotty/tools/dotc/tastyreflect/KernelImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
//
Expand Down
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/typer/Inliner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions library/src/scala/tasty/Reflection.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ abstract class Reflection
with PatternOps
with PositionOps
with Printers
with ReportingOps
with RootPosition
with SettingsOps
with SignatureOps
Expand Down
10 changes: 10 additions & 0 deletions library/src/scala/tasty/reflect/Kernel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
//
Expand Down
11 changes: 11 additions & 0 deletions library/src/scala/tasty/reflect/ReportingOps.scala
Original file line number Diff line number Diff line change
@@ -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)

}
16 changes: 16 additions & 0 deletions tests/neg/tasty-macro-error.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[486..500] in quoted_2.scala
here is the the argument is _root_.scala.StringContext.apply(("abc", "": scala.<repeated>[scala#Predef.String])).s(("def": scala.<repeated>[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.<repeated>[scala#Predef.String])).s(("def": scala.<repeated>[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
25 changes: 25 additions & 0 deletions tests/neg/tasty-macro-error/quoted_1.scala
Original file line number Diff line number Diff line change
@@ -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)
'{}
}

}
38 changes: 38 additions & 0 deletions tests/neg/tasty-macro-error/quoted_2.scala
Original file line number Diff line number Diff line change
@@ -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
}