Skip to content

Commit 5e4a689

Browse files
committed
Fix handling of creator applications with type arguments
1 parent c930b72 commit 5e4a689

File tree

4 files changed

+156
-17
lines changed

4 files changed

+156
-17
lines changed

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import Denotations._
1515
import SymDenotations._
1616
import StdNames.{nme, tpnme}
1717
import ast.{Trees, untpd}
18-
import typer.{Implicits, Namer}
18+
import typer.{Implicits, Namer, Applications}
1919
import typer.ProtoTypes._
2020
import Trees._
2121
import TypeApplications._
@@ -578,6 +578,8 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
578578
else keywordStr("'{") ~ toTextGlobal(dropBlock(tree)) ~ keywordStr("}")
579579
case Splice(tree) =>
580580
keywordStr("${") ~ toTextGlobal(dropBlock(tree)) ~ keywordStr("}")
581+
case tree: Applications.IntegratedTypeArgs =>
582+
toText(tree.app) ~ "(with integrated type args)"
581583
case Thicket(trees) =>
582584
"Thicket {" ~~ toTextGlobal(trees, "\n") ~~ "}"
583585
case _ =>

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

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2243,8 +2243,16 @@ class Typer extends Namer
22432243
val tycon = typed(tpt)
22442244
if (ctx.reporter.hasErrors)
22452245
EmptyTree // signal that we should return the error in fallBack
2246-
else
2247-
typed(untpd.Select(untpd.New(untpd.TypedSplice(tycon)), nme.CONSTRUCTOR), pt)
2246+
else {
2247+
def recur(tpt: Tree, pt: Type): Tree = pt.revealIgnored match {
2248+
case PolyProto(targs, pt1) if !targs.exists(_.isInstanceOf[NamedArg]) =>
2249+
IntegratedTypeArgs(recur(AppliedTypeTree(tpt, targs), pt1))
2250+
case _ =>
2251+
typed(untpd.Select(untpd.New(untpd.TypedSplice(tpt)), nme.CONSTRUCTOR), pt)
2252+
}
2253+
recur(tycon, pt)
2254+
.reporting(res => i"try new $tree -> $res", typr)
2255+
}
22482256
} { (nu, nuState) =>
22492257
if (nu.isEmpty) fallBack
22502258
else {
@@ -2969,7 +2977,7 @@ class Typer extends Namer
29692977
adaptToArgs(wtp, pt)
29702978
case pt: PolyProto =>
29712979
tree match {
2972-
case _: ExtMethodApply => tree
2980+
case _: IntegratedTypeArgs => tree
29732981
case _ => tryInsertApplyOrImplicit(tree, pt, locked)(tree) // error will be reported in typedTypeApply
29742982
}
29752983
case _ =>

tests/neg/creator-applys.scala

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
class Test {
2+
class A {
3+
def run = "A"
4+
}
5+
object A
6+
class B[T] {
7+
def run = "B"
8+
}
9+
class C[S, T](x: S, y: T) {
10+
def run = s"C $x $y"
11+
}
12+
13+
val x1 = new Test().A() // error: object A does not take parameters
14+
val x2 = new Test().B() // error: value B is not a member of Test
15+
val x3 = new Test().B[Int]() // error: value B is not a member of Test
16+
}
17+
18+
19+
object Test2 {
20+
class A(s: String = "A") {
21+
def run = s
22+
}
23+
object A {
24+
def apply() = A("X") // error: recursive method needs return type
25+
}
26+
}
27+
28+
object Test3 {
29+
class A(s: String = "A") {
30+
def run = s
31+
}
32+
object A {
33+
def apply(): A = A("X") // error too many arguments
34+
}
35+
}

tests/run/creator-applys.scala

Lines changed: 107 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ object Test extends App {
1818
val x2 = B[String]()
1919
assert(x2.run == "B")
2020

21-
val x3: B[String] = B()
21+
val x3: B[String] = Test.B()
2222
assert(x3.run == "B")
2323

2424
val x4: C[String, Int] = C("a", 1)
@@ -27,19 +27,18 @@ object Test extends App {
2727
val x5 = C[String, Int]("a", 1)
2828
assert(x5.run == "C a 1")
2929

30+
val x5a = C[S = String, T = Int]("a", 1)
31+
assert(x5a.run == "C a 1")
32+
33+
val x5b = C[T = Int]("a", 1)
34+
assert(x5b.run == "C a 1")
35+
3036
val x6 = C("a", 1)
3137
assert((x6: C[String, Int]).run == "C a 1")
32-
/*
33-
val x7 = C[S = String]("a", 1)
34-
assert((x7: C[String, Int]).run == "C a 1")
35-
36-
val x8 = C[T = Int]("a", 1)
37-
assert((x8: C[String, Int]).run == "C a 1")
38-
*/
39-
Test2
38+
Test1
4039
}
4140

42-
object Test2 {
41+
object Test1 {
4342
class A {
4443
def run = "A"
4544
}
@@ -50,21 +49,116 @@ object Test2 {
5049
def run = s"C $x $y"
5150
}
5251

52+
val x1 = A()
53+
assert(x1.run == "A")
54+
55+
val x2 = B[String]()
56+
assert(x2.run == "B")
57+
58+
val x3: B[String] = B()
59+
assert(x3.run == "B")
60+
61+
val x4: C[String, Int] = C("a", 1)
62+
assert(x4.run == "C a 1")
63+
64+
val x5 = C[String, Int]("a", 1)
65+
assert(x5.run == "C a 1")
66+
67+
val x6 = C("a", 1)
68+
assert((x6: C[String, Int]).run == "C a 1")
69+
Test2
70+
}
71+
72+
object Test2 {
5373
val x1 = Test.A()
5474
assert(x1.run == "A")
5575

5676
val x2 = Test.B[String]()
5777
assert(x2.run == "B")
5878

59-
val x3: B[String] = Test.B()
79+
val x3: Test.B[String] = Test.B()
6080
assert(x3.run == "B")
6181

62-
val x4: C[String, Int] = Test.C("a", 1)
82+
val x4: Test.C[String, Int] = Test.C("a", 1)
6383
assert(x4.run == "C a 1")
6484

6585
val x5 = Test.C[String, Int]("a", 1)
6686
assert(x5.run == "C a 1")
6787

6888
val x6 = Test.C("a", 1)
69-
assert((x6: C[String, Int]).run == "C a 1")
89+
assert((x6: Test.C[String, Int]).run == "C a 1")
90+
Test3
91+
}
92+
93+
object Test3 {
94+
val x1 = Test1.A()
95+
assert(x1.run == "A")
96+
97+
val x2 = Test1.B[String]()
98+
assert(x2.run == "B")
99+
100+
val x3: Test1.B[String] = Test1.B()
101+
assert(x3.run == "B")
102+
103+
val x4: Test1.C[String, Int] = Test1.C("a", 1)
104+
assert(x4.run == "C a 1")
105+
106+
val x5 = Test1.C[String, Int]("a", 1)
107+
assert(x5.run == "C a 1")
108+
109+
val x6 = Test1.C("a", 1)
110+
assert((x6: Test1.C[String, Int]).run == "C a 1")
111+
Test4
112+
}
113+
114+
object Test4 {
115+
type A = Test.A
116+
type AA[T] = A
117+
type B[T] = Test.B[T]
118+
type C[T] = Test.C[T, Int]
119+
120+
val x1 = A()
121+
assert(x1.run == "A")
122+
123+
val x1a = AA[Int]()
124+
assert(x1a.run == "A")
125+
126+
val x2 = B[String]()
127+
assert(x2.run == "B")
128+
129+
val x3: B[String] = B()
130+
assert(x3.run == "B")
131+
132+
val x5 = C[String]("a", 1)
133+
assert(x5.run == "C a 1")
134+
Test5
135+
}
136+
137+
object Test5 {
138+
val x1 = Test4.A()
139+
assert(x1.run == "A")
140+
141+
val x1a = Test4.AA[Int]()
142+
assert(x1a.run == "A")
143+
144+
val x2 = Test4.B[String]()
145+
assert(x2.run == "B")
146+
147+
val x3: Test4.B[String] = Test4.B()
148+
assert(x3.run == "B")
149+
150+
val x5 = Test4.C[String]("a", 1)
151+
assert(x5.run == "C a 1")
152+
Test6
153+
}
154+
155+
object Test6 {
156+
class A(s: String = "A") {
157+
def run = s
158+
}
159+
object A {
160+
def apply(): A = new A("X")
161+
}
162+
val x1 = A()
163+
assert(x1.run == "X")
70164
}

0 commit comments

Comments
 (0)