Skip to content

Commit ef27b1e

Browse files
committed
Fix #12729: Don't encode <init> and <clinit> only.
In addition, reject `<init>` and `<clinit>` in the parser, so that users don't write them in source code.
1 parent 8c18a71 commit ef27b1e

File tree

5 files changed

+17
-2
lines changed

5 files changed

+17
-2
lines changed

.scalafmt.conf

Whitespace-only changes.

compiler/src/dotty/tools/dotc/core/Names.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,8 @@ object Names {
342342

343343
override def encode: SimpleName = {
344344
val dontEncode =
345-
length >= 3 &&
346-
head == '<' && last == '>' && isIdentifierStart(apply(1))
345+
length >= 6 &&
346+
head == '<' && (this == StdNames.nme.CONSTRUCTOR || this == StdNames.nme.STATIC_CONSTRUCTOR)
347347
if (dontEncode) this else NameTransformer.encode(this)
348348
}
349349

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,10 @@ object Parsers {
978978
def ident(): TermName =
979979
if (isIdent) {
980980
val name = in.name
981+
if name == nme.CONSTRUCTOR || name == nme.STATIC_CONSTRUCTOR then
982+
report.error(
983+
i"""Illegal backquoted identifier: `<init>` and `<clinit>` are forbidden""",
984+
in.sourcePos())
981985
in.nextToken()
982986
name
983987
}
@@ -996,6 +1000,7 @@ object Parsers {
9961000

9971001
private def makeIdent(tok: Token, offset: Offset, name: Name) = {
9981002
val tree = Ident(name)
1003+
9991004
if (tok == BACKQUOTED_IDENT) tree.pushAttachment(Backquoted, ())
10001005

10011006
// Make sure that even trees with parsing errors have a offset that is within the offset

tests/neg/i12729.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class Test(i: Int):
2+
val `<init>` = "init" // error: Illegal backquoted identifier: `<init>` and `<clinit>` are forbidden
3+
val `<clinit>` = "clinit" // error: Illegal backquoted identifier: `<init>` and `<clinit>` are forbidden
4+
class `<init>`: // error: Illegal backquoted identifier: `<init>` and `<clinit>` are forbidden
5+
def `<init>`(in: String) = ??? // error: Illegal backquoted identifier: `<init>` and `<clinit>` are forbidden
6+
class `<clinit>`: // error: Illegal backquoted identifier: `<init>` and `<clinit>` are forbidden
7+
def `<clinit>`(in: String) = ??? // error: Illegal backquoted identifier: `<init>` and `<clinit>` are forbidden

tests/run/i12729.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Test:
2+
val `<x>` = "hello!"
3+
def main(args: Array[String]): Unit = println(`<x>`)

0 commit comments

Comments
 (0)