Skip to content

Optimize typeSymbol and classSymbol #9887

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Sep 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
genLoad(rhs, symInfoTK(lhs.symbol))
lineNumber(tree)
// receiverClass is used in the bytecode to access the field. using sym.owner may lead to IllegalAccessError
val receiverClass = qual.tpe.widenDealias.typeSymbol
val receiverClass = qual.tpe.typeSymbol
fieldStore(lhs.symbol, receiverClass)

case Assign(lhs, rhs) =>
Expand Down Expand Up @@ -385,7 +385,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
def genLoadQualUnlessElidable(): Unit = { if (!qualSafeToElide) { genLoadQualifier(tree) } }

// receiverClass is used in the bytecode to access the field. using sym.owner may lead to IllegalAccessError
def receiverClass = qualifier.tpe.widenDealias.typeSymbol
def receiverClass = qualifier.tpe.typeSymbol
if (sym.is(Module)) {
genLoadQualUnlessElidable()
genLoadModule(tree)
Expand Down Expand Up @@ -806,7 +806,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
val receiverClass = if (!invokeStyle.isVirtual) null else {
// receiverClass is used in the bytecode to as the method receiver. using sym.owner
// may lead to IllegalAccessErrors, see 9954eaf / aladdin bug 455.
val qualSym = qual.tpe.widenDealias.typeSymbol
val qualSym = qual.tpe.typeSymbol
if (qualSym == defn.ArrayClass) {
// For invocations like `Array(1).hashCode` or `.wait()`, use Object as receiver
// in the bytecode. Using the array descriptor (like we do for clone above) seems
Expand Down Expand Up @@ -1373,7 +1373,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
(sym derivesFrom defn.BoxedCharClass) ||
(sym derivesFrom defn.BoxedBooleanClass)
}
!areSameFinals && isMaybeBoxed(l.tpe.widenDealias.typeSymbol) && isMaybeBoxed(r.tpe.widenDealias.typeSymbol)
!areSameFinals && isMaybeBoxed(l.tpe.typeSymbol) && isMaybeBoxed(r.tpe.typeSymbol)
}
def isNull(t: Tree): Boolean = t match {
case Literal(Constant(null)) => true
Expand Down Expand Up @@ -1467,7 +1467,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
if (invokeStyle != asm.Opcodes.H_INVOKESTATIC) capturedParamsTypes = lambdaTarget.owner.info :: capturedParamsTypes

// Requires https://github.com/scala/scala-java8-compat on the runtime classpath
val returnUnit = lambdaTarget.info.resultType.widenDealias.typeSymbol == defn.UnitClass
val returnUnit = lambdaTarget.info.resultType.typeSymbol == defn.UnitClass
val functionalInterfaceDesc: String = generatedType.descriptor
val desc = capturedParamsTypes.map(tpe => toTypeKind(tpe)).mkString(("("), "", ")") + functionalInterfaceDesc
// TODO specialization
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ trait BCodeSkelBuilder extends BCodeHelpers {
private def initJClass(jclass: asm.ClassVisitor): Unit = {

val ps = claszSymbol.info.parents
val superClass: String = if (ps.isEmpty) ObjectReference.internalName else internalName(ps.head.widenDealias.typeSymbol)
val superClass: String = if (ps.isEmpty) ObjectReference.internalName else internalName(ps.head.typeSymbol)
val interfaceNames0 = classBTypeFromSymbol(claszSymbol).info.interfaces map {
case classBType =>
if (classBType.isNestedClass) { innerClassBufferASM += classBType }
Expand Down
14 changes: 7 additions & 7 deletions compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1553,7 +1553,7 @@ class JSCodeGen()(using genCtx: Context) {
assert(ctor.isClassConstructor,
"'new' call to non-constructor: " + ctor.name)

val clsSym = tpe.widenDealias.typeSymbol
val clsSym = tpe.typeSymbol

if (isHijackedClass(clsSym)) {
genNewHijackedClass(clsSym, ctor, args.map(genExpr))
Expand Down Expand Up @@ -1922,8 +1922,8 @@ class JSCodeGen()(using genCtx: Context) {
private def genEqEqPrimitive(ltpe: Type, rtpe: Type, lsrc: js.Tree, rsrc: js.Tree)(
implicit pos: SourcePosition): js.Tree = {
report.debuglog(s"$ltpe == $rtpe")
val lsym = ltpe.widenDealias.typeSymbol.asClass
val rsym = rtpe.widenDealias.typeSymbol.asClass
val lsym = ltpe.typeSymbol.asClass
val rsym = rtpe.typeSymbol.asClass

/* True if the equality comparison is between values that require the
* use of the rich equality comparator
Expand Down Expand Up @@ -2098,7 +2098,7 @@ class JSCodeGen()(using genCtx: Context) {
val exception = args.head
val genException = genExpr(exception)
js.Throw {
if (exception.tpe.widenDealias.typeSymbol.derivesFrom(jsdefn.JavaScriptExceptionClass)) {
if (exception.tpe.typeSymbol.derivesFrom(jsdefn.JavaScriptExceptionClass)) {
genModuleApplyMethod(
jsdefn.Runtime_unwrapJavaScriptException,
List(genException))
Expand Down Expand Up @@ -2594,7 +2594,7 @@ class JSCodeGen()(using genCtx: Context) {
box(call, sym.info.finalResultType)
}

val funInterfaceSym = functionalInterface.tpe.widenDealias.typeSymbol
val funInterfaceSym = functionalInterface.tpe.typeSymbol

if (jsdefn.isJSThisFunctionClass(funInterfaceSym)) {
val thisParam :: otherParams = formalParams
Expand Down Expand Up @@ -2688,7 +2688,7 @@ class JSCodeGen()(using genCtx: Context) {
private def genAsInstanceOf(value: js.Tree, to: Type)(
implicit pos: Position): js.Tree = {

val sym = to.widenDealias.typeSymbol
val sym = to.typeSymbol

if (sym == defn.ObjectClass || isJSType(sym)) {
/* asInstanceOf[Object] always succeeds, and
Expand Down Expand Up @@ -2716,7 +2716,7 @@ class JSCodeGen()(using genCtx: Context) {
/** Gen JS code for an isInstanceOf test (for reference types only) */
private def genIsInstanceOf(value: js.Tree, to: Type)(
implicit pos: SourcePosition): js.Tree = {
val sym = to.widenDealias.typeSymbol
val sym = to.typeSymbol

if (sym == defn.ObjectClass) {
js.BinaryOp(js.BinaryOp.!==, value, js.Null())
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>

private def isSimpleThrowable(tp: Type)(using Context): Boolean = tp match {
case tp @ TypeRef(pre, _) =>
(pre == NoPrefix || pre.widen.typeSymbol.isStatic) &&
(pre == NoPrefix || pre.typeSymbol.isStatic) &&
(tp.symbol derivesFrom defn.ThrowableClass) && !tp.symbol.is(Trait)
case _ =>
false
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
private def followOuterLinks(t: Tree)(using Context) = t match {
case t: This if ctx.erasedTypes && !(t.symbol == ctx.owner.enclosingClass || t.symbol.isStaticOwner) =>
// after erasure outer paths should be respected
ExplicitOuter.OuterOps(ctx).path(toCls = t.tpe.widen.classSymbol)
ExplicitOuter.OuterOps(ctx).path(toCls = t.tpe.classSymbol)
case t =>
t
}
Expand Down
22 changes: 11 additions & 11 deletions compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -998,11 +998,10 @@ class Definitions {
FunctionType(args.length, isContextual, isErased).appliedTo(args ::: resultType :: Nil)
def unapply(ft: Type)(using Context): Option[(List[Type], Type, Boolean, Boolean)] = {
val tsym = ft.typeSymbol
if (isFunctionClass(tsym)) {
if isFunctionClass(tsym) && ft.isRef(tsym) then
val targs = ft.dealias.argInfos
if (targs.isEmpty) None
else Some(targs.init, targs.last, tsym.name.isContextFunction, tsym.name.isErasedFunction)
}
else None
}
}
Expand Down Expand Up @@ -1379,15 +1378,16 @@ class Definitions {
/** Is `tp` (an alias) of either a scala.FunctionN or a scala.ContextFunctionN
* instance?
*/
def isNonRefinedFunction(tp: Type)(using Context): Boolean = {
def isNonRefinedFunction(tp: Type)(using Context): Boolean =
val arity = functionArity(tp)
val sym = tp.dealias.typeSymbol

arity >= 0 &&
isFunctionClass(sym) &&
tp.isRef(FunctionType(arity, sym.name.isContextFunction, sym.name.isErasedFunction).typeSymbol) &&
!tp.isInstanceOf[RefinedType]
}
arity >= 0
&& isFunctionClass(sym)
&& tp.isRef(
FunctionType(arity, sym.name.isContextFunction, sym.name.isErasedFunction).typeSymbol,
skipRefined = false)
end isNonRefinedFunction

/** Is `tp` a representation of a (possibly dependent) function type or an alias of such? */
def isFunctionType(tp: Type)(using Context): Boolean =
Expand Down Expand Up @@ -1460,9 +1460,9 @@ class Definitions {
if ctx.erasedTypes then
atPhase(erasurePhase)(unapply(tp))
else
val tp1 = tp.dealias
if isContextFunctionClass(tp1.typeSymbol) then
val args = asContextFunctionType(tp).dropDependentRefinement.argInfos
val tp1 = asContextFunctionType(tp)
if tp1.exists then
val args = tp1.dropDependentRefinement.argInfos
Some((args.init, args.last, tp1.typeSymbol.name.isErasedFunction))
else None

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ trait PatternTypeConstrainer { self: TypeComparer =>

def classesMayBeCompatible: Boolean = {
import Flags._
val patClassSym = pat.widenSingleton.classSymbol
val scrutClassSym = scrut.widenSingleton.classSymbol
val patClassSym = pat.classSymbol
val scrutClassSym = scrut.classSymbol
!patClassSym.exists || !scrutClassSym.exists || {
if (patClassSym.is(Final)) patClassSym.derivesFrom(scrutClassSym)
else if (scrutClassSym.is(Final)) scrutClassSym.derivesFrom(patClassSym)
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/TypeApplications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ class TypeApplications(val self: Type) extends AnyVal {
* otherwise return Nil.
* Existential types in arguments are returned as TypeBounds instances.
*/
final def argInfos(using Context): List[Type] = self.stripTypeVar.stripAnnots match {
final def argInfos(using Context): List[Type] = self.stripped match {
case AppliedType(tycon, args) => args
case _ => Nil
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
def compareThis = {
val cls2 = tp2.cls
tp1 match {
case tp1: NamedType if cls2.is(Module) && cls2.eq(tp1.widen.typeSymbol) =>
case tp1: NamedType if cls2.is(Module) && cls2.eq(tp1.typeSymbol) =>
cls2.isStaticOwner ||
recur(tp1.prefix, cls2.owner.thisType) ||
secondTry
Expand Down Expand Up @@ -391,7 +391,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
case tp1: ThisType =>
val cls1 = tp1.cls
tp2 match {
case tp2: TermRef if cls1.is(Module) && cls1.eq(tp2.widen.typeSymbol) =>
case tp2: TermRef if cls1.is(Module) && cls1.eq(tp2.typeSymbol) =>
cls1.isStaticOwner ||
recur(cls1.owner.thisType, tp2.prefix) ||
thirdTry
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/TypeErasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
/** The erasure of a function result type. */
private def eraseResult(tp: Type)(using Context): Type = tp match {
case tp: TypeRef =>
val sym = tp.typeSymbol
val sym = tp.symbol
if (sym eq defn.UnitClass) sym.typeRef
// For a value class V, "new V(x)" should have type V for type adaptation to work
// correctly (see SIP-15 and [[Erasure.Boxing.adaptToType]]), so the return type of a
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/TypeOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ object TypeOps:
// variance. As this logic is only needed in exhaustivity check,
// we manually patch subtyping check instead of changing TypeComparer.
// See tests/patmat/i3645b.scala
def parentQualify(tp1: Type, tp2: Type) = tp1.widen.classSymbol.info.parents.exists { parent =>
def parentQualify(tp1: Type, tp2: Type) = tp1.classSymbol.info.parents.exists { parent =>
parent.argInfos.nonEmpty && approximateTypeParams(parent) <:< tp2
}

Expand Down
39 changes: 15 additions & 24 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -419,9 +419,8 @@ object Types {
/** The type symbol associated with the type */
@tailrec final def typeSymbol(using Context): Symbol = this match {
case tp: TypeRef => tp.symbol
case tp: ClassInfo => tp.cls
case tp: SingletonType => NoSymbol
case tp: TypeProxy => tp.underlying.typeSymbol
case tp: ClassInfo => tp.cls
case _: JavaArrayType => defn.ArrayClass
case _ => NoSymbol
}
Expand All @@ -431,17 +430,13 @@ object Types {
* value type, or because superclasses are ambiguous).
*/
final def classSymbol(using Context): Symbol = this match {
case ConstantType(constant) =>
constant.tpe.classSymbol
case tp: TypeRef =>
val sym = tp.symbol
if (sym.isClass) sym else tp.superType.classSymbol
case tp: ClassInfo =>
tp.cls
case tp: SingletonType =>
NoSymbol
case tp: TypeProxy =>
tp.underlying.classSymbol
case tp: ClassInfo =>
tp.cls
case AndType(l, r) =>
val lsym = l.classSymbol
val rsym = r.classSymbol
Expand All @@ -459,13 +454,13 @@ object Types {
/** The least (wrt <:<) set of symbols satisfying the `include` predicate of which this type is a subtype
*/
final def parentSymbols(include: Symbol => Boolean)(using Context): List[Symbol] = this match {
case tp: ClassInfo =>
tp.cls :: Nil
case tp: TypeRef =>
val sym = tp.symbol
if (include(sym)) sym :: Nil else tp.superType.parentSymbols(include)
case tp: TypeProxy =>
tp.underlying.parentSymbols(include)
case tp: ClassInfo =>
tp.cls :: Nil
case AndType(l, r) =>
l.parentSymbols(include) | r.parentSymbols(include)
case OrType(l, r) =>
Expand Down Expand Up @@ -775,8 +770,8 @@ object Types {
core.println(s"findMember exception for $this member $name, pre = $pre, recCount = $recCount")

def showPrefixSafely(pre: Type)(using Context): String = pre.stripTypeVar match {
case pre: TermRef => i"${pre.termSymbol.name}."
case pre: TypeRef => i"${pre.typeSymbol.name}#"
case pre: TermRef => i"${pre.symbol.name}."
case pre: TypeRef => i"${pre.symbol.name}#"
case pre: TypeProxy => showPrefixSafely(pre.underlying)
case _ => if (pre.typeSymbol.exists) i"${pre.typeSymbol.name}#" else "."
}
Expand Down Expand Up @@ -2377,7 +2372,7 @@ object Types {
/** A reference like this one, but with the given prefix. */
final def withPrefix(prefix: Type)(using Context): NamedType = {
def reload(): NamedType = {
val allowPrivate = !lastSymbol.exists || lastSymbol.is(Private) && prefix.classSymbol == this.prefix.classSymbol
val allowPrivate = !lastSymbol.exists || lastSymbol.is(Private)
var d = memberDenot(prefix, name, allowPrivate)
if (d.isOverloaded && lastSymbol.exists)
d = disambiguate(d,
Expand Down Expand Up @@ -3833,18 +3828,14 @@ object Types {

private var validSuper: Period = Nowhere
private var cachedSuper: Type = _
private var myStableHash: Byte = 0

private var isGroundKnown: Boolean = false
private var isGroundCache: Boolean = _
// Boolean caches: 0 = uninitialized, -1 = false, 1 = true
private var myStableHash: Byte = 0
private var myGround: Byte = 0

def isGround(acc: TypeAccumulator[Boolean])(using Context): Boolean = {
if (!isGroundKnown) {
isGroundCache = acc.foldOver(true, this)
isGroundKnown = true
}
isGroundCache
}
def isGround(acc: TypeAccumulator[Boolean])(using Context): Boolean =
if myGround == 0 then myGround = if acc.foldOver(true, this) then 1 else -1
myGround > 0

override def underlying(using Context): Type = tycon

Expand Down Expand Up @@ -5645,7 +5636,7 @@ object Types {
foldOver(cs + tp.typeSymbol, tp)
case tp: TypeRef if tp.info.isTypeAlias =>
apply(cs, tp.superType)
case tp: TypeRef if tp.typeSymbol.isClass =>
case tp: TypeRef if tp.symbol.isClass =>
foldOver(cs + tp.typeSymbol, tp)
case tp: TermRef =>
val tsym = if (tp.termSymbol.is(Param)) tp.underlying.typeSymbol else tp.termSymbol
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/reporting/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ import ast.tpd

class NotAMember(site: Type, val name: Name, selected: String, addendum: => String = "")(using Context)
extends NotFoundMsg(NotAMemberID) {
//println(i"site = $site, decls = ${site.decls}, source = ${site.widen.typeSymbol.sourceFile}") //DEBUG
//println(i"site = $site, decls = ${site.decls}, source = ${site.typeSymbol.sourceFile}") //DEBUG

def msg = {
import core.Flags._
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class ArrayConstructors extends MiniPhase {
}
else if ((tree.fun.symbol.maybeOwner eq defn.ArrayModule.moduleClass) && (tree.fun.symbol.name eq nme.ofDim) && !tree.tpe.isInstanceOf[MethodicType]) {
val Apply(Apply(TypeApply(_, List(tp)), _), _) = tree
val cs = tp.tpe.widen.classSymbol
val cs = tp.tpe.classSymbol
tree.fun match {
case Apply(TypeApply(t: Ident, targ), dims)
if !TypeErasure.isGeneric(targ.head.tpe) && !ValueClasses.isDerivedValueClass(cs) =>
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/transform/ElimOpaque.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class ElimOpaque extends MiniPhase with DenotTransformer {
if sym == defn.Any_== || sym == defn.Any_!= then
tree match
case Apply(Select(receiver, name: TermName), args)
if atPhase(thisPhase)(receiver.tpe.widen.dealias.typeSymbol.isOpaqueAlias) =>
if atPhase(thisPhase)(receiver.tpe.widenDealias.typeSymbol.isOpaqueAlias) =>
applyOverloaded(receiver, name, args, Nil, defn.BooleanType)
case _ =>
tree
Expand Down
Loading