diff options
Diffstat (limited to 'src/compiler/scala/reflect')
-rw-r--r-- | src/compiler/scala/reflect/internal/Flags.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/reflect/internal/Symbols.scala | 22 | ||||
-rw-r--r-- | src/compiler/scala/reflect/internal/Types.scala | 7 |
3 files changed, 22 insertions, 9 deletions
diff --git a/src/compiler/scala/reflect/internal/Flags.scala b/src/compiler/scala/reflect/internal/Flags.scala index 8aae80eed4..3110d73461 100644 --- a/src/compiler/scala/reflect/internal/Flags.scala +++ b/src/compiler/scala/reflect/internal/Flags.scala @@ -107,7 +107,7 @@ class ModifierFlags { // pre: PRIVATE or PROTECTED are also set final val JAVA = 0x00100000 // symbol was defined by a Java class final val STATIC = 0x00800000 // static field, method or class - final val CASEACCESSOR = 0x01000000 // symbol is a case parameter (or its accessor) + final val CASEACCESSOR = 0x01000000 // symbol is a case parameter (or its accessor, or a GADT skolem) final val TRAIT = 0x02000000 // symbol is a trait final val DEFAULTPARAM = 0x02000000 // the parameter has a default value final val PARAMACCESSOR = 0x20000000 // for field definitions generated for primary constructor diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 9678d2b8cd..7673aec4c7 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -269,11 +269,17 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Create a new existential type skolem with this symbol its owner, * based on the given symbol and origin. */ - def newExistentialSkolem(basis: Symbol, origin: AnyRef, name: TypeName = null, info: Type = null): TypeSkolem = { - val skolem = newTypeSkolemSymbol(if (name eq null) basis.name.toTypeName else name, origin, basis.pos, (basis.flags | EXISTENTIAL) & ~PARAM) - skolem setInfo (if (info eq null) basis.info cloneInfo skolem else info) + def newExistentialSkolem(basis: Symbol, origin: AnyRef): TypeSkolem = { + val skolem = newTypeSkolemSymbol(basis.name.toTypeName, origin, basis.pos, (basis.flags | EXISTENTIAL) & ~PARAM) + skolem setInfo (basis.info cloneInfo skolem) } + // flags set up to maintain TypeSkolem's invariant: origin.isInstanceOf[Symbol] == !hasFlag(EXISTENTIAL) + // CASEACCESSOR | SYNTHETIC used to single this symbol out in deskolemizeGADT + def newGADTSkolem(name: TypeName, origin: Symbol, info: Type): TypeSkolem = + newTypeSkolemSymbol(name, origin, origin.pos, origin.flags & ~(EXISTENTIAL | PARAM) | CASEACCESSOR | SYNTHETIC) setInfo info + + final def newExistential(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): Symbol = newAbstractType(name, pos, EXISTENTIAL | newFlags) @@ -495,6 +501,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => // List[T] forSome { type T } final def isExistentialSkolem = isExistentiallyBound && isSkolem final def isExistentialQuantified = isExistentiallyBound && !isSkolem + final def isGADTSkolem = isSkolem && hasFlag(CASEACCESSOR | SYNTHETIC) // class C extends D( { class E { ... } ... } ). Here, E is a class local to a constructor final def isClassLocalToConstructor = isClass && hasFlag(INCONSTRUCTOR) @@ -2129,12 +2136,17 @@ trait Symbols extends api.Symbols { self: SymbolTable => else if (owner.isRefinementClass) ExplicitFlags & ~OVERRIDE else ExplicitFlags + // make the error message more googlable + def flagsExplanationString = + if (isGADTSkolem) " (this is a GADT skolem)" + else "" + def accessString = hasFlagsToString(PRIVATE | PROTECTED | LOCAL) def defaultFlagString = hasFlagsToString(defaultFlagMask) private def defStringCompose(infoString: String) = compose( defaultFlagString, keyString, - varianceString + nameString + infoString + varianceString + nameString + infoString + flagsExplanationString ) /** String representation of symbol's definition. It uses the * symbol's raw info to avoid forcing types. @@ -2477,7 +2489,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * where the skolem was introduced (this is important for knowing when to pack it * again into ab Existential). origin is `null` only in skolemizeExistentials called * from <:< or isAsSpecific, because here its value does not matter. - * I elieve the following invariant holds: + * I believe the following invariant holds: * * origin.isInstanceOf[Symbol] == !hasFlag(EXISTENTIAL) */ diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 2382413a9a..549c9e4607 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -1041,8 +1041,8 @@ trait Types extends api.Types { self: SymbolTable => baseClasses.head.newOverloaded(this, members.toList) } } - /** The existential skolems and existentially quantified variables which are free in this type */ - def existentialSkolems: List[Symbol] = { + /** The (existential or otherwise) skolems and existentially quantified variables which are free in this type */ + def skolemsExceptMethodTypeParams: List[Symbol] = { var boundSyms: List[Symbol] = List() var skolems: List[Symbol] = List() for (t <- this) { @@ -1050,7 +1050,8 @@ trait Types extends api.Types { self: SymbolTable => case ExistentialType(quantified, qtpe) => boundSyms = boundSyms ::: quantified case TypeRef(_, sym, _) => - if ((sym hasFlag EXISTENTIAL) && !(boundSyms contains sym) && !(skolems contains sym)) + if ((sym.isExistentialSkolem || sym.isGADTSkolem) && // treat GADT skolems like existential skolems + !((boundSyms contains sym) || (skolems contains sym))) skolems = sym :: skolems case _ => } |