From d1794c15f5a5743763adeb8f8e248f9ca5f53869 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 12 Mar 2013 11:58:32 +0100 Subject: Revising of Denotation#exists exists now is only false for NoDenotation. A denotation with NoType as info counts as existing, but it is not accessible from any prefix. Also, renamed binary exists, forall or existsPart, forallParts to avoid ambiguities. --- src/dotty/tools/dotc/core/Denotations.scala | 9 ++------- src/dotty/tools/dotc/core/SymDenotations.scala | 14 ++++++-------- src/dotty/tools/dotc/core/TypedTrees.scala | 4 ++-- src/dotty/tools/dotc/core/Types.scala | 17 ++++++++--------- src/dotty/tools/dotc/core/pickling/UnPickler.scala | 2 +- 5 files changed, 19 insertions(+), 27 deletions(-) (limited to 'src/dotty/tools/dotc') diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index 02b1550d5..170233ee2 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -140,12 +140,7 @@ object Denotations { /** The variant of this denotation that's current in the given context. */ def current(implicit ctx: Context): Denotation - /** Does this denotation exist? - * A denotation does not exist if it has NoType as an info. - * This is the case for NoDenotation, and also for SymDenotations - * that come from package members (classes or modules) where no - * corresponding symbol was found in a classfile or source. - */ + /** Is this denotation different from NoDenotation? */ def exists: Boolean = true /** If this denotation does not exist, fallback to alternative */ @@ -184,7 +179,7 @@ object Denotations { */ def requiredSymbol(p: Symbol => Boolean, name: Name, source: AbstractFile = null)(implicit ctx: Context): Symbol = { val sym = disambiguate(p).symbol - if (sym != NoSymbol) sym // note would like to ask sym.exists instead, but this would force too much + if (sym.exists) sym else { val firstSym = ((NoSymbol: Symbol) /: alternatives.map(_.symbol)) (_ orElse _) val owner = if (firstSym.exists) firstSym.owner else NoSymbol diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 3e1af6c9a..68aa2f0fa 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -181,13 +181,6 @@ object SymDenotations { /** is this symbol the result of an erroneous definition? */ def isError: Boolean = false - /** Does this denotation refer to an existing definition? - * @return `false` if denotation is either `NoDenotation` or it - * refers to a toplevel class or object that has no - * definition in the source or classfile from which it is loaded. - */ - override final def exists: Boolean = info ne NoType - /** Make denotation not exist */ final def markAbsent(): Unit = _info = NoType @@ -305,6 +298,8 @@ object SymDenotations { /** Is this definition accessible as a member of tree with type `pre`? * @param pre The type of the tree from which the selection is made * @param superAccess Access is via super + * Everything is accessible if `pre` is `NoPrefix`. + * A symbol with type `NoType` is not accessible for any other prefix. */ final def isAccessibleFrom(pre: Type, superAccess: Boolean = false)(implicit ctx: Context): Boolean = { @@ -354,7 +349,9 @@ object SymDenotations { else true } - (pre == NoPrefix) || { + if (pre eq NoPrefix) true + else if (info eq NoType) false + else { val boundary = accessBoundary(owner) ( boundary.isTerm @@ -896,6 +893,7 @@ object SymDenotations { object NoDenotation extends SymDenotation( NoSymbol, NoSymbol, "".toTermName, EmptyFlags, NoType) { + override def exists = false override def isTerm = false override def isType = false override def owner: Symbol = throw new AssertionError("NoDenotation.owner") diff --git a/src/dotty/tools/dotc/core/TypedTrees.scala b/src/dotty/tools/dotc/core/TypedTrees.scala index 791f0b40a..d7179e9ac 100644 --- a/src/dotty/tools/dotc/core/TypedTrees.scala +++ b/src/dotty/tools/dotc/core/TypedTrees.scala @@ -484,7 +484,7 @@ object TypedTrees { noLeaksInClass(sym.asClass) } } - def noLeaksIn(tp: Type): Boolean = tp forall { + def noLeaksIn(tp: Type): Boolean = tp forallParts { case tp: NamedType => isNonLocal(tp.symbol) case _ => true } @@ -543,7 +543,7 @@ object TypedTrees { val rsym = r.symbol check(rsym.isTerm || rsym.isAbstractOrAliasType) if (rsym.isAbstractType) check(tpt.tpe.member(rsym.name).exists) - check(rsym.info forall { + check(rsym.info forallParts { case nt: NamedType => !(forbidden contains nt.symbol) case _ => true }) diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index d4b826bbc..966150ab3 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -95,7 +95,7 @@ object Types { (typeSymbol is Erroneous) || (termSymbol is Erroneous) /** Is some part of this type produced as a repair for an error? */ - final def isErroneous(implicit ctx: Context): Boolean = exists(_.isError) + final def isErroneous(implicit ctx: Context): Boolean = existsPart(_.isError) /** 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 @@ -119,12 +119,12 @@ object Types { /** Returns true if there is a part of this type that satisfies predicate `p`. */ - final def exists(p: Type => Boolean): Boolean = + final def existsPart(p: Type => Boolean): Boolean = new ExistsAccumulator(p)(false, this) /** Returns true if all parts of this type that satisfy predicate `p`. */ - final def forall(p: Type => Boolean): Boolean = !exists(!p(_)) + final def forallParts(p: Type => Boolean): Boolean = !existsPart(!p(_)) /** Map function over elements of an AndType, rebuilding with & */ def mapAnd(f: Type => Type)(implicit ctx: Context): Type = this match { @@ -746,13 +746,12 @@ object Types { lastDenotation.current } else { val d = loadDenot - if (d.exists || ctx.phaseId == FirstPhaseId) { - if (!d.symbol.isAliasType && !prefix.isLegalPrefix) - throw new MalformedType(prefix, d.asInstanceOf[SymDenotation]) + if (d.exists && !d.symbol.isAliasType && !prefix.isLegalPrefix) + throw new MalformedType(prefix, d.asInstanceOf[SymDenotation]) + if (d.exists || ctx.phaseId == FirstPhaseId) d - } else {// name has changed; try load in earlier phase and make current + else // name has changed; try load in earlier phase and make current denot(ctx.fresh.withPhase(ctx.phaseId - 1)).current - } } } lastDenotation @@ -1011,7 +1010,7 @@ object Types { def isJava = false def isImplicit = false - lazy val isDependent = resultType exists { + lazy val isDependent = resultType existsPart { case MethodParam(mt, _) => mt eq this case _ => false } diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala index 27cc10ee6..db3370601 100644 --- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala +++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala @@ -454,7 +454,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleRoot: Clas } val tp1 = elim(tp) val isBound = (tp: Type) => boundSyms contains tp.typeSymbol - if (tp1 exists isBound) { + if (tp1 existsPart isBound) { val tp2 = tp1.subst(boundSyms, boundSyms map (_ => defn.AnyType)) cctx.warning(s"""failure to eliminate existential |original type : $tp forSome {${cctx.showDcls(boundSyms, "; ")}} -- cgit v1.2.3