Skip to content

Commit ee137ff

Browse files
authored
Fix #13197: Deskolemize lifted named arguments (#13590)
1 parent abc11ac commit ee137ff

File tree

5 files changed

+32
-11
lines changed

5 files changed

+32
-11
lines changed

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,6 +1389,17 @@ object Types {
13891389
/** Like `dealiasKeepAnnots`, but keeps only refining annotations */
13901390
final def dealiasKeepRefiningAnnots(using Context): Type = dealias1(keepIfRefining)
13911391

1392+
/** Approximate this type with a type that does not contain skolem types. */
1393+
final def deskolemized(using Context): Type =
1394+
val deskolemizer = new ApproximatingTypeMap {
1395+
def apply(tp: Type) = /*trace(i"deskolemize($tp) at $variance", show = true)*/
1396+
tp match {
1397+
case tp: SkolemType => range(defn.NothingType, atVariance(1)(apply(tp.info)))
1398+
case _ => mapOver(tp)
1399+
}
1400+
}
1401+
deskolemizer(this)
1402+
13921403
/** The result of normalization using `tryNormalize`, or the type itself if
13931404
* tryNormlize yields NoType
13941405
*/

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ abstract class Lifter {
4848
else {
4949
val name = UniqueName.fresh(prefix)
5050
// don't instantiate here, as the type params could be further constrained, see tests/pos/pickleinf.scala
51-
var liftedType = expr.tpe.widen
51+
var liftedType = expr.tpe.widen.deskolemized
5252
if (liftedFlags.is(Method)) liftedType = ExprType(liftedType)
5353
val lifted = newSymbol(ctx.owner, name, liftedFlags | Synthetic, liftedType, coord = spanCoord(expr.span))
5454
defs += liftedDef(lifted, expr)

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

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1704,16 +1704,7 @@ class Namer { typer: Typer =>
17041704
// it would be erased to BoxedUnit.
17051705
def dealiasIfUnit(tp: Type) = if (tp.isRef(defn.UnitClass)) defn.UnitType else tp
17061706

1707-
// Approximate a type `tp` with a type that does not contain skolem types.
1708-
val deskolemize = new ApproximatingTypeMap {
1709-
def apply(tp: Type) = /*trace(i"deskolemize($tp) at $variance", show = true)*/
1710-
tp match {
1711-
case tp: SkolemType => range(defn.NothingType, atVariance(1)(apply(tp.info)))
1712-
case _ => mapOver(tp)
1713-
}
1714-
}
1715-
1716-
def cookedRhsType = deskolemize(dealiasIfUnit(rhsType))
1707+
def cookedRhsType = dealiasIfUnit(rhsType).deskolemized
17171708
def lhsType = fullyDefinedType(cookedRhsType, "right-hand side", mdef.span)
17181709
//if (sym.name.toString == "y") println(i"rhs = $rhsType, cooked = $cookedRhsType")
17191710
if (inherited.exists)

tests/explicit-nulls/pos/i13197.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
trait Bar:
2+
def b: String | Null
3+
4+
class Foo(a: String = "", b: String)
5+
6+
object Foo:
7+
def foo(bar: Bar) = Foo(b = bar.b.nn)

tests/pos/i13197.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// this test is similar to explicit-nulls/pos/i13197.scala, but without explicit nulls
2+
3+
extension [T](x: T | String) inline def forceString: x.type & String =
4+
x.asInstanceOf
5+
6+
trait Bar:
7+
def b: String | Int
8+
9+
class Foo(a: String = "", b: String)
10+
11+
object Foo:
12+
def foo(bar: Bar) = Foo(b = bar.b.forceString)

0 commit comments

Comments
 (0)