diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 5df2d0005d42..d3c0eeab73d9 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -1208,7 +1208,6 @@ object Types { if tp.isOverloaded then tp else tp.underlying.widen case tp: SingletonType => tp.underlying.widen case tp: ExprType => tp.resultType.widen - case tp: AndType => tp.derivedAndType(tp.tp1.widen, tp.tp2.widen) case tp => val tp1 = tp.stripped if tp1 eq tp then tp @@ -1390,6 +1389,17 @@ object Types { /** Like `dealiasKeepAnnots`, but keeps only refining annotations */ final def dealiasKeepRefiningAnnots(using Context): Type = dealias1(keepIfRefining) + /** Approximate this type with a type that does not contain skolem types. */ + final def deskolemized(using Context): Type = + val deskolemizer = new ApproximatingTypeMap { + def apply(tp: Type) = /*trace(i"deskolemize($tp) at $variance", show = true)*/ + tp match { + case tp: SkolemType => range(defn.NothingType, atVariance(1)(apply(tp.info))) + case _ => mapOver(tp) + } + } + deskolemizer(this) + /** The result of normalization using `tryNormalize`, or the type itself if * tryNormlize yields NoType */ diff --git a/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala b/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala index 74891fccd985..c04b5f1d2d85 100644 --- a/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala +++ b/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala @@ -48,7 +48,7 @@ abstract class Lifter { else { val name = UniqueName.fresh(prefix) // don't instantiate here, as the type params could be further constrained, see tests/pos/pickleinf.scala - var liftedType = expr.tpe.widen + var liftedType = expr.tpe.widen.deskolemized if (liftedFlags.is(Method)) liftedType = ExprType(liftedType) val lifted = newSymbol(ctx.owner, name, liftedFlags | Synthetic, liftedType, coord = spanCoord(expr.span)) defs += liftedDef(lifted, expr) diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 1eb6c47bce4a..c0ed720bb369 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -1713,7 +1713,7 @@ class Namer { typer: Typer => } } - def cookedRhsType = deskolemize(dealiasIfUnit(rhsType)) + def cookedRhsType = dealiasIfUnit(rhsType).deskolemized def lhsType = fullyDefinedType(cookedRhsType, "right-hand side", mdef.span) //if (sym.name.toString == "y") println(i"rhs = $rhsType, cooked = $cookedRhsType") if (inherited.exists) diff --git a/tests/pos/i13197.scala b/tests/pos/i13197.scala index f8f9e53de7f3..cf8b2bb3ef0d 100644 --- a/tests/pos/i13197.scala +++ b/tests/pos/i13197.scala @@ -6,7 +6,7 @@ extension [T](x: T | String) inline def forceString: x.type & String = trait Bar: def b: String | Int -class Foo(a: String = "", b: Any) +class Foo(a: String = "", b: String) object Foo: def foo(bar: Bar) = Foo(b = bar.b.forceString) \ No newline at end of file