Skip to content

Commit 74aa068

Browse files
committed
More modifier lock down in Types.
Perhaps controversially seals the hierarchy and as a consequence moves two types from the unpickler into Types.scala.
1 parent ce42e92 commit 74aa068

File tree

2 files changed

+67
-65
lines changed

2 files changed

+67
-65
lines changed

src/dotty/tools/dotc/core/Types.scala

Lines changed: 67 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ object Types {
249249
}
250250

251251
/** The elements of an AndType or OrType */
252-
def factors(implicit ctx: Context): List[Type] = this match {
252+
final def factors(implicit ctx: Context): List[Type] = this match {
253253
case tp: AndType =>
254254
def components(tp: Type): List[Type] = tp match {
255255
case AndType(tp1, tp2) => components(tp1) ++ components(tp2)
@@ -266,7 +266,7 @@ object Types {
266266
}
267267

268268
/** The parameter types of a PolyType or MethodType, Empty list for others */
269-
def paramTypess: List[List[Type]] = this match {
269+
final def paramTypess: List[List[Type]] = this match {
270270
case mt: MethodType => mt.paramTypes :: mt.resultType.paramTypess
271271
case pt: PolyType => pt.paramTypess
272272
case _ => Nil
@@ -281,13 +281,13 @@ object Types {
281281
}
282282

283283
/** Map function over elements of an AndType, rebuilding with & */
284-
def mapAnd(f: Type => Type)(implicit ctx: Context): Type = this match {
284+
final def mapAnd(f: Type => Type)(implicit ctx: Context): Type = this match {
285285
case AndType(tp1, tp2) => tp1.mapAnd(f) & tp2.mapAnd(f)
286286
case _ => f(this)
287287
}
288288

289289
/** Map function over elements of an OrType, rebuilding with | */
290-
def mapOr(f: Type => Type)(implicit ctx: Context): Type = this match {
290+
final def mapOr(f: Type => Type)(implicit ctx: Context): Type = this match {
291291
case OrType(tp1, tp2) => tp1.mapOr(f) | tp2.mapOr(f)
292292
case _ => f(this)
293293
}
@@ -402,7 +402,7 @@ object Types {
402402
* - Or phase.erasedTypes is false and both types are neither method nor
403403
* poly types.
404404
*/
405-
def matches(that: Type)(implicit ctx: Context): Boolean =
405+
final def matches(that: Type)(implicit ctx: Context): Boolean =
406406
ctx.typeComparer.matchesType(this, that, !ctx.phase.erasedTypes)
407407

408408
/** Does this type match that type
@@ -614,41 +614,41 @@ object Types {
614614
finishHash(hashing.mix(seed, elemHash), arity + 1, tps)
615615
}
616616

617-
protected def doHash(x: Any): Int =
617+
protected final def doHash(x: Any): Int =
618618
finishHash(hashing.mix(hashSeed, x.hashCode), 1)
619619

620-
protected def doHash(tp: Type): Int =
620+
protected final def doHash(tp: Type): Int =
621621
finishHash(hashSeed, 0, tp)
622622

623-
protected def doHash(x1: Any, tp2: Type): Int =
623+
protected final def doHash(x1: Any, tp2: Type): Int =
624624
finishHash(hashing.mix(hashSeed, x1.hashCode), 1, tp2)
625625

626-
protected def doHash(tp1: Type, tp2: Type): Int =
626+
protected final def doHash(tp1: Type, tp2: Type): Int =
627627
finishHash(hashSeed, 0, tp1, tp2)
628628

629-
protected def doHash(x1: Any, tp2: Type, tp3: Type): Int =
629+
protected final def doHash(x1: Any, tp2: Type, tp3: Type): Int =
630630
finishHash(hashing.mix(hashSeed, x1.hashCode), 1, tp2, tp3)
631631

632-
protected def doHash(tp1: Type, tps2: List[Type]): Int =
632+
protected final def doHash(tp1: Type, tps2: List[Type]): Int =
633633
finishHash(hashSeed, 0, tp1, tps2)
634634

635-
protected def doHash(x1: Any, tp2: Type, tps3: List[Type]): Int =
635+
protected final def doHash(x1: Any, tp2: Type, tps3: List[Type]): Int =
636636
finishHash(hashing.mix(hashSeed, x1.hashCode), 1, tp2, tps3)
637637

638638
} // end Type
639639

640640
/** A marker trait for cached types */
641-
trait CachedType extends Type
641+
sealed trait CachedType extends Type
642642

643-
def unique[T <: Type](tp: T)(implicit ctx: Context): T = {
643+
final def unique[T <: Type](tp: T)(implicit ctx: Context): T = {
644644
if (tp.hash == NotCached) tp
645645
else ctx.uniques.findEntryOrUpdate(tp).asInstanceOf[T]
646646
}
647647

648648
/** A marker trait for type proxies.
649649
* Each implementation is expected to redefine the `underlying` method.
650650
*/
651-
abstract class TypeProxy extends Type {
651+
sealed abstract class TypeProxy extends Type {
652652
/** The type to which this proxy forwards operations. */
653653
def underlying(implicit ctx: Context): Type
654654
}
@@ -659,50 +659,50 @@ object Types {
659659
// is for efficiency.
660660

661661
/** Instances of this class are cached and are not proxies. */
662-
abstract class CachedGroundType extends Type with CachedType {
662+
sealed abstract class CachedGroundType extends Type with CachedType {
663663
final val hash = computeHash
664664
override final def hashCode = hash
665665
def computeHash: Int
666666
}
667667

668668
/** Instances of this class are cached and are proxies. */
669-
abstract class CachedProxyType extends TypeProxy with CachedType {
669+
sealed abstract class CachedProxyType extends TypeProxy with CachedType {
670670
final val hash = computeHash
671671
override final def hashCode = hash
672672
def computeHash: Int
673673
}
674674

675675
/** Instances of this class are uncached and are not proxies. */
676-
abstract class UncachedGroundType extends Type {
676+
sealed abstract class UncachedGroundType extends Type {
677677
final def hash = NotCached
678678
}
679679

680680
/** Instances of this class are uncached and are proxies. */
681-
abstract class UncachedProxyType extends TypeProxy {
681+
sealed abstract class UncachedProxyType extends TypeProxy {
682682
final def hash = NotCached
683683
}
684684

685685
/** A marker trait for types that are guaranteed to contain only a
686686
* single non-null value (they might contain null in addition).
687687
*/
688-
trait SingletonType extends TypeProxy
688+
sealed trait SingletonType extends TypeProxy
689689

690690
/** A marker trait for types that apply only to type symbols */
691-
trait TypeType extends Type
691+
sealed trait TypeType extends Type
692692

693693
// --- NamedTypes ------------------------------------------------------------------
694694

695695
/** A NamedType of the form Prefix # name
696696
*/
697-
abstract class NamedType extends CachedProxyType {
697+
sealed abstract class NamedType extends CachedProxyType {
698698

699699
val prefix: Type
700700
val name: Name
701701

702702
private[this] var lastDenotation: Denotation = null
703703

704704
/** The denotation currently denoted by this type */
705-
def denot(implicit ctx: Context): Denotation = {
705+
final def denot(implicit ctx: Context): Denotation = {
706706
val validPeriods =
707707
if (lastDenotation != null) lastDenotation.validFor else Nowhere
708708
if (!(validPeriods contains ctx.period)) {
@@ -728,17 +728,17 @@ object Types {
728728

729729
protected def loadDenot(implicit ctx: Context) = prefix.member(name)
730730

731-
def isType = name.isTypeName
732-
def isTerm = name.isTermName
731+
final def isType = name.isTypeName
732+
final def isTerm = name.isTermName
733733

734734
def symbol(implicit ctx: Context): Symbol = denot.symbol
735-
def info(implicit ctx: Context): Type = denot.info
735+
final def info(implicit ctx: Context): Type = denot.info
736736

737737
override def underlying(implicit ctx: Context): Type = info
738738

739-
def isAbstractType(implicit ctx: Context) = info.isRealTypeBounds
739+
final def isAbstractType(implicit ctx: Context) = info.isRealTypeBounds
740740

741-
def derivedNamedType(prefix: Type, name: Name)(implicit ctx: Context): Type =
741+
final def derivedNamedType(prefix: Type, name: Name)(implicit ctx: Context): Type =
742742
if (prefix eq this.prefix) this
743743
else NamedType(prefix, name)
744744

@@ -749,10 +749,10 @@ object Types {
749749

750750
sealed abstract case class TypeRef(override val prefix: Type, name: TypeName) extends NamedType
751751

752-
trait HasFixedSym extends NamedType {
752+
sealed trait HasFixedSym extends NamedType {
753753
protected val fixedSym: Symbol
754-
override def symbol(implicit ctx: Context): Symbol = fixedSym
755-
override def loadDenot(implicit ctx: Context) = {
754+
override final def symbol(implicit ctx: Context): Symbol = fixedSym
755+
override final def loadDenot(implicit ctx: Context) = {
756756
val denot = fixedSym.denot
757757
val owner = denot.owner
758758
if (owner.isTerm) denot else denot.asSeenFrom(prefix, owner).toDenot
@@ -859,7 +859,7 @@ object Types {
859859
override def computeHash = doHash(name, info, parent)
860860
}
861861

862-
class CachedRefinedType(parent: Type, name: Name, infof: RefinedType => Type) extends RefinedType(parent, name)(infof)
862+
final class CachedRefinedType(parent: Type, name: Name, infof: RefinedType => Type) extends RefinedType(parent, name)(infof)
863863

864864
object RefinedType {
865865
def make(parent: Type, names: List[Name], infofs: List[RefinedType => Type])(implicit ctx: Context): Type =
@@ -879,7 +879,7 @@ object Types {
879879

880880
type This <: AndType
881881

882-
def derivedAndType(t1: Type, t2: Type)(implicit ctx: Context) =
882+
final def derivedAndType(t1: Type, t2: Type)(implicit ctx: Context) =
883883
if ((t1 eq tp1) && (t2 eq tp2)) this
884884
else AndType(t1, t2)
885885

@@ -894,11 +894,11 @@ object Types {
894894
}
895895

896896
sealed abstract case class OrType(tp1: Type, tp2: Type) extends CachedGroundType {
897-
def derivedOrType(t1: Type, t2: Type)(implicit ctx: Context) =
897+
final def derivedOrType(t1: Type, t2: Type)(implicit ctx: Context) =
898898
if ((t1 eq tp1) && (t2 eq tp2)) this
899899
else OrType(t1, t2)
900900

901-
override def computeHash = doHash(tp1, tp2)
901+
override final def computeHash = doHash(tp1, tp2)
902902
}
903903

904904
final class CachedOrType(tp1: Type, tp2: Type) extends OrType(tp1, tp2)
@@ -910,14 +910,14 @@ object Types {
910910

911911
// ----- Method types: MethodType/ExprType/PolyType/MethodParam/PolyParam ---------------
912912

913-
trait BindingType extends Type
913+
sealed trait BindingType extends Type
914914

915915
// Note: method types are cached whereas poly types are not.
916916
// The reason is that most poly types are cyclic via poly params,
917917
// and therefore two different poly types would never be equal.
918918

919919
sealed abstract case class MethodType(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type) extends CachedGroundType with BindingType {
920-
override lazy val resultType = resultTypeExp(this)
920+
override final lazy val resultType = resultTypeExp(this)
921921
def isJava = false
922922
def isImplicit = false
923923

@@ -926,7 +926,7 @@ object Types {
926926
case _ => false
927927
}
928928

929-
override lazy val signature: List[TypeName] = {
929+
override final lazy val signature: List[TypeName] = {
930930
def paramSig(tp: Type): TypeName = ???
931931
val followSig = resultType match {
932932
case rtp: MethodType => rtp.signature
@@ -935,7 +935,7 @@ object Types {
935935
(paramTypes map paramSig) ++ followSig
936936
}
937937

938-
def derivedMethodType(paramNames: List[TermName], paramTypes: List[Type], restpe: Type)(implicit ctx: Context) =
938+
final def derivedMethodType(paramNames: List[TermName], paramTypes: List[Type], restpe: Type)(implicit ctx: Context) =
939939
if ((paramNames eq this.paramNames) && (paramTypes eq this.paramTypes) && (restpe eq this.resultType)) this
940940
else {
941941
val restpeExpr = (x: MethodType) => restpe.subst(this, x)
@@ -944,11 +944,11 @@ object Types {
944944
else MethodType(paramNames, paramTypes)(restpeExpr)
945945
}
946946

947-
def instantiate(argTypes: List[Type])(implicit ctx: Context): Type =
947+
final def instantiate(argTypes: List[Type])(implicit ctx: Context): Type =
948948
if (isDependent) new InstMethodMap(this, argTypes) apply resultType
949949
else resultType
950950

951-
override def computeHash = doHash(paramNames, resultType, paramTypes)
951+
override final def computeHash = doHash(paramNames, resultType, paramTypes)
952952
}
953953

954954
final class CachedMethodType(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type)
@@ -964,9 +964,9 @@ object Types {
964964
override def isImplicit = true
965965
}
966966

967-
abstract class GenericMethodType {
967+
sealed abstract class GenericMethodType {
968968
def apply(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType
969-
def fromSymbols(params: List[Symbol], resultType: Type)(implicit ctx: Context) = {
969+
final def fromSymbols(params: List[Symbol], resultType: Type)(implicit ctx: Context) = {
970970
def transResult(mt: MethodType) =
971971
resultType.subst(params, (0 until params.length).toList map (MethodParam(mt, _)))
972972
apply(params map (_.name.asTermName), params map (_.info))(transResult _)
@@ -1042,7 +1042,7 @@ object Types {
10421042
}
10431043
}
10441044

1045-
abstract class BoundType extends UncachedProxyType {
1045+
sealed abstract class BoundType extends UncachedProxyType {
10461046
type BT <: BindingType
10471047
def binder: BT
10481048
def copy(bt: BT): Type
@@ -1076,19 +1076,19 @@ object Types {
10761076
/* def typeTemplate(implicit ctx: Context): Type =
10771077
classd.typeTemplate asSeenFrom (prefix, classd.symbol)
10781078
*/
1079-
def typeConstructor(implicit ctx: Context): Type =
1079+
final def typeConstructor(implicit ctx: Context): Type =
10801080
NamedType(prefix, classd.symbol.name)
10811081

10821082
// cached because baseType needs parents
1083-
private var parentsCache: List[TypeRef] = null
1083+
private final var parentsCache: List[TypeRef] = null
10841084

1085-
override def parents(implicit ctx: Context): List[TypeRef] = {
1085+
override final def parents(implicit ctx: Context): List[TypeRef] = {
10861086
if (parentsCache == null)
10871087
parentsCache = classd.parents.mapConserve(_.substThis(classd.symbol, prefix).asInstanceOf[TypeRef])
10881088
parentsCache
10891089
}
10901090

1091-
override def computeHash = doHash(classd.symbol, prefix)
1091+
override final def computeHash = doHash(classd.symbol, prefix)
10921092
}
10931093

10941094
final class CachedClassInfo(prefix: Type, classd: ClassDenotation) extends ClassInfo(prefix, classd)
@@ -1099,25 +1099,25 @@ object Types {
10991099
}
11001100

11011101
sealed abstract case class TypeBounds(lo: Type, hi: Type) extends CachedProxyType with TypeType {
1102-
override def underlying(implicit ctx: Context): Type = hi
1103-
def derivedTypeBounds(lo1: Type, hi1: Type)(implicit ctx: Context) =
1102+
override final def underlying(implicit ctx: Context): Type = hi
1103+
final def derivedTypeBounds(lo1: Type, hi1: Type)(implicit ctx: Context) =
11041104
if ((lo1 eq lo) && (hi1 eq hi)) this
11051105
else TypeBounds(lo, hi)
11061106

1107-
def contains(tp: Type)(implicit ctx: Context) = lo <:< tp && tp <:< hi
1107+
final def contains(tp: Type)(implicit ctx: Context) = lo <:< tp && tp <:< hi
11081108

1109-
def &(that: TypeBounds)(implicit ctx: Context): TypeBounds =
1109+
final def &(that: TypeBounds)(implicit ctx: Context): TypeBounds =
11101110
TypeBounds(this.lo | that.lo, this.hi & that.hi)
1111-
def |(that: TypeBounds)(implicit ctx: Context): TypeBounds =
1111+
final def |(that: TypeBounds)(implicit ctx: Context): TypeBounds =
11121112
TypeBounds(this.lo & that.lo, this.hi | that.hi)
11131113

1114-
def substBounds(from: PolyType, to: PolyType)(implicit ctx: Context) =
1114+
final def substBounds(from: PolyType, to: PolyType)(implicit ctx: Context) =
11151115
subst(from, to).asInstanceOf[TypeBounds]
11161116

1117-
def map(f: Type => Type)(implicit ctx: Context): TypeBounds =
1117+
final def map(f: Type => Type)(implicit ctx: Context): TypeBounds =
11181118
TypeBounds(f(lo), f(hi))
11191119

1120-
override def computeHash = doHash(lo, hi)
1120+
override final def computeHash = doHash(lo, hi)
11211121
}
11221122

11231123
final class CachedTypeBounds(lo: Type, hi: Type) extends TypeBounds(lo, hi)
@@ -1155,6 +1155,13 @@ object Types {
11551155

11561156
final case class ImportType(expr: TypedTree) extends UncachedGroundType
11571157

1158+
// Unpickler Types -----------------------------------------------------------------
1159+
final case class TempPolyType(tparams: List[Symbol], tpe: Type) extends UncachedGroundType
1160+
1161+
/** Temporary type for classinfos, will be decomposed on completion of the class */
1162+
final case class TempClassInfoType(parentTypes: List[Type], decls: Scope, clazz: Symbol) extends UncachedGroundType
1163+
1164+
11581165
// Special type objects ------------------------------------------------------------
11591166

11601167
case object NoType extends UncachedGroundType {
@@ -1167,7 +1174,7 @@ object Types {
11671174
override def computeHash = hashSeed
11681175
}
11691176

1170-
abstract class ErrorType extends UncachedGroundType
1177+
sealed abstract class ErrorType extends UncachedGroundType
11711178

11721179
object ErrorType extends ErrorType
11731180

@@ -1224,14 +1231,14 @@ object Types {
12241231

12251232
}
12261233

1227-
class InstMethodMap(mt: MethodType, argtypes: List[Type])(implicit ctx: Context) extends TypeMap {
1234+
final class InstMethodMap(mt: MethodType, argtypes: List[Type])(implicit ctx: Context) extends TypeMap {
12281235
def apply(tp: Type) = tp match {
12291236
case MethodParam(`mt`, n) => argtypes(n)
12301237
case _ => mapOver(tp)
12311238
}
12321239
}
12331240

1234-
class InstPolyMap(pt: PolyType, argtypes: List[Type])(implicit ctx: Context) extends TypeMap {
1241+
final class InstPolyMap(pt: PolyType, argtypes: List[Type])(implicit ctx: Context) extends TypeMap {
12351242
def apply(tp: Type) = tp match {
12361243
case PolyParam(`pt`, n) => argtypes(n)
12371244
case _ => mapOver(tp)
@@ -1280,7 +1287,7 @@ object Types {
12801287
}
12811288
}
12821289

1283-
class ExistsAccumulator(p: Type => Boolean) extends TypeAccumulator[Boolean] {
1290+
final class ExistsAccumulator(p: Type => Boolean) extends TypeAccumulator[Boolean] {
12841291
def apply(x: Boolean, tp: Type) = x || p(tp) || foldOver(x, tp)
12851292
}
12861293

0 commit comments

Comments
 (0)