diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def index cf2d07d817aed..55819a27def21 100644 --- a/include/swift/AST/DiagnosticsParse.def +++ b/include/swift/AST/DiagnosticsParse.def @@ -1295,7 +1295,11 @@ ERROR(swift_native_objc_runtime_base_must_be_identifier,none, "@_swift_native_objc_runtime_base class name must be an identifier", ()) ERROR(attr_interpolated_string,none, -"%0 cannot be an interpolated string literal", (StringRef)) +"'%0' cannot be an interpolated string literal", (StringRef)) +ERROR(attr_multiline_string,none, +"'%0' cannot be a multiline string literal", (StringRef)) +ERROR(attr_extended_escaping_string,none, +"'%0' cannot be an extended escaping string literal", (StringRef)) ERROR(attr_only_at_non_local_scope, none, "attribute '%0' can only be used in a non-local scope", (StringRef)) diff --git a/lib/Parse/Lexer.cpp b/lib/Parse/Lexer.cpp index d77fda48834d9..cbdf56e0dcdef 100644 --- a/lib/Parse/Lexer.cpp +++ b/lib/Parse/Lexer.cpp @@ -2108,26 +2108,6 @@ StringRef Lexer::getEncodedStringSegment(StringRef Bytes, // range check subscripting on the StringRef. const char *BytesPtr = Bytes.begin(); - // Special case when being called from EncodedDiagnosticMessage(...). - // This allows multiline and delimited strings to work in attributes. - // The string has already been validated by the initial parse. - if (IndentToStrip == ~0u && CustomDelimiterLen == ~0u) { - IndentToStrip = CustomDelimiterLen = 0; - - // Restore trailing indent removal for multiline. - const char *Backtrack = BytesPtr - 1; - if (Backtrack[-1] == '"' && Backtrack[-2] == '"') { - Backtrack -= 2; - for (const char *Trailing = Bytes.end() - 1; - *Trailing == ' ' || *Trailing == '\t'; Trailing--) - IndentToStrip++; - } - - // Restore delimiter if any. - while (*--Backtrack == '#') - CustomDelimiterLen++; - } - bool IsEscapedNewline = false; while (BytesPtr < Bytes.end()) { char CurChar = *BytesPtr++; diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 6a05539a7ebf9..c00fba15a8650 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -300,6 +300,16 @@ bool Parser::parseTopLevel() { static Optional getStringLiteralIfNotInterpolated(Parser &P, SourceLoc Loc, const Token &Tok, StringRef DiagText) { + // FIXME: Support extended escaping / multiline string literal. + if (Tok.getCustomDelimiterLen()) { + P.diagnose(Loc, diag::attr_extended_escaping_string, DiagText); + return None; + } + if (Tok.isMultilineString()) { + P.diagnose(Loc, diag::attr_multiline_string, DiagText); + return None; + } + SmallVector Segments; P.L->getStringLiteralSegments(Tok, Segments); if (Segments.size() != 1 || diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h index 7d64ecad386f9..5e55ef3344b55 100644 --- a/lib/Sema/TypeChecker.h +++ b/lib/Sema/TypeChecker.h @@ -2164,7 +2164,7 @@ class EncodedDiagnosticMessage { public: /// \param S A string with an encoded message EncodedDiagnosticMessage(StringRef S) - : Message(Lexer::getEncodedStringSegment(S, Buf, true, true, ~0, ~0)) {} + : Message(Lexer::getEncodedStringSegment(S, Buf)) {} /// The unescaped message to display to the user. const StringRef Message; diff --git a/test/Parse/diagnose_availability.swift b/test/Parse/diagnose_availability.swift index 1b35b9af90fa5..ad41d26644a7e 100644 --- a/test/Parse/diagnose_availability.swift +++ b/test/Parse/diagnose_availability.swift @@ -62,3 +62,22 @@ func swiftDeprecatedObsoleted() {} // expected-warning@-1 {{expected 'introduced', 'deprecated', or 'obsoleted' in 'available' attribute for platform 'swift'}} func swiftMessage() {} +@available(*, unavailable, message: "\("message")") +// expected-error@-1{{'message' cannot be an interpolated string literal}} +func interpolatedMessage() {} + +// expected-error@+1{{'message' cannot be a multiline string literal}} +@available(*, unavailable, message: """ + foobar message. + """) +func multilineMessage() {} + +// expected-error@+1{{'message' cannot be an extended escaping string literal}} +@available(*, unavailable, message: #""" + foobar message. + """#) +func extendedEscapedMultilineMessage() {} + +// expected-error@+1{{'renamed' cannot be an extended escaping string literal}} +@available(*, unavailable, renamed: #"avialable()"#) +func extenedEscpaedRenamed() {}