Skip to content

Commit

Permalink
gives a more specific signature to computeMacroDefType
Browse files Browse the repository at this point in the history
I guess having `computeMacroDefType` is the remnant from the times when
we considered an immediate possibility of having non-defdef macros, for
instance type macros, which would be TypeDefs.

These happy early days are gone, type macros have been long buried,
and the perspectives of extensions to the existing def macro scheme are
unclear. Therefore let’s have maximally precise types right away and then
think of generalization later on, once/if we get there.
  • Loading branch information
xeno-by committed Dec 30, 2013
1 parent 9737b80 commit 9e14058
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 13 deletions.
7 changes: 4 additions & 3 deletions src/compiler/scala/tools/nsc/typechecker/Namers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -828,9 +828,10 @@ trait Namers extends MethodSynthesis {
* assigns the type to the tpt's node. Returns the type.
*/
private def assignTypeToTree(tree: ValOrDefDef, defnTyper: Typer, pt: Type): Type = {
val rhsTpe =
if (tree.symbol.isTermMacro) defnTyper.computeMacroDefType(tree, pt)
else defnTyper.computeType(tree.rhs, pt)
val rhsTpe = tree match {
case ddef: DefDef if tree.symbol.isTermMacro => defnTyper.computeMacroDefType(ddef, pt)
case _ => defnTyper.computeType(tree.rhs, pt)
}

val defnTpe = widenIfNecessary(tree.symbol, rhsTpe, pt)
tree.tpt defineType defnTpe setPos tree.pos.focus
Expand Down
18 changes: 8 additions & 10 deletions src/compiler/scala/tools/nsc/typechecker/Typers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5500,25 +5500,23 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
tpe
}

def computeMacroDefType(tree: Tree, pt: Type): Type = {
def computeMacroDefType(ddef: DefDef, pt: Type): Type = {
assert(context.owner.isMacro, context.owner)
assert(tree.symbol.isMacro, tree.symbol)
assert(tree.isInstanceOf[DefDef], tree.getClass)
val ddef = tree.asInstanceOf[DefDef]
assert(ddef.symbol.isMacro, ddef.symbol)

val tree1 =
val rhs1 =
if (transformed contains ddef.rhs) {
// macro defs are typechecked in `methodSig` (by calling this method) in order to establish their link to macro implementation asap
// if a macro def doesn't have explicitly specified return type, this method will be called again by `assignTypeToTree`
// here we guard against this case
transformed(ddef.rhs)
} else {
val tree1 = typedMacroBody(this, ddef)
transformed(ddef.rhs) = tree1
tree1
val rhs1 = typedMacroBody(this, ddef)
transformed(ddef.rhs) = rhs1
rhs1
}

val isMacroBodyOkay = !tree.symbol.isErroneous && !(tree1 exists (_.isErroneous)) && tree1 != EmptyTree
val isMacroBodyOkay = !ddef.symbol.isErroneous && !(rhs1 exists (_.isErroneous)) && rhs1 != EmptyTree
val shouldInheritMacroImplReturnType = ddef.tpt.isEmpty
if (isMacroBodyOkay && shouldInheritMacroImplReturnType) {
val commonMessage = "macro defs must have explicitly specified return types"
Expand All @@ -5530,7 +5528,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
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 {
computeMacroDefTypeFromMacroImplRef(ddef, rhs1) match {
case ErrorType => ErrorType
case NothingTpe => NothingTpe
case NoType => reportFailure(); AnyTpe
Expand Down

0 comments on commit 9e14058

Please sign in to comment.