aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala12
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala17
-rw-r--r--src/dotty/tools/dotc/core/TypeOps.scala11
-rw-r--r--src/dotty/tools/dotc/core/Types.scala30
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 */