Skip to content
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

Turn some calls to underlying into superType. #15455

Merged
merged 7 commits into from
Jun 20, 2022
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
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/CheckRealizable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class CheckRealizable(using Context) {
case tp: RefinedType => refinedNames(tp.parent) + tp.refinedName
case tp: AndType => refinedNames(tp.tp1) ++ refinedNames(tp.tp2)
case tp: OrType => refinedNames(tp.tp1) ++ refinedNames(tp.tp2)
case tp: TypeProxy => refinedNames(tp.underlying)
case tp: TypeProxy => refinedNames(tp.superType)
case _ => Set.empty
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1565,8 +1565,8 @@ class Definitions {
def tupleTypes(tp: Type, bound: Int = Int.MaxValue)(using Context): Option[List[Type]] = {
@tailrec def rec(tp: Type, acc: List[Type], bound: Int): Option[List[Type]] = tp.normalized.dealias match {
case _ if bound < 0 => Some(acc.reverse)
case tp: AppliedType if defn.PairClass == tp.classSymbol => rec(tp.args(1), tp.args.head :: acc, bound - 1)
case tp: AppliedType if defn.isTupleClass(tp.tycon.classSymbol) => Some(acc.reverse ::: tp.args)
case tp: AppliedType if PairClass == tp.classSymbol => rec(tp.args(1), tp.args.head :: acc, bound - 1)
case tp: AppliedType if isTupleNType(tp) => Some(acc.reverse ::: tp.args)
case tp: TermRef if tp.symbol == defn.EmptyTupleModule => Some(acc.reverse)
case _ => None
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ trait PatternTypeConstrainer { self: TypeComparer =>
def refinementIsInvariant(tp: Type): Boolean = tp match {
case tp: SingletonType => true
case tp: ClassInfo => tp.cls.is(Final) || tp.cls.is(Case)
case tp: TypeProxy => refinementIsInvariant(tp.underlying)
case tp: TypeProxy => refinementIsInvariant(tp.superType)
case _ => false
}

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 @@ -1584,7 +1584,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
case tp: RecType => fix(tp.parent).substRecThis(tp, anchor)
case tp @ RefinedType(parent, rname, rinfo) => tp.derivedRefinedType(fix(parent), rname, rinfo)
case tp: TypeParamRef => fixOrElse(bounds(tp).hi, tp)
case tp: TypeProxy => fixOrElse(tp.underlying, tp)
case tp: TypeProxy => fixOrElse(tp.superType, tp)
case tp: AndType => tp.derivedAndType(fix(tp.tp1), fix(tp.tp2))
case tp: OrType => tp.derivedOrType (fix(tp.tp1), fix(tp.tp2))
case tp => tp
Expand Down Expand Up @@ -1857,7 +1857,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
final def ensureStableSingleton(tp: Type): SingletonType = tp.stripTypeVar match {
case tp: SingletonType if tp.isStable => tp
case tp: ValueType => SkolemType(tp)
case tp: TypeProxy => ensureStableSingleton(tp.underlying)
case tp: TypeProxy => ensureStableSingleton(tp.superType)
case tp => assert(ctx.reporter.errorsReported); SkolemType(tp)
}

Expand Down
4 changes: 3 additions & 1 deletion compiler/src/dotty/tools/dotc/core/TypeEval.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ object TypeEval:
// final val one = 1
// type Two = one.type + one.type
// ```
case tp: TypeProxy if tp.underlying.isStable => tp.underlying.fixForEvaluation
case tp: TypeProxy =>
val tp1 = tp.superType
if tp1.isStable then tp1.fixForEvaluation else tp
case tp => tp

def constValue(tp: Type): Option[Any] = tp.fixForEvaluation match
Expand Down
40 changes: 15 additions & 25 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -248,19 +248,6 @@ object Types {
val d = defn
hasClassSymbol(d.NothingClass) || hasClassSymbol(d.NullClass)

/** Does this type refer exactly to class symbol `sym`, instead of to a subclass of `sym`?
* Implemented like `isRef`, but follows more types: all type proxies as well as and- and or-types
*/
private[Types] def isTightPrefix(sym: Symbol)(using Context): Boolean = stripTypeVar match {
case tp: NamedType => tp.info.isTightPrefix(sym)
case tp: ClassInfo => tp.cls eq sym
case tp: Types.ThisType => tp.cls eq sym
case tp: TypeProxy => tp.underlying.isTightPrefix(sym)
case tp: AndType => tp.tp1.isTightPrefix(sym) && tp.tp2.isTightPrefix(sym)
case tp: OrType => tp.tp1.isTightPrefix(sym) || tp.tp2.isTightPrefix(sym)
case _ => false
}

/** True if this type is an instance of the given `cls` or an instance of
* a non-bottom subclass of `cls`.
*/
Expand Down Expand Up @@ -331,7 +318,7 @@ object Types {
val sym = tp.symbol
if (sym.isClass) sym == defn.AnyKindClass else loop(tp.translucentSuperType)
case tp: TypeProxy =>
loop(tp.underlying)
loop(tp.underlying) // underlying OK here since an AnyKinded type cannot be a type argument of another type
case _ =>
false
}
Expand All @@ -342,6 +329,7 @@ object Types {
final def isNotNull(using Context): Boolean = this match {
case tp: ConstantType => tp.value.value != null
case tp: ClassInfo => !tp.cls.isNullableClass && tp.cls != defn.NothingClass
case tp: AppliedType => tp.superType.isNotNull
case tp: TypeBounds => tp.lo.isNotNull
case tp: TypeProxy => tp.underlying.isNotNull
case AndType(tp1, tp2) => tp1.isNotNull || tp2.isNotNull
Expand Down Expand Up @@ -501,7 +489,7 @@ object Types {
val sym = tp.symbol
if (sym.isClass) sym else tp.superType.classSymbol
case tp: TypeProxy =>
tp.underlying.classSymbol
tp.superType.classSymbol
case tp: ClassInfo =>
tp.cls
case AndType(l, r) =>
Expand Down Expand Up @@ -535,7 +523,7 @@ object Types {
val sym = tp.symbol
if (include(sym)) sym :: Nil else tp.superType.parentSymbols(include)
case tp: TypeProxy =>
tp.underlying.parentSymbols(include)
tp.superType.parentSymbols(include)
case tp: ClassInfo =>
tp.cls :: Nil
case AndType(l, r) =>
Expand All @@ -557,7 +545,7 @@ object Types {
val sym = tp.symbol
sym == cls || !sym.isClass && tp.superType.hasClassSymbol(cls)
case tp: TypeProxy =>
tp.underlying.hasClassSymbol(cls)
tp.superType.hasClassSymbol(cls)
case tp: ClassInfo =>
tp.cls == cls
case AndType(l, r) =>
Expand All @@ -571,12 +559,14 @@ object Types {
* bounds of type variables in the constraint.
*/
def isMatchableBound(using Context): Boolean = dealias match
case tp: TypeRef => tp.symbol == defn.MatchableClass
case tp: TypeRef =>
val sym = tp.symbol
sym == defn.MatchableClass || !sym.isClass && tp.superType.isMatchableBound
case tp: TypeParamRef =>
ctx.typerState.constraint.entry(tp) match
case bounds: TypeBounds => bounds.hi.isMatchableBound
case _ => false
case tp: TypeProxy => tp.underlying.isMatchableBound
case tp: TypeProxy => tp.superType.isMatchableBound
case tp: AndType => tp.tp1.isMatchableBound || tp.tp2.isMatchableBound
case tp: OrType => tp.tp1.isMatchableBound && tp.tp2.isMatchableBound
case _ => false
Expand Down Expand Up @@ -615,7 +605,7 @@ object Types {
case tp: ClassInfo =>
tp.decls
case tp: TypeProxy =>
tp.underlying.decls
tp.superType.decls
case _ =>
EmptyScope
}
Expand All @@ -641,7 +631,7 @@ object Types {
case tp: ClassInfo =>
tp.decls.denotsNamed(name).filterWithFlags(EmptyFlags, excluded).toDenot(NoPrefix)
case tp: TypeProxy =>
tp.underlying.findDecl(name, excluded)
tp.superType.findDecl(name, excluded)
case err: ErrorType =>
newErrorSymbol(classSymbol orElse defn.RootClass, name, err.msg)
case _ =>
Expand Down Expand Up @@ -885,7 +875,7 @@ object Types {
def showPrefixSafely(pre: Type)(using Context): String = pre.stripTypeVar match {
case pre: TermRef => i"${pre.symbol.name}."
case pre: TypeRef => i"${pre.symbol.name}#"
case pre: TypeProxy => showPrefixSafely(pre.underlying)
case pre: TypeProxy => showPrefixSafely(pre.superType)
case _ => if (pre.typeSymbol.exists) i"${pre.typeSymbol.name}#" else "."
}

Expand All @@ -912,7 +902,7 @@ object Types {
val ns = tp.parent.memberNames(keepOnly, pre)
if (keepOnly(pre, tp.refinedName)) ns + tp.refinedName else ns
case tp: TypeProxy =>
tp.underlying.memberNames(keepOnly, pre)
tp.superType.memberNames(keepOnly, pre)
case tp: AndType =>
tp.tp1.memberNames(keepOnly, pre) | tp.tp2.memberNames(keepOnly, pre)
case tp: OrType =>
Expand Down Expand Up @@ -1368,7 +1358,7 @@ object Types {
// which ensures that `X$ <:< X.type` returns true.
single(tp.symbol.companionModule.termRef.asSeenFrom(tp.prefix, tp.symbol.owner))
case tp: TypeProxy =>
tp.underlying.atoms match
tp.superType.atoms match
case Atoms.Range(_, hi) => Atoms.Range(Set.empty, hi)
case Atoms.Unknown => Atoms.Unknown
case _ => Atoms.Unknown
Expand Down Expand Up @@ -1612,7 +1602,7 @@ object Types {
case tp: ClassInfo =>
tp.prefix
case tp: TypeProxy =>
tp.underlying.normalizedPrefix
tp.superType.normalizedPrefix
case _ =>
NoType
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/interactive/Completion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ object Completion {
val symbol = newSymbol(owner = NoSymbol, name, flags, info)
val denot = SymDenotation(symbol, NoSymbol, name, flags, info)
denot +: extractRefinements(parent)
case tp: TypeProxy => extractRefinements(tp.underlying)
case tp: TypeProxy => extractRefinements(tp.superType)
case _ => List.empty

/** @param site The type to inspect.
Expand Down
6 changes: 6 additions & 0 deletions compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,12 @@ object ExplicitOuter {
case _ =>
// Need to be careful to dealias before erasure, otherwise we lose prefixes.
atPhaseNoLater(erasurePhase)(outerPrefix(tpe.underlying))
// underlying is fine here and below since we are calling this after erasure.
// However, there is some weird stuff going on with parboiled2 where an
// AppliedType with a type alias as constructor is fed to outerPrefix.
// For some other unknown reason this works with underlying but not with superType.
// I was not able to minimize the problem and parboiled2 spits out way too much
// macro generated code to be able to pinpoint the root problem.
}
case tpe: TypeProxy =>
outerPrefix(tpe.underlying)
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/transform/TypeUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ object TypeUtils {
val arity2 = self.tp2.tupleArity
if arity1 == arity2 then arity1 else -1
case _ =>
if defn.isTupleClass(self.classSymbol) then self.dealias.argInfos.length
if defn.isTupleNType(self) then self.dealias.argInfos.length
else -1
}

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

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

/** Is this type a methodic type that takes implicit parameters (both old and new) at some point? */
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/Deriving.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ trait Deriving {
case tp: TypeRef if tp.symbol.isClass => tp
case tp: TypeRef if tp.symbol.isAbstractType => NoType
case tp: TermRef => NoType
case tp: TypeProxy => underlyingClassRef(tp.underlying)
case tp: TypeProxy => underlyingClassRef(tp.superType)
case _ => NoType
}

Expand Down Expand Up @@ -286,7 +286,7 @@ trait Deriving {
case tp @ TypeRef(prefix, _) if tp.symbol.isClass =>
prefix.select(tp.symbol.companionModule).asInstanceOf[TermRef]
case tp: TypeProxy =>
companionRef(tp.underlying)
companionRef(tp.superType)
}
val resultType = instantiated(sym.info)
val companion = companionRef(resultType)
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ class ImplicitSearchError(
.map(userDefinedImplicitNotFoundTypeMessage)
.find(_.isDefined).flatten
case tp: TypeProxy =>
recur(tp.underlying)
recur(tp.superType)
case tp: AndType =>
recur(tp.tp1).orElse(recur(tp.tp2))
case _ =>
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,7 @@ trait ImplicitRunInfo:
WildcardType
else
seen += t
t.underlying match
t.superType match
case TypeBounds(lo, hi) =>
if lo.isBottomTypeAfterErasure then apply(hi)
else AndType.make(apply(lo), apply(hi))
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Synthesizer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
// avoid type aliases for tuples
Right(MirrorSource.GenericTuple(types))
case _ => reduce(tp.underlying)
case _ => reduce(tp.underlying)
case _ => reduce(tp.superType)
case tp @ AndType(l, r) =>
for
lsrc <- reduce(l)
Expand Down
10 changes: 5 additions & 5 deletions compiler/test-resources/repl/i6474
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ scala> object Foo2 { type T[+A] = [B] =>> (A, B) }
scala> object Foo3 { type T[+A] = [B] =>> [C] =>> (A, B) }
// defined object Foo3
scala> ((1, 2): Foo1.T[Int]): Foo1.T[Any]
val res0: (Any, Int) = (1,2)
val res0: Foo1.T[Any] = (1,2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's nice

scala> ((1, 2): Foo2.T[Int][Int]): Foo2.T[Any][Int]
val res1: (Any, Int) = (1,2)
val res1: Foo2.T[Any][Int] = (1,2)
scala> (1, 2): Foo3.T[Int][Int]
-- [E056] Syntax Error: --------------------------------------------------------
1 | (1, 2): Foo3.T[Int][Int]
| ^^^^^^^^^^^^^^^^
| Missing type parameter for Foo3.T[Int][Int]
1 error found
scala> ((1, 2): Foo3.T[Int][Int][Int]): Foo3.T[Any][Int][Int]
val res2: (Any, Int) = (1,2)
val res2: Foo3.T[Any][Int][Int] = (1,2)
scala> object Foo3 { type T[A] = [B] =>> [C] =>> (A, B) }
// defined object Foo3
scala> ((1, 2): Foo3.T[Int][Int][Int])
val res3: (Int, Int) = (1,2)
val res3: Foo3.T[Int][Int][Int] = (1,2)
scala> ((1, 2): Foo3.T[Int][Int][Int])
val res4: (Int, Int) = (1,2)
val res4: Foo3.T[Int][Int][Int] = (1,2)