summaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/scala/reflect/api/ImplicitTags.scala108
-rw-r--r--src/reflect/scala/reflect/api/Symbols.scala2
-rw-r--r--src/reflect/scala/reflect/api/Types.scala107
-rw-r--r--src/reflect/scala/reflect/internal/Flags.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala133
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala2
-rw-r--r--src/reflect/scala/reflect/internal/util/Statistics.scala2
7 files changed, 193 insertions, 163 deletions
diff --git a/src/reflect/scala/reflect/api/ImplicitTags.scala b/src/reflect/scala/reflect/api/ImplicitTags.scala
new file mode 100644
index 0000000000..3f377d6cff
--- /dev/null
+++ b/src/reflect/scala/reflect/api/ImplicitTags.scala
@@ -0,0 +1,108 @@
+package scala.reflect
+package api
+
+trait ImplicitTags {
+ self: Types =>
+
+ /** A tag that preserves the identity of the `Type` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ * @group Tags
+ */
+ implicit val TypeTagg: ClassTag[Type]
+
+ /** A tag that preserves the identity of the `SingletonType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ * @group Tags
+ */
+ implicit val SingletonTypeTag: ClassTag[SingletonType]
+
+ /** A tag that preserves the identity of the `ThisType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ * @group Tags
+ */
+ implicit val ThisTypeTag: ClassTag[ThisType]
+
+ /** A tag that preserves the identity of the `SingleType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ * @group Tags
+ */
+ implicit val SingleTypeTag: ClassTag[SingleType]
+
+ /** A tag that preserves the identity of the `SuperType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ * @group Tags
+ */
+ implicit val SuperTypeTag: ClassTag[SuperType]
+
+ /** A tag that preserves the identity of the `ConstantType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ * @group Tags
+ */
+ implicit val ConstantTypeTag: ClassTag[ConstantType]
+
+ /** A tag that preserves the identity of the `TypeRef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ * @group Tags
+ */
+ implicit val TypeRefTag: ClassTag[TypeRef]
+
+ /** A tag that preserves the identity of the `CompoundType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ * @group Tags
+ */
+ implicit val CompoundTypeTag: ClassTag[CompoundType]
+
+ /** A tag that preserves the identity of the `RefinedType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ * @group Tags
+ */
+ implicit val RefinedTypeTag: ClassTag[RefinedType]
+
+ /** A tag that preserves the identity of the `ClassInfoType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ * @group Tags
+ */
+ implicit val ClassInfoTypeTag: ClassTag[ClassInfoType]
+
+ /** A tag that preserves the identity of the `MethodType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ * @group Tags
+ */
+ implicit val MethodTypeTag: ClassTag[MethodType]
+
+ /** A tag that preserves the identity of the `NullaryMethodType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ * @group Tags
+ */
+ implicit val NullaryMethodTypeTag: ClassTag[NullaryMethodType]
+
+ /** A tag that preserves the identity of the `PolyType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ * @group Tags
+ */
+ implicit val PolyTypeTag: ClassTag[PolyType]
+
+ /** A tag that preserves the identity of the `ExistentialType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ * @group Tags
+ */
+ implicit val ExistentialTypeTag: ClassTag[ExistentialType]
+
+ /** A tag that preserves the identity of the `AnnotatedType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ * @group Tags
+ */
+ implicit val AnnotatedTypeTag: ClassTag[AnnotatedType]
+
+ /** A tag that preserves the identity of the `TypeBounds` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ * @group Tags
+ */
+ implicit val TypeBoundsTag: ClassTag[TypeBounds]
+
+ /** A tag that preserves the identity of the `BoundedWildcardType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ * @group Tags
+ */
+ implicit val BoundedWildcardTypeTag: ClassTag[BoundedWildcardType]
+}
diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala
index a4a4277239..dbad3dd478 100644
--- a/src/reflect/scala/reflect/api/Symbols.scala
+++ b/src/reflect/scala/reflect/api/Symbols.scala
@@ -946,7 +946,7 @@ trait Symbols { self: Universe =>
def knownDirectSubclasses: Set[Symbol]
/** The list of all base classes of this type (including its own typeSymbol)
- * in reverse linearization order, starting with the class itself and ending
+ * in linearization order, starting with the class itself and ending
* in class Any.
*
* @group Class
diff --git a/src/reflect/scala/reflect/api/Types.scala b/src/reflect/scala/reflect/api/Types.scala
index 143438b8f5..e5140f23e5 100644
--- a/src/reflect/scala/reflect/api/Types.scala
+++ b/src/reflect/scala/reflect/api/Types.scala
@@ -50,7 +50,8 @@ package api
*
* @contentDiagram hideNodes "*Api"
*/
-trait Types { self: Universe =>
+trait Types extends ImplicitTags {
+ self: Universe =>
/** The type of Scala types, and also Scala type signatures.
* (No difference is internally made between the two).
@@ -59,12 +60,6 @@ trait Types { self: Universe =>
*/
type Type >: Null <: TypeApi
- /** A tag that preserves the identity of the `Type` abstract type from erasure.
- * Can be used for pattern matching, instance tests, serialization and likes.
- * @group Tags
- */
- implicit val TypeTagg: ClassTag[Type]
-
/** This constant is used as a special value that indicates that no meaningful type exists.
* @group Types
*/
@@ -149,7 +144,7 @@ trait Types { self: Universe =>
def =:= (that: Type): Boolean
/** The list of all base classes of this type (including its own typeSymbol)
- * in reverse linearization order, starting with the class itself and ending
+ * in linearization order, starting with the class itself and ending
* in class Any.
*/
def baseClasses: List[Symbol]
@@ -256,12 +251,6 @@ trait Types { self: Universe =>
*/
type SingletonType >: Null <: Type
- /** A tag that preserves the identity of the `SingletonType` abstract type from erasure.
- * Can be used for pattern matching, instance tests, serialization and likes.
- * @group Tags
- */
- implicit val SingletonTypeTag: ClassTag[SingletonType]
-
/** A singleton type that describes types of the form on the left with the
* corresponding `ThisType` representation to the right:
* {{{
@@ -272,12 +261,6 @@ trait Types { self: Universe =>
*/
type ThisType >: Null <: AnyRef with SingletonType with ThisTypeApi
- /** A tag that preserves the identity of the `ThisType` abstract type from erasure.
- * Can be used for pattern matching, instance tests, serialization and likes.
- * @group Tags
- */
- implicit val ThisTypeTag: ClassTag[ThisType]
-
/** The constructor/extractor for `ThisType` instances.
* @group Extractors
*/
@@ -316,12 +299,6 @@ trait Types { self: Universe =>
*/
type SingleType >: Null <: AnyRef with SingletonType with SingleTypeApi
- /** A tag that preserves the identity of the `SingleType` abstract type from erasure.
- * Can be used for pattern matching, instance tests, serialization and likes.
- * @group Tags
- */
- implicit val SingleTypeTag: ClassTag[SingleType]
-
/** The constructor/extractor for `SingleType` instances.
* @group Extractors
*/
@@ -361,12 +338,6 @@ trait Types { self: Universe =>
*/
type SuperType >: Null <: AnyRef with SingletonType with SuperTypeApi
- /** A tag that preserves the identity of the `SuperType` abstract type from erasure.
- * Can be used for pattern matching, instance tests, serialization and likes.
- * @group Tags
- */
- implicit val SuperTypeTag: ClassTag[SuperType]
-
/** The constructor/extractor for `SuperType` instances.
* @group Extractors
*/
@@ -406,12 +377,6 @@ trait Types { self: Universe =>
*/
type ConstantType >: Null <: AnyRef with SingletonType with ConstantTypeApi
- /** A tag that preserves the identity of the `ConstantType` abstract type from erasure.
- * Can be used for pattern matching, instance tests, serialization and likes.
- * @group Tags
- */
- implicit val ConstantTypeTag: ClassTag[ConstantType]
-
/** The constructor/extractor for `ConstantType` instances.
* @group Extractors
*/
@@ -450,12 +415,6 @@ trait Types { self: Universe =>
*/
type TypeRef >: Null <: AnyRef with Type with TypeRefApi
- /** A tag that preserves the identity of the `TypeRef` abstract type from erasure.
- * Can be used for pattern matching, instance tests, serialization and likes.
- * @group Tags
- */
- implicit val TypeRefTag: ClassTag[TypeRef]
-
/** The constructor/extractor for `TypeRef` instances.
* @group Extractors
*/
@@ -497,12 +456,6 @@ trait Types { self: Universe =>
*/
type CompoundType >: Null <: AnyRef with Type
- /** A tag that preserves the identity of the `CompoundType` abstract type from erasure.
- * Can be used for pattern matching, instance tests, serialization and likes.
- * @group Tags
- */
- implicit val CompoundTypeTag: ClassTag[CompoundType]
-
/** The `RefinedType` type defines types of any of the forms on the left,
* with their RefinedType representations to the right.
* {{{
@@ -515,12 +468,6 @@ trait Types { self: Universe =>
*/
type RefinedType >: Null <: AnyRef with CompoundType with RefinedTypeApi
- /** A tag that preserves the identity of the `RefinedType` abstract type from erasure.
- * Can be used for pattern matching, instance tests, serialization and likes.
- * @group Tags
- */
- implicit val RefinedTypeTag: ClassTag[RefinedType]
-
/** The constructor/extractor for `RefinedType` instances.
* @group Extractors
*/
@@ -567,12 +514,6 @@ trait Types { self: Universe =>
*/
type ClassInfoType >: Null <: AnyRef with CompoundType with ClassInfoTypeApi
- /** A tag that preserves the identity of the `ClassInfoType` abstract type from erasure.
- * Can be used for pattern matching, instance tests, serialization and likes.
- * @group Tags
- */
- implicit val ClassInfoTypeTag: ClassTag[ClassInfoType]
-
/** The constructor/extractor for `ClassInfoType` instances.
* @group Extractors
*/
@@ -610,12 +551,6 @@ trait Types { self: Universe =>
*/
type MethodType >: Null <: AnyRef with Type with MethodTypeApi
- /** A tag that preserves the identity of the `MethodType` abstract type from erasure.
- * Can be used for pattern matching, instance tests, serialization and likes.
- * @group Tags
- */
- implicit val MethodTypeTag: ClassTag[MethodType]
-
/** The constructor/extractor for `MethodType` instances.
* @group Extractors
*/
@@ -660,12 +595,6 @@ trait Types { self: Universe =>
*/
type NullaryMethodType >: Null <: AnyRef with Type with NullaryMethodTypeApi
- /** A tag that preserves the identity of the `NullaryMethodType` abstract type from erasure.
- * Can be used for pattern matching, instance tests, serialization and likes.
- * @group Tags
- */
- implicit val NullaryMethodTypeTag: ClassTag[NullaryMethodType]
-
/** The constructor/extractor for `NullaryMethodType` instances.
* @group Extractors
*/
@@ -696,12 +625,6 @@ trait Types { self: Universe =>
*/
type PolyType >: Null <: AnyRef with Type with PolyTypeApi
- /** A tag that preserves the identity of the `PolyType` abstract type from erasure.
- * Can be used for pattern matching, instance tests, serialization and likes.
- * @group Tags
- */
- implicit val PolyTypeTag: ClassTag[PolyType]
-
/** The constructor/extractor for `PolyType` instances.
* @group Extractors
*/
@@ -736,12 +659,6 @@ trait Types { self: Universe =>
*/
type ExistentialType >: Null <: AnyRef with Type with ExistentialTypeApi
- /** A tag that preserves the identity of the `ExistentialType` abstract type from erasure.
- * Can be used for pattern matching, instance tests, serialization and likes.
- * @group Tags
- */
- implicit val ExistentialTypeTag: ClassTag[ExistentialType]
-
/** The constructor/extractor for `ExistentialType` instances.
* @group Extractors
*/
@@ -777,12 +694,6 @@ trait Types { self: Universe =>
*/
type AnnotatedType >: Null <: AnyRef with Type with AnnotatedTypeApi
- /** A tag that preserves the identity of the `AnnotatedType` abstract type from erasure.
- * Can be used for pattern matching, instance tests, serialization and likes.
- * @group Tags
- */
- implicit val AnnotatedTypeTag: ClassTag[AnnotatedType]
-
/** The constructor/extractor for `AnnotatedType` instances.
* @group Extractors
*/
@@ -828,12 +739,6 @@ trait Types { self: Universe =>
*/
type TypeBounds >: Null <: AnyRef with Type with TypeBoundsApi
- /** A tag that preserves the identity of the `TypeBounds` abstract type from erasure.
- * Can be used for pattern matching, instance tests, serialization and likes.
- * @group Tags
- */
- implicit val TypeBoundsTag: ClassTag[TypeBounds]
-
/** The constructor/extractor for `TypeBounds` instances.
* @group Extractors
*/
@@ -885,12 +790,6 @@ trait Types { self: Universe =>
*/
type BoundedWildcardType >: Null <: AnyRef with Type with BoundedWildcardTypeApi
- /** A tag that preserves the identity of the `BoundedWildcardType` abstract type from erasure.
- * Can be used for pattern matching, instance tests, serialization and likes.
- * @group Tags
- */
- implicit val BoundedWildcardTypeTag: ClassTag[BoundedWildcardType]
-
/** The constructor/extractor for `BoundedWildcardType` instances.
* @group Extractors
*/
diff --git a/src/reflect/scala/reflect/internal/Flags.scala b/src/reflect/scala/reflect/internal/Flags.scala
index 45c5279574..06f6c46fc3 100644
--- a/src/reflect/scala/reflect/internal/Flags.scala
+++ b/src/reflect/scala/reflect/internal/Flags.scala
@@ -287,7 +287,7 @@ class Flags extends ModifierFlags {
* from Modifiers. Others which may be applied at creation time are:
* SYNTHETIC.
*/
- final val ValueParameterFlags = BYNAMEPARAM | IMPLICIT | DEFAULTPARAM | STABLE
+ final val ValueParameterFlags = BYNAMEPARAM | IMPLICIT | DEFAULTPARAM | STABLE | SYNTHETIC
final val BeanPropertyFlags = DEFERRED | OVERRIDE | STATIC
final val VarianceFlags = COVARIANT | CONTRAVARIANT
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 4f6dab3e7c..fbf14e8156 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -853,12 +853,13 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Is this a term symbol only defined in a refinement (so that it needs
* to be accessed by reflection)?
*/
- def isOnlyRefinementMember: Boolean =
+ def isOnlyRefinementMember: Boolean = (
isTerm && // type members are not affected
owner.isRefinementClass && // owner must be a refinement class
(owner.info decl name) == this && // symbol must be explicitly declared in the refinement (not synthesized from glb)
- allOverriddenSymbols.isEmpty && // symbol must not override a symbol in a base class
+ !isOverridingSymbol && // symbol must not override a symbol in a base class
!isConstant // symbol must not be a constant. Question: Can we exclude @inline methods as well?
+ )
final def isStructuralRefinementMember = owner.isStructuralRefinement && isPossibleInRefinement && isPublic
final def isPossibleInRefinement = !isConstructor && !isOverridingSymbol
@@ -960,14 +961,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def ownerChain: List[Symbol] = this :: owner.ownerChain
def originalOwnerChain: List[Symbol] = this :: originalOwner.getOrElse(this, rawowner).originalOwnerChain
- // All the symbols overridden by this symbol and this symbol at the head,
- // or Nil if this is NoSymbol.
- def overrideChain = (
- if (this eq NoSymbol) Nil
- else if (!owner.isClass) this :: Nil
- else this :: allOverriddenSymbols
- )
-
// Non-classes skip self and return rest of owner chain; overridden in ClassSymbol.
def enclClassChain: List[Symbol] = owner.enclClassChain
@@ -2070,81 +2063,111 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* @param ofclazz The class containing the symbol's definition
* @param site The base type from which member types are computed
*/
- final def matchingSymbol(ofclazz: Symbol, site: Type): Symbol = {
- //OPT cut down on #closures by special casing non-overloaded case
- // was: ofclazz.info.nonPrivateDecl(name) filter (sym =>
- // !sym.isTerm || (site.memberType(this) matches site.memberType(sym)))
- val result = ofclazz.info.nonPrivateDecl(name)
- def qualifies(sym: Symbol) = !sym.isTerm || (site.memberType(this) matches site.memberType(sym))
- if ((result eq NoSymbol) || !result.isOverloaded && qualifies(result)) result
- else result filter qualifies
- }
+ final def matchingSymbol(ofclazz: Symbol, site: Type): Symbol =
+ matchingSymbolInternal(site, ofclazz.info nonPrivateDecl name)
/** The non-private member of `site` whose type and name match the type of this symbol. */
final def matchingSymbol(site: Type, admit: Long = 0L): Symbol =
- site.nonPrivateMemberAdmitting(name, admit).filter(sym =>
- !sym.isTerm || (site.memberType(this) matches site.memberType(sym)))
+ matchingSymbolInternal(site, site.nonPrivateMemberAdmitting(name, admit))
- /** The symbol, in class `ofclazz`, that is overridden by this symbol.
+ private def matchingSymbolInternal(site: Type, candidate: Symbol): Symbol = {
+ def qualifies(sym: Symbol) = !sym.isTerm || ((site memberType this) matches (site memberType sym))
+ //OPT cut down on #closures by special casing non-overloaded case
+ if (candidate.isOverloaded) candidate filter qualifies
+ else if (qualifies(candidate)) candidate
+ else NoSymbol
+ }
+
+ /** The symbol, in class `baseClass`, that is overridden by this symbol.
*
- * @param ofclazz is a base class of this symbol's owner.
+ * @param baseClass is a base class of this symbol's owner.
*/
- final def overriddenSymbol(ofclazz: Symbol): Symbol =
- if (isClassConstructor) NoSymbol else matchingSymbol(ofclazz, owner.thisType)
+ final def overriddenSymbol(baseClass: Symbol): Symbol = (
+ // concrete always overrides abstract, so don't let an abstract definition
+ // claim to be overriding an inherited concrete one.
+ matchingInheritedSymbolIn(baseClass) filter (res => res.isDeferred || !this.isDeferred)
+ )
+
+ private def matchingInheritedSymbolIn(baseClass: Symbol): Symbol =
+ if (canMatchInheritedSymbols) matchingSymbol(baseClass, owner.thisType) else NoSymbol
/** The symbol overriding this symbol in given subclass `ofclazz`.
*
* @param ofclazz is a subclass of this symbol's owner
*/
- final def overridingSymbol(ofclazz: Symbol): Symbol =
- if (isClassConstructor) NoSymbol else matchingSymbol(ofclazz, ofclazz.thisType)
+ final def overridingSymbol(ofclazz: Symbol): Symbol = (
+ if (canMatchInheritedSymbols)
+ matchingSymbol(ofclazz, ofclazz.thisType)
+ else
+ NoSymbol
+ )
- /** Returns all symbols overriden by this symbol. */
- final def allOverriddenSymbols: List[Symbol] = (
- if ((this eq NoSymbol) || !owner.isClass) Nil
- else {
- def loop(xs: List[Symbol]): List[Symbol] = xs match {
- case Nil => Nil
- case x :: xs =>
- overriddenSymbol(x) match {
- case NoSymbol => loop(xs)
- case sym => sym :: loop(xs)
- }
- }
- loop(owner.ancestors)
- }
+ /** If false, this symbol cannot possibly participate in an override,
+ * either as overrider or overridee. For internal use; you should consult
+ * with isOverridingSymbol. This is used by isOverridingSymbol to escape
+ * the recursive knot.
+ */
+ private def canMatchInheritedSymbols = (
+ (this ne NoSymbol)
+ && owner.isClass
+ && !this.isClass
+ && !this.isConstructor
+ )
+
+ // All the symbols overridden by this symbol and this symbol at the head,
+ // or Nil if this is NoSymbol.
+ def overrideChain = (
+ if (this eq NoSymbol) Nil
+ else if (isOverridingSymbol) this :: allOverriddenSymbols
+ else this :: Nil
)
+ /** Returns all symbols overridden by this symbol. */
+ final def allOverriddenSymbols: List[Symbol] = {
+ def loop(xs: List[Symbol]): List[Symbol] = xs match {
+ case Nil => Nil
+ case x :: xs =>
+ overriddenSymbol(x) match {
+ case NoSymbol => loop(xs)
+ case sym => sym :: loop(xs)
+ }
+ }
+ if (isOverridingSymbol) loop(owner.ancestors) else Nil
+ }
+
/** Equivalent to allOverriddenSymbols.nonEmpty, but more efficient. */
- // !!! When if ever will this answer differ from .isOverride?
- // How/where is the OVERRIDE flag managed, as compared to how checks
- // based on type membership will evaluate?
- def isOverridingSymbol = owner.isClass && (
- owner.ancestors exists (cls => matchingSymbol(cls, owner.thisType) != NoSymbol)
+ lazy val isOverridingSymbol = (
+ canMatchInheritedSymbols
+ && owner.ancestors.exists(base => overriddenSymbol(base) != NoSymbol)
)
+
/** Equivalent to allOverriddenSymbols.head (or NoSymbol if no overrides) but more efficient. */
def nextOverriddenSymbol: Symbol = {
- if ((this ne NoSymbol) && owner.isClass) owner.ancestors foreach { base =>
- val sym = overriddenSymbol(base)
- if (sym != NoSymbol)
- return sym
+ @tailrec def loop(bases: List[Symbol]): Symbol = bases match {
+ case Nil => NoSymbol
+ case base :: rest =>
+ val sym = overriddenSymbol(base)
+ if (sym == NoSymbol) loop(rest) else sym
}
- NoSymbol
+ if (isOverridingSymbol) loop(owner.ancestors) else NoSymbol
}
/** Returns all symbols overridden by this symbol, plus all matching symbols
* defined in parents of the selftype.
*/
- final def extendedOverriddenSymbols: List[Symbol] =
- if (!owner.isClass) Nil
- else owner.thisSym.ancestors map overriddenSymbol filter (_ != NoSymbol)
+ final def extendedOverriddenSymbols: List[Symbol] = (
+ if (canMatchInheritedSymbols)
+ owner.thisSym.ancestors map overriddenSymbol filter (_ != NoSymbol)
+ else
+ Nil
+ )
/** The symbol accessed by a super in the definition of this symbol when
* seen from class `base`. This symbol is always concrete.
* pre: `this.owner` is in the base class sequence of `base`.
*/
final def superSymbol(base: Symbol): Symbol = {
- var bcs = base.info.baseClasses.dropWhile(owner != _).tail
+ var bcs = base.info.baseClasses dropWhile (owner != _) drop 1
var sym: Symbol = NoSymbol
while (!bcs.isEmpty && sym == NoSymbol) {
if (!bcs.head.isImplClass)
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index ce7fae8628..5cb6f78874 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -372,7 +372,7 @@ trait Types extends api.Types { self: SymbolTable =>
* This is assessed to be the case if the class is final,
* and all type parameters (if any) are invariant.
*/
- def isFinalType = typeSymbol.hasOnlyBottomSubclasses
+ def isFinalType = typeSymbol.hasOnlyBottomSubclasses && prefix.isStable
/** Is this type completed (i.e. not a lazy type)? */
def isComplete: Boolean = true
diff --git a/src/reflect/scala/reflect/internal/util/Statistics.scala b/src/reflect/scala/reflect/internal/util/Statistics.scala
index b078b7d4f9..0fa798058d 100644
--- a/src/reflect/scala/reflect/internal/util/Statistics.scala
+++ b/src/reflect/scala/reflect/internal/util/Statistics.scala
@@ -109,7 +109,7 @@ quant)
* Quantities with non-empty prefix are printed in the statistics info.
*/
trait Quantity {
- if (prefix.nonEmpty) {
+ if (enabled && prefix.nonEmpty) {
val key = s"${if (underlying != this) underlying.prefix else ""}/$prefix"
qs(key) = this
}