summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2012-04-14 09:27:15 -0700
committerMartin Odersky <odersky@gmail.com>2012-04-14 09:27:15 -0700
commitfb0024ce18e57bd24d87ca9bab6b81af4d52a5ce (patch)
treeabe2fe8b03520fed9d38594dfca5155fba221cfa /src/compiler
parent9b50dc0dc2c11990e88a8de045dd6e92a409a0cf (diff)
downloadscala-fb0024ce18e57bd24d87ca9bab6b81af4d52a5ce.tar.gz
scala-fb0024ce18e57bd24d87ca9bab6b81af4d52a5ce.tar.bz2
scala-fb0024ce18e57bd24d87ca9bab6b81af4d52a5ce.zip
Made checkFeature conditionally run immediately. Adapted Macros to make use of it.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala11
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala27
2 files changed, 24 insertions, 14 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index b7e0eaef2b..62a0e08aad 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -185,16 +185,7 @@ trait Macros { self: Analyzer =>
import typer.context
if (macroDebug) println("typechecking macro def %s at %s".format(ddef.symbol, ddef.pos))
- typer.checkFeature(ddef.pos, MacrosFeature)
-
- // [Eugene to Martin] todo. copy/pasted this from checkFeature, because don't know a better way
- // this is necessary to prevent macros from typechecking/expanding when they are not enabled
- // `checkFeature` call alone is not enough, because it merely posts validation callback to unit.toCheck
- def hasImport = inferImplicit(EmptyTree: Tree, MacrosFeature.tpe, true, false, typer.context) != SearchFailure
- val nestedOwners = MacrosFeature.owner.ownerChain.takeWhile(_ != languageFeatureModule.moduleClass).reverse
- val featureName = (nestedOwners map (_.name + ".")).mkString + MacrosFeature.name
- def hasOption = settings.language.value contains featureName
- if (!hasImport && !hasOption) {
+ if (!typer.checkFeature(ddef.pos, MacrosFeature, immediate = true)) {
ddef.symbol setFlag IS_ERROR
return EmptyTree
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 0541f85f31..043e826d32 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -733,15 +733,27 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
}
- def checkFeature(pos: Position, featureTrait: Symbol, construct: => String = "") =
- if (!isPastTyper) {
+ /** Check whether feature given by `featureTrait` is enabled.
+ * If it is not, issue an error or a warning depending on whether the feature is required.
+ * @param construct A string expression that is substituted for "#" in the feature description string
+ * @param immediate When set, feature check is run immediately, otherwise it is run
+ * at the end of the typechecking run for the enclosing unit. This
+ * is done to avoid potential cyclic reference errors by implicits
+ * that are forced too early.
+ * @return if feature check is run immediately: true if feature is enabled, false otherwise
+ * if feature check is delayed or suppressed because we are past typer: true
+ */
+ def checkFeature(pos: Position, featureTrait: Symbol, construct: => String = "", immediate: Boolean = false): Boolean =
+ if (isPastTyper) true
+ else {
val nestedOwners =
featureTrait.owner.ownerChain.takeWhile(_ != languageFeatureModule.moduleClass).reverse
val featureName = (nestedOwners map (_.name + ".")).mkString + featureTrait.name
- unit.toCheck += { () =>
+ def action(): Boolean = {
def hasImport = inferImplicit(EmptyTree: Tree, featureTrait.tpe, true, false, context) != SearchFailure
def hasOption = settings.language.value contains featureName
- if (!hasImport && !hasOption) {
+ val OK = hasImport || hasOption
+ if (!OK) {
val Some(AnnotationInfo(_, List(Literal(Constant(featureDesc: String)), Literal(Constant(required: Boolean))), _)) =
featureTrait getAnnotation LanguageFeatureAnnot
val req = if (required) "needs to" else "should"
@@ -757,6 +769,13 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if (required) unit.error(pos, msg)
else currentRun.featureWarnings.warn(pos, msg)
}
+ OK
+ }
+ if (immediate) {
+ action()
+ } else {
+ unit.toCheck += action
+ true
}
}