Skip to content

Commit 0bdf644

Browse files
committed
Restore ambigious-named-tuple-assignment migration rewrite
1 parent 3b4a36a commit 0bdf644

File tree

9 files changed

+57
-16
lines changed

9 files changed

+57
-16
lines changed

compiler/src/dotty/tools/dotc/reporting/messages.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3362,7 +3362,7 @@ end QuotedTypeMissing
33623362

33633363
final class DeprecatedAssignmentSyntax(key: Name, value: untpd.Tree)(using Context) extends SyntaxMsg(DeprecatedAssignmentSyntaxID):
33643364
override protected def msg(using Context): String =
3365-
i"""Deprecated syntax: in the future it would be interpreted as a named tuple with one element,
3365+
i"""Ambiguous syntax: this is interpreted as a named tuple with one element,
33663366
|not as an assignment.
33673367
|
33683368
|To assign a value, use curly braces: `{${key} = ${value}}`."""

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

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3500,19 +3500,22 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
35003500
/** Checks if `tree` is a named tuple with one element that could be
35013501
* interpreted as an assignment, such as `(x = 1)`. If so, issues a warning.
35023502
*/
3503-
def checkDeprecatedAssignmentSyntax(tree: untpd.Tuple)(using Context): Unit =
3504-
tree.trees match
3505-
case List(NamedArg(name, value)) =>
3503+
def checkDeprecatedAssignmentSyntax(tree: untpd.Tuple | untpd.Parens)(using Context): Unit =
3504+
val assignmentArgs = tree match {
3505+
case untpd.Tuple(List(NamedArg(name, value))) =>
35063506
val tmpCtx = ctx.fresh.setNewTyperState()
35073507
typedAssign(untpd.Assign(untpd.Ident(name), value), WildcardType)(using tmpCtx)
3508-
if !tmpCtx.reporter.hasErrors then
3509-
// If there are no errors typing the above, then the named tuple is
3510-
// ambiguous and we issue a warning.
3511-
report.migrationWarning(DeprecatedAssignmentSyntax(name, value), tree.srcPos)
3512-
if MigrationVersion.AmbiguousNamedTupleSyntax.needsPatch then
3513-
patch(tree.source, Span(tree.span.start, tree.span.start + 1), "{")
3514-
patch(tree.source, Span(tree.span.end - 1, tree.span.end), "}")
3515-
case _ => ()
3508+
Option.unless(tmpCtx.reporter.hasErrors)(name -> value)
3509+
case untpd.Parens(Assign(ident: untpd.Ident, value)) => Some(ident.name -> value)
3510+
case _ => None
3511+
}
3512+
assignmentArgs.foreach: (name, value) =>
3513+
// If there are no errors typing the above, then the named tuple is
3514+
// ambiguous and we issue a warning.
3515+
report.migrationWarning(DeprecatedAssignmentSyntax(name, value), tree.srcPos)
3516+
if MigrationVersion.AmbiguousNamedTupleSyntax.needsPatch then
3517+
patch(tree.source, Span(tree.span.start, tree.span.start + 1), "{")
3518+
patch(tree.source, Span(tree.span.end - 1, tree.span.end), "}")
35163519

35173520
/** Retrieve symbol attached to given tree */
35183521
protected def retrieveSym(tree: untpd.Tree)(using Context): Symbol = tree.removeAttachment(SymOfTree) match {
@@ -3621,6 +3624,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
36213624
case tree: untpd.SplicePattern => typedSplicePattern(tree, pt)
36223625
case tree: untpd.MacroTree => report.error("Unexpected macro", tree.srcPos); tpd.nullLiteral // ill-formed code may reach here
36233626
case tree: untpd.Hole => typedHole(tree, pt)
3627+
case tree: untpd.Parens =>
3628+
checkDeprecatedAssignmentSyntax(tree)
3629+
typedUnadapted(desugar(tree, pt), pt, locked)
36243630
case _ => typedUnadapted(desugar(tree, pt), pt, locked)
36253631
}
36263632

compiler/test/dotty/tools/dotc/CompilationTests.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class CompilationTests {
7979
compileFile("tests/rewrites/i20002.scala", defaultOptions.and("-indent", "-rewrite")),
8080
compileDir("tests/rewrites/annotation-named-pararamters", defaultOptions.and("-rewrite", "-source:3.6-migration")),
8181
compileFile("tests/rewrites/i21418.scala", unindentOptions.and("-rewrite", "-source:3.5-migration")),
82+
compileFile("tests/rewrites/ambiguous-named-tuple-assignment.scala", defaultOptions.and("-rewrite", "-source:3.6-migration")),
8283
compileFile("tests/rewrites/i21382.scala", defaultOptions.and("-indent", "-rewrite")),
8384
compileFile("tests/rewrites/unused.scala", defaultOptions.and("-rewrite", "-Wunused:all")),
8485
compileFile("tests/rewrites/i22440.scala", defaultOptions.and("-rewrite"))
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
object i21770:
2+
def f(g: Int => Unit) = g(0)
3+
var cache: Option[Int] = None
4+
f(i => {cache = Some(i)})
5+
6+
object i21861:
7+
var age: Int = 28
8+
{
9+
age = 29
10+
}
11+
12+
13+
object i21861c:
14+
def age: Int = ???
15+
def age_=(x: Int): Unit = ()
16+
age = 29
17+
{ age = 29 }
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
object i21770:
2+
def f(g: Int => Unit) = g(0)
3+
var cache: Option[Int] = None
4+
f(i => (cache = Some(i)))
5+
6+
object i21861:
7+
var age: Int = 28
8+
(
9+
age = 29
10+
)
11+
12+
13+
object i21861c:
14+
def age: Int = ???
15+
def age_=(x: Int): Unit = ()
16+
age = 29
17+
( age = 29 )

tests/warn/21681.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
-- [E203] Syntax Migration Warning: tests/warn/21681.scala:3:2 ---------------------------------------------------------
22
3 | (age = 29) // warn
33
| ^^^^^^^^^^
4-
| Deprecated syntax: in the future it would be interpreted as a named tuple with one element,
4+
| Ambiguous syntax: this is interpreted as a named tuple with one element,
55
| not as an assignment.
66
|
77
| To assign a value, use curly braces: `{age = 29}`.

tests/warn/21681b.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
-- [E203] Syntax Migration Warning: tests/warn/21681b.scala:3:2 --------------------------------------------------------
22
3 | (age = 29) // warn
33
| ^^^^^^^^^^
4-
| Deprecated syntax: in the future it would be interpreted as a named tuple with one element,
4+
| Ambiguous syntax: this is interpreted as a named tuple with one element,
55
| not as an assignment.
66
|
77
| To assign a value, use curly braces: `{age = 29}`.

tests/warn/21681c.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
-- [E203] Syntax Migration Warning: tests/warn/21681c.scala:5:2 --------------------------------------------------------
22
5 | (age = 29) // warn
33
| ^^^^^^^^^^
4-
| Deprecated syntax: in the future it would be interpreted as a named tuple with one element,
4+
| Ambiguous syntax: this is interpreted as a named tuple with one element,
55
| not as an assignment.
66
|
77
| To assign a value, use curly braces: `{age = 29}`.

tests/warn/21770.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
-- [E203] Syntax Migration Warning: tests/warn/21770.scala:5:9 ---------------------------------------------------------
22
5 | f(i => (cache = Some(i))) // warn
33
| ^^^^^^^^^^^^^^^^^
4-
| Deprecated syntax: in the future it would be interpreted as a named tuple with one element,
4+
| Ambiguous syntax: this is interpreted as a named tuple with one element,
55
| not as an assignment.
66
|
77
| To assign a value, use curly braces: `{cache = Some(i)}`.

0 commit comments

Comments
 (0)