diff options
author | Lex Spoon <lex@lexspoon.org> | 2007-11-30 16:01:14 +0000 |
---|---|---|
committer | Lex Spoon <lex@lexspoon.org> | 2007-11-30 16:01:14 +0000 |
commit | c73986baa5ae1570852e708a1cf43ce7ef5cd6ea (patch) | |
tree | 26a993ef596b40b719b7052482748ad6910149ce | |
parent | 493ab4a848e09908bac5c4ed523ef79bfba563c4 (diff) | |
download | scala-c73986baa5ae1570852e708a1cf43ce7ef5cd6ea.tar.gz scala-c73986baa5ae1570852e708a1cf43ce7ef5cd6ea.tar.bz2 scala-c73986baa5ae1570852e708a1cf43ce7ef5cd6ea.zip |
- When -Yself-in-annots is turned on, be carefu...
- When -Yself-in-annots is turned on, be careful not to re-type the same
annotation tree and thus use the wrong self symbol. Duplicate the tree
each time to prevent this. - mkAttributedQualifier can be given a term
symbol to use, if all else fails in converting the type to a tree. -
AsSeenFromMap will sometimes use the above facility.
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/TreeGen.scala | 17 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Types.scala | 12 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 15 |
3 files changed, 36 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index d4544252fc..1aaa2f41bf 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -18,9 +18,21 @@ abstract class TreeGen { import definitions._ import posAssigner.atPos + + /** Builds a reference to value whose type is given stable prefix. + * The type must be suitable for this. For example, it + * must not be a TypeRef pointing to an abstract type variable. + */ + def mkAttributedQualifier(tpe: Type): Tree = + mkAttributedQualifier(tpe, NoSymbol) + /** Builds a reference to value whose type is given stable prefix. + * If the type is unsuitable, e.g. it is a TypeRef for an + * abstract type variable, then an Ident will be made using + * termSym as the Ident's symbol. In that case, termSym must + * not be NoSymbol. */ - def mkAttributedQualifier(tpe: Type): Tree = tpe match { + def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree = tpe match { case NoPrefix => EmptyTree case ThisType(clazz) => @@ -48,6 +60,9 @@ abstract class TreeGen { } else if (sym.isModule || sym.isClass) { assert(phase.erasedTypes, tpe) mkAttributedThis(sym) + } else if (sym.isType) { + assert(termSym != NoSymbol) + mkAttributedIdent(termSym) setType tpe } else { mkAttributedRef(pre, sym) } diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index 8a28452072..0a6aa4df52 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -2477,9 +2477,13 @@ A type's typeSymbol should never be inspected directly. case This(_) if (tree.symbol isNonBottomSubClass clazz) && (pre.widen.typeSymbol isNonBottomSubClass tree.symbol) => - if (pre.isStable) - mkAttributedQualifier(pre) - else + if (pre.isStable) { + val termSym = + pre.typeSymbol.owner.newValue( + pre.typeSymbol.pos, + pre.typeSymbol.name).setInfo(pre) // what symbol should really be used? + mkAttributedQualifier(pre, termSym) + } else giveup() case tree => tree @@ -2810,7 +2814,7 @@ A type's typeSymbol should never be inspected directly. case DeBruijnIndex(level, pid) => if (level == 1) { if (actuals(pid).isStable) - mkAttributedQualifier(actuals(pid)) + mkAttributedQualifier(actuals(pid), tree.symbol) else { val sym = existSymFor(pid, tree.symbol) (Ident(tree.symbol.name) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 2fdf3e561f..b1cf36c53c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1804,17 +1804,26 @@ trait Typers { self: Analyzer => // and then stripping the "self =>" and substituting // in the supplied selfsym. val funcparm = ValDef(NoMods, nme.self, TypeTree(selfsym.info), EmptyTree) - val func = Function(List(funcparm), annot.constr) + val func = Function(List(funcparm), annot.constr.duplicate) + // The .duplicate of annot.constr + // deals with problems that + // accur if this annotation is + // later typed again, which + // the compiler sometimes does. + // The problem is that "self" + // ident's within annot.constr + // will retain the old symbol + // from the previous typing. val fun1clazz = FunctionClass(1) val funcType = typeRef(fun1clazz.tpe.prefix, fun1clazz, List(selfsym.info, AnnotationClass.tpe)) - typed (func, mode, funcType) match { + typed(func, mode, funcType) match { case t @ Function(List(arg), rhs) => val subs = new TreeSymSubstituter(List(arg.symbol),List(selfsym)) - subs(rhs) + subs(rhs) } } |