mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Change diagnostic error thrown for when string interpolations aren't closed by a parenthesis (#58882)
[Parse] Diagnose unclosed string interpolations
This commit is contained in:
@@ -1353,6 +1353,11 @@ ERROR(expected_type_after_as,none,
|
||||
ERROR(string_interpolation_extra,none,
|
||||
"extra tokens after interpolated string expression", ())
|
||||
|
||||
// String interpolation isnt closed by a )
|
||||
// ie: `let west = "ye \("`
|
||||
ERROR(string_interpolation_unclosed, none,
|
||||
"cannot find ')' to match opening '(' in string interpolation", ())
|
||||
|
||||
// Interpolations with parameter labels or multiple values
|
||||
WARNING(string_interpolation_list_changing,none,
|
||||
"interpolating multiple values will not form a tuple in Swift 5", ())
|
||||
|
||||
@@ -1884,13 +1884,21 @@ void Lexer::lexStringLiteral(unsigned CustomDelimiterLen) {
|
||||
// Successfully scanned the body of the expression literal.
|
||||
++CurPtr;
|
||||
continue;
|
||||
} else if ((*CurPtr == '\r' || *CurPtr == '\n') && IsMultilineString) {
|
||||
// The only case we reach here is unterminated single line string in the
|
||||
// interpolation. For better recovery, go on after emitting an error.
|
||||
diagnose(CurPtr, diag::lex_unterminated_string);
|
||||
wasErroneous = true;
|
||||
continue;
|
||||
} else {
|
||||
if ((*CurPtr == '\r' || *CurPtr == '\n') && IsMultilineString) {
|
||||
diagnose(--TmpPtr, diag::string_interpolation_unclosed);
|
||||
|
||||
// The only case we reach here is unterminated single line string in
|
||||
// the interpolation. For better recovery, go on after emitting
|
||||
// an error.
|
||||
diagnose(CurPtr, diag::lex_unterminated_string);
|
||||
wasErroneous = true;
|
||||
continue;
|
||||
} else if (!IsMultilineString || CurPtr == BufferEnd) {
|
||||
diagnose(--TmpPtr, diag::string_interpolation_unclosed);
|
||||
}
|
||||
|
||||
// As a fallback, just emit an unterminated string error.
|
||||
diagnose(TokStart, diag::lex_unterminated_string);
|
||||
return formToken(tok::unknown, TokStart);
|
||||
}
|
||||
|
||||
@@ -126,15 +126,17 @@ _ = "hello\("""
|
||||
world
|
||||
"""
|
||||
)!"
|
||||
// expected-error@-4 {{unterminated string literal}}
|
||||
// expected-error@-2 {{unterminated string literal}}
|
||||
// expected-error@-4 {{cannot find ')' to match opening '(' in string interpolation}}
|
||||
// expected-error@-5 {{unterminated string literal}}
|
||||
// expected-error@-3 {{unterminated string literal}}
|
||||
|
||||
_ = "hello\(
|
||||
"""
|
||||
world
|
||||
""")!"
|
||||
// expected-error@-4 {{unterminated string literal}}
|
||||
// expected-error@-2 {{unterminated string literal}}
|
||||
// expected-error@-4 {{cannot find ')' to match opening '(' in string interpolation}}
|
||||
// expected-error@-5 {{unterminated string literal}}
|
||||
// expected-error@-3 {{unterminated string literal}}
|
||||
|
||||
_ = """
|
||||
line one \ non-whitespace
|
||||
@@ -190,4 +192,6 @@ let _ = """
|
||||
let _ = """
|
||||
foo
|
||||
\("bar
|
||||
baz
|
||||
baz
|
||||
"""
|
||||
// expected-error@-3 {{cannot find ')' to match opening '(' in string interpolation}}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
// NOTE: DO NOT add a newline at EOF.
|
||||
// expected-error@+1 {{unterminated string literal}}
|
||||
// expected-error@+2 {{unterminated string literal}}
|
||||
// expected-error@+1 {{cannot find ')' to match opening '(' in string interpolation}}
|
||||
_ = "foo\(
|
||||
@@ -1,5 +1,6 @@
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
// NOTE: DO NOT add a newline at EOF.
|
||||
// expected-error@+2 {{cannot find ')' to match opening '(' in string interpolation}}
|
||||
// expected-error@+1 {{unterminated string literal}}
|
||||
_ = "foo\("bar
|
||||
@@ -1,7 +1,8 @@
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
// NOTE: DO NOT add a newline at EOF.
|
||||
// expected-error@+1 {{unterminated string literal}}
|
||||
// expected-error@+2 {{unterminated string literal}}
|
||||
// expected-error@+3 {{cannot find ')' to match opening '(' in string interpolation}}
|
||||
_ = """
|
||||
foo
|
||||
\(
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
// NOTE: DO NOT add a newline at EOF.
|
||||
// expected-error@+1 {{unterminated string literal}}
|
||||
// expected-error@+2 {{unterminated string literal}}
|
||||
// expected-error@+3 {{cannot find ')' to match opening '(' in string interpolation}}
|
||||
_ = """
|
||||
foo
|
||||
\("bar
|
||||
@@ -1,7 +1,7 @@
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
// expected-error@+4 {{unterminated string literal}}
|
||||
// expected-error@+1 {{unterminated string literal}}
|
||||
// expected-error@+4 {{cannot find ')' to match opening '(' in string interpolation}}
|
||||
// expected-error@+1 {{unterminated string literal}} expected-error@+3 {{unterminated string literal}}
|
||||
_ = """
|
||||
foo
|
||||
\("bar
|
||||
|
||||
33
test/Parse/unclosed-string-interpolation.swift
Normal file
33
test/Parse/unclosed-string-interpolation.swift
Normal file
@@ -0,0 +1,33 @@
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
let mid = "pete"
|
||||
|
||||
_ = "mid == \(pete"
|
||||
// expected-error @-1 {{cannot find ')' to match opening '(' in string interpolation}}
|
||||
// expected-error @-2 {{unterminated string literal}}
|
||||
|
||||
let theGoat = "kanye \("
|
||||
// expected-error @-1 {{cannot find ')' to match opening '(' in string interpolation}}
|
||||
// expected-error @-2 {{unterminated string literal}}
|
||||
|
||||
let equation1 = "2 + 2 = \(2 + 2"
|
||||
// expected-error @-1 {{cannot find ')' to match opening '(' in string interpolation}}
|
||||
// expected-error @-2 {{unterminated string literal}}
|
||||
|
||||
let s = "\(x"; print(x)
|
||||
// expected-error @-1 {{cannot find ')' to match opening '(' in string interpolation}}
|
||||
// expected-error @-2 {{unterminated string literal}}
|
||||
|
||||
let zzz = "\(x; print(x)
|
||||
// expected-error @-1 {{cannot find ')' to match opening '(' in string interpolation}}
|
||||
// expected-error @-2 {{unterminated string literal}}
|
||||
|
||||
let goatedAlbum = "The Life Of \("Pablo"
|
||||
// expected-error @-1 {{cannot find ')' to match opening '(' in string interpolation}}
|
||||
// expected-error @-2 {{unterminated string literal}}
|
||||
|
||||
// expected-error @+3 {{cannot find ')' to match opening '(' in string interpolation}}
|
||||
// expected-error @+1 {{unterminated string literal}}
|
||||
_ = """
|
||||
\(
|
||||
"""
|
||||
@@ -475,9 +475,11 @@ func stringliterals(_ d: [String: Int]) {
|
||||
let x = 4
|
||||
"Hello \(x+1) world" // expected-warning {{string literal is unused}}
|
||||
|
||||
"Error: \(x+1"; // expected-error {{unterminated string literal}}
|
||||
|
||||
"Error: \(x+1 // expected-error {{unterminated string literal}}
|
||||
// expected-error @+1 {{unterminated string literal}}
|
||||
"Error: \(x+1"; // expected-error {{cannot find ')' to match opening '(' in string interpolation}}
|
||||
|
||||
// expected-error @+1 {{unterminated string literal}}
|
||||
"Error: \(x+1 // expected-error {{cannot find ')' to match opening '(' in string interpolation}}
|
||||
; // expected-error {{';' statements are not allowed}}
|
||||
|
||||
// rdar://14050788 [DF] String Interpolations can't contain quotes
|
||||
@@ -488,15 +490,16 @@ func stringliterals(_ d: [String: Int]) {
|
||||
"test \("quoted-paren (")"
|
||||
"test \("\\")"
|
||||
"test \("\n")"
|
||||
"test \("\")" // expected-error {{unterminated string literal}}
|
||||
"test \("\")" // expected-error {{cannot find ')' to match opening '(' in string interpolation}} expected-error {{unterminated string literal}}
|
||||
|
||||
"test \
|
||||
// expected-error @-1 {{unterminated string literal}} expected-error @-1 {{invalid escape sequence in literal}}
|
||||
"test \("\
|
||||
// expected-error @-1 {{unterminated string literal}}
|
||||
// expected-error @-1 {{cannot find ')' to match opening '(' in string interpolation}} expected-error @-1 {{unterminated string literal}}
|
||||
"test newline \("something" +
|
||||
"something else")"
|
||||
// expected-error @-2 {{unterminated string literal}} expected-error @-1 {{unterminated string literal}}
|
||||
// expected-error @-2 {{cannot find ')' to match opening '(' in string interpolation}}
|
||||
// expected-error @-2 {{unterminated string literal}} expected-error @-3 {{unterminated string literal}}
|
||||
|
||||
// expected-warning @+2 {{variable 'x2' was never used; consider replacing with '_' or removing it}}
|
||||
// expected-error @+1 {{unterminated string literal}}
|
||||
@@ -939,10 +942,10 @@ let _ = 0xFFF_FFFF_FFFF_FFFF as Int64
|
||||
|
||||
// rdar://problem/20289969 - string interpolation with comment containing ')' or '"'
|
||||
let _ = "foo \(42 /* ) " ) */)"
|
||||
let _ = "foo \(foo // ) " // expected-error {{unterminated string literal}}
|
||||
let _ = "foo \(foo // ) " // expected-error {{cannot find ')' to match opening '(' in string interpolation}} expected-error {{unterminated string literal}}
|
||||
let _ = "foo \(42 /*
|
||||
* multiline comment
|
||||
*/)end"
|
||||
// expected-error @-3 {{unterminated string literal}}
|
||||
// expected-error @-3 {{cannot find ')' to match opening '(' in string interpolation}} expected-error @-3 {{unterminated string literal}}
|
||||
// expected-error @-2 {{expected expression}}
|
||||
// expected-error @-3 {{unterminated string literal}}
|
||||
|
||||
Reference in New Issue
Block a user