diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index e4a0e282a5a8..6d495c7d16f0 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -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) => @@ -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) @@ -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 @@ -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 @@ -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 diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 2c575309d9f1..eff9c170c2df 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -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 } diff --git a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala index 3621b6fcb0ae..cd7b1ba1ce26 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala @@ -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)) @@ -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 @@ -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)) @@ -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 @@ -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 @@ -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()) diff --git a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala index bce2265a8924..145864315875 100644 --- a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala +++ b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala @@ -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 diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala index 80984541f050..a26c5e86cf34 100644 --- a/compiler/src/dotty/tools/dotc/ast/tpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala @@ -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 } diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 88849ff6f798..79269d93ccc7 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -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 } } @@ -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 = @@ -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 diff --git a/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala b/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala index 5935fbd91705..d0f9a49cf216 100644 --- a/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala +++ b/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala @@ -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) diff --git a/compiler/src/dotty/tools/dotc/core/TypeApplications.scala b/compiler/src/dotty/tools/dotc/core/TypeApplications.scala index eaf0fa9ad420..3732968aa884 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeApplications.scala @@ -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 } diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index 3d92cddd6d24..7d8a609c67db 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -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 @@ -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 diff --git a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala index f259d9eec08d..e8726f9eb73b 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala @@ -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 diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index ba63eb48c8a3..73bdcad169c5 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -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 } diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index bba5b627b571..c14942e12a67 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -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 } @@ -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 @@ -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) => @@ -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 "." } @@ -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, @@ -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 @@ -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 diff --git a/compiler/src/dotty/tools/dotc/reporting/messages.scala b/compiler/src/dotty/tools/dotc/reporting/messages.scala index f4c46317ab98..07864790acaf 100644 --- a/compiler/src/dotty/tools/dotc/reporting/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/messages.scala @@ -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._ diff --git a/compiler/src/dotty/tools/dotc/transform/ArrayConstructors.scala b/compiler/src/dotty/tools/dotc/transform/ArrayConstructors.scala index 6ba4244560ff..437ff0490822 100644 --- a/compiler/src/dotty/tools/dotc/transform/ArrayConstructors.scala +++ b/compiler/src/dotty/tools/dotc/transform/ArrayConstructors.scala @@ -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) => diff --git a/compiler/src/dotty/tools/dotc/transform/ElimOpaque.scala b/compiler/src/dotty/tools/dotc/transform/ElimOpaque.scala index 55ad79dbe3e9..3eca6ea6b28c 100644 --- a/compiler/src/dotty/tools/dotc/transform/ElimOpaque.scala +++ b/compiler/src/dotty/tools/dotc/transform/ElimOpaque.scala @@ -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 diff --git a/compiler/src/dotty/tools/dotc/transform/Erasure.scala b/compiler/src/dotty/tools/dotc/transform/Erasure.scala index 1d628bb75daa..e66606fd2882 100644 --- a/compiler/src/dotty/tools/dotc/transform/Erasure.scala +++ b/compiler/src/dotty/tools/dotc/transform/Erasure.scala @@ -161,7 +161,7 @@ class Erasure extends Phase with DenotTransformer { def assertErased(tp: Type, tree: tpd.Tree = tpd.EmptyTree)(using Context): Unit = { def isAllowed(cls: Symbol, sourceName: String) = - tp.widen.typeSymbol == cls && ctx.compilationUnit.source.file.name == sourceName + tp.typeSymbol == cls && ctx.compilationUnit.source.file.name == sourceName assert(isErasedType(tp) || isAllowed(defn.ArrayClass, "Array.scala") || isAllowed(defn.TupleClass, "Tuple.scala") || @@ -229,7 +229,7 @@ object Erasure { */ private def safelyRemovableUnboxArg(tree: Tree)(using Context): Tree = tree match { case Apply(fn, arg :: Nil) - if isUnbox(fn.symbol) && defn.ScalaBoxedClasses().contains(arg.tpe.widen.typeSymbol) => + if isUnbox(fn.symbol) && defn.ScalaBoxedClasses().contains(arg.tpe.typeSymbol) => arg case _ => EmptyTree @@ -287,7 +287,7 @@ object Erasure { cast(tree1, pt) case _ => - val cls = pt.widen.classSymbol + val cls = pt.classSymbol if (cls eq defn.UnitClass) constant(tree, Literal(Constant(()))) else { assert(cls ne defn.ArrayClass) @@ -430,7 +430,7 @@ object Erasure { val implResultType = implType.resultType val samResultType = sam.resultType - if (!defn.isSpecializableFunction(implClosure.tpe.widen.classSymbol.asClass, implParamTypes, implResultType)) { + if (!defn.isSpecializableFunction(implClosure.tpe.classSymbol.asClass, implParamTypes, implResultType)) { def autoAdaptedParam(tp: Type) = !tp.isErasedValueType && !tp.isPrimitiveValueType val explicitSAMType = implClosure.tpt.tpe.exists def autoAdaptedResult(tp: Type) = !tp.isErasedValueType && @@ -640,7 +640,7 @@ object Erasure { if !sym.exists && tree.name == nme.apply then // PolyFunction apply Selects will not have a symbol, so deduce the owner // from the typed qual. - val owner = qual1.tpe.widen.typeSymbol + val owner = qual1.tpe.typeSymbol if defn.isFunctionClass(owner) then owner else NoSymbol else val owner = sym.maybeOwner diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala index 6c0b63e3c1cd..a8e43bc1adaa 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -398,7 +398,7 @@ object ExplicitOuter { count: Int = -1): Tree = try @tailrec def loop(tree: Tree, count: Int): Tree = - val treeCls = tree.tpe.widen.classSymbol + val treeCls = tree.tpe.classSymbol report.log(i"outer to $toCls of $tree: ${tree.tpe}, looking for ${atPhaseNoLater(lambdaLiftPhase)(outerAccName(treeCls.asClass))} in $treeCls") if (count == 0 || count < 0 && treeCls == toCls) tree else diff --git a/compiler/src/dotty/tools/dotc/transform/FunctionalInterfaces.scala b/compiler/src/dotty/tools/dotc/transform/FunctionalInterfaces.scala index ba49b22ce263..26c67a2e504a 100644 --- a/compiler/src/dotty/tools/dotc/transform/FunctionalInterfaces.scala +++ b/compiler/src/dotty/tools/dotc/transform/FunctionalInterfaces.scala @@ -28,7 +28,7 @@ class FunctionalInterfaces extends MiniPhase { private val functionPackage = "dotty.runtime.function.".toTermName override def transformClosure(tree: Closure)(using Context): Tree = { - val cls = tree.tpe.widen.classSymbol.asClass + val cls = tree.tpe.classSymbol.asClass val implType = tree.meth.tpe.widen val List(implParamTypes) = implType.paramInfoss diff --git a/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala b/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala index 1b0359692b01..eaa77ff56c6c 100644 --- a/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala +++ b/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala @@ -48,7 +48,7 @@ class InterceptedMethods extends MiniPhase { // TODO: add missing cases from scalac private def poundPoundValue(tree: Tree)(using Context) = { - val s = tree.tpe.widen.typeSymbol + val s = tree.tpe.typeSymbol def staticsCall(methodName: TermName): Tree = ref(defn.staticsMethodRef(methodName)).appliedTo(tree) diff --git a/compiler/src/dotty/tools/dotc/transform/TryCatchPatterns.scala b/compiler/src/dotty/tools/dotc/transform/TryCatchPatterns.scala index cab2fa3328a4..6be58352e6dc 100644 --- a/compiler/src/dotty/tools/dotc/transform/TryCatchPatterns.scala +++ b/compiler/src/dotty/tools/dotc/transform/TryCatchPatterns.scala @@ -72,7 +72,7 @@ class TryCatchPatterns extends MiniPhase { private def isSimpleThrowable(tp: Type)(using Context): Boolean = tp.stripAnnots match { case tp @ TypeRef(pre, _) => - (pre == NoPrefix || pre.widen.typeSymbol.isStatic) && // Does not require outer class check + (pre == NoPrefix || pre.typeSymbol.isStatic) && // Does not require outer class check !tp.symbol.is(Flags.Trait) && // Traits not supported by JVM tp.derivesFrom(defn.ThrowableClass) case tp: AppliedType => diff --git a/compiler/src/dotty/tools/dotc/transform/TypeUtils.scala b/compiler/src/dotty/tools/dotc/transform/TypeUtils.scala index cd4b9695047a..d92812409ffe 100644 --- a/compiler/src/dotty/tools/dotc/transform/TypeUtils.scala +++ b/compiler/src/dotty/tools/dotc/transform/TypeUtils.scala @@ -41,8 +41,8 @@ object TypeUtils { case AppliedType(tycon, _ :: tl :: Nil) if tycon.isRef(defn.PairClass) => val arity = tl.tupleArity if (arity < 0) arity else arity + 1 - case self: TermRef if self.symbol == defn.EmptyTupleModule => - 0 + case self: SingletonType => + if self.termSymbol == defn.EmptyTupleModule then 0 else -1 case self if defn.isTupleClass(self.classSymbol) => self.dealias.argInfos.length case _ => @@ -53,7 +53,8 @@ object TypeUtils { def tupleElementTypes(using Context): List[Type] = self match { case AppliedType(tycon, hd :: tl :: Nil) if tycon.isRef(defn.PairClass) => hd :: tl.tupleElementTypes - case self: TermRef if self.symbol == defn.EmptyTupleModule => + case self: SingletonType => + assert(self.termSymbol == defn.EmptyTupleModule, "not a tuple") Nil case self if defn.isTupleClass(self.classSymbol) => self.dealias.argInfos diff --git a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala index f7c3fc5b45a5..2120a00984cf 100644 --- a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala +++ b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala @@ -486,7 +486,7 @@ class SpaceEngine(using Context) extends SpaceLogic { case tp @ RefinedType(parent, _, _) => erase(parent) - case tref: TypeRef if tref.typeSymbol.isPatternBound => + case tref: TypeRef if tref.symbol.isPatternBound => if (inArray) tref.underlying else WildcardType case _ => tp @@ -645,26 +645,22 @@ class SpaceEngine(using Context) extends SpaceLogic { /** Abstract sealed types, or-types, Boolean and Java enums can be decomposed */ - def canDecompose(tp: Type): Boolean = { - val dealiasedTp = tp.dealias - val res = - (tp.classSymbol.is(Sealed) && - tp.classSymbol.isOneOf(AbstractOrTrait) && - !tp.classSymbol.hasAnonymousChild && - tp.classSymbol.children.nonEmpty ) || - dealiasedTp.isInstanceOf[OrType] || - (dealiasedTp.isInstanceOf[AndType] && { - val and = dealiasedTp.asInstanceOf[AndType] - canDecompose(and.tp1) || canDecompose(and.tp2) - }) || - tp.isRef(defn.BooleanClass) || - tp.isRef(defn.UnitClass) || - tp.classSymbol.isAllOf(JavaEnumTrait) - + def canDecompose(tp: Type): Boolean = + val res = tp.dealias match + case _: SingletonType => false + case _: OrType => true + case and: AndType => canDecompose(and.tp1) || canDecompose(and.tp2) + case _ => + val cls = tp.classSymbol + cls.is(Sealed) + && cls.isOneOf(AbstractOrTrait) + && !cls.hasAnonymousChild + && cls.children.nonEmpty + || cls.isAllOf(JavaEnumTrait) + || tp.isRef(defn.BooleanClass) + || tp.isRef(defn.UnitClass) debug.println(s"decomposable: ${tp.show} = $res") - res - } /** Show friendly type name with current scope in mind * @@ -765,7 +761,8 @@ class SpaceEngine(using Context) extends SpaceLogic { if (flattenList && tp <:< scalaNilType) "" else tp.symbol.showName case Typ(tp, decomposed) => - val sym = tp.widen.classSymbol + + val sym = tp.classSymbol if (ctx.definitions.isTupleType(tp)) params(tp).map(_ => "_").mkString("(", ", ", ")") diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index c9c6564abc30..a2113ce2946f 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -116,7 +116,7 @@ object Applications { if (sel.exists) sel :: tupleSelectors(n + 1, tp) else Nil } def genTupleSelectors(n: Int, tp: Type): List[Type] = tp match { - case tp: AppliedType if !defn.isTupleClass(tp.typeSymbol) && tp.derivesFrom(defn.PairClass) => + case tp: AppliedType if !defn.isTupleClass(tp.tycon.typeSymbol) && tp.derivesFrom(defn.PairClass) => val List(head, tail) = tp.args head :: genTupleSelectors(n, tail) case _ => tupleSelectors(n, tp) @@ -2039,7 +2039,7 @@ trait Applications extends Compatibility { case ConstantType(c: Constant) if c.tag == IntTag => targetClass(ts1, cls, true) case t => - val sym = t.widen.classSymbol + val sym = t.classSymbol if (!sym.isNumericValueClass || cls.exists && cls != sym) NoSymbol else targetClass(ts1, sym, intLitSeen) } diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index ad0d7406369c..9a01bb16a096 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -920,7 +920,7 @@ trait Checking { if (caller.is(Module)) { val traverser = new TreeTraverser { def traverse(tree: Tree)(using Context) = tree match { - case tree: RefTree if tree.isTerm && (tree.tpe.widen.classSymbol eq caller) => + case tree: RefTree if tree.isTerm && (tree.tpe.classSymbol eq caller) => report.error("super constructor cannot be passed a self reference", tree.srcPos) case _ => traverseChildren(tree) diff --git a/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala b/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala index a88af260eed0..50ba3b13dc5f 100644 --- a/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala +++ b/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala @@ -186,7 +186,7 @@ class ImportInfo(symf: Context ?=> Symbol, def featureImported(feature: TermName, owner: Symbol)(using Context): Boolean = def compute = - val isImportOwner = site.widen.typeSymbol.eq(owner) + val isImportOwner = site.typeSymbol.eq(owner) if isImportOwner && forwardMapping.contains(feature) then true else if isImportOwner && excluded.contains(feature) then false else diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index 7326d77262b2..00db8df2a6e0 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -466,7 +466,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) { val sortedProxies = thisProxy.toList.map { case (cls, proxy) => // The class that the this-proxy `selfSym` represents - def classOf(selfSym: Symbol) = selfSym.info.widen.classSymbol + def classOf(selfSym: Symbol) = selfSym.info.classSymbol // The total nesting depth of the class represented by `selfSym`. def outerLevel(selfSym: Symbol): Int = classOf(selfSym).ownersIterator.length (outerLevel(cls), proxy.symbol) @@ -1082,7 +1082,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) { scrut.widenTermRefExpr =:= pat.tpe case pat: RefTree => scrut =:= pat.tpe || - scrut.widen.classSymbol.is(Module) && scrut.widen =:= pat.tpe.widen && { + scrut.classSymbol.is(Module) && scrut.widen =:= pat.tpe.widen && { scrut.prefix match { case _: SingletonType | NoPrefix => true case _ => false diff --git a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala index 473e9ea95d5b..f7c85c76ab72 100644 --- a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala +++ b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala @@ -327,7 +327,7 @@ trait QuotesAndSplices { val isFreshTypeBindings = freshTypeBindings.map(_.symbol).toSet val typeMap = new TypeMap() { def apply(tp: Type): Type = tp match { - case tp: TypeRef if tp.typeSymbol.isTypeSplice => + case tp: TypeRef if tp.symbol.isTypeSplice => val tp1 = tp.dealias if (isFreshTypeBindings(tp1.typeSymbol)) tp1 else tp @@ -408,7 +408,7 @@ trait QuotesAndSplices { class ReplaceBindings extends TypeMap() { override def apply(tp: Type): Type = tp match { case tp: TypeRef => - val tp1 = if (tp.typeSymbol.isTypeSplice) tp.dealias else tp + val tp1 = if (tp.symbol.isTypeSplice) tp.dealias else tp mapOver(typeBindings.get(tp1.typeSymbol).fold(tp)(_.symbol.typeRef)) case tp => mapOver(tp) } diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index c85aee7aa65b..d09dad5ca063 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -99,7 +99,7 @@ object RefChecks { def checkSelfConforms(other: ClassSymbol, category: String, relation: String) = { val otherSelf = other.declaredSelfTypeAsSeenFrom(cls.thisType) if otherSelf.exists && !(cinfo.selfType <:< otherSelf) then - report.error(DoesNotConformToSelfType(category, cinfo.selfType, cls, otherSelf, relation, other.classSymbol), + report.error(DoesNotConformToSelfType(category, cinfo.selfType, cls, otherSelf, relation, other), cls.srcPos) } val parents = cinfo.classParents @@ -1166,7 +1166,7 @@ class RefChecks extends MiniPhase { thisPhase => case _ => false } def underlyingClass(tp: Type): Symbol = { - val sym = tp.widen.typeSymbol + val sym = tp.typeSymbol if (sym.isAbstractOrParamType) underlyingClass(sym.info.bounds.hi) else sym } diff --git a/tests/neg/i6226.scala b/tests/neg/i6226.scala index ed2dddc1b297..922038619e64 100644 --- a/tests/neg/i6226.scala +++ b/tests/neg/i6226.scala @@ -7,6 +7,6 @@ object O2 { } object O3 { // error - opaque type R[X] = T[X] + opaque type R[X] = T[X] // error opaque type T[X] = R[X] // error } diff --git a/tests/neg/i8337.scala b/tests/neg/i8337.scala index 71701acf7ef0..7955c471fb70 100644 --- a/tests/neg/i8337.scala +++ b/tests/neg/i8337.scala @@ -2,5 +2,5 @@ trait Foo[F <: Foo[F]] class Bar extends Foo[Bar] object Q { // error: recursion limit exceeded - opaque type X <: Foo[X] = Bar // error: out of bounds + opaque type X <: Foo[X] = Bar // error: out of bounds // error } \ No newline at end of file