From 1e70081069055630821bb6ca6c1e307e1ab074b4 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 5 Mar 2013 21:59:50 +0100 Subject: More polishing of types. --- src/dotty/tools/dotc/config/JavaPlatform.scala | 2 +- src/dotty/tools/dotc/config/Platform.scala | 2 +- src/dotty/tools/dotc/core/Contexts.scala | 1 - src/dotty/tools/dotc/core/SymDenotations.scala | 23 ++++++++++---------- src/dotty/tools/dotc/core/TypeOps.scala | 30 +++++++++++--------------- src/dotty/tools/dotc/core/Types.scala | 27 +++++++++++------------ 6 files changed, 39 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/dotty/tools/dotc/config/JavaPlatform.scala b/src/dotty/tools/dotc/config/JavaPlatform.scala index 7f234b613..0698ac929 100644 --- a/src/dotty/tools/dotc/config/JavaPlatform.scala +++ b/src/dotty/tools/dotc/config/JavaPlatform.scala @@ -28,7 +28,7 @@ class JavaPlatform extends Platform { * to anything but other booleans, but it should be present in * case this is put to other uses. */ - def isMaybeBoxed(sym: Symbol)(implicit ctx: Context) = { + def isMaybeBoxed(sym: ClassSymbol)(implicit ctx: Context) = { val d = defn import d._ (sym == ObjectClass) || diff --git a/src/dotty/tools/dotc/config/Platform.scala b/src/dotty/tools/dotc/config/Platform.scala index 304ddb2f1..7dc2507f2 100644 --- a/src/dotty/tools/dotc/config/Platform.scala +++ b/src/dotty/tools/dotc/config/Platform.scala @@ -28,7 +28,7 @@ abstract class Platform { //def platformPhases: List[SubComponent] /** The various ways a boxed primitive might materialize at runtime. */ - def isMaybeBoxed(sym: Symbol)(implicit ctx: Context): Boolean + def isMaybeBoxed(sym: ClassSymbol)(implicit ctx: Context): Boolean /** Create a new class loader to load class file `bin` */ def newClassLoader(bin: AbstractFile)(implicit ctx: Context): SymbolLoader diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index f769ad318..080e45341 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -300,7 +300,6 @@ object Contexts { override def hash(x: Type): Int = x.hash } - // Types state /** The number of recursive invocation of underlying on a NamedType */ private[core] var underlyingRecursions: Int = 0 diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 5f8cc1ffe..0af7d7b3a 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -295,11 +295,6 @@ object SymDenotations { */ def isNonBottomSubClass(base: Symbol)(implicit ctx: Context) = false - /** Is this a subclass of `base` or a companion object of such a subclass? */ - final def isSubClassOrCompanion(base: Symbol)(implicit ctx: Context): Boolean = - isNonBottomSubClass(base) || - isModuleClass && linkedClass.isNonBottomSubClass(base) - /** Is this symbol a class that does not extend `AnyVal`? */ final def isNonValueClass(implicit ctx: Context): Boolean = isClass && !isSubClass(defn.AnyValClass) @@ -345,10 +340,10 @@ object SymDenotations { |enclosing ${ctx.owner.enclosingClass.showLocated} is not a subclass of |${owner.showLocated} where target is defined""".stripMargin) else if ( - !(isType || // allow accesses to types from arbitrary subclasses fixes #4737 - pre.widen.typeSymbol.isSubClassOrCompanion(cls) || - cls.isModuleClass && - pre.widen.typeSymbol.isSubClassOrCompanion(cls.linkedClass))) + !( isType // allow accesses to types from arbitrary subclasses fixes #4737 + || pre.baseType(cls).exists + || owner.isModuleClass // don't perform this check for static members + )) fail( s"""Access to protected ${symbol.show} not permitted because |prefix type ${pre.widen.show} does not conform to @@ -800,8 +795,14 @@ object SymDenotations { case p :: ps1 => reduce(bt & baseTypeOf(p), ps1) case _ => bt } - if (tp.cls eq symbol) tp.typeConstructor - else tp.rebase(reduce(NoType, tp.classParents)) + if (tp.cls eq symbol) + tp.typeConstructor + else if (tp.cls.classDenot.superClassBits contains symbol.superId) + tp.rebase(reduce(NoType, tp.classParents)) + else + NoType + case _ => + NoType } if (symbol.isStatic) symbol.typeConstructor diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala index 82bd252f0..b81eb4a55 100644 --- a/src/dotty/tools/dotc/core/TypeOps.scala +++ b/src/dotty/tools/dotc/core/TypeOps.scala @@ -4,22 +4,18 @@ import Contexts._, Types._, Symbols._, Names._, Flags._, Scopes._ trait TypeOps { this: Context => - final def asSeenFrom(tp: Type, pre: Type, clazz: Symbol, theMap: AsSeenFromMap): Type = { + final def asSeenFrom(tp: Type, pre: Type, cls: Symbol, theMap: AsSeenFromMap): Type = { - def skipPrefixOf(pre: Type, clazz: Symbol) = - (pre eq NoType) || (pre eq NoPrefix) || clazz.isPackageClass - - def toPrefix(pre: Type, clazz: Symbol, thisclazz: ClassSymbol): Type = - if (skipPrefixOf(pre, clazz)) + def toPrefix(pre: Type, cls: Symbol, thiscls: ClassSymbol): Type = + if ((pre eq NoType) || (pre eq NoPrefix) || cls.isPackageClass) tp - else if ((thisclazz isNonBottomSubClass clazz) && - (pre.widen.typeSymbol isNonBottomSubClass thisclazz)) + else if (thiscls.isNonBottomSubClass(cls) && pre.baseType(thiscls).exists) pre match { case SuperType(thispre, _) => thispre case _ => pre } else - toPrefix(pre.baseType(clazz).normalizedPrefix, clazz.owner, thisclazz) + toPrefix(pre.baseType(cls).normalizedPrefix, cls.owner, thiscls) tp match { case tp: NamedType => @@ -27,7 +23,7 @@ trait TypeOps { this: Context => if (sym.isStatic) tp else { val pre0 = tp.prefix - val pre1 = asSeenFrom(pre0, pre, clazz, theMap) + val pre1 = asSeenFrom(pre0, pre, cls, theMap) if (pre1 eq pre0) tp else { val tp1 = NamedType(pre1, tp.name) @@ -43,23 +39,23 @@ trait TypeOps { this: Context => tp1 } } - case ThisType(thisclazz) => - toPrefix(pre, clazz, thisclazz) + case ThisType(thiscls) => + toPrefix(pre, cls, thiscls) case _: BoundType | NoPrefix => tp case tp: RefinedType => tp.derivedRefinedType( - asSeenFrom(tp.parent, pre, clazz, theMap), + asSeenFrom(tp.parent, pre, cls, theMap), tp.refinedName, - asSeenFrom(tp.refinedInfo, pre, clazz, theMap)) + asSeenFrom(tp.refinedInfo, pre, cls, theMap)) case _ => - (if (theMap != null) theMap else new AsSeenFromMap(pre, clazz)) + (if (theMap != null) theMap else new AsSeenFromMap(pre, cls)) .mapOver(tp) } } - class AsSeenFromMap(pre: Type, clazz: Symbol) extends TypeMap { - def apply(tp: Type) = asSeenFrom(tp, pre, clazz, this) + class AsSeenFromMap(pre: Type, cls: Symbol) extends TypeMap { + def apply(tp: Type) = asSeenFrom(tp, pre, cls, this) } final def isVolatile(tp: Type): Boolean = { diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index e48eece8d..6d3849435 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -401,16 +401,8 @@ object Types { * poly types. */ def matches(that: Type)(implicit ctx: Context): Boolean = - ctx.typeComparer.matchesType(this, that, !ctx.phase.erasedTypes) - - /** Does this type match that type - * - */ - - /** The info of `denot`, seen as a member of this type. */ -// final def memberInfo(denot: SymDenotation)(implicit ctx: Context): Type = { -// denot.info.asSeenFrom(this, denot.owner) -// } + ctx.typeComparer.matchesType( + this, that, alwaysMatchSimple = !ctx.phase.erasedTypes) /** The info of `sym`, seen as a member of this type. */ final def memberInfo(sym: Symbol)(implicit ctx: Context): Type = { @@ -428,7 +420,7 @@ object Types { */ final def widen(implicit ctx: Context): Type = this match { case tp: SingletonType => tp.underlying.widen - case tp: ExprType => tp.underlying.widen + case tp: ExprType => tp.resultType.widen case _ => this } @@ -452,10 +444,14 @@ object Types { case _ => Nil } + /** This type seen as if it were the type of a member of prefix type `pre` + * declared in class `cls`. + */ final def asSeenFrom(pre: Type, cls: Symbol)(implicit ctx: Context): Type = - if ((cls is PackageClass) || - ctx.erasedTypes && cls != defn.ArrayClass || - (pre eq cls.thisType)) this + if ( (cls is PackageClass) + || ctx.erasedTypes && cls != defn.ArrayClass + || (pre eq cls.thisType) + ) this else ctx.asSeenFrom(this, pre, cls, null) /** The signature of this type. This is by default NotAMethod, @@ -574,7 +570,7 @@ object Types { } final def isWrong: Boolean = !exists // !!! needed? - final def exists: Boolean = true + def exists: Boolean = true final def &(that: Type)(implicit ctx: Context): Type = ctx.glb(this, that) @@ -1256,6 +1252,7 @@ object Types { case object NoType extends UncachedGroundType { def symbol = NoSymbol def info = NoType + override def exists = false } /** Cached for efficiency because hashing is faster */ -- cgit v1.2.3