From 861beeef093501717bf322a5b442199188664daa Mon Sep 17 00:00:00 2001 From: Wojciech Mazur Date: Wed, 27 Nov 2024 22:36:20 +0100 Subject: [PATCH] Add migration rewrite for deprecated assignment syntax --- .../tools/dotc/config/MigrationVersion.scala | 2 +- .../dotty/tools/dotc/parsing/Parsers.scala | 4 ++-- .../tools/dotc/reporting/ErrorMessageID.scala | 4 ++-- .../dotty/tools/dotc/reporting/messages.scala | 18 ++++++++--------- .../src/dotty/tools/dotc/typer/Typer.scala | 6 +++--- tests/neg/infix-named-args.check | 20 ++++++++----------- tests/warn/21681.check | 2 +- tests/warn/21681b.check | 2 +- tests/warn/21681c.check | 2 +- tests/warn/21770.check | 2 +- 10 files changed, 28 insertions(+), 34 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/config/MigrationVersion.scala b/compiler/src/dotty/tools/dotc/config/MigrationVersion.scala index 247e3f62a98d..1d99caa789d3 100644 --- a/compiler/src/dotty/tools/dotc/config/MigrationVersion.scala +++ b/compiler/src/dotty/tools/dotc/config/MigrationVersion.scala @@ -26,7 +26,7 @@ enum MigrationVersion(val warnFrom: SourceVersion, val errorFrom: SourceVersion) case WithOperator extends MigrationVersion(`3.4`, future) case FunctionUnderscore extends MigrationVersion(`3.4`, future) case NonNamedArgumentInJavaAnnotation extends MigrationVersion(`3.6`, `3.6`) - case AmbiguousNamedTupleInfixApply extends MigrationVersion(`3.6`, never) + case AmbiguousNamedTupleSyntax extends MigrationVersion(`3.6`, future) case ImportWildcard extends MigrationVersion(future, future) case ImportRename extends MigrationVersion(future, future) case ParameterEnclosedByParenthesis extends MigrationVersion(future, future) diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 3ea4131d5d78..220053e277a5 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -1149,8 +1149,8 @@ object Parsers { if isType then infixOp else infixOp.right match case Tuple(args) if args.exists(_.isInstanceOf[NamedArg]) && !isNamedTupleOperator => - report.errorOrMigrationWarning(AmbiguousNamedTupleInfixApply(), infixOp.right.srcPos, MigrationVersion.AmbiguousNamedTupleInfixApply) - if MigrationVersion.AmbiguousNamedTupleInfixApply.needsPatch then + report.errorOrMigrationWarning(DeprecatedInfixNamedArgumentSyntax(), infixOp.right.srcPos, MigrationVersion.AmbiguousNamedTupleSyntax) + if MigrationVersion.AmbiguousNamedTupleSyntax.needsPatch then val asApply = cpy.Apply(infixOp)(Select(opInfo.operand, opInfo.operator.name), args) patch(source, infixOp.span, asApply.show(using ctx.withoutColors)) asApply // allow to use pre-3.6 syntax in migration mode diff --git a/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala b/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala index 35c170858bbf..2c3774b59a9a 100644 --- a/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala +++ b/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala @@ -216,8 +216,8 @@ 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 - case AmbiguousNamedTupleInfixApplyID // errorNumber: 204 + case DeprecatedAssignmentSyntaxID // errorNumber: 203 + case DeprecatedInfixNamedArgumentSyntaxID // errorNumber: 204 def errorNumber = ordinal - 1 diff --git a/compiler/src/dotty/tools/dotc/reporting/messages.scala b/compiler/src/dotty/tools/dotc/reporting/messages.scala index f94a4b58d6fb..2e74c5816c5e 100644 --- a/compiler/src/dotty/tools/dotc/reporting/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/messages.scala @@ -3344,21 +3344,19 @@ 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): +final class DeprecatedAssignmentSyntax(key: Name, value: untpd.Tree)(using Context) extends SyntaxMsg(DeprecatedAssignmentSyntaxID): override protected def msg(using Context): String = - i"""Ambiguous syntax: this is interpreted as a named tuple with one element, + i"""Deprecated syntax: in the future it would be 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 = "" -class AmbiguousNamedTupleInfixApply()(using Context) extends SyntaxMsg(AmbiguousNamedTupleInfixApplyID): +class DeprecatedInfixNamedArgumentSyntax()(using Context) extends SyntaxMsg(DeprecatedInfixNamedArgumentSyntaxID): def msg(using Context) = - "Ambigious syntax: this infix call argument list is interpreted as single named tuple argument, not as an named arguments list." - + Message.rewriteNotice("This", version = SourceVersion.`3.6-migration`) + i"""Deprecated syntax: infix named arguments lists are deprecated; in the future it would be interpreted as a single name tuple argument. + |To avoid this warning, either remove the argument names or use dotted selection.""" + + Message.rewriteNotice("This", version = SourceVersion.`3.6-migration`) - def explain(using Context) = - i"""Starting with Scala 3.6 infix named arguments are interpretted as Named Tuple. - | - |To avoid this warning, either remove the argument names or use dotted selection.""" + def explain(using Context) = "" diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 57a027653241..d74a69f2a114 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -3404,7 +3404,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer /** Translate tuples of all arities */ def typedTuple(tree: untpd.Tuple, pt: Type)(using Context): Tree = val tree1 = desugar.tuple(tree, pt) - checkAmbiguousNamedTupleAssignment(tree) + checkDeprecatedAssignmentSyntax(tree) if tree1 ne tree then typed(tree1, pt) else val arity = tree.trees.length @@ -3433,7 +3433,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer /** Checks if `tree` is a named tuple with one element that could be * interpreted as an assignment, such as `(x = 1)`. If so, issues a warning. */ - def checkAmbiguousNamedTupleAssignment(tree: untpd.Tuple)(using Context): Unit = + def checkDeprecatedAssignmentSyntax(tree: untpd.Tuple)(using Context): Unit = tree.trees match case List(NamedArg(name, value)) => val tmpCtx = ctx.fresh.setNewTyperState() @@ -3441,7 +3441,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer if !tmpCtx.reporter.hasErrors then // If there are no errors typing the above, then the named tuple is // ambiguous and we issue a warning. - report.migrationWarning(AmbiguousNamedTupleAssignment(name, value), tree.srcPos) + report.migrationWarning(DeprecatedAssignmentSyntax(name, value), tree.srcPos) case _ => () /** Retrieve symbol attached to given tree */ diff --git a/tests/neg/infix-named-args.check b/tests/neg/infix-named-args.check index 291c7616a57c..d960892a9624 100644 --- a/tests/neg/infix-named-args.check +++ b/tests/neg/infix-named-args.check @@ -14,28 +14,24 @@ -- [E204] Syntax Warning: tests/neg/infix-named-args.scala:4:15 -------------------------------------------------------- 4 | def f = 42 + (x = 1) // error // werror | ^^^^^^^ - |Ambigious syntax: this infix call argument list is interpreted as single named tuple argument, not as an named arguments list. + |Deprecated syntax: infix named arguments lists are deprecated; in the future it would be interpreted as a single name tuple argument. + |To avoid this warning, either remove the argument names or use dotted selection. |This can be rewritten automatically under -rewrite -source 3.6-migration. - | - | longer explanation available when compiling with `-explain` -- [E204] Syntax Warning: tests/neg/infix-named-args.scala:7:26 -------------------------------------------------------- 7 | def g = new C() `multi` (x = 42, y = 27) // werror | ^^^^^^^^^^^^^^^^ - |Ambigious syntax: this infix call argument list is interpreted as single named tuple argument, not as an named arguments list. + |Deprecated syntax: infix named arguments lists are deprecated; in the future it would be interpreted as a single name tuple argument. + |To avoid this warning, either remove the argument names or use dotted selection. |This can be rewritten automatically under -rewrite -source 3.6-migration. - | - | longer explanation available when compiling with `-explain` -- [E204] Syntax Warning: tests/neg/infix-named-args.scala:8:21 -------------------------------------------------------- 8 | def h = new C() ** (x = 42, y = 27) // werror | ^^^^^^^^^^^^^^^^ - |Ambigious syntax: this infix call argument list is interpreted as single named tuple argument, not as an named arguments list. + |Deprecated syntax: infix named arguments lists are deprecated; in the future it would be interpreted as a single name tuple argument. + |To avoid this warning, either remove the argument names or use dotted selection. |This can be rewritten automatically under -rewrite -source 3.6-migration. - | - | longer explanation available when compiling with `-explain` -- [E204] Syntax Warning: tests/neg/infix-named-args.scala:15:18 ------------------------------------------------------- 15 | def f = this ** (x = 2) // werror | ^^^^^^^ - |Ambigious syntax: this infix call argument list is interpreted as single named tuple argument, not as an named arguments list. + |Deprecated syntax: infix named arguments lists are deprecated; in the future it would be interpreted as a single name tuple argument. + |To avoid this warning, either remove the argument names or use dotted selection. |This can be rewritten automatically under -rewrite -source 3.6-migration. - | - | longer explanation available when compiling with `-explain` diff --git a/tests/warn/21681.check b/tests/warn/21681.check index 6ca2c3816b01..5156a600d609 100644 --- a/tests/warn/21681.check +++ b/tests/warn/21681.check @@ -1,7 +1,7 @@ -- [E203] Syntax Migration Warning: tests/warn/21681.scala:5:2 --------------------------------------------------------- 5 | (age = 29) // warn | ^^^^^^^^^^ - | Ambiguous syntax: this is interpreted as a named tuple with one element, + | Deprecated syntax: in the future it would be interpreted as a named tuple with one element, | not as an assignment. | | To assign a value, use curly braces: `{age = 29}`. diff --git a/tests/warn/21681b.check b/tests/warn/21681b.check index c77c1438d9a6..dd28df3168ed 100644 --- a/tests/warn/21681b.check +++ b/tests/warn/21681b.check @@ -1,7 +1,7 @@ -- [E203] Syntax Migration Warning: tests/warn/21681b.scala:5:2 -------------------------------------------------------- 5 | (age = 29) // warn | ^^^^^^^^^^ - | Ambiguous syntax: this is interpreted as a named tuple with one element, + | Deprecated syntax: in the future it would be interpreted as a named tuple with one element, | not as an assignment. | | To assign a value, use curly braces: `{age = 29}`. diff --git a/tests/warn/21681c.check b/tests/warn/21681c.check index 00c74ddba5bc..bfb62618cbb9 100644 --- a/tests/warn/21681c.check +++ b/tests/warn/21681c.check @@ -1,7 +1,7 @@ -- [E203] Syntax Migration Warning: tests/warn/21681c.scala:7:2 -------------------------------------------------------- 7 | (age = 29) // warn | ^^^^^^^^^^ - | Ambiguous syntax: this is interpreted as a named tuple with one element, + | Deprecated syntax: in the future it would be interpreted as a named tuple with one element, | not as an assignment. | | To assign a value, use curly braces: `{age = 29}`. diff --git a/tests/warn/21770.check b/tests/warn/21770.check index 10a1c287599c..6c978a6078a2 100644 --- a/tests/warn/21770.check +++ b/tests/warn/21770.check @@ -1,7 +1,7 @@ -- [E203] Syntax Migration Warning: tests/warn/21770.scala:7:9 --------------------------------------------------------- 7 | f(i => (cache = Some(i))) // warn | ^^^^^^^^^^^^^^^^^ - | Ambiguous syntax: this is interpreted as a named tuple with one element, + | Deprecated syntax: in the future it would be interpreted as a named tuple with one element, | not as an assignment. | | To assign a value, use curly braces: `{cache = Some(i)}`.