From b6d7b28403c34f61c5317c37acce1b4118a4181c Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 18 Nov 2013 19:04:33 +0100 Subject: Various cleanups --- src/dotty/tools/dotc/ast/CheckTrees.scala | 11 ++-- src/dotty/tools/dotc/core/TypeComparer.scala | 6 +- src/dotty/tools/dotc/core/Types.scala | 70 ++++++++++------------ src/dotty/tools/dotc/core/pickling/UnPickler.scala | 4 +- src/dotty/tools/dotc/core/transform/Erasure.scala | 6 +- src/dotty/tools/dotc/typer/Inferencing.scala | 2 +- 6 files changed, 44 insertions(+), 55 deletions(-) (limited to 'src/dotty/tools/dotc') diff --git a/src/dotty/tools/dotc/ast/CheckTrees.scala b/src/dotty/tools/dotc/ast/CheckTrees.scala index cce68c557..4d8e25ae3 100644 --- a/src/dotty/tools/dotc/ast/CheckTrees.scala +++ b/src/dotty/tools/dotc/ast/CheckTrees.scala @@ -105,7 +105,7 @@ object CheckTrees { check(escapingRefs(tree).isEmpty) case If(cond, thenp, elsep) => check(cond.isValue); check(thenp.isValue); check(elsep.isValue) - check(cond.tpe.derivesFrom(defn.BooleanClass)) + check(cond.tpe isRef defn.BooleanClass) case Closure(env, meth, target) => meth.tpe.widen match { case mt @ MethodType(_, paramTypes) => @@ -195,7 +195,7 @@ object CheckTrees { } case Alternative(alts) => for (alt <- alts) check(alt.isValueOrPattern) - case UnApply(fun, args) => + case UnApply(fun, args) => // todo: review check(fun.isTerm) for (arg <- args) check(arg.isValueOrPattern) val funtpe @ MethodType(_, _) = fun.tpe.widen @@ -206,17 +206,16 @@ object CheckTrees { check(args.head.isInstanceOf[SeqLiteral]) case nme.unapply => val rtp = funtpe.resultType - val rsym = rtp.dealiasedTypeSymbol - if (rsym == defn.BooleanClass) + if (rtp isRef defn.BooleanClass) check(args.isEmpty) else { - check(rsym == defn.OptionClass) + check(rtp isRef defn.OptionClass) val normArgs = rtp.typeArgs match { case optionArg :: Nil => optionArg.typeArgs match { case Nil => optionArg :: Nil - case tupleArgs if defn.TupleClasses contains optionArg.dealiasedTypeSymbol => + case tupleArgs if defn.isTupleType(optionArg) => tupleArgs } case _ => diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index 7b718c9c8..a4d96019e 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -206,7 +206,7 @@ class TypeComparer(initctx: Context) extends DotClass { tp2 == tp1 || { isSubTypeWhenFrozen(tp1, bounds(tp2).lo) || { constraint(tp2) match { - case TypeBounds(lo, _) => addConstraint(tp2, tp1.widen.dealias_*, fromBelow = true) + case TypeBounds(lo, _) => addConstraint(tp2, tp1.widen.dealias, fromBelow = true) case _ => secondTry(tp1, tp2) } } @@ -245,7 +245,7 @@ class TypeComparer(initctx: Context) extends DotClass { isSubTypeWhenFrozen(bounds(tp1).hi, tp2) || { assert(frozenConstraint || !(tp2 isRef defn.NothingClass)) // !!!DEBUG constraint(tp1) match { - case TypeBounds(_, hi) => addConstraint(tp1, tp2.dealias_*, fromBelow = false) + case TypeBounds(_, hi) => addConstraint(tp1, tp2.dealias, fromBelow = false) case _ => thirdTry(tp1, tp2) } } @@ -359,7 +359,7 @@ class TypeComparer(initctx: Context) extends DotClass { def fourthTry(tp1: Type, tp2: Type): Boolean = tp1 match { case tp1: TypeRef => ((tp1.symbol eq NothingClass) - || (tp1.symbol eq NullClass) && tp2.dealiasedTypeSymbol.isNonValueClass + || (tp1.symbol eq NullClass) && tp2.dealias.typeSymbol.isNonValueClass || (tp1.info match { case TypeBounds(lo1, hi1) => isSubType(hi1, tp2) || diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 854c7e2f6..dd17f5672 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -118,9 +118,6 @@ object Types { final def derivesFrom(cls: Symbol)(implicit defctx: Context): Boolean = classSymbol.derivesFrom(cls) - /** Is this an array type? */ - final def isArray(implicit ctx: Context): Boolean = isRef(defn.ArrayClass) - /** A type T is a legal prefix in a type selection T#A if * T is stable or T contains no uninstantiated type variables. */ @@ -164,13 +161,13 @@ object Types { /** Does the type carry an annotation that is an instance of `cls`? */ final def hasAnnotation(cls: ClassSymbol)(implicit ctx: Context): Boolean = stripTypeVar match { - case AnnotatedType(annot, tp) => annot.symbol == cls || tp.hasAnnotation(cls) + case AnnotatedType(annot, tp) => (annot matches cls) || (tp hasAnnotation cls) case _ => false } /** Does this type occur as a part of type `that`? */ final def occursIn(that: Type)(implicit ctx: Context): Boolean = - that.existsPart(this == _) + that existsPart (this == _) def isRepeatedParam(implicit ctx: Context): Boolean = defn.RepeatedParamClasses contains typeSymbol @@ -184,30 +181,29 @@ object Types { /** Returns true if all parts of this type satisfy predicate `p`. */ - final def forallParts(p: Type => Boolean)(implicit ctx: Context): Boolean = !existsPart(!p(_)) + final def forallParts(p: Type => Boolean)(implicit ctx: Context): Boolean = + !existsPart(!p(_)) /** The parts of this type which are type or term refs */ final def namedParts(implicit ctx: Context): Set[NamedType] = namedPartsWith(Function.const(true)) + /** The parts of this type which are type or term refs and which + * satisfy predicate `p`. + */ def namedPartsWith(p: NamedType => Boolean)(implicit ctx: Context): Set[NamedType] = new NamedPartsAccumulator(p).apply(Set(), this) - final def foreach(f: Type => Unit): Unit = ??? - - /** Map function over elements of an AndType, rebuilding with & */ - def mapAnd(f: Type => Type)(implicit ctx: Context): Type = - mapReduceAnd(f)(_ & _) + // needed? + //final def foreach(f: Type => Unit): Unit = ??? + /** Map function `f` over elements of an AndType, rebuilding with function `g` */ def mapReduceAnd[T](f: Type => T)(g: (T, T) => T)(implicit ctx: Context): T = stripTypeVar match { case AndType(tp1, tp2) => g(tp1.mapReduceAnd(f)(g), tp2.mapReduceAnd(f)(g)) case _ => f(this) } - /** Map function over elements of an OrType, rebuilding with | */ - final def mapOr(f: Type => Type)(implicit ctx: Context): Type = - mapReduceOr(f)(_ | _) - + /** Map function `f` over elements of an OrType, rebuilding with function `g` */ final def mapReduceOr[T](f: Type => T)(g: (T, T) => T)(implicit ctx: Context): T = stripTypeVar match { case OrType(tp1, tp2) => g(tp1.mapReduceOr(f)(g), tp2.mapReduceOr(f)(g)) case _ => f(this) @@ -218,33 +214,24 @@ object Types { /** The type symbol associated with the type */ final def typeSymbol(implicit ctx: Context): Symbol = this match { case tp: TypeRef => tp.symbol - case tp: TermRef => NoSymbol case tp: ClassInfo => tp.cls + case tp: SingletonType => NoSymbol case ThisType(cls) => cls case tp: TypeProxy => tp.underlying.typeSymbol case _ => NoSymbol } - /** The type symbol associated with the type, skipping alises */ - final def dealiasedTypeSymbol(implicit ctx: Context): Symbol = this match { - case tp: TermRef => NoSymbol - case tp: ClassInfo => tp.cls - case ThisType(cls) => cls - case tp: TypeProxy => tp.underlying.dealiasedTypeSymbol - case _ => NoSymbol - } - /** The least class or trait of which this type is a subtype, or * NoSymbol if none exists (either because this type is not a * value type, or because superclasses are ambiguous). */ final def classSymbol(implicit ctx: Context): Symbol = this match { - case tp: ClassInfo => - tp.cls case tp: TypeRef => val sym = tp.symbol if (sym.isClass) sym else tp.underlying.classSymbol - case tp: TermRef => + case tp: ClassInfo => + tp.cls + case tp: SingletonType => NoSymbol case tp: TypeProxy => tp.underlying.classSymbol @@ -615,7 +602,7 @@ object Types { // ----- Unwrapping types ----------------------------------------------- /** Map a TypeVar to either its instance if it is instantiated, or its origin, - * if not. Identity on all other types. + * if not, until the result is no longer a TypeVar. Identity on all other types. */ def stripTypeVar(implicit ctx: Context): Type = this @@ -637,6 +624,9 @@ object Types { case _ => this } + /** Widen from singleton type to its underlying non-singleton + * base type by applying one or more `underlying` dereferences, + */ final def widenSingleton(implicit ctx: Context): Type = this match { case tp: SingletonType => tp.underlying.widenSingleton case _ => this @@ -649,21 +639,16 @@ object Types { case _ => this } - /** If this is an alias type, its alias, otherwise the type itself */ - final def dealias(implicit ctx: Context): Type = stripTypeVar match { - case tp: TypeRef if tp.symbol.isAliasType => tp.info.bounds.hi - case _ => this - } - - final def dealias_*(implicit ctx: Context): Type = this match { + /** Follow aliases until type is no longer an alias type. */ + final def dealias(implicit ctx: Context): Type = this match { case tp: TypeRef => tp.info match { - case TypeBounds(lo, hi) if lo eq hi => hi.dealias_* + case TypeBounds(lo, hi) if lo eq hi => hi.dealias case _ => tp } case tp: TypeVar => val tp1 = tp.instanceOpt - if (tp1.exists) tp1.dealias_* else tp + if (tp1.exists) tp1.dealias else tp case tp => tp } @@ -687,7 +672,7 @@ object Types { if (res.exists) res else TypeRef(this, name) } - /** The type , reduced if possible, with given denotation if undreduced */ + /** The type , reduced if possible, with given denotation if unreduced */ def select(name: Name, denot: Denotation)(implicit ctx: Context): Type = name match { case name: TermName => TermRef(this, name).withDenot(denot) @@ -1037,7 +1022,7 @@ object Types { */ final def splitArray(implicit ctx: Context): (Int, Type) = { def recur(n: Int, tp: Type): (Int, Type) = tp.stripTypeVar match { - case RefinedType(tycon, _) if tycon.isArray => + case RefinedType(tycon, _) if tycon isRef defn.ArrayClass => tp.typeArgs match { case arg :: Nil => recur(n + 1, arg) case _ => (n, tp) @@ -1492,6 +1477,11 @@ object Types { abstract case class TermRef(override val prefix: Type, name: TermName) extends NamedType with SingletonType { protected def sig: Signature = UnknownSignature + override def underlying(implicit ctx: Context): Type = { + val d = denot + if (d.isOverloaded) NoType else d.info + } + override def signature(implicit ctx: Context): Signature = denot.signature def isOverloaded(implicit ctx: Context) = denot.isOverloaded diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala index 400fcba86..386ea3d85 100644 --- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala +++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala @@ -73,7 +73,7 @@ object UnPickler { def arrayToRepeated(tp: Type)(implicit ctx: Context): Type = tp match { case tp @ MethodType(paramNames, paramTypes) => val lastArg = paramTypes.last - assert(lastArg.isArray) + assert(lastArg isRef defn.ArrayClass) val elemtp0 :: Nil = lastArg.baseTypeArgs(defn.ArrayClass) val elemtp = elemtp0 match { case AndType(t1, t2) if t1.typeSymbol.isAbstractType && (t2 isRef defn.ObjectClass) => @@ -555,7 +555,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: case info: TypeRef if boundSyms contains info.symbol => val info1 = info.symbol.info assert(info1.derivesFrom(defn.SingletonClass)) - RefinedType(parent1, name, info1.mapAnd(removeSingleton)) + RefinedType(parent1, name, info1.mapReduceAnd(removeSingleton)(_ & _)) case info => tp.derivedRefinedType(parent1, name, info) } diff --git a/src/dotty/tools/dotc/core/transform/Erasure.scala b/src/dotty/tools/dotc/core/transform/Erasure.scala index a0438fc4f..119400fdb 100644 --- a/src/dotty/tools/dotc/core/transform/Erasure.scala +++ b/src/dotty/tools/dotc/core/transform/Erasure.scala @@ -42,7 +42,7 @@ object Erasure { else erasure(tp.info) case tp: RefinedType => val parent = tp.parent - if (parent.isArray) eraseArray(tp) + if (parent isRef defn.ArrayClass) eraseArray(tp) else erasure(parent) case ConstantType(_) | NoType | NoPrefix => tp @@ -112,9 +112,9 @@ object Erasure { else paramSignature(tp.info) case tp: RefinedType => val parent = tp.parent - if (parent.isArray) + if (parent isRef defn.ArrayClass) eraseArray(tp) match { - case tp1: RefinedType if tp1.parent.isArray => + case tp1: RefinedType if tp1.parent isRef defn.ArrayClass => paramSignature(tp1.refinedInfo) ++ "[]" case tp1 => paramSignature(tp1) diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala index f804feda4..eb88c0764 100644 --- a/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/src/dotty/tools/dotc/typer/Inferencing.scala @@ -184,7 +184,7 @@ object Inferencing { case tp: TypeRef if tp.symbol.isClass => checkStable(tp.prefix, pos) tp.symbol.asClass - case /* _: RefinedType |*/ _: TypeVar | _: AnnotatedType => + case _: TypeVar | _: AnnotatedType => checkClassTypeWithStablePrefix(tp.asInstanceOf[TypeProxy].underlying, pos) case _ => ctx.error(i"$tp is not a class type", pos) -- cgit v1.2.3