diff --git a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala index 84a181769e3b..0fa71dd02a8b 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala @@ -135,10 +135,13 @@ object Scanners { */ protected def putChar(c: Char): Unit = litBuf.append(c) - /** Clear buffer and set name and token - * If `target` is different from `this`, don't treat identifiers as end tokens + /** Finish an IDENTIFIER with `this.name`. */ + inline def finishNamed(): Unit = finishNamedToken(IDENTIFIER, this) + + /** Clear buffer and set name and token. + * If `target` is different from `this`, don't treat identifiers as end tokens. */ - def finishNamed(idtoken: Token = IDENTIFIER, target: TokenData = this): Unit = + def finishNamedToken(idtoken: Token, target: TokenData): Unit = target.name = termName(litBuf.chars, 0, litBuf.length) litBuf.clear() target.token = idtoken @@ -242,24 +245,18 @@ object Scanners { /** A buffer for comments */ private val commentBuf = CharBuffer() - private def handleMigration(keyword: Token): Token = - if scala3keywords.contains(keyword) && migrateTo3 then treatAsIdent() - else keyword - - private def treatAsIdent(): Token = - val name0 = name // don't capture the `name` var in the message closure, it may be null later - report.errorOrMigrationWarning( - i"$name0 is now a keyword, write `$name0` instead of $name0 to keep it as an identifier", - sourcePos()) - patch(source, Span(offset), "`") - patch(source, Span(offset + name.length), "`") - IDENTIFIER - - def toToken(name: SimpleName): Token = { - val idx = name.start + def toToken(identifier: SimpleName): Token = + def handleMigration(keyword: Token): Token = + if scala3keywords.contains(keyword) && migrateTo3 then + val what = tokenString(keyword) + report.errorOrMigrationWarning(i"$what is now a keyword, write `$what` instead of $what to keep it as an identifier", sourcePos()) + patch(source, Span(offset), "`") + patch(source, Span(offset + identifier.length), "`") + IDENTIFIER + else keyword + val idx = identifier.start if (idx >= 0 && idx <= lastKeywordStart) handleMigration(kwArray(idx)) else IDENTIFIER - } def newTokenData: TokenData = new TokenData {} @@ -1002,7 +999,7 @@ object Scanners { getLitChars('`') if (ch == '`') { nextChar() - finishNamed(BACKQUOTED_IDENT) + finishNamedToken(BACKQUOTED_IDENT, target = this) if (name.length == 0) error("empty quoted identifier") else if (name == nme.WILDCARD) @@ -1168,7 +1165,7 @@ object Scanners { nextRawChar() ch != SU && Character.isUnicodeIdentifierPart(ch) do () - finishNamed(target = next) + finishNamedToken(IDENTIFIER, target = next) } else error("invalid string interpolation: `$$`, `$\"`, `$`ident or `$`BlockExpr expected") diff --git a/tests/neg-custom-args/fatal-warnings/i13440.check b/tests/neg-custom-args/fatal-warnings/i13440.check index 0e9dd7dd5e50..fde8133419b6 100644 --- a/tests/neg-custom-args/fatal-warnings/i13440.check +++ b/tests/neg-custom-args/fatal-warnings/i13440.check @@ -1,4 +1,12 @@ --- Error: tests/neg-custom-args/fatal-warnings/i13440.scala:3:13 ------------------------------------------------------- -3 |case class A(enum: List[Int] = Nil) // error +-- Error: tests/neg-custom-args/fatal-warnings/i13440.scala:3:4 -------------------------------------------------------- +3 |def given = 42 // error + | ^ + | given is now a keyword, write `given` instead of given to keep it as an identifier +-- Error: tests/neg-custom-args/fatal-warnings/i13440.scala:5:13 ------------------------------------------------------- +5 |case class C(enum: List[Int] = Nil) { // error | ^ | enum is now a keyword, write `enum` instead of enum to keep it as an identifier +-- Error: tests/neg-custom-args/fatal-warnings/i13440.scala:6:11 ------------------------------------------------------- +6 | val s = s"$enum" // error + | ^ + | enum is now a keyword, write `enum` instead of enum to keep it as an identifier diff --git a/tests/neg-custom-args/fatal-warnings/i13440.scala b/tests/neg-custom-args/fatal-warnings/i13440.scala index 8e3af76ad3fa..6cb4956e7434 100644 --- a/tests/neg-custom-args/fatal-warnings/i13440.scala +++ b/tests/neg-custom-args/fatal-warnings/i13440.scala @@ -1,3 +1,7 @@ import language.`3.0-migration` -case class A(enum: List[Int] = Nil) // error +def given = 42 // error + +case class C(enum: List[Int] = Nil) { // error + val s = s"$enum" // error +}