diff options
author | Martin Odersky <odersky@gmail.com> | 2013-03-12 10:51:20 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-03-12 10:51:20 +0100 |
commit | 54400119585ca41c28baae1cbfbeefb76b5c912a (patch) | |
tree | 85d0559c2991d5bde6732a77d068d9bd6ff67a30 /src/dotty/tools | |
parent | bf8e854c9f2dc2b03be5a44c84183af21510e6ef (diff) | |
download | dotty-54400119585ca41c28baae1cbfbeefb76b5c912a.tar.gz dotty-54400119585ca41c28baae1cbfbeefb76b5c912a.tar.bz2 dotty-54400119585ca41c28baae1cbfbeefb76b5c912a.zip |
Checking abstractness of types by their flags.
Previously we looked at the info, but this forces too much. As a consequence we now systematically prefer concrete over abstract when computing & denotations. This could have the strange(?) effect that the symbol of a joint denotation is a class, yet its info is a TypeBounds value.
Diffstat (limited to 'src/dotty/tools')
-rw-r--r-- | src/dotty/tools/dotc/core/Denotations.scala | 12 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 17 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeOps.scala | 11 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 30 |
4 files changed, 22 insertions, 48 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index 693c3c0c5..02b1550d5 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -220,14 +220,6 @@ object Denotations { case denot1: SingleDenotation => if (denot1 eq denot2) denot1 else if (denot1.signature == denot2.signature) { - /** symbols eligible for a joint denotation are: - * - type symbols, as long as they are not classes - * - term symbols, where concrete symbols take precedence over abstract ones. - */ - def isEligible(sym1: Symbol, sym2: Symbol) = - if (sym1.isType) !sym1.isClass - else sym1.exists && ( - !(sym1 is Deferred) || !sym2.exists || (sym2 is Deferred)) /** Convert class info C to bounds C..C */ def normalize(info: Type) = if (isType) info.bounds else info @@ -235,8 +227,8 @@ object Denotations { val info1 = denot1.info val sym2 = denot2.symbol val info2 = denot2.info - val sym1Eligible = isEligible(sym1, sym2) - val sym2Eligible = isEligible(sym2, sym1) + val sym1Eligible = sym1.isAsConcrete(sym2) + val sym2Eligible = sym2.isAsConcrete(sym1) val bounds1 = normalize(info1) val bounds2 = normalize(info2) if (sym2Eligible && bounds2 <:< bounds1) denot2 diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 6dd45a4a2..3e1af6c9a 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -207,13 +207,13 @@ object SymDenotations { initial.asSymDenotation.name startsWith tpnme.ANON_CLASS /** Is this symbol an abstract type? */ - final def isAbstractType = isType && info.isRealTypeBounds + final def isAbstractType = isType && (this is Deferred) /** Is this symbol an alias type? */ - final def isAliasType = isType && info.isAliasTypeBounds + final def isAliasType = isAbstractOrAliasType && !(this is Deferred) /** Is this symbol an abstract or alias type? */ - final def isAbstractOrAliasType = isType & info.isInstanceOf[TypeBounds] + final def isAbstractOrAliasType = isType & !isClass /** Is this definition contained in `boundary`? * Same as `ownersIterator contains boundary` but more efficient. @@ -251,9 +251,12 @@ object SymDenotations { /** Is this a denotation of a stable term (or an arbitrary type)? */ final def isStable(implicit ctx: Context) = { val isUnstable = - this.is(UnstableValue, butNot = Stable) || + (this is UnstableValue) || info.isVolatile && !hasAnnotation(defn.uncheckedStableClass) - !(isTerm && isUnstable) + (this is Stable) || isType || { + if (isUnstable) false + else { setFlag(Stable); true } + } } /** Is this a user defined "def" method? Excluded are accessors and stable values */ @@ -380,6 +383,10 @@ object SymDenotations { || (pre eq thisType) ) + /** Is this symbol concrete, or that symbol deferred? */ + def isAsConcrete(that: Symbol)(implicit ctx: Context): Boolean = + !(this is Deferred) || (that is Deferred) + // def isOverridable: Boolean = !!! need to enforce that classes cannot be redefined // def isSkolem: Boolean = ??? diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala index 7660b8f2d..48cd03f60 100644 --- a/src/dotty/tools/dotc/core/TypeOps.scala +++ b/src/dotty/tools/dotc/core/TypeOps.scala @@ -23,13 +23,8 @@ trait TypeOps { this: Context => if (sym.isStatic) tp else { val tp1 = tp.derivedNamedType(asSeenFrom(tp.prefix, pre, cls, theMap)) - if ((tp1 ne tp) && (sym is TypeParam)) - // short-circuit instantiated type parameters - // by replacing pre.tp with its alias, if it has one. - tp1.info match { - case TypeBounds(lo, hi) if lo eq hi => hi - case _ => tp1 - } + // short-circuit instantiated type parameters + if ((tp1 ne tp) && (sym is (TypeParam, butNot = Deferred))) tp1.dealias else tp1 } case ThisType(thiscls) => @@ -74,7 +69,7 @@ trait TypeOps { this: Context => } needsChecking(tp, false) && { tp.DNF forall { case (parents, refinedNames) => - val absParents = parents filter (_.info.isRealTypeBounds) + val absParents = parents filter (_.symbol is Deferred) absParents.size >= 2 || { val ap = absParents.head (parents exists (p => diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 80a56d76b..d4b826bbc 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -72,7 +72,7 @@ object Types { /** Does this type denote a stable reference (i.e. singleton type)? */ final def isStable(implicit ctx: Context): Boolean = this match { - case tp: TermRef => tp.prefix.isStable && tp.termSymbol.isStable + case tp: TermRef => tp.termSymbol.isStable case _: SingletonType => true case _ => false } @@ -97,21 +97,6 @@ object Types { /** Is some part of this type produced as a repair for an error? */ final def isErroneous(implicit ctx: Context): Boolean = exists(_.isError) - /** Is this type a TypeBounds instance, with lower and upper bounds - * that are not identical? - */ - final def isRealTypeBounds: Boolean = this match { - case tp: TypeBounds => tp.lo ne tp.hi - case _ => false - } - - /** Is this type a TypeBounds instance, with lower and upper bounds - * that are identical? - */ - final def isAliasTypeBounds: Boolean = this match { - case tp: TypeBounds => tp.lo eq tp.hi - case _ => false - } /** A type is volatile if its DNF contains an alternative of the form * {P1, ..., Pn}, {N1, ..., Nk}, where the Pi are parent typerefs and the * Nj are refinement names, and one the 4 following conditions is met: @@ -414,7 +399,7 @@ object Types { */ final def normalizedPrefix(implicit ctx: Context): Type = this match { case tp: NamedType => - if (tp.info.isAliasTypeBounds) tp.info.normalizedPrefix else tp.prefix + if (tp.symbol.isAliasType) tp.info.normalizedPrefix else tp.prefix case tp: ClassInfo => tp.prefix case tp: TypeProxy => @@ -458,7 +443,7 @@ object Types { */ final def DNF(implicit ctx: Context): Set[(Set[TypeRef], Set[Name])] = this match { case tp: TypeRef => - if (tp.info.isAliasTypeBounds) tp.info.bounds.hi.DNF + if (tp.symbol.isAliasType) tp.info.bounds.hi.DNF else Set((Set(tp), Set())) case RefinedType(parent, name) => for ((ps, rs) <- parent.DNF) yield (ps, rs + name) @@ -762,12 +747,7 @@ object Types { } else { val d = loadDenot if (d.exists || ctx.phaseId == FirstPhaseId) { - val checkPrefix = d.info match { - case TypeBounds(lo, hi) => lo ne hi - case _: ClassInfo => true - case _ => false - } - if (checkPrefix && !prefix.isLegalPrefix) + if (!d.symbol.isAliasType && !prefix.isLegalPrefix) throw new MalformedType(prefix, d.asInstanceOf[SymDenotation]) d } else {// name has changed; try load in earlier phase and make current @@ -1469,7 +1449,7 @@ object Types { /** A filter for names of abstract types of a given type */ object abstractTypeNameFilter extends NameFilter { def apply(pre: Type, name: Name)(implicit ctx: Context): Boolean = - name.isTypeName && (pre member name).info.isRealTypeBounds + name.isTypeName && ((pre member name).symbol is Deferred) } /** A filter for names of deferred term definitions of a given type */ |