aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-12-21 12:11:42 +0100
committerMartin Odersky <odersky@gmail.com>2016-12-21 12:11:42 +0100
commitec35b840e71c34ea2d7c7a59a9c69ce0f44c4740 (patch)
treee99e65055b9612245540a4315ea13a958ae9efcf
parentcf4f773840ba3955b2907b04208b378d22d37651 (diff)
downloaddotty-ec35b840e71c34ea2d7c7a59a9c69ce0f44c4740.tar.gz
dotty-ec35b840e71c34ea2d7c7a59a9c69ce0f44c4740.tar.bz2
dotty-ec35b840e71c34ea2d7c7a59a9c69ce0f44c4740.zip
Tweak the way annotations are represented in desugaring
Need to be careful not to read a classfile before a compilation unit defining the annotation is entered.
-rw-r--r--compiler/src/dotty/tools/dotc/ast/Desugar.scala30
-rw-r--r--compiler/src/dotty/tools/dotc/typer/FrontEnd.scala16
-rw-r--r--compiler/test/dotc/scala-collections.blacklist3
-rw-r--r--compiler/test/dotc/scala-collections.whitelist2
4 files changed, 40 insertions, 11 deletions
diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
index 13ddff08c..211683c0a 100644
--- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
@@ -7,6 +7,7 @@ import util.Positions._, Types._, Contexts._, Constants._, Names._, NameOps._, F
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
import Decorators._
import language.higherKinds
+import typer.FrontEnd
import collection.mutable.ListBuffer
import util.Property
import reporting.diagnostic.messages._
@@ -363,7 +364,7 @@ object desugar {
if (mods.is(Abstract) || hasRepeatedParam) Nil // cannot have default arguments for repeated parameters, hence copy method is not issued
else {
def copyDefault(vparam: ValDef) =
- makeAnnotated(defn.UncheckedVarianceAnnot, refOfDef(vparam))
+ makeAnnotated("scala.annotation.unchecked.uncheckedVariance", refOfDef(vparam))
val copyFirstParams = derivedVparamss.head.map(vparam =>
cpy.ValDef(vparam)(rhs = copyDefault(vparam)))
val copyRestParamss = derivedVparamss.tail.nestedMap(vparam =>
@@ -559,7 +560,7 @@ object desugar {
case VarPattern(named, tpt) =>
derivedValDef(original, named, tpt, rhs, mods)
case _ =>
- val rhsUnchecked = makeAnnotated(defn.UncheckedAnnot, rhs)
+ val rhsUnchecked = makeAnnotated("scala.unchecked", rhs)
val vars = getVariables(pat)
val isMatchingTuple: Tree => Boolean = {
case Tuple(es) => es.length == vars.length
@@ -688,11 +689,28 @@ object desugar {
new ImplicitFunction(params, body)
}
- /** Add annotation with class `cls` to tree:
- * tree @cls
+ /** Add annotation to tree:
+ * tree @fullName
+ *
+ * The annotation is usually represented as a TypeTree referring to the class
+ * with the given name `fullName`. However, if the annotation matches a file name
+ * that is still to be entered, the annotation is represented as a cascade of `Selects`
+ * following `fullName`. This is necessary so that we avoid reading an annotation from
+ * the classpath that is also compiled from source.
*/
- def makeAnnotated(cls: Symbol, tree: Tree)(implicit ctx: Context) =
- Annotated(tree, untpd.New(untpd.TypeTree(cls.typeRef), Nil))
+ def makeAnnotated(fullName: String, tree: Tree)(implicit ctx: Context) = {
+ val parts = fullName.split('.')
+ val ttree = ctx.typerPhase match {
+ case phase: FrontEnd if phase.stillToBeEntered(parts.last) =>
+ val prefix =
+ ((Ident(nme.ROOTPKG): Tree) /: parts.init)((qual, name) =>
+ Select(qual, name.toTermName))
+ Select(prefix, parts.last.toTypeName)
+ case _ =>
+ TypeTree(ctx.requiredClass(fullName).typeRef)
+ }
+ Annotated(tree, untpd.New(ttree, Nil))
+ }
private def derivedValDef(original: Tree, named: NameTree, tpt: Tree, rhs: Tree, mods: Modifiers)(implicit ctx: Context) = {
val vdef = ValDef(named.name.asTermName, tpt, rhs)
diff --git a/compiler/src/dotty/tools/dotc/typer/FrontEnd.scala b/compiler/src/dotty/tools/dotc/typer/FrontEnd.scala
index cd374e32c..90ffbcdae 100644
--- a/compiler/src/dotty/tools/dotc/typer/FrontEnd.scala
+++ b/compiler/src/dotty/tools/dotc/typer/FrontEnd.scala
@@ -19,6 +19,15 @@ class FrontEnd extends Phase {
override def isTyper = true
import ast.tpd
+ /** The contexts for compilation units that are parsed but not yet entered */
+ private var remaining: List[Context] = Nil
+
+ /** Does a source file ending with `<name>.scala` belong to a compilation unit
+ * that is parsed but not yet entered?
+ */
+ def stillToBeEntered(name: String): Boolean =
+ remaining.exists(_.compilationUnit.toString.endsWith(name + ".scala"))
+
def monitor(doing: String)(body: => Unit)(implicit ctx: Context) =
try body
catch {
@@ -75,7 +84,12 @@ class FrontEnd extends Phase {
}
unitContexts foreach (parse(_))
record("parsedTrees", ast.Trees.ntrees)
- unitContexts.foreach(enterSyms(_))
+ unitContexts.foreach(ctx => println(ctx.compilationUnit))
+ remaining = unitContexts
+ while (remaining.nonEmpty) {
+ enterSyms(remaining.head)
+ remaining = remaining.tail
+ }
unitContexts.foreach(enterAnnotations(_))
unitContexts.foreach(typeCheck(_))
record("total trees after typer", ast.Trees.ntrees)
diff --git a/compiler/test/dotc/scala-collections.blacklist b/compiler/test/dotc/scala-collections.blacklist
index 342317825..7d3008bbc 100644
--- a/compiler/test/dotc/scala-collections.blacklist
+++ b/compiler/test/dotc/scala-collections.blacklist
@@ -1,8 +1,5 @@
## Errors having to do with bootstrap
-../scala-scala/src/library/scala/annotation/unchecked/uncheckedVariance.scala
-#java.lang.AssertionError: assertion failed: data race? overwriting symbol of type scala.annotation.unchecked.uncheckedVariance,
-
../scala-scala/src/library/scala/Function1.scala
../scala-scala/src/library/scala/Function2.scala
# Cyclic reference because of @specialized annotation
diff --git a/compiler/test/dotc/scala-collections.whitelist b/compiler/test/dotc/scala-collections.whitelist
index 1590120d3..cb7fd29b9 100644
--- a/compiler/test/dotc/scala-collections.whitelist
+++ b/compiler/test/dotc/scala-collections.whitelist
@@ -537,7 +537,7 @@
../scala-scala/src/library/scala/annotation/tailrec.scala
../scala-scala/src/library/scala/annotation/TypeConstraint.scala
../scala-scala/src/library/scala/annotation/unchecked/uncheckedStable.scala
-#../scala-scala/src/library/scala/annotation/unchecked/uncheckedVariance.scala
+../scala-scala/src/library/scala/annotation/unchecked/uncheckedVariance.scala
../scala-scala/src/library/scala/annotation/unspecialized.scala
../scala-scala/src/library/scala/annotation/varargs.scala