Skip to content

Commit f64cc82

Browse files
committed
More applied constructor types fixes
- only type applied constructor types in Typer - handle multiple parameter lists - add tests for mixed tracked and not tracked parameters
1 parent 9c0f0fc commit f64cc82

File tree

4 files changed

+32
-16
lines changed

4 files changed

+32
-16
lines changed

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

+12-12
Original file line numberDiff line numberDiff line change
@@ -1694,18 +1694,18 @@ trait Applications extends Compatibility {
16941694
def typedUnApply(tree: untpd.UnApply, selType: Type)(using Context): UnApply =
16951695
throw new UnsupportedOperationException("cannot type check an UnApply node")
16961696

1697-
def typedAppliedConstructorType(tree: untpd.Apply)(using Context) = tree.fun match
1698-
case Select(New(tpt), _) =>
1699-
val tree1 = typedExpr(tree)
1700-
val widenSkolemsMap = new TypeMap:
1701-
def apply(tp: Type) = mapOver(tp.widenSkolem)
1702-
val preciseTp = widenSkolemsMap(tree1.tpe)
1703-
val classTp = typedType(tpt).tpe
1704-
if !preciseTp.isError && (preciseTp frozen_=:= classTp) then
1705-
report.warning(PointlessAppliedConstructorType(tpt, tree.args, classTp), tree.srcPos)
1706-
TypeTree(preciseTp)
1707-
case _ =>
1708-
throw TypeError(em"Unexpected applied constructor type: $tree")
1697+
def typedAppliedConstructorType(tree: untpd.Apply)(using Context) = untpd.methPart(tree) match
1698+
case Select(New(tpt), _) =>
1699+
val tree1 = typedExpr(tree)
1700+
val widenSkolemsMap = new TypeMap:
1701+
def apply(tp: Type) = mapOver(tp.widenSkolem)
1702+
val preciseTp = widenSkolemsMap(tree1.tpe)
1703+
val classTp = typedType(tpt).tpe
1704+
if !preciseTp.isError && (preciseTp frozen_=:= classTp) then
1705+
report.warning(PointlessAppliedConstructorType(tpt, tree.args, classTp), tree.srcPos)
1706+
TypeTree(preciseTp)
1707+
case _ =>
1708+
throw TypeError(em"Unexpected applied constructor type: $tree")
17091709

17101710
/** Is given method reference applicable to argument trees `args`?
17111711
* @param resultType The expected result type of the application

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -3518,7 +3518,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
35183518
def typedUnnamed(tree: untpd.Tree): Tree = tree match {
35193519
case tree: untpd.Apply =>
35203520
if (ctx.mode is Mode.Pattern) typedUnApply(tree, pt)
3521-
else if (ctx.mode is Mode.Type) typedAppliedConstructorType(tree)
3521+
else if (ctx.mode.is(Mode.Type) && !ctx.isAfterTyper) typedAppliedConstructorType(tree)
35223522
else typedApply(tree, pt)
35233523
case tree: untpd.This => typedThis(tree)
35243524
case tree: untpd.Number => typedNumber(tree, pt)

docs/_docs/reference/experimental/modularity.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ the comment is the resulting type of the applied constructor types.
208208
```scala
209209
import scala.language.experimental.modularity
210210

211-
class Box(tracked val v: Any)
211+
class C(tracked val v: Any)
212212

213213
val c: C(42) /* C { val v: 42 } */ = C(42)
214214
```

tests/pos/applied_constructor_types.scala

+18-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@ class F[A](tracked val a: Int)
88
class G[A](tracked val a: A)
99
class NF[A](tracked val f: F[A])
1010

11+
class Person(val name: String, tracked val age: Int)
12+
class PersonPrime(val name: String)(tracked val age: Int)
13+
class PersonBis(tracked val name: String)(val age: Int)
14+
1115
object O:
12-
val m: Int = 42
16+
val m: Int = 27
1317

1418
class InnerClass(tracked val x: Int)
1519

@@ -23,11 +27,23 @@ object Test extends App {
2327
val f3: F(42) = F(42)
2428
val g: G(42) = G(42)
2529

26-
val n: Int = 42
30+
val n: Int = 27
2731
val c2: C(n) = C(n)
2832
val c3: C(O.m) = C(O.m)
2933

3034
val box: Box(O.InnerClass(42)) = Box(O.InnerClass(42))
3135
val box2: Box(O.InnerClass(n)) = Box(O.InnerClass(n))
3236
val box3: Box(O.InnerClass(O.m)) = Box(O.InnerClass(O.m))
37+
38+
val person: Person("Kasia", 27) = Person("Kasia", 27)
39+
val person1: Person("Kasia", n) = Person("Kasia", n)
40+
val person2: Person("Kasia", O.m) = Person("Kasia", O.m)
41+
42+
val personPrime: PersonPrime("Kasia")(27) = PersonPrime("Kasia")(27)
43+
val personPrime1: PersonPrime("Kasia")(n) = PersonPrime("Kasia")(n)
44+
val personPrime2: PersonPrime("Kasia")(O.m) = PersonPrime("Kasia")(O.m)
45+
46+
val personBis: PersonBis("Kasia")(27) = PersonBis("Kasia")(27)
47+
val personBis1: PersonBis("Kasia")(n) = PersonBis("Kasia")(n)
48+
val personBis2: PersonBis("Kasia")(O.m) = PersonBis("Kasia")(O.m)
3349
}

0 commit comments

Comments
 (0)