From a5369556a9d0a77d3b9181df7ee1642807e0a879 Mon Sep 17 00:00:00 2001 From: odersky Date: Sat, 18 Jun 2022 18:53:35 +0200 Subject: [PATCH 1/7] Turn some calls to `underlying` into `superType`. --- .../src/dotty/tools/dotc/core/Definitions.scala | 4 ++-- compiler/src/dotty/tools/dotc/core/Types.scala | 17 ++++++++++------- .../dotty/tools/dotc/transform/TypeUtils.scala | 4 ++-- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 5b8bfd646530..51a15f77142a 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -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 } diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 6557e3649377..15c7ddcb8306 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -255,7 +255,7 @@ object Types { 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: TypeProxy => tp.superType.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 @@ -331,7 +331,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 } @@ -342,6 +342,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 @@ -501,7 +502,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) => @@ -535,7 +536,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) => @@ -557,7 +558,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) => @@ -571,12 +572,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 diff --git a/compiler/src/dotty/tools/dotc/transform/TypeUtils.scala b/compiler/src/dotty/tools/dotc/transform/TypeUtils.scala index cf9fcbabf536..becf0b4ea789 100644 --- a/compiler/src/dotty/tools/dotc/transform/TypeUtils.scala +++ b/compiler/src/dotty/tools/dotc/transform/TypeUtils.scala @@ -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 } @@ -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 } From 4b476c9bca446dd3a6ea7fed291d4e6b67c2cbcb Mon Sep 17 00:00:00 2001 From: odersky Date: Sun, 19 Jun 2022 10:11:52 +0200 Subject: [PATCH 2/7] More underlying -> supertype conversions in Types --- compiler/src/dotty/tools/dotc/core/Types.scala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 15c7ddcb8306..f0ffcda309ae 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -618,7 +618,7 @@ object Types { case tp: ClassInfo => tp.decls case tp: TypeProxy => - tp.underlying.decls + tp.superType.decls case _ => EmptyScope } @@ -644,7 +644,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 _ => @@ -888,7 +888,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 "." } @@ -915,7 +915,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 => @@ -1371,7 +1371,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 @@ -1615,7 +1615,7 @@ object Types { case tp: ClassInfo => tp.prefix case tp: TypeProxy => - tp.underlying.normalizedPrefix + tp.superType.normalizedPrefix case _ => NoType } From 6d6c409341bfca315a12f3ce7d7d87474830da10 Mon Sep 17 00:00:00 2001 From: odersky Date: Wed, 15 Jun 2022 22:05:44 +0200 Subject: [PATCH 3/7] Drop isTightPrefix --- compiler/src/dotty/tools/dotc/core/Types.scala | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index f0ffcda309ae..20f1ebb2964c 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -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.superType.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`. */ From 5aa3bf67415242fee05601beac18a288c6092056 Mon Sep 17 00:00:00 2001 From: odersky Date: Sun, 19 Jun 2022 10:18:23 +0200 Subject: [PATCH 4/7] Convert underlying -> superType elsewhere in front end --- compiler/src/dotty/tools/dotc/core/CheckRealizable.scala | 2 +- .../src/dotty/tools/dotc/core/PatternTypeConstrainer.scala | 2 +- compiler/src/dotty/tools/dotc/core/TypeComparer.scala | 4 ++-- compiler/src/dotty/tools/dotc/interactive/Completion.scala | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala b/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala index a83f35ccd65a..4b441d512dec 100644 --- a/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala +++ b/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala @@ -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 } diff --git a/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala b/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala index a689405b4044..5cd8d4f50eeb 100644 --- a/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala +++ b/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala @@ -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 } diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index f66ee12491aa..f095662eb699 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -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 @@ -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) } diff --git a/compiler/src/dotty/tools/dotc/interactive/Completion.scala b/compiler/src/dotty/tools/dotc/interactive/Completion.scala index 476da61b5426..4d953bdb16cc 100644 --- a/compiler/src/dotty/tools/dotc/interactive/Completion.scala +++ b/compiler/src/dotty/tools/dotc/interactive/Completion.scala @@ -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. From 567d95ffec2ab379b11b94b1f5521ea243655eb4 Mon Sep 17 00:00:00 2001 From: odersky Date: Sun, 19 Jun 2022 10:20:05 +0200 Subject: [PATCH 5/7] Fix repltest The fixed frontend dealiases less in the inferred types of i6474, which is a good thing. --- compiler/test-resources/repl/i6474 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/test-resources/repl/i6474 b/compiler/test-resources/repl/i6474 index 0957bbbe2761..1390dce7042f 100644 --- a/compiler/test-resources/repl/i6474 +++ b/compiler/test-resources/repl/i6474 @@ -5,9 +5,9 @@ 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) 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] @@ -15,10 +15,10 @@ scala> (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) \ No newline at end of file From 6fa476763d777939658928d412ab27057aec6d48 Mon Sep 17 00:00:00 2001 From: odersky Date: Sun, 19 Jun 2022 10:27:56 +0200 Subject: [PATCH 6/7] Map underlying -> superType in transformations --- compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala | 6 ++++++ compiler/src/dotty/tools/dotc/transform/TypeUtils.scala | 2 +- compiler/src/dotty/tools/dotc/typer/Deriving.scala | 2 +- compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala | 2 +- compiler/src/dotty/tools/dotc/typer/Implicits.scala | 2 +- compiler/src/dotty/tools/dotc/typer/Synthesizer.scala | 2 +- 6 files changed, 11 insertions(+), 5 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala index 978ec2ce777f..d428575d0e4a 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -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) diff --git a/compiler/src/dotty/tools/dotc/transform/TypeUtils.scala b/compiler/src/dotty/tools/dotc/transform/TypeUtils.scala index becf0b4ea789..00c09a3ebf07 100644 --- a/compiler/src/dotty/tools/dotc/transform/TypeUtils.scala +++ b/compiler/src/dotty/tools/dotc/transform/TypeUtils.scala @@ -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? */ diff --git a/compiler/src/dotty/tools/dotc/typer/Deriving.scala b/compiler/src/dotty/tools/dotc/typer/Deriving.scala index 22c73b92802a..13c1f6672ac5 100644 --- a/compiler/src/dotty/tools/dotc/typer/Deriving.scala +++ b/compiler/src/dotty/tools/dotc/typer/Deriving.scala @@ -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) diff --git a/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala b/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala index e81e6acf3d2c..215fe9bfa687 100644 --- a/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala +++ b/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala @@ -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 _ => diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 7c22c30116c3..9a42babcd38e 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -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)) diff --git a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala index f2b7b82a680e..8b0fa88ad5a9 100644 --- a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala @@ -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) From 0bdbc87a5d31bb26b6aa8868049bfa98961a1620 Mon Sep 17 00:00:00 2001 From: odersky Date: Sun, 19 Jun 2022 10:32:07 +0200 Subject: [PATCH 7/7] Change underlying to superType in TypeEval --- compiler/src/dotty/tools/dotc/core/TypeEval.scala | 4 +++- compiler/src/dotty/tools/dotc/typer/Deriving.scala | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/TypeEval.scala b/compiler/src/dotty/tools/dotc/core/TypeEval.scala index de623bbea75a..187b4e903065 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeEval.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeEval.scala @@ -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 diff --git a/compiler/src/dotty/tools/dotc/typer/Deriving.scala b/compiler/src/dotty/tools/dotc/typer/Deriving.scala index 13c1f6672ac5..0f3a138d0390 100644 --- a/compiler/src/dotty/tools/dotc/typer/Deriving.scala +++ b/compiler/src/dotty/tools/dotc/typer/Deriving.scala @@ -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 }