Skip to content

Commit 939abf1

Browse files
committed
SI-10120 Extra advice on unclosed char literal
Folks from other languages might mistakenly enclose a string in single quotes. Since this presents as a symbol literal followed by the unpaired single quote, we can add a syntax reminder. Also polish the wording for bad string interpolation.
1 parent 855492c commit 939abf1

File tree

4 files changed

+21
-8
lines changed

4 files changed

+21
-8
lines changed

src/compiler/scala/tools/nsc/ast/parser/Scanners.scala

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,15 @@ trait Scanners extends ScannersCommon {
532532
}
533533
fetchDoubleQuote()
534534
case '\'' =>
535+
def unclosedCharLit() = {
536+
val msg = "unclosed character literal"
537+
// previous token was Symbol contiguous with the orphan single quote at offset
538+
if (token == SYMBOLLIT && offset == lastOffset) {
539+
syntaxError(s"""$msg (or use " for string literal "$strVal")""")
540+
} else {
541+
syntaxError(msg)
542+
}
543+
}
535544
def fetchSingleQuote() = {
536545
nextChar()
537546
if (isIdentifierStart(ch))
@@ -545,16 +554,14 @@ trait Scanners extends ScannersCommon {
545554
}
546555
else if (!isAtEnd && (ch != SU && ch != CR && ch != LF || isUnicodeEscape)) {
547556
getLitChar()
548-
if (ch == '\'') {
557+
if (ch != '\'') unclosedCharLit()
558+
else {
549559
nextChar()
550560
token = CHARLIT
551561
setStrVal()
552-
} else {
553-
syntaxError("unclosed character literal")
554562
}
555563
}
556-
else
557-
syntaxError("unclosed character literal")
564+
else unclosedCharLit()
558565
}
559566
fetchSingleQuote()
560567
case '.' =>
@@ -786,7 +793,7 @@ trait Scanners extends ScannersCommon {
786793
next.token = kwArray(idx)
787794
}
788795
} else {
789-
syntaxError("invalid string interpolation: `$$', `$'ident or `$'BlockExpr expected")
796+
syntaxError(s"invalid string interpolation $$$ch, expected: $$$$, $$identifier or $${expression}")
790797
}
791798
} else {
792799
val isUnclosedLiteral = !isUnicodeEscape && (ch == SU || (!multiLine && (ch == CR || ch == LF)))

test/files/neg/badtok-1.check

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@ badtok-1.scala:2: error: unclosed character literal
77
badtok-1.scala:6: error: empty character literal (use '\'' for single quote)
88
'''
99
^
10-
three errors found
10+
badtok-1.scala:9: error: unclosed character literal (or use " for string literal "abc")
11+
'abc'
12+
^
13+
four errors found

test/files/neg/badtok-1.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@
44

55
// SI-10133
66
'''
7+
8+
// SI-10120
9+
'abc'

test/files/neg/t5856.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
t5856.scala:10: error: invalid string interpolation: `$$', `$'ident or `$'BlockExpr expected
1+
t5856.scala:10: error: invalid string interpolation $", expected: $$, $identifier or ${expression}
22
val s9 = s"$"
33
^
44
t5856.scala:10: error: unclosed string literal

0 commit comments

Comments
 (0)