summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-04-25 06:43:45 -0700
committerPaul Phillips <paulp@improving.org>2012-04-25 06:43:45 -0700
commitedc7071d3b284fcf82bd17c7a1cf83f23e32788f (patch)
tree848344b1cfca8015a125723960691b60732ba30e
parentbf621aa912ec76ba5794280b88f62d0861aa530d (diff)
downloadscala-edc7071d3b284fcf82bd17c7a1cf83f23e32788f.tar.gz
scala-edc7071d3b284fcf82bd17c7a1cf83f23e32788f.tar.bz2
scala-edc7071d3b284fcf82bd17c7a1cf83f23e32788f.zip
Fix reifier crashing repl.
Very first time I tried "reify" in the repl and it crashed. I changed an assert to issue a proper error, as best I could figure out how. We probably need to do a lot more of this.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala34
-rw-r--r--test/files/run/reify-repl-fail-gracefully.check21
-rw-r--r--test/files/run/reify-repl-fail-gracefully.scala10
4 files changed, 54 insertions, 16 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index c13be0e39d..2d1369b11d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -343,6 +343,11 @@ trait ContextErrors {
issueNormalTypeError(tree, "macros cannot be eta-expanded")
setError(tree)
}
+
+ def MacroPartialApplicationError(tree: Tree) = {
+ issueNormalTypeError(tree, "macros cannot be partially applied")
+ setError(tree)
+ }
//typedReturn
def ReturnOutsideOfDefError(tree: Tree) = {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index 5d4cd0be77..4d35549773 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -855,7 +855,7 @@ trait Macros { self: Analyzer =>
val numParamLists = paramss_without_evidences.length
val numArgLists = argss.length
if (numParamLists != numArgLists) {
- typer.context.error(expandee.pos, "macros cannot be partially applied")
+ typer.TyperErrorGen.MacroPartialApplicationError(expandee)
return None
}
@@ -953,6 +953,11 @@ trait Macros { self: Analyzer =>
* the expandee with an error marker set if there has been an error
*/
def macroExpand(typer: Typer, expandee: Tree, mode: Int = EXPRmode, pt: Type = WildcardType): Tree = {
+ def fail(what: String, tree: Tree): Tree = {
+ val err = typer.context.errBuffer.head
+ this.fail(typer, tree, "failed to perform %s: %s at %s".format(what, err.errMsg, err.errPos))
+ return expandee
+ }
val start = startTimer(macroExpandNanos)
incCounter(macroExpandCount)
try {
@@ -979,15 +984,9 @@ trait Macros { self: Analyzer =>
case _ => ;
}
- def fail(what: String): Tree = {
- val err = typer.context.errBuffer.head
- this.fail(typer, expanded, "failed to perform %s: %s at %s".format(what, err.errMsg, err.errPos))
- return expandee
- }
-
if (macroDebug) println("typechecking1 against %s: %s".format(expectedTpe, expanded))
var typechecked = typer.context.withImplicitsEnabled(typer.typed(expanded, EXPRmode, expectedTpe))
- if (typer.context.hasErrors) fail("typecheck1")
+ if (typer.context.hasErrors) fail("typecheck1", expanded)
if (macroDebug) {
println("typechecked1:")
println(typechecked)
@@ -996,7 +995,7 @@ trait Macros { self: Analyzer =>
if (macroDebug) println("typechecking2 against %s: %s".format(pt, expanded))
typechecked = typer.context.withImplicitsEnabled(typer.typed(typechecked, EXPRmode, pt))
- if (typer.context.hasErrors) fail("typecheck2")
+ if (typer.context.hasErrors) fail("typecheck2", expanded)
if (macroDebug) {
println("typechecked2:")
println(typechecked)
@@ -1009,13 +1008,16 @@ trait Macros { self: Analyzer =>
}
case Delay(expandee) =>
// need to save the context to preserve enclosures
- val args = macroArgs(typer, expandee)
- assert(args.isDefined, expandee)
- val context = args.get.head.asInstanceOf[MacroContext]
- var result = expandee withAttachment MacroAttachment(delayed = true, context = Some(context))
- // adapting here would be premature, we must wait until undetparams are inferred
-// result = typer.adapt(result, mode, pt)
- result
+ macroArgs(typer, expandee) match {
+ case Some((context: MacroContext) :: _) =>
+ // adapting here would be premature, we must wait until undetparams are inferred
+ expandee withAttachment MacroAttachment(delayed = true, context = Some(context))
+ case _ =>
+ // !!! The correct place to issue an error needs to be clarified.
+ // I have the else condition here only as a fallback.
+ if (expandee.isErroneous) expandee
+ else fail("macros cannot be partially applied", expandee)
+ }
case Fallback(fallback) =>
typer.context.withImplicitsEnabled(typer.typed(fallback, EXPRmode, pt))
case Other(result) =>
diff --git a/test/files/run/reify-repl-fail-gracefully.check b/test/files/run/reify-repl-fail-gracefully.check
new file mode 100644
index 0000000000..680db12667
--- /dev/null
+++ b/test/files/run/reify-repl-fail-gracefully.check
@@ -0,0 +1,21 @@
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> import language.experimental.macros
+import language.experimental.macros
+
+scala> import scala.reflect.mirror._
+import scala.reflect.mirror._
+
+scala>
+
+scala> reify
+<console>:12: error: macros cannot be partially applied
+ reify
+ ^
+
+scala>
+
+scala>
diff --git a/test/files/run/reify-repl-fail-gracefully.scala b/test/files/run/reify-repl-fail-gracefully.scala
new file mode 100644
index 0000000000..d7a06e8da8
--- /dev/null
+++ b/test/files/run/reify-repl-fail-gracefully.scala
@@ -0,0 +1,10 @@
+import scala.tools.partest.ReplTest
+
+object Test extends ReplTest {
+ def code = """
+ |import language.experimental.macros
+ |import scala.reflect.mirror._
+ |
+ |reify
+ """.stripMargin
+}