diff options
author | Paul Phillips <paulp@improving.org> | 2013-02-01 17:38:56 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2013-02-01 17:38:56 -0800 |
commit | a45a78a1d4111709acdc0bca9a1ac869a8e53ea5 (patch) | |
tree | 5c909c41db2470c460cbb3c33672294c9342b914 /src/reflect | |
parent | 26de4394b19d6614b7d414b33f66ebf7adcb8833 (diff) | |
parent | 644eb7078a11613a06dcaaefb807cbcc44f65ea7 (diff) | |
download | scala-a45a78a1d4111709acdc0bca9a1ac869a8e53ea5.tar.gz scala-a45a78a1d4111709acdc0bca9a1ac869a8e53ea5.tar.bz2 scala-a45a78a1d4111709acdc0bca9a1ac869a8e53ea5.zip |
Merge commit '644eb7078a' into wip/fresh-merge2
Conflicts:
build.xml
src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
Diffstat (limited to 'src/reflect')
-rw-r--r-- | src/reflect/scala/reflect/internal/Symbols.scala | 38 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/TreeInfo.scala | 18 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Types.scala | 12 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/util/Position.scala | 8 |
4 files changed, 53 insertions, 23 deletions
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 6894c68062..bd9c1576a1 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -1611,8 +1611,21 @@ trait Symbols extends api.Symbols { self: SymbolTable => setAnnotations(annot :: annotations) // Convenience for the overwhelmingly common case - def addAnnotation(sym: Symbol, args: Tree*): this.type = + def addAnnotation(sym: Symbol, args: Tree*): this.type = { + // The assertion below is meant to prevent from issues like SI-7009 but it's disabled + // due to problems with cycles while compiling Scala library. It's rather shocking that + // just checking if sym is monomorphic type introduces nasty cycles. We are definitively + // forcing too much because monomorphism is a local property of a type that can be checked + // syntactically + // assert(sym.initialize.isMonomorphicType, sym) addAnnotation(AnnotationInfo(sym.tpe, args.toList, Nil)) + } + + /** Use that variant if you want to pass (for example) an applied type */ + def addAnnotation(tp: Type, args: Tree*): this.type = { + assert(tp.typeParams.isEmpty, tp) + addAnnotation(AnnotationInfo(tp, args.toList, Nil)) + } // ------ comparisons ---------------------------------------------------------------- @@ -1769,8 +1782,27 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** For a case class, the symbols of the accessor methods, one for each * argument in the first parameter list of the primary constructor. * The empty list for all other classes. - */ - final def caseFieldAccessors: List[Symbol] = + * + * This list will be sorted to correspond to the declaration order + * in the constructor parameter + */ + final def caseFieldAccessors: List[Symbol] = { + // We can't rely on the ordering of the case field accessors within decls -- + // handling of non-public parameters seems to change the order (see SI-7035.) + // + // Luckily, the constrParamAccessors are still sorted properly, so sort the field-accessors using them + // (need to undo name-mangling, including the sneaky trailing whitespace) + // + // The slightly more principled approach of using the paramss of the + // primary constructor leads to cycles in, for example, pos/t5084.scala. + val primaryNames = constrParamAccessors.map(acc => nme.dropLocalSuffix(acc.name)) + caseFieldAccessorsUnsorted.sortBy { acc => + primaryNames indexWhere { orig => + (acc.name == orig) || (acc.name startsWith (orig append "$")) + } + } + } + private final def caseFieldAccessorsUnsorted: List[Symbol] = (info.decls filter (_.isCaseAccessorMethod)).toList final def constrParamAccessors: List[Symbol] = diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala index 4c67771485..9b8f86751e 100644 --- a/src/reflect/scala/reflect/internal/TreeInfo.scala +++ b/src/reflect/scala/reflect/internal/TreeInfo.scala @@ -253,22 +253,24 @@ abstract class TreeInfo { * in the position `for { <tree> <- expr }` based only * on information at the `parser` phase? To qualify, there * may be no subtree that will be interpreted as a - * Stable Identifier Pattern. + * Stable Identifier Pattern, nor any type tests, even + * on TupleN. See SI-6968. * * For instance: * * {{{ - * foo @ (bar, (baz, quux)) + * (foo @ (bar @ _)) = 0 * }}} * - * is a variable pattern; if the structure matches, - * then the remainder is inevitable. + * is a not a variable pattern; if only binds names. * * The following are not variable patterns. * * {{{ - * foo @ (bar, (`baz`, quux)) // back quoted ident, not at top level - * foo @ (bar, Quux) // UpperCase ident, not at top level + * `bar` + * Bar + * (a, b) + * _: T * }}} * * If the pattern is a simple identifier, it is always @@ -297,10 +299,6 @@ abstract class TreeInfo { tree match { case Bind(name, pat) => isVarPatternDeep0(pat) case Ident(name) => isVarPattern(tree) - case Apply(sel, args) => - ( isReferenceToScalaMember(sel, TupleClass(args.size).name.toTermName) - && (args forall isVarPatternDeep0) - ) case _ => false } } diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 0dfa3abf29..71343cfce2 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -732,7 +732,7 @@ trait Types extends api.Types { self: SymbolTable => val trivial = ( this.isTrivial || phase.erasedTypes && pre.typeSymbol != ArrayClass - || pre.normalize.isTrivial && !isPossiblePrefix(clazz) + || skipPrefixOf(pre, clazz) ) if (trivial) this else { @@ -4341,14 +4341,15 @@ trait Types extends api.Types { self: SymbolTable => */ def isPossiblePrefix(clazz: Symbol) = clazz.isClass && !clazz.isPackageClass + private def skipPrefixOf(pre: Type, clazz: Symbol) = ( + (pre eq NoType) || (pre eq NoPrefix) || !isPossiblePrefix(clazz) + ) + /** A map to compute the asSeenFrom method */ class AsSeenFromMap(pre: Type, clazz: Symbol) extends TypeMap with KeepOnlyTypeConstraints { var capturedSkolems: List[Symbol] = List() var capturedParams: List[Symbol] = List() - private def skipPrefixOf(pre: Type, clazz: Symbol) = ( - (pre eq NoType) || (pre eq NoPrefix) || !isPossiblePrefix(clazz) - ) override def mapOver(tree: Tree, giveup: ()=>Nothing): Tree = { object annotationArgRewriter extends TypeMapTransformer { private def canRewriteThis(sym: Symbol) = ( @@ -4381,8 +4382,7 @@ trait Types extends api.Types { self: SymbolTable => } def apply(tp: Type): Type = - if (skipPrefixOf(pre, clazz)) tp - else tp match { + tp match { case ThisType(sym) => def toPrefix(pre: Type, clazz: Symbol): Type = if (skipPrefixOf(pre, clazz)) tp diff --git a/src/reflect/scala/reflect/internal/util/Position.scala b/src/reflect/scala/reflect/internal/util/Position.scala index 1c29cabe24..f0185372c5 100644 --- a/src/reflect/scala/reflect/internal/util/Position.scala +++ b/src/reflect/scala/reflect/internal/util/Position.scala @@ -91,7 +91,7 @@ abstract class Position extends scala.reflect.api.Position { self => /** An optional value containing the source file referred to by this position, or * None if not defined. */ - def source: SourceFile = throw new UnsupportedOperationException("Position.source") + def source: SourceFile = throw new UnsupportedOperationException(s"Position.source on ${this.getClass}") /** Is this position neither a NoPosition nor a FakePosition? * If isDefined is true, offset and source are both defined. @@ -111,19 +111,19 @@ abstract class Position extends scala.reflect.api.Position { self => def makeTransparent: Position = this /** The start of the position's range, error if not a range position */ - def start: Int = throw new UnsupportedOperationException("Position.start") + def start: Int = throw new UnsupportedOperationException(s"Position.start on ${this.getClass}") /** The start of the position's range, or point if not a range position */ def startOrPoint: Int = point /** The point (where the ^ is) of the position */ - def point: Int = throw new UnsupportedOperationException("Position.point") + def point: Int = throw new UnsupportedOperationException(s"Position.point on ${this.getClass}") /** The point (where the ^ is) of the position, or else `default` if undefined */ def pointOrElse(default: Int): Int = default /** The end of the position's range, error if not a range position */ - def end: Int = throw new UnsupportedOperationException("Position.end") + def end: Int = throw new UnsupportedOperationException(s"Position.end on ${this.getClass}") /** The end of the position's range, or point if not a range position */ def endOrPoint: Int = point |