Skip to content

Commit 2188612

Browse files
mbovelWojciechMazur
authored andcommitted
Move AmbiguousNamedTupleAssignment check to Typer
Co-Authored-By: Nicolas Stucki <[email protected]> Co-Authored-By: Oliver Bračevac <[email protected]> [Cherry-picked a00a806]
1 parent 008abbd commit 2188612

File tree

5 files changed

+39
-2
lines changed

5 files changed

+39
-2
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1639,8 +1639,6 @@ object desugar {
16391639
if ctx.mode.is(Mode.Type) then
16401640
AppliedTypeTree(ref(defn.NamedTupleTypeRef), namesTuple :: tup :: Nil)
16411641
else
1642-
if names.length == 1 && ctx.scope.lookup(names.head).is(Flags.Mutable) then
1643-
report.migrationWarning(AmbiguousNamedTupleAssignment(names.head, elemValues.head), tree.srcPos)
16441642
Apply(
16451643
Apply(
16461644
TypeApply(

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3395,6 +3395,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
33953395
/** Translate tuples of all arities */
33963396
def typedTuple(tree: untpd.Tuple, pt: Type)(using Context): Tree =
33973397
val tree1 = desugar.tuple(tree, pt)
3398+
checkAmbiguousNamedTupleAssignment(tree)
33983399
if tree1 ne tree then typed(tree1, pt)
33993400
else
34003401
val arity = tree.trees.length
@@ -3420,6 +3421,18 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
34203421
val resTpe = TypeOps.nestedPairs(elemTpes)
34213422
app1.cast(resTpe)
34223423

3424+
/** Checks if `tree` is a named tuple with one element that could be
3425+
* interpreted as an assignment, such as `(x = 1)`. If so, issues a warning.
3426+
*/
3427+
def checkAmbiguousNamedTupleAssignment(tree: untpd.Tuple)(using Context): Unit =
3428+
tree.trees match
3429+
case List(NamedArg(name, value)) =>
3430+
val typedName = typedIdent(untpd.Ident(name), WildcardType)
3431+
val sym = typedName.symbol
3432+
if sym.exists && (sym.is(Flags.Mutable) || sym.setter.exists) then
3433+
report.migrationWarning(AmbiguousNamedTupleAssignment(name, value), tree.srcPos)
3434+
case _ => ()
3435+
34233436
/** Retrieve symbol attached to given tree */
34243437
protected def retrieveSym(tree: untpd.Tree)(using Context): Symbol = tree.removeAttachment(SymOfTree) match {
34253438
case Some(sym) =>

tests/pos/21681d.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
def test1() =
2+
class Person:
3+
def age: Int = ???
4+
def age_=(x: Int): Unit = ???
5+
6+
val person = Person()
7+
8+
(person.age = 29) // no warn (interpreted as `person.age_=(29)`)
9+
10+
def test2() =
11+
class Person:
12+
var age: Int = 28
13+
14+
val person = Person()
15+
16+
(person.age = 29) // no warn (interpreted as `person.age_=(29)`)

tests/warn/21681b.check

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-- [E203] Syntax Migration Warning: tests/warn/21681b.scala:3:2 --------------------------------------------------------
2+
3 | (age = 29) // warn
3+
| ^^^^^^^^^^
4+
| Ambiguous syntax: this is interpreted as a named tuple with one element,
5+
| not as an assignment.
6+
|
7+
| To assign a value, use curly braces: `{age = 29}`.

tests/warn/21681b.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Test:
2+
var age: Int = 28
3+
(age = 29) // warn

0 commit comments

Comments
 (0)