Skip to content

Commit 8fde4f0

Browse files
committed
Reject normal tuples with ValDefs in them
This comes up when trying to parse parameters out of tuples.
1 parent a04576b commit 8fde4f0

File tree

3 files changed

+41
-8
lines changed

3 files changed

+41
-8
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,15 @@ object Parsers {
463463
case _ =>
464464
fail()
465465

466+
/** Checks that tuples don't contain a parameter. */
467+
def checkNonParamTuple(t: Tree) = t match
468+
case Tuple(ts) => ts.collectFirst {
469+
case param: ValDef =>
470+
syntaxError(em"invalid parameter definition syntax in tuple value", param.span)
471+
}
472+
case _ =>
473+
474+
466475
/** Convert (qual)ident to type identifier
467476
*/
468477
def convertToTypeId(tree: Tree): Tree = tree match {
@@ -2127,7 +2136,9 @@ object Parsers {
21272136
else if isWildcard(t) then
21282137
placeholderParams = placeholderParams ::: saved
21292138
t
2130-
else wrapPlaceholders(t)
2139+
else
2140+
checkNonParamTuple(t)
2141+
wrapPlaceholders(t)
21312142
}
21322143

21332144
def expr1(location: Location = Location.ElseWhere): Tree = in.token match
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
@main def Test() =
2+
val x = 5
3+
val y = 7
4+
5+
val t1 = (x, erased y) // error
6+
val t2 = (erased x, y) // error
7+
val t1a = (x: Int, erased y: Int) // error
8+
val t2a = (erased x: Int, y: Int) // error
9+
10+
val nest = (x, (x, erased y)) // error
11+
12+
def use(f: (Int, Int) => Any) = f(5, 6)
13+
14+
use((_, erased _)) // error
15+
16+
(x, erased y) // error

tests/run-custom-args/erased/lambdas.scala

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
// lambdas should parse and work
22

3-
type F = (Int, erased String) => Int
3+
type F = (erased Int, String) => String
4+
type S = (Int, erased String) => Int
45

5-
def use(f: F) = f(5, "a")
6+
def useF(f: F) = f(5, "a")
7+
def useS(f: S) = f(5, "a")
68

7-
val fv: F = (x, erased y) => x
8-
val fvExpl = (x: Int, erased y: String) => x
9+
val ff: F = (erased x, y) => y
10+
11+
val fs: S = (x, erased y) => x
12+
val fsExpl = (x: Int, erased y: String) => x
913

1014
// contextual lambdas should work
1115

@@ -21,9 +25,11 @@ val fCvExpl = (x: Int, erased y: String) ?=> x
2125
val nested: Int => (String, erased Int) => FC = a => (_, erased _) => (c, erased d) ?=> a + c
2226

2327
@main def Test() =
24-
assert(5 == use(fv))
25-
assert(5 == use(fvExpl))
26-
assert(5 == use { (x, erased y) => x })
28+
assert("a" == useF(ff))
29+
30+
assert(5 == useS(fs))
31+
assert(5 == useS(fsExpl))
32+
assert(5 == useS { (x, erased y) => x })
2733

2834
assert(5 == useCtx(fCv))
2935
assert(5 == useCtx(fCvExpl))

0 commit comments

Comments
 (0)