Skip to content

Commit 979f83c

Browse files
committed
Merge pull request scala#3237 from xeno-by/topic/macrodef-returntype-inference
deprecates macro def return type inference
2 parents 75cc6cf + 87979ad commit 979f83c

File tree

102 files changed

+245
-235
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+245
-235
lines changed

src/compiler/scala/reflect/macros/compiler/Validators.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ trait Validators {
155155
else mmap(macroDdef.vparamss)(param)
156156
val macroDefRet =
157157
if (!macroDdef.tpt.isEmpty) typer.typedType(macroDdef.tpt).tpe
158-
else computeMacroDefTypeFromMacroImplRef(macroDdef, macroImplRef)
158+
else computeMacroDefTypeFromMacroImplRef(macroDdef, macroImplRef) orElse AnyTpe
159159
val implReturnType = sigma(increaseMetalevel(ctxPrefix, macroDefRet))
160160

161161
object SigmaTypeMap extends TypeMap {

src/compiler/scala/reflect/macros/util/Helpers.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ trait Helpers {
7777

7878
/** Decreases metalevel of the type, i.e. transforms:
7979
* * c.Expr[T] to T
80-
* * Anything else to Any
80+
* * Nothing to Nothing
81+
* * Anything else to NoType
8182
*
8283
* @see Metalevels.scala for more information and examples about metalevels
8384
*/
@@ -86,7 +87,10 @@ trait Helpers {
8687
import runDefinitions._
8788
transparentShallowTransform(RepeatedParamClass, tp) {
8889
case ExprClassOf(runtimeType) => runtimeType
89-
case _ => AnyTpe // so that macro impls with rhs = ??? don't screw up our inference
90+
// special-casing Nothing here is a useful convention
91+
// that enables no-hassle prototyping with `macro ???` and `macro { ...; ??? }`
92+
case nothing if nothing =:= NothingTpe => NothingTpe
93+
case _ => NoType
9094
}
9195
}
9296
}

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5517,7 +5517,23 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
55175517

55185518
val isMacroBodyOkay = !tree.symbol.isErroneous && !(tree1 exists (_.isErroneous)) && tree1 != EmptyTree
55195519
val shouldInheritMacroImplReturnType = ddef.tpt.isEmpty
5520-
if (isMacroBodyOkay && shouldInheritMacroImplReturnType) computeMacroDefTypeFromMacroImplRef(ddef, tree1) else AnyTpe
5520+
if (isMacroBodyOkay && shouldInheritMacroImplReturnType) {
5521+
val commonMessage = "macro defs must have explicitly specified return types"
5522+
def reportFailure() = {
5523+
ddef.symbol.setFlag(IS_ERROR)
5524+
unit.error(ddef.pos, commonMessage)
5525+
}
5526+
def reportWarning(inferredType: Type) = {
5527+
val explanation = s"inference of $inferredType from macro impl's c.Expr[$inferredType] is deprecated and is going to stop working in 2.12"
5528+
unit.deprecationWarning(ddef.pos, s"$commonMessage ($explanation)")
5529+
}
5530+
computeMacroDefTypeFromMacroImplRef(ddef, tree1) match {
5531+
case ErrorType => ErrorType
5532+
case NothingTpe => NothingTpe
5533+
case NoType => reportFailure(); AnyTpe
5534+
case tpe => reportWarning(tpe); tpe
5535+
}
5536+
} else AnyTpe
55215537
}
55225538

55235539
def transformedOr(tree: Tree, op: => Tree): Tree = transformed remove tree match {

test/files/neg/macro-blackbox-extractor/Macros_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import scala.reflect.macros.BlackboxContext
22
import language.experimental.macros
33

44
object Extractor {
5-
def unapply(x: Int) = macro Macros.unapplyImpl
5+
def unapply(x: Int): Any = macro Macros.unapplyImpl
66
}
77

88
object Macros {

test/files/neg/macro-blackbox-structural/Impls_Macros_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ object Macros {
1111
"""
1212
}
1313

14-
def foo = macro impl
14+
def foo: Any = macro impl
1515
}

test/files/neg/macro-bundle-object.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
macro-bundle-object.scala:10: error: macro implementation has incompatible shape:
2-
required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Any]
2+
required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Nothing]
33
or : (c: scala.reflect.macros.BlackboxContext): c.Tree
44
found : : Nothing
55
number of parameter sections differ

test/files/neg/macro-invalidret.check

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,24 @@ Macros_Test_2.scala:3: error: macro implementation has incompatible shape:
1212
type mismatch for return type: reflect.runtime.universe.Literal does not conform to c.Expr[Any]
1313
def foo2 = macro Impls.foo2
1414
^
15-
two errors found
15+
Macros_Test_2.scala:6: error: macro defs must have explicitly specified return types
16+
def foo5 = macro Impls.foo5
17+
^
18+
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)
19+
def foo6 = macro Impls.foo6
20+
^
21+
Macros_Test_2.scala:14: error: exception during macro expansion:
22+
scala.NotImplementedError: an implementation is missing
23+
at scala.Predef$.$qmark$qmark$qmark(Predef.scala:227)
24+
at Impls$.foo3(Impls_1.scala:7)
25+
26+
foo3
27+
^
28+
Macros_Test_2.scala:15: error: macro implementation is missing
29+
foo4
30+
^
31+
Macros_Test_2.scala:17: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
32+
foo6
33+
^
34+
two warnings found
35+
5 errors found

test/files/neg/macro-invalidret.flags

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
-language:experimental.macros
1+
-language:experimental.macros
2+
-Xfatal-warnings
3+
-deprecation

test/files/neg/macro-invalidret/Impls_1.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@ import scala.reflect.runtime.{universe => ru}
44
object Impls {
55
def foo1(c: BlackboxContext) = 2
66
def foo2(c: BlackboxContext) = ru.Literal(ru.Constant(42))
7+
def foo3(c: BlackboxContext) = ???
8+
def foo5(c: BlackboxContext) = c.universe.Literal(c.universe.Constant(42))
9+
def foo6(c: BlackboxContext) = c.Expr[Int](c.universe.Literal(c.universe.Constant(42)))
710
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
object Macros {
22
def foo1 = macro Impls.foo1
33
def foo2 = macro Impls.foo2
4+
def foo3 = macro Impls.foo3
5+
def foo4 = macro ???
6+
def foo5 = macro Impls.foo5
7+
def foo6 = macro Impls.foo6
48
}
59

610
object Test extends App {
711
import Macros._
812
foo1
913
foo2
14+
foo3
15+
foo4
16+
foo5
17+
foo6
1018
}

0 commit comments

Comments
 (0)