From 8ec93aef3a927972a98de0f58c9d4419347a93cf Mon Sep 17 00:00:00 2001 From: Kacper Korban Date: Wed, 29 Jan 2025 10:03:09 +0100 Subject: [PATCH] Widen skolem types when adding parent refinements --- compiler/src/dotty/tools/dotc/core/NamerOps.scala | 14 ++++++++------ .../tools/dotc/core/tasty/TreeUnpickler.scala | 2 +- compiler/src/dotty/tools/dotc/typer/Namer.scala | 2 +- tests/pos/i22456.scala | 4 ++++ 4 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 tests/pos/i22456.scala diff --git a/compiler/src/dotty/tools/dotc/core/NamerOps.scala b/compiler/src/dotty/tools/dotc/core/NamerOps.scala index 363a01665564..d92c408c0a6b 100644 --- a/compiler/src/dotty/tools/dotc/core/NamerOps.scala +++ b/compiler/src/dotty/tools/dotc/core/NamerOps.scala @@ -8,6 +8,7 @@ import ContextOps.enter import TypeApplications.EtaExpansion import collection.mutable import config.Printers.typr +import ast.untpd /** Operations that are shared between Namer and TreeUnpickler */ object NamerOps: @@ -38,19 +39,20 @@ object NamerOps: * unless it is null. */ extension (tp: Type) - def separateRefinements(cls: ClassSymbol, refinements: mutable.LinkedHashMap[Name, Type] | Null)(using Context): Type = + def separateRefinements(cls: ClassSymbol, refinements: mutable.LinkedHashMap[Name, Type] | Null, parent: untpd.Tree)(using Context): Type = tp match case RefinedType(tp1, rname, rinfo) => - try tp1.separateRefinements(cls, refinements) + try tp1.separateRefinements(cls, refinements, parent) finally if refinements != null then + val rinfo1 = rinfo.widenSkolem refinements(rname) = refinements.get(rname) match - case Some(tp) => tp & rinfo - case None => rinfo + case Some(tp) => tp & rinfo1 + case None => rinfo1 case tp @ AnnotatedType(tp1, ann) => - tp.derivedAnnotatedType(tp1.separateRefinements(cls, refinements), ann) + tp.derivedAnnotatedType(tp1.separateRefinements(cls, refinements, parent), ann) case tp: RecType => - tp.parent.substRecThis(tp, cls.thisType).separateRefinements(cls, refinements) + tp.parent.substRecThis(tp, cls.thisType).separateRefinements(cls, refinements, parent) case tp => tp diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index c07121a52191..01771c4d141f 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -1080,7 +1080,7 @@ class TreeUnpickler(reader: TastyReader, } val parentReader = fork val parents = readParents(withArgs = false)(using parentCtx) - val parentTypes = parents.map(_.tpe.dealiasKeepAnnots.separateRefinements(cls, null)) + val parentTypes = parents.map(p => p.tpe.dealiasKeepAnnots.separateRefinements(cls, null, p)) if cls.is(JavaDefined) && parentTypes.exists(_.derivesFrom(defn.JavaAnnotationClass)) then cls.setFlag(JavaAnnotation) val self = diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 21ef0fc5d123..4445089eadf3 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -1615,7 +1615,7 @@ class Namer { typer: Typer => else { val pt = checkClassType( if Feature.enabled(modularity) - then ptype.separateRefinements(cls, parentRefinements) + then ptype.separateRefinements(cls, parentRefinements, parent) else ptype, parent.srcPos, traitReq = parent ne parents.head, diff --git a/tests/pos/i22456.scala b/tests/pos/i22456.scala new file mode 100644 index 000000000000..ed1241bc4b39 --- /dev/null +++ b/tests/pos/i22456.scala @@ -0,0 +1,4 @@ +import language.experimental.modularity + +class T(tracked val y: Int) +class C(tracked val x: Int) extends T(x + 1)