Skip to content

Commit

Permalink
Merge pull request scala#3237 from xeno-by/topic/macrodef-returntype-…
Browse files Browse the repository at this point in the history
…inference

deprecates macro def return type inference
  • Loading branch information
retronym committed Dec 10, 2013
2 parents 75cc6cf + 87979ad commit 979f83c
Show file tree
Hide file tree
Showing 102 changed files with 245 additions and 235 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ trait Validators {
else mmap(macroDdef.vparamss)(param)
val macroDefRet =
if (!macroDdef.tpt.isEmpty) typer.typedType(macroDdef.tpt).tpe
else computeMacroDefTypeFromMacroImplRef(macroDdef, macroImplRef)
else computeMacroDefTypeFromMacroImplRef(macroDdef, macroImplRef) orElse AnyTpe
val implReturnType = sigma(increaseMetalevel(ctxPrefix, macroDefRet))

object SigmaTypeMap extends TypeMap {
Expand Down
8 changes: 6 additions & 2 deletions src/compiler/scala/reflect/macros/util/Helpers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ trait Helpers {

/** Decreases metalevel of the type, i.e. transforms:
* * c.Expr[T] to T
* * Anything else to Any
* * Nothing to Nothing
* * Anything else to NoType
*
* @see Metalevels.scala for more information and examples about metalevels
*/
Expand All @@ -86,7 +87,10 @@ trait Helpers {
import runDefinitions._
transparentShallowTransform(RepeatedParamClass, tp) {
case ExprClassOf(runtimeType) => runtimeType
case _ => AnyTpe // so that macro impls with rhs = ??? don't screw up our inference
// special-casing Nothing here is a useful convention
// that enables no-hassle prototyping with `macro ???` and `macro { ...; ??? }`
case nothing if nothing =:= NothingTpe => NothingTpe
case _ => NoType
}
}
}
18 changes: 17 additions & 1 deletion src/compiler/scala/tools/nsc/typechecker/Typers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5517,7 +5517,23 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper

val isMacroBodyOkay = !tree.symbol.isErroneous && !(tree1 exists (_.isErroneous)) && tree1 != EmptyTree
val shouldInheritMacroImplReturnType = ddef.tpt.isEmpty
if (isMacroBodyOkay && shouldInheritMacroImplReturnType) computeMacroDefTypeFromMacroImplRef(ddef, tree1) else AnyTpe
if (isMacroBodyOkay && shouldInheritMacroImplReturnType) {
val commonMessage = "macro defs must have explicitly specified return types"
def reportFailure() = {
ddef.symbol.setFlag(IS_ERROR)
unit.error(ddef.pos, commonMessage)
}
def reportWarning(inferredType: Type) = {
val explanation = s"inference of $inferredType from macro impl's c.Expr[$inferredType] is deprecated and is going to stop working in 2.12"
unit.deprecationWarning(ddef.pos, s"$commonMessage ($explanation)")
}
computeMacroDefTypeFromMacroImplRef(ddef, tree1) match {
case ErrorType => ErrorType
case NothingTpe => NothingTpe
case NoType => reportFailure(); AnyTpe
case tpe => reportWarning(tpe); tpe
}
} else AnyTpe
}

def transformedOr(tree: Tree, op: => Tree): Tree = transformed remove tree match {
Expand Down
2 changes: 1 addition & 1 deletion test/files/neg/macro-blackbox-extractor/Macros_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import scala.reflect.macros.BlackboxContext
import language.experimental.macros

object Extractor {
def unapply(x: Int) = macro Macros.unapplyImpl
def unapply(x: Int): Any = macro Macros.unapplyImpl
}

object Macros {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ object Macros {
"""
}

def foo = macro impl
def foo: Any = macro impl
}
2 changes: 1 addition & 1 deletion test/files/neg/macro-bundle-object.check
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
macro-bundle-object.scala:10: error: macro implementation has incompatible shape:
required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Any]
required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Nothing]
or : (c: scala.reflect.macros.BlackboxContext): c.Tree
found : : Nothing
number of parameter sections differ
Expand Down
22 changes: 21 additions & 1 deletion test/files/neg/macro-invalidret.check
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,24 @@ Macros_Test_2.scala:3: error: macro implementation has incompatible shape:
type mismatch for return type: reflect.runtime.universe.Literal does not conform to c.Expr[Any]
def foo2 = macro Impls.foo2
^
two errors found
Macros_Test_2.scala:6: error: macro defs must have explicitly specified return types
def foo5 = macro Impls.foo5
^
Macros_Test_2.scala:7: warning: macro defs must have explicitly specified return types (inference of Int from macro impl's c.Expr[Int] is deprecated and is going to stop working in 2.12)
def foo6 = macro Impls.foo6
^
Macros_Test_2.scala:14: error: exception during macro expansion:
scala.NotImplementedError: an implementation is missing
at scala.Predef$.$qmark$qmark$qmark(Predef.scala:227)
at Impls$.foo3(Impls_1.scala:7)

foo3
^
Macros_Test_2.scala:15: error: macro implementation is missing
foo4
^
Macros_Test_2.scala:17: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
foo6
^
two warnings found
5 errors found
4 changes: 3 additions & 1 deletion test/files/neg/macro-invalidret.flags
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
-language:experimental.macros
-language:experimental.macros
-Xfatal-warnings
-deprecation
3 changes: 3 additions & 0 deletions test/files/neg/macro-invalidret/Impls_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ import scala.reflect.runtime.{universe => ru}
object Impls {
def foo1(c: BlackboxContext) = 2
def foo2(c: BlackboxContext) = ru.Literal(ru.Constant(42))
def foo3(c: BlackboxContext) = ???
def foo5(c: BlackboxContext) = c.universe.Literal(c.universe.Constant(42))
def foo6(c: BlackboxContext) = c.Expr[Int](c.universe.Literal(c.universe.Constant(42)))
}
8 changes: 8 additions & 0 deletions test/files/neg/macro-invalidret/Macros_Test_2.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
object Macros {
def foo1 = macro Impls.foo1
def foo2 = macro Impls.foo2
def foo3 = macro Impls.foo3
def foo4 = macro ???
def foo5 = macro Impls.foo5
def foo6 = macro Impls.foo6
}

object Test extends App {
import Macros._
foo1
foo2
foo3
foo4
foo5
foo6
}
2 changes: 1 addition & 1 deletion test/files/neg/macro-invalidsig-params-badtype.check
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Impls_Macros_1.scala:8: error: macro implementation has incompatible shape:
required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int]): c.Expr[Any]
required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int]): c.Expr[Nothing]
or : (c: scala.reflect.macros.BlackboxContext)(x: c.Tree): c.Tree
found : (c: scala.reflect.macros.BlackboxContext)(x: Int): Nothing
type mismatch for parameter x: c.Expr[Int] does not conform to Int
Expand Down
30 changes: 15 additions & 15 deletions test/files/neg/macro-invalidsig.check
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
Macros_Test_2.scala:2: error: macro implementations cannot have implicit parameters other than WeakTypeTag evidences
def foo[U] = macro Impls1.foo[U]
^
def foo[U]: Int = macro Impls1.foo[U]
^
Macros_Test_2.scala:6: error: macro implementation has incompatible shape:
required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Any]
required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Nothing]
or : (c: scala.reflect.macros.BlackboxContext): c.Tree
found : : Nothing
number of parameter sections differ
def foo = macro Impls2.foo
^
Macros_Test_2.scala:10: error: macro implementation has incompatible shape:
required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Any]
required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Nothing]
or : (c: scala.reflect.macros.BlackboxContext): c.Tree
found : (c: scala.reflect.api.Universe): Nothing
type mismatch for parameter c: scala.reflect.macros.BlackboxContext does not conform to scala.reflect.api.Universe
def foo = macro Impls3.foo
^
Macros_Test_2.scala:14: error: macro implementation has incompatible shape:
required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Any]
required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Nothing]
or : (c: scala.reflect.macros.BlackboxContext): c.Tree
found : (cs: scala.reflect.macros.BlackboxContext*): Nothing
types incompatible for parameter cs: corresponding is not a vararg parameter
def foo = macro Impls4.foo
^
Macros_Test_2.scala:18: error: macro implementation has incompatible shape:
required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Any]): c.Expr[Any]
required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Any]): c.Expr[Nothing]
or : (c: scala.reflect.macros.BlackboxContext)(x: c.Tree): c.Tree
found : (c: scala.reflect.macros.BlackboxContext): Nothing
number of parameter sections differ
Expand All @@ -33,35 +33,35 @@ Macros_Test_2.scala:22: error: macro implementations cannot have implicit parame
def foo[U](x: Int) = macro Impls6.foo[T, U]
^
Macros_Test_2.scala:26: error: macro implementation has incompatible shape:
required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int]): c.Expr[Any]
required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int]): c.Expr[Nothing]
or : (c: scala.reflect.macros.BlackboxContext)(x: c.Tree): c.Tree
found : (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int], y: c.Expr[Int]): Nothing
parameter lists have different length, found extra parameter y: c.Expr[Int]
def foo(x: Int) = macro Impls7.foo
^
Macros_Test_2.scala:30: error: macro implementation has incompatible shape:
required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int]): c.Expr[Any]
required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int]): c.Expr[Nothing]
or : (c: scala.reflect.macros.BlackboxContext)(x: c.Tree): c.Tree
found : (c: scala.reflect.macros.BlackboxContext)(x: c.universe.Symbol): Nothing
type mismatch for parameter x: c.Expr[Int] does not conform to c.universe.Symbol
def foo(x: Int) = macro Impls8.foo
^
Macros_Test_2.scala:34: error: macro implementation has incompatible shape:
required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Any]
required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Nothing]
or : (c: scala.reflect.macros.BlackboxContext)(x: c.Tree, y: c.Tree): c.Tree
found : (c: scala.reflect.macros.BlackboxContext)(xs: c.Expr[Int]*): Nothing
parameter lists have different length, required extra parameter y: c.Expr[Int]
def foo(x: Int, y: Int) = macro Impls9.foo
^
Macros_Test_2.scala:38: error: macro implementation has incompatible shape:
required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Any]
required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Nothing]
or : (c: scala.reflect.macros.BlackboxContext)(x: c.Tree, y: c.Tree): c.Tree
found : (c: scala.reflect.macros.BlackboxContext)(y: c.Expr[Int], x: c.Expr[Int]): Nothing
parameter names differ: x != y
def foo(x: Int, y: Int) = macro Impls10.foo
^
Macros_Test_2.scala:42: error: macro implementation has incompatible shape:
required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Any]
required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Nothing]
or : (c: scala.reflect.macros.BlackboxContext): c.Tree
found : (c: scala.reflect.macros.BlackboxContext)(U: c.universe.Type): Nothing
number of parameter sections differ
Expand All @@ -77,9 +77,9 @@ Macros_Test_2.scala:54: error: macro implementation reference has too few type a
def foo = macro Impls14.foo
^
Macros_Test_2.scala:59: error: macro implementation reference has too few type arguments for method foo: [T, U, V](c: scala.reflect.macros.BlackboxContext)(implicit evidence$5: c.WeakTypeTag[T], implicit evidence$6: c.WeakTypeTag[U], implicit V: c.WeakTypeTag[V])c.Expr[Unit]
def foo15[V] = macro Impls15.foo
^
def foo15[V]: Unit = macro Impls15.foo
^
Macros_Test_2.scala:60: error: wrong number of type parameters for method foo: [T, U, V](c: scala.reflect.macros.BlackboxContext)(implicit evidence$7: c.WeakTypeTag[T], implicit evidence$8: c.WeakTypeTag[U], implicit V: c.WeakTypeTag[V])c.Expr[Unit]
def foo16[V] = macro Impls16.foo[V]
^
def foo16[V]: Unit = macro Impls16.foo[V]
^
16 errors found
6 changes: 3 additions & 3 deletions test/files/neg/macro-invalidsig/Macros_Test_2.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
object Macros1 {
def foo[U] = macro Impls1.foo[U]
def foo[U]: Int = macro Impls1.foo[U]
}

object Macros2 {
Expand Down Expand Up @@ -56,8 +56,8 @@ object Macros14 {

class D[T] {
class C[U] {
def foo15[V] = macro Impls15.foo
def foo16[V] = macro Impls16.foo[V]
def foo15[V]: Unit = macro Impls15.foo
def foo16[V]: Unit = macro Impls16.foo[V]
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
object Macros { def foo(x: Int) = macro Impls.foo }
object Macros { def foo(x: Int): Int = macro Impls.foo }
import Macros._

object Test extends App {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
object Macros {
def foo[U <: String] = macro Impls.foo[U]
def foo[U <: String]: Unit = macro Impls.foo[U]
}

object Test extends App {
Expand Down
10 changes: 5 additions & 5 deletions test/files/neg/macro-invalidusage-badtargs.check
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
Macros_Test_2.scala:11: error: macro method foo1: (x: Int)Int does not take type parameters.
Macros_Test_2.scala:13: error: macro method foo1: (x: Int)Int does not take type parameters.
foo1[String](42)
^
Macros_Test_2.scala:12: error: wrong number of type parameters for macro method foo2: [T](x: Int)Int
Macros_Test_2.scala:14: error: wrong number of type parameters for macro method foo2: [T](x: Int)Int
foo2[String, String](42)
^
Macros_Test_2.scala:13: error: wrong number of type parameters for macro method foo3: [T, U](x: Int)Int
Macros_Test_2.scala:15: error: wrong number of type parameters for macro method foo3: [T, U](x: Int)Int
foo3[String](42)
^
Macros_Test_2.scala:14: error: String takes no type parameters, expected: one
Macros_Test_2.scala:16: error: String takes no type parameters, expected: one
foo4[String](42)
^
Macros_Test_2.scala:15: error: kinds of the type arguments (List) do not conform to the expected kinds of the type parameters (type T).
Macros_Test_2.scala:17: error: kinds of the type arguments (List) do not conform to the expected kinds of the type parameters (type T).
List's type parameters do not match type T's expected parameters:
type A has no type parameters, but type U has one
foo5[List](42)
Expand Down
12 changes: 7 additions & 5 deletions test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import scala.language.higherKinds

object Macros {
def foo1(x: Int) = macro Impls.foo
def foo2[T](x: Int) = macro Impls.foo
def foo3[T, U](x: Int) = macro Impls.foo
def foo4[T[_]](x: Int) = macro Impls.foo
def foo5[T[U[_]]](x: Int) = macro Impls.foo
def foo1(x: Int): Int = macro Impls.foo
def foo2[T](x: Int): Int = macro Impls.foo
def foo3[T, U](x: Int): Int = macro Impls.foo
def foo4[T[_]](x: Int): Int = macro Impls.foo
def foo5[T[U[_]]](x: Int): Int = macro Impls.foo
}

object Test extends App {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
object Macros {
def foo = macro Impls.foo
def foo: Unit = macro Impls.foo
}

object Test extends App {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Impls_Macros_1.scala:12: error: overriding method foo in trait Foo of type (x: Int)Int;
macro method foo cannot be used here - term macros cannot override abstract methods
def foo(x: Int) = macro Impls.impl
def foo(x: Int): Int = macro Impls.impl
^
one error found
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ trait Foo {
}

object Macros extends Foo {
def foo(x: Int) = macro Impls.impl
def foo(x: Int): Int = macro Impls.impl
}
2 changes: 1 addition & 1 deletion test/files/neg/macro-override-method-overrides-macro.check
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Macros_Test_2.scala:8: error: overriding macro method foo in class B of type (x: String)Unit;
method foo cannot be used here - only term macros can override term macros
override def foo(x: String) = println("fooDString")
override def foo(x: String): Unit = println("fooDString")
^
one error found
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
class B {
def foo(x: String) = macro Impls.fooBString
def foo(x: Int) = macro Impls.fooBInt
def foo(x: Boolean) = println("fooBBoolean")
def foo(x: String): Unit = macro Impls.fooBString
def foo(x: Int): Unit = macro Impls.fooBInt
def foo(x: Boolean): Unit = println("fooBBoolean")
}

class D extends B {
override def foo(x: String) = println("fooDString")
override def foo(x: Int) = macro Impls.fooDInt
override def foo(x: String): Unit = println("fooDString")
override def foo(x: Int): Unit = macro Impls.fooDInt
}

class Z extends D {
override def foo(x: String) = macro Impls.fooZString
override def foo(x: Boolean) = println("fooZBoolean")
override def foo(x: String): Unit = macro Impls.fooZString
override def foo(x: Boolean): Unit = println("fooZBoolean")
}
6 changes: 3 additions & 3 deletions test/files/neg/macro-quasiquotes.check
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Macros_1.scala:14: error: macro implementation has incompatible shape:
required: (x: Impls.this.c.Expr[Int]): Impls.this.c.Expr[Any]
required: (x: Impls.this.c.Expr[Int]): Impls.this.c.Expr[Unit]
or : (x: Impls.this.c.Tree): Impls.this.c.Tree
found : (x: Impls.this.c.universe.Block): Impls.this.c.Tree
type mismatch for parameter x: Impls.this.c.Expr[Int] does not conform to Impls.this.c.universe.Block
def m3(x: Int) = macro Impls.impl3
^
def m3(x: Int): Unit = macro Impls.impl3
^
one error found
6 changes: 3 additions & 3 deletions test/files/neg/macro-quasiquotes/Macros_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ trait Impls extends BlackboxMacro {
}

object Macros {
def m1(x: Int) = macro Impls.impl1
def m2(x: Int) = macro Impls.impl2
def m3(x: Int) = macro Impls.impl3
def m1(x: Int): Unit = macro Impls.impl1
def m2(x: Int): Unit = macro Impls.impl2
def m3(x: Int): Unit = macro Impls.impl3
}
2 changes: 1 addition & 1 deletion test/files/neg/t5753/Impls_Macros_1.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import scala.reflect.macros.{BlackboxContext => Ctx}

trait Impls {
def impl(c: Ctx)(x: c.Expr[Any]) = x
def impl(c: Ctx)(x: c.Expr[Any]) = x
}

Loading

0 comments on commit 979f83c

Please sign in to comment.