summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-08-17 11:50:01 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-08-17 11:57:18 +0200
commitddf27a1e0e4b9eae521651704e74298c33c9af6c (patch)
tree4d1adea4ffa6cd520e71c6997c6a69264acf0291 /src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
parent78f9ef3906c78413ff8835fdad3849bfe5516be2 (diff)
downloadscala-ddf27a1e0e4b9eae521651704e74298c33c9af6c.tar.gz
scala-ddf27a1e0e4b9eae521651704e74298c33c9af6c.tar.bz2
scala-ddf27a1e0e4b9eae521651704e74298c33c9af6c.zip
more cleanup for typedMacroBody
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala209
1 files changed, 91 insertions, 118 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index f6785b6541..5a110739cd 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -16,6 +16,7 @@ trait ContextErrors {
import global._
import definitions._
+ import treeInfo._
object ErrorKinds extends Enumeration {
type ErrorKind = Value
@@ -429,8 +430,11 @@ trait ContextErrors {
def AbstractionFromVolatileTypeError(vd: ValDef) =
issueNormalTypeError(vd, "illegal abstraction from value with volatile type "+vd.symbol.tpe)
+ private[ContextErrors] def TypedApplyWrongNumberOfTpeParametersErrorMessage(fun: Tree) =
+ "wrong number of type parameters for "+treeSymTypeMsg(fun)
+
def TypedApplyWrongNumberOfTpeParametersError(tree: Tree, fun: Tree) = {
- issueNormalTypeError(tree, "wrong number of type parameters for "+treeSymTypeMsg(fun))
+ issueNormalTypeError(tree, TypedApplyWrongNumberOfTpeParametersErrorMessage(fun))
setError(tree)
}
@@ -755,21 +759,24 @@ trait ContextErrors {
kindErrors.toList.mkString("\n", ", ", ""))
}
- def NotWithinBounds(tree: Tree, prefix: String, targs: List[Type],
- tparams: List[Symbol], kindErrors: List[String]) = {
- if (settings.explaintypes.value) {
+ private[ContextErrors] def NotWithinBoundsErrorMessage(prefix: String, targs: List[Type], tparams: List[Symbol], explaintypes: Boolean) = {
+ if (explaintypes) {
val bounds = tparams map (tp => tp.info.instantiateTypeParams(tparams, targs).bounds)
(targs, bounds).zipped foreach ((targ, bound) => explainTypes(bound.lo, targ))
(targs, bounds).zipped foreach ((targ, bound) => explainTypes(targ, bound.hi))
()
}
- issueNormalTypeError(tree,
- prefix + "type arguments " + targs.mkString("[", ",", "]") +
- " do not conform to " + tparams.head.owner + "'s type parameter bounds " +
- (tparams map (_.defString)).mkString("[", ",", "]"))
+ prefix + "type arguments " + targs.mkString("[", ",", "]") +
+ " do not conform to " + tparams.head.owner + "'s type parameter bounds " +
+ (tparams map (_.defString)).mkString("[", ",", "]")
}
+ def NotWithinBounds(tree: Tree, prefix: String, targs: List[Type],
+ tparams: List[Symbol], kindErrors: List[String]) =
+ issueNormalTypeError(tree,
+ NotWithinBoundsErrorMessage(prefix, targs, tparams, settings.explaintypes.value))
+
//substExpr
def PolymorphicExpressionInstantiationError(tree: Tree, undetparams: List[Symbol], pt: Type) =
issueNormalTypeError(tree,
@@ -1093,144 +1100,115 @@ trait ContextErrors {
// using an exception here is actually a good idea
// because the lifespan of this exception is extremely small and controlled
// moreover exceptions let us avoid an avalanche of "if (!hasError) do stuff" checks
- case class MacroBodyTypecheckException() extends Exception
+ case object MacroBodyTypecheckException extends Exception with scala.util.control.ControlThrowable
trait MacroErrors {
self: MacroTyper =>
- implicit val context = typer.context
+ private implicit val context0 = typer.context
+ val context = typer.context
+
+ // helpers
+
+ private def lengthMsg(flavor: String, violation: String, extra: Symbol) = {
+ val noun = if (flavor == "value") "parameter" else "type parameter"
+ val message = noun + " lists have different length, " + violation + " extra " + noun
+ val suffix = if (extra ne NoSymbol) " " + extra.defString else ""
+ message + suffix
+ }
+
+ private def abbreviateCoreAliases(s: String): String = List("AbsTypeTag", "Expr").foldLeft(s)((res, x) => res.replace("c.universe." + x, "c." + x))
- def fail() = {
+ private def showMeth(pss: List[List[Symbol]], restpe: Type, abbreviate: Boolean) = {
+ var argsPart = (pss map (ps => ps map (_.defString) mkString ("(", ", ", ")"))).mkString
+ if (abbreviate) argsPart = abbreviateCoreAliases(argsPart)
+ var retPart = restpe.toString
+ if (abbreviate || macroDdef.tpt.tpe == null) retPart = abbreviateCoreAliases(retPart)
+ argsPart + ": " + retPart
+ }
+
+ // not exactly an error generator, but very related
+ // and I dearly wanted to push it away from Macros.scala
+ private def checkSubType(slot: String, rtpe: Type, atpe: Type) = {
+ val ok = if (macroDebugVerbose || settings.explaintypes.value) {
+ if (rtpe eq atpe) println(rtpe + " <: " + atpe + "?" + EOL + "true")
+ withTypesExplained(rtpe <:< atpe)
+ } else rtpe <:< atpe
+ if (!ok) {
+ compatibilityError("type mismatch for %s: %s does not conform to %s".format(slot, abbreviateCoreAliases(rtpe.toString), abbreviateCoreAliases(atpe.toString)))
+ }
+ }
+
+ // errors
+
+ private def fail() = {
// need to set the IS_ERROR flag to prohibit spurious expansions
if (macroDef != null) macroDef setFlag IS_ERROR
// not setting ErrorSymbol as in `infer.setError`, because we still need to know that it's a macro
// otherwise assignTypeToTree in Namers might fail if macroDdef.tpt == EmptyTree
macroDdef setType ErrorType
- throw MacroBodyTypecheckException()
+ throw MacroBodyTypecheckException
}
- def MacroDefIsHardwired() = {
- macroLogVerbose("typecheck terminated unexpectedly: macro is hardwired")
- assert(!macroDdef.tpt.isEmpty, "hardwired macros must provide result type")
- throw MacroBodyTypecheckException()
+ private def genericError(tree: Tree, message: String) = {
+ issueNormalTypeError(tree, message)
+ fail()
}
- def MacroFeatureNotEnabled() = {
- macroLogVerbose("typecheck terminated unexpectedly: language.experimental.macros feature is not enabled")
- macroDef setFlag IS_ERROR
- throw MacroBodyTypecheckException()
- }
+ private def implRefError(message: String) = genericError(methPart(macroDdef.rhs), message)
- def MacroDefUntypeableBodyError() = {
- // do nothing, just fail
- // relevant typecheck errors have already been reported
- fail()
- }
+ private def compatibilityError(message: String) =
+ implRefError(
+ "macro implementation has wrong shape:"+
+ "\n required: " + showMeth(rparamss, rret, abbreviate = true) +
+ "\n found : " + showMeth(aparamss, aret, abbreviate = false) +
+ "\n" + message)
- def MacroDefInvalidBodyError() = {
- issueNormalTypeError(macroDdef,
- "macro body has wrong shape:" +
- "\n required: macro [<implementation object>].<method name>[[<type args>]]")
- fail()
- }
+ // Phase I: sanity checks
- def MacroImplNotPublicError() = {
- issueNormalTypeError(macroDdef.rhs, "macro implementation must be public")
- fail()
+ def MacroDefIsFastTrack() = {
+ macroLogVerbose("typecheck terminated unexpectedly: macro is fast track")
+ assert(!macroDdef.tpt.isEmpty, "fast track macros must provide result type")
+ throw MacroBodyTypecheckException // don't call fail, because we don't need IS_ERROR
}
- def MacroImplOverloadedError() = {
- issueNormalTypeError(macroDdef.rhs, "macro implementation cannot be overloaded")
+ def MacroFeatureNotEnabled() = {
+ macroLogVerbose("typecheck terminated unexpectedly: language.experimental.macros feature is not enabled")
fail()
}
- def MacroImplNeedsTypeArgumentsError() = {
- issueNormalTypeError(macroDdef.rhs, "macro implementation reference needs type arguments")
- fail()
- }
+ // Phase II: typecheck the right-hand side of the macro def
- def MacroImplDoesntNeedTypeArgumentsError() = {
- issueNormalTypeError(macroDdef.rhs, "macro implementation reference doesn't need type arguments")
- fail()
- }
+ // do nothing, just fail. relevant typecheck errors have already been reported
+ def MacroDefUntypeableBodyError() = fail()
- def MacroImplNotStaticError() = {
- issueNormalTypeError(macroDdef.rhs, "macro implementation must be in statically accessible object")
- fail()
- }
+ def MacroDefInvalidBodyError() = genericError(macroDdef, "macro body has wrong shape:\n required: macro [<implementation object>].<method name>[[<type args>]]")
- // prohibit implicit params on macro implementations
- // we don't have to do this, but it appears to be more clear than allowing them
- def MacroImplNonTagImplicitParameters(params: List[Symbol]) = {
- issueSymbolTypeError(params.head, "macro implementations cannot have implicit parameters other than AbsTypeTag evidences")
- fail()
- }
+ def MacroImplNotPublicError() = implRefError("macro implementation must be public")
- private def abbreviateCoreAliases(s: String): String = {
- var result = s
- result = result.replace("c.universe.AbsTypeTag", "c.AbsTypeTag")
- result = result.replace("c.universe.Expr", "c.Expr")
- result
- }
+ def MacroImplOverloadedError() = implRefError("macro implementation cannot be overloaded")
- private def showMeth(pss: List[List[Symbol]], restpe: Type, abbreviate: Boolean) = {
- var argsPart = (pss map (ps => ps map (_.defString) mkString ("(", ", ", ")"))).mkString
- if (abbreviate) argsPart = abbreviateCoreAliases(argsPart)
- var retPart = restpe.toString
- if (abbreviate || macroDdef.tpt.tpe == null) retPart = abbreviateCoreAliases(retPart)
- argsPart + ": " + retPart
- }
+ def MacroImplWrongNumberOfTypeArgumentsError(macroImplRef: Tree) = implRefError(typer.TyperErrorGen.TypedApplyWrongNumberOfTpeParametersErrorMessage(macroImplRef))
- private def compatibilityError(message: String) = {
- issueNormalTypeError(macroDdef.rhs,
- "macro implementation has wrong shape:"+
- "\n required: " + showMeth(rparamss, rret, abbreviate = true) +
- "\n found : " + showMeth(aparamss, aret, abbreviate = false) +
- "\n" + message)
- fail()
- }
+ def MacroImplNotStaticError() = implRefError("macro implementation must be in statically accessible object")
- def MacroImplParamssMismatchError() = {
- compatibilityError("number of parameter sections differ")
- }
+ // Phase III: check compatibility between the macro def and its macro impl
+ // aXXX (e.g. aparams) => characteristics of the macro impl ("a" stands for "actual")
+ // rXXX (e.g. rparams) => characteristics of a reference macro impl signature synthesized from the macro def ("r" stands for "reference")
- private def lengthMsg(which: String, extra: Symbol) = {
- "parameter lists have different length, " + which + " extra parameter " + extra.defString
- }
+ def MacroImplNonTagImplicitParameters(params: List[Symbol]) = compatibilityError("macro implementations cannot have implicit parameters other than AbsTypeTag evidences")
- def MacroImplExtraParamsError(aparams: List[Symbol], rparams: List[Symbol]) = {
- compatibilityError(lengthMsg("found", aparams(rparams.length)))
- }
+ def MacroImplParamssMismatchError() = compatibilityError("number of parameter sections differ")
- def MacroImplMissingParamsError(aparams: List[Symbol], rparams: List[Symbol]) = {
- compatibilityError(abbreviateCoreAliases(lengthMsg("required", rparams(aparams.length))))
- }
+ def MacroImplExtraParamsError(aparams: List[Symbol], rparams: List[Symbol]) = compatibilityError(lengthMsg("value", "found", aparams(rparams.length)))
- // not exactly an error generator, but very related
- // and I dearly wanted to push it away from Macros.scala
- def checkSubType(slot: String, rtpe: Type, atpe: Type) = {
- val ok = if (macroDebugVerbose) {
- if (rtpe eq atpe) println(rtpe + " <: " + atpe + "?" + EOL + "true")
- withTypesExplained(rtpe <:< atpe)
- } else rtpe <:< atpe
- if (!ok) {
- compatibilityError("type mismatch for %s: %s does not conform to %s".format(slot, abbreviateCoreAliases(rtpe.toString), abbreviateCoreAliases(atpe.toString)))
- }
- }
+ def MacroImplMissingParamsError(aparams: List[Symbol], rparams: List[Symbol]) = compatibilityError(abbreviateCoreAliases(lengthMsg("value", "required", rparams(aparams.length))))
- def checkMacroImplParamTypeMismatch(atpe: Type, rparam: Symbol) = {
- checkSubType("parameter " + rparam.name, rparam.tpe, atpe)
- }
+ def checkMacroImplParamTypeMismatch(atpe: Type, rparam: Symbol) = checkSubType("parameter " + rparam.name, rparam.tpe, atpe)
- def checkMacroImplResultTypeMismatch(atpe: Type, rret: Type) = {
- checkSubType("return type", atpe, rret)
- }
+ def checkMacroImplResultTypeMismatch(atpe: Type, rret: Type) = checkSubType("return type", atpe, rret)
- def MacroImplParamNameMismatchError(aparam: Symbol, rparam: Symbol) = {
- // in the error message rparamss come first
- // hence rparam should also come first if possible
- compatibilityError("parameter names differ: " + rparam.name + " != " + aparam.name)
- }
+ def MacroImplParamNameMismatchError(aparam: Symbol, rparam: Symbol) = compatibilityError("parameter names differ: " + rparam.name + " != " + aparam.name)
def MacroImplVarargMismatchError(aparam: Symbol, rparam: Symbol) = {
if (isRepeated(rparam) && !isRepeated(aparam))
@@ -1239,17 +1217,12 @@ trait ContextErrors {
compatibilityError("types incompatible for parameter " + aparam.name + ": corresponding is not a vararg parameter")
}
- def MacroImplTargMismatchError(atargs: List[Type], atparams: List[Symbol]) = {
- val bounds = atparams map (tp => tp.info.instantiateTypeParams(atparams, atargs).bounds)
- compatibilityError("type arguments " + atargs.mkString("[", ",", "]") +
- " do not conform to " + atparams.head.owner + "'s type parameter bounds " +
- (atparams map (_.defString)).mkString("[", ",", "]"))
- }
+ def MacroImplTargMismatchError(atargs: List[Type], atparams: List[Symbol]) =
+ compatibilityError(typer.infer.InferErrorGen.NotWithinBoundsErrorMessage("", atargs, atparams, macroDebugVerbose || settings.explaintypes.value))
- def MacroImplTparamInstantiationError(atparams: List[Symbol], ex: NoInstance) = {
+ def MacroImplTparamInstantiationError(atparams: List[Symbol], ex: NoInstance) =
compatibilityError(
"type parameters "+(atparams map (_.defString) mkString ", ")+" cannot be instantiated\n"+
ex.getMessage)
- }
}
}