diff options
-rw-r--r-- | src/reflect/scala/reflect/internal/Symbols.scala | 12 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Types.scala | 3 |
2 files changed, 12 insertions, 3 deletions
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index ec280f5413..e14c617f24 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -574,6 +574,17 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ def isEffectiveRoot = false + /** Can this symbol only be subclassed by bottom classes? This is assessed + * to be the case if it is final, and any type parameters are invariant. + */ + def hasOnlyBottomSubclasses = { + def loop(tparams: List[Symbol]): Boolean = tparams match { + case Nil => true + case x :: xs => x.variance.isInvariant && loop(xs) + } + isClass && isFinal && loop(typeParams) + } + final def isLazyAccessor = isLazy && lazyAccessor != NoSymbol final def isOverridableMember = !(isClass || isEffectivelyFinal) && (this ne NoSymbol) && owner.isClass @@ -3286,7 +3297,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => // ----- Hoisted closures and convenience methods, for compile time reductions ------- private[scala] final val symbolIsPossibleInRefinement = (sym: Symbol) => sym.isPossibleInRefinement - private[scala] final val symbolIsNonVariant = (sym: Symbol) => sym.variance.isInvariant @tailrec private[scala] final def allSymbolsHaveOwner(syms: List[Symbol], owner: Symbol): Boolean = syms match { diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index f613b6fa17..d2a539db5e 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -365,8 +365,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.isFinal && (typeSymbol.typeParams forall symbolIsNonVariant) + def isFinalType = typeSymbol.hasOnlyBottomSubclasses /** Is this type completed (i.e. not a lazy type)? */ def isComplete: Boolean = true |