diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-03-12 17:58:34 +0100 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-03-19 17:06:51 +0100 |
commit | 910a701fcc93e0663f0a6a15ac11499beb1ca6a9 (patch) | |
tree | 77e246101fc16226237b5a22a2b904908e1d7287 /src/compiler/scala/reflect/internal/Symbols.scala | |
parent | 78c15103d54e58b0ecd193b90e2d56b967967d6c (diff) | |
download | scala-910a701fcc93e0663f0a6a15ac11499beb1ca6a9.tar.gz scala-910a701fcc93e0663f0a6a15ac11499beb1ca6a9.tar.bz2 scala-910a701fcc93e0663f0a6a15ac11499beb1ca6a9.zip |
SI-5189: refined GADT soundness fix
extrapolate GADT skolems: only complicate types when needed
make sure we only deskolemize GADT skolems after typedCase
Diffstat (limited to 'src/compiler/scala/reflect/internal/Symbols.scala')
-rw-r--r-- | src/compiler/scala/reflect/internal/Symbols.scala | 22 |
1 files changed, 17 insertions, 5 deletions
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) */ |