Skip to content

Commit

Permalink
Warn when named tuples resemble assignments
Browse files Browse the repository at this point in the history
Co-Authored-By: Nicolas Stucki <3648029+nicolasstucki@users.noreply.github.com>
Co-Authored-By: Oliver Bračevac <bracevac@users.noreply.github.com>
  • Loading branch information
3 people committed Oct 22, 2024
1 parent 6e32627 commit 8566f53
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 3 deletions.
9 changes: 6 additions & 3 deletions compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1605,9 +1605,10 @@ object desugar {

/** Translate tuple expressions
*
* () ==> ()
* (t) ==> t
* (t1, ..., tN) ==> TupleN(t1, ..., tN)
* () ==> ()
* (t) ==> t
* (t1, ..., tN) ==> TupleN(t1, ..., tN)
* (n1 = t1, ..., nN = tN) ==> NamedTuple.build[(n1, ..., nN)]()(TupleN(t1, ..., tN))
*/
def tuple(tree: Tuple, pt: Type)(using Context): Tree =
var elems = checkWellFormedTupleElems(tree.trees)
Expand Down Expand Up @@ -1638,6 +1639,8 @@ object desugar {
if ctx.mode.is(Mode.Type) then
AppliedTypeTree(ref(defn.NamedTupleTypeRef), namesTuple :: tup :: Nil)
else
if names.length == 1 && ctx.scope.lookup(names.head).is(Flags.Mutable) then
report.migrationWarning(AmbiguousNamedTupleAssignment(names.head, elemValues.head), tree.srcPos)
Apply(
Apply(
TypeApply(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ enum ErrorMessageID(val isActive: Boolean = true) extends java.lang.Enum[ErrorMe
case FinalLocalDefID // errorNumber: 200
case NonNamedArgumentInJavaAnnotationID // errorNumber: 201
case QuotedTypeMissingID // errorNumber: 202
case AmbiguousNamedTupleAssignmentID // errorNumber: 203

def errorNumber = ordinal - 1

Expand Down
9 changes: 9 additions & 0 deletions compiler/src/dotty/tools/dotc/reporting/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3343,3 +3343,12 @@ final class QuotedTypeMissing(tpe: Type)(using Context) extends StagingMessage(Q
|"""

end QuotedTypeMissing

final class AmbiguousNamedTupleAssignment(key: Name, value: untpd.Tree)(using Context) extends SyntaxMsg(AmbiguousNamedTupleAssignmentID):
override protected def msg(using Context): String =
i"""Ambiguous syntax: this is interpreted as a named tuple with one element,
|not as an assignment.
|
|To assign a value, use curly braces: `{${key} = ${value}}`."""

override protected def explain(using Context): String = ""
7 changes: 7 additions & 0 deletions tests/warn/21681.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- [E203] Syntax Migration Warning: tests/warn/21681.scala:4:2 ---------------------------------------------------------
4 | (age = 29) // warn
| ^^^^^^^^^^
| Ambiguous syntax: this is interpreted as a named tuple with one element,
| not as an assignment.
|
| To assign a value, use curly braces: `{age = 29}`.
3 changes: 3 additions & 0 deletions tests/warn/21681.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
def main() =
var age: Int = 28
(age = 29)
7 changes: 7 additions & 0 deletions tests/warn/21770.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- [E203] Syntax Migration Warning: tests/warn/21770.scala:5:9 ---------------------------------------------------------
5 | f(i => (cache = Some(i))) // warn
| ^^^^^^^^^^^^^^^^^
| Ambiguous syntax: this is interpreted as a named tuple with one element,
| not as an assignment.
|
| To assign a value, use curly braces: `{cache = Some(i)}`.
5 changes: 5 additions & 0 deletions tests/warn/21770.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
def f(g: Int => Unit) = g(0)

def test =
var cache: Option[Int] = None
f(i => (cache = Some(i))) // warn

0 comments on commit 8566f53

Please sign in to comment.