Skip to content

Commit 80a2630

Browse files
authored
Merge pull request #15455 from dotty-staging/fix-underlying
Turn some calls to `underlying` into `superType`.
2 parents 2636cc1 + 0bdbc87 commit 80a2630

14 files changed

+44
-46
lines changed

compiler/src/dotty/tools/dotc/core/CheckRealizable.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class CheckRealizable(using Context) {
132132
case tp: RefinedType => refinedNames(tp.parent) + tp.refinedName
133133
case tp: AndType => refinedNames(tp.tp1) ++ refinedNames(tp.tp2)
134134
case tp: OrType => refinedNames(tp.tp1) ++ refinedNames(tp.tp2)
135-
case tp: TypeProxy => refinedNames(tp.underlying)
135+
case tp: TypeProxy => refinedNames(tp.superType)
136136
case _ => Set.empty
137137
}
138138

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1565,8 +1565,8 @@ class Definitions {
15651565
def tupleTypes(tp: Type, bound: Int = Int.MaxValue)(using Context): Option[List[Type]] = {
15661566
@tailrec def rec(tp: Type, acc: List[Type], bound: Int): Option[List[Type]] = tp.normalized.dealias match {
15671567
case _ if bound < 0 => Some(acc.reverse)
1568-
case tp: AppliedType if defn.PairClass == tp.classSymbol => rec(tp.args(1), tp.args.head :: acc, bound - 1)
1569-
case tp: AppliedType if defn.isTupleClass(tp.tycon.classSymbol) => Some(acc.reverse ::: tp.args)
1568+
case tp: AppliedType if PairClass == tp.classSymbol => rec(tp.args(1), tp.args.head :: acc, bound - 1)
1569+
case tp: AppliedType if isTupleNType(tp) => Some(acc.reverse ::: tp.args)
15701570
case tp: TermRef if tp.symbol == defn.EmptyTupleModule => Some(acc.reverse)
15711571
case _ => None
15721572
}

compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ trait PatternTypeConstrainer { self: TypeComparer =>
234234
def refinementIsInvariant(tp: Type): Boolean = tp match {
235235
case tp: SingletonType => true
236236
case tp: ClassInfo => tp.cls.is(Final) || tp.cls.is(Case)
237-
case tp: TypeProxy => refinementIsInvariant(tp.underlying)
237+
case tp: TypeProxy => refinementIsInvariant(tp.superType)
238238
case _ => false
239239
}
240240

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,7 +1590,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
15901590
case tp: RecType => fix(tp.parent).substRecThis(tp, anchor)
15911591
case tp @ RefinedType(parent, rname, rinfo) => tp.derivedRefinedType(fix(parent), rname, rinfo)
15921592
case tp: TypeParamRef => fixOrElse(bounds(tp).hi, tp)
1593-
case tp: TypeProxy => fixOrElse(tp.underlying, tp)
1593+
case tp: TypeProxy => fixOrElse(tp.superType, tp)
15941594
case tp: AndType => tp.derivedAndType(fix(tp.tp1), fix(tp.tp2))
15951595
case tp: OrType => tp.derivedOrType (fix(tp.tp1), fix(tp.tp2))
15961596
case tp => tp
@@ -1863,7 +1863,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
18631863
final def ensureStableSingleton(tp: Type): SingletonType = tp.stripTypeVar match {
18641864
case tp: SingletonType if tp.isStable => tp
18651865
case tp: ValueType => SkolemType(tp)
1866-
case tp: TypeProxy => ensureStableSingleton(tp.underlying)
1866+
case tp: TypeProxy => ensureStableSingleton(tp.superType)
18671867
case tp => assert(ctx.reporter.errorsReported); SkolemType(tp)
18681868
}
18691869

compiler/src/dotty/tools/dotc/core/TypeEval.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ object TypeEval:
1818
// final val one = 1
1919
// type Two = one.type + one.type
2020
// ```
21-
case tp: TypeProxy if tp.underlying.isStable => tp.underlying.fixForEvaluation
21+
case tp: TypeProxy =>
22+
val tp1 = tp.superType
23+
if tp1.isStable then tp1.fixForEvaluation else tp
2224
case tp => tp
2325

2426
def constValue(tp: Type): Option[Any] = tp.fixForEvaluation match

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

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -248,19 +248,6 @@ object Types {
248248
val d = defn
249249
hasClassSymbol(d.NothingClass) || hasClassSymbol(d.NullClass)
250250

251-
/** Does this type refer exactly to class symbol `sym`, instead of to a subclass of `sym`?
252-
* Implemented like `isRef`, but follows more types: all type proxies as well as and- and or-types
253-
*/
254-
private[Types] def isTightPrefix(sym: Symbol)(using Context): Boolean = stripTypeVar match {
255-
case tp: NamedType => tp.info.isTightPrefix(sym)
256-
case tp: ClassInfo => tp.cls eq sym
257-
case tp: Types.ThisType => tp.cls eq sym
258-
case tp: TypeProxy => tp.underlying.isTightPrefix(sym)
259-
case tp: AndType => tp.tp1.isTightPrefix(sym) && tp.tp2.isTightPrefix(sym)
260-
case tp: OrType => tp.tp1.isTightPrefix(sym) || tp.tp2.isTightPrefix(sym)
261-
case _ => false
262-
}
263-
264251
/** True if this type is an instance of the given `cls` or an instance of
265252
* a non-bottom subclass of `cls`.
266253
*/
@@ -331,7 +318,7 @@ object Types {
331318
val sym = tp.symbol
332319
if (sym.isClass) sym == defn.AnyKindClass else loop(tp.translucentSuperType)
333320
case tp: TypeProxy =>
334-
loop(tp.underlying)
321+
loop(tp.underlying) // underlying OK here since an AnyKinded type cannot be a type argument of another type
335322
case _ =>
336323
false
337324
}
@@ -342,6 +329,7 @@ object Types {
342329
final def isNotNull(using Context): Boolean = this match {
343330
case tp: ConstantType => tp.value.value != null
344331
case tp: ClassInfo => !tp.cls.isNullableClass && tp.cls != defn.NothingClass
332+
case tp: AppliedType => tp.superType.isNotNull
345333
case tp: TypeBounds => tp.lo.isNotNull
346334
case tp: TypeProxy => tp.underlying.isNotNull
347335
case AndType(tp1, tp2) => tp1.isNotNull || tp2.isNotNull
@@ -501,7 +489,7 @@ object Types {
501489
val sym = tp.symbol
502490
if (sym.isClass) sym else tp.superType.classSymbol
503491
case tp: TypeProxy =>
504-
tp.underlying.classSymbol
492+
tp.superType.classSymbol
505493
case tp: ClassInfo =>
506494
tp.cls
507495
case AndType(l, r) =>
@@ -535,7 +523,7 @@ object Types {
535523
val sym = tp.symbol
536524
if (include(sym)) sym :: Nil else tp.superType.parentSymbols(include)
537525
case tp: TypeProxy =>
538-
tp.underlying.parentSymbols(include)
526+
tp.superType.parentSymbols(include)
539527
case tp: ClassInfo =>
540528
tp.cls :: Nil
541529
case AndType(l, r) =>
@@ -557,7 +545,7 @@ object Types {
557545
val sym = tp.symbol
558546
sym == cls || !sym.isClass && tp.superType.hasClassSymbol(cls)
559547
case tp: TypeProxy =>
560-
tp.underlying.hasClassSymbol(cls)
548+
tp.superType.hasClassSymbol(cls)
561549
case tp: ClassInfo =>
562550
tp.cls == cls
563551
case AndType(l, r) =>
@@ -571,12 +559,14 @@ object Types {
571559
* bounds of type variables in the constraint.
572560
*/
573561
def isMatchableBound(using Context): Boolean = dealias match
574-
case tp: TypeRef => tp.symbol == defn.MatchableClass
562+
case tp: TypeRef =>
563+
val sym = tp.symbol
564+
sym == defn.MatchableClass || !sym.isClass && tp.superType.isMatchableBound
575565
case tp: TypeParamRef =>
576566
ctx.typerState.constraint.entry(tp) match
577567
case bounds: TypeBounds => bounds.hi.isMatchableBound
578568
case _ => false
579-
case tp: TypeProxy => tp.underlying.isMatchableBound
569+
case tp: TypeProxy => tp.superType.isMatchableBound
580570
case tp: AndType => tp.tp1.isMatchableBound || tp.tp2.isMatchableBound
581571
case tp: OrType => tp.tp1.isMatchableBound && tp.tp2.isMatchableBound
582572
case _ => false
@@ -615,7 +605,7 @@ object Types {
615605
case tp: ClassInfo =>
616606
tp.decls
617607
case tp: TypeProxy =>
618-
tp.underlying.decls
608+
tp.superType.decls
619609
case _ =>
620610
EmptyScope
621611
}
@@ -641,7 +631,7 @@ object Types {
641631
case tp: ClassInfo =>
642632
tp.decls.denotsNamed(name).filterWithFlags(EmptyFlags, excluded).toDenot(NoPrefix)
643633
case tp: TypeProxy =>
644-
tp.underlying.findDecl(name, excluded)
634+
tp.superType.findDecl(name, excluded)
645635
case err: ErrorType =>
646636
newErrorSymbol(classSymbol orElse defn.RootClass, name, err.msg)
647637
case _ =>
@@ -885,7 +875,7 @@ object Types {
885875
def showPrefixSafely(pre: Type)(using Context): String = pre.stripTypeVar match {
886876
case pre: TermRef => i"${pre.symbol.name}."
887877
case pre: TypeRef => i"${pre.symbol.name}#"
888-
case pre: TypeProxy => showPrefixSafely(pre.underlying)
878+
case pre: TypeProxy => showPrefixSafely(pre.superType)
889879
case _ => if (pre.typeSymbol.exists) i"${pre.typeSymbol.name}#" else "."
890880
}
891881

@@ -912,7 +902,7 @@ object Types {
912902
val ns = tp.parent.memberNames(keepOnly, pre)
913903
if (keepOnly(pre, tp.refinedName)) ns + tp.refinedName else ns
914904
case tp: TypeProxy =>
915-
tp.underlying.memberNames(keepOnly, pre)
905+
tp.superType.memberNames(keepOnly, pre)
916906
case tp: AndType =>
917907
tp.tp1.memberNames(keepOnly, pre) | tp.tp2.memberNames(keepOnly, pre)
918908
case tp: OrType =>
@@ -1365,7 +1355,7 @@ object Types {
13651355
// which ensures that `X$ <:< X.type` returns true.
13661356
single(tp.symbol.companionModule.termRef.asSeenFrom(tp.prefix, tp.symbol.owner))
13671357
case tp: TypeProxy =>
1368-
tp.underlying.atoms match
1358+
tp.superType.atoms match
13691359
case Atoms.Range(_, hi) => Atoms.Range(Set.empty, hi)
13701360
case Atoms.Unknown => Atoms.Unknown
13711361
case _ => Atoms.Unknown
@@ -1609,7 +1599,7 @@ object Types {
16091599
case tp: ClassInfo =>
16101600
tp.prefix
16111601
case tp: TypeProxy =>
1612-
tp.underlying.normalizedPrefix
1602+
tp.superType.normalizedPrefix
16131603
case _ =>
16141604
NoType
16151605
}

compiler/src/dotty/tools/dotc/interactive/Completion.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ object Completion {
483483
val symbol = newSymbol(owner = NoSymbol, name, flags, info)
484484
val denot = SymDenotation(symbol, NoSymbol, name, flags, info)
485485
denot +: extractRefinements(parent)
486-
case tp: TypeProxy => extractRefinements(tp.underlying)
486+
case tp: TypeProxy => extractRefinements(tp.superType)
487487
case _ => List.empty
488488

489489
/** @param site The type to inspect.

compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,12 @@ object ExplicitOuter {
317317
case _ =>
318318
// Need to be careful to dealias before erasure, otherwise we lose prefixes.
319319
atPhaseNoLater(erasurePhase)(outerPrefix(tpe.underlying))
320+
// underlying is fine here and below since we are calling this after erasure.
321+
// However, there is some weird stuff going on with parboiled2 where an
322+
// AppliedType with a type alias as constructor is fed to outerPrefix.
323+
// For some other unknown reason this works with underlying but not with superType.
324+
// I was not able to minimize the problem and parboiled2 spits out way too much
325+
// macro generated code to be able to pinpoint the root problem.
320326
}
321327
case tpe: TypeProxy =>
322328
outerPrefix(tpe.underlying)

compiler/src/dotty/tools/dotc/transform/TypeUtils.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ object TypeUtils {
6363
val arity2 = self.tp2.tupleArity
6464
if arity1 == arity2 then arity1 else -1
6565
case _ =>
66-
if defn.isTupleClass(self.classSymbol) then self.dealias.argInfos.length
66+
if defn.isTupleNType(self) then self.dealias.argInfos.length
6767
else -1
6868
}
6969

@@ -80,7 +80,7 @@ object TypeUtils {
8080
case OrType(tp1, tp2) =>
8181
None // We can't combine the type of two tuples
8282
case _ =>
83-
if defn.isTupleClass(self.classSymbol) then Some(self.dealias.argInfos)
83+
if defn.isTupleClass(self.typeSymbol) then Some(self.dealias.argInfos)
8484
else None
8585
}
8686

@@ -104,7 +104,7 @@ object TypeUtils {
104104
case self @ TypeRef(prefix, _) if self.symbol.isClass =>
105105
prefix.select(self.symbol.companionModule).asInstanceOf[TermRef]
106106
case self: TypeProxy =>
107-
self.underlying.mirrorCompanionRef
107+
self.superType.mirrorCompanionRef
108108
}
109109

110110
/** Is this type a methodic type that takes implicit parameters (both old and new) at some point? */

compiler/src/dotty/tools/dotc/typer/Deriving.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ trait Deriving {
3333
case tp: TypeRef if tp.symbol.isClass => tp
3434
case tp: TypeRef if tp.symbol.isAbstractType => NoType
3535
case tp: TermRef => NoType
36-
case tp: TypeProxy => underlyingClassRef(tp.underlying)
36+
case tp: TypeProxy => underlyingClassRef(tp.superType)
3737
case _ => NoType
3838
}
3939

@@ -286,7 +286,7 @@ trait Deriving {
286286
case tp @ TypeRef(prefix, _) if tp.symbol.isClass =>
287287
prefix.select(tp.symbol.companionModule).asInstanceOf[TermRef]
288288
case tp: TypeProxy =>
289-
companionRef(tp.underlying)
289+
companionRef(tp.superType)
290290
}
291291
val resultType = instantiated(sym.info)
292292
val companion = companionRef(resultType)

compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ class ImplicitSearchError(
387387
.map(userDefinedImplicitNotFoundTypeMessage)
388388
.find(_.isDefined).flatten
389389
case tp: TypeProxy =>
390-
recur(tp.underlying)
390+
recur(tp.superType)
391391
case tp: AndType =>
392392
recur(tp.tp1).orElse(recur(tp.tp2))
393393
case _ =>

compiler/src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,7 @@ trait ImplicitRunInfo:
763763
WildcardType
764764
else
765765
seen += t
766-
t.underlying match
766+
t.superType match
767767
case TypeBounds(lo, hi) =>
768768
if lo.isBottomTypeAfterErasure then apply(hi)
769769
else AndType.make(apply(lo), apply(hi))

compiler/src/dotty/tools/dotc/typer/Synthesizer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
366366
// avoid type aliases for tuples
367367
Right(MirrorSource.GenericTuple(types))
368368
case _ => reduce(tp.underlying)
369-
case _ => reduce(tp.underlying)
369+
case _ => reduce(tp.superType)
370370
case tp @ AndType(l, r) =>
371371
for
372372
lsrc <- reduce(l)

compiler/test-resources/repl/i6474

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@ scala> object Foo2 { type T[+A] = [B] =>> (A, B) }
55
scala> object Foo3 { type T[+A] = [B] =>> [C] =>> (A, B) }
66
// defined object Foo3
77
scala> ((1, 2): Foo1.T[Int]): Foo1.T[Any]
8-
val res0: (Any, Int) = (1,2)
8+
val res0: Foo1.T[Any] = (1,2)
99
scala> ((1, 2): Foo2.T[Int][Int]): Foo2.T[Any][Int]
10-
val res1: (Any, Int) = (1,2)
10+
val res1: Foo2.T[Any][Int] = (1,2)
1111
scala> (1, 2): Foo3.T[Int][Int]
1212
-- [E056] Syntax Error: --------------------------------------------------------
1313
1 | (1, 2): Foo3.T[Int][Int]
1414
| ^^^^^^^^^^^^^^^^
1515
| Missing type parameter for Foo3.T[Int][Int]
1616
1 error found
1717
scala> ((1, 2): Foo3.T[Int][Int][Int]): Foo3.T[Any][Int][Int]
18-
val res2: (Any, Int) = (1,2)
18+
val res2: Foo3.T[Any][Int][Int] = (1,2)
1919
scala> object Foo3 { type T[A] = [B] =>> [C] =>> (A, B) }
2020
// defined object Foo3
2121
scala> ((1, 2): Foo3.T[Int][Int][Int])
22-
val res3: (Int, Int) = (1,2)
22+
val res3: Foo3.T[Int][Int][Int] = (1,2)
2323
scala> ((1, 2): Foo3.T[Int][Int][Int])
24-
val res4: (Int, Int) = (1,2)
24+
val res4: Foo3.T[Int][Int][Int] = (1,2)

0 commit comments

Comments
 (0)