diff --git a/test/Utils/update-verify-tests/expansion.swift b/test/Utils/update-verify-tests/expansion.swift index 82d0b7318c2..bb29d80fc37 100644 --- a/test/Utils/update-verify-tests/expansion.swift +++ b/test/Utils/update-verify-tests/expansion.swift @@ -42,6 +42,11 @@ // RUN: not %target-swift-frontend-verify -I %t -plugin-path %swift-plugin-dir -typecheck %t/unparsed.swift 2>%t/output.txt -Rmacro-expansions // RUN: not %update-verify-tests < %t/output.txt | %FileCheck --check-prefix CHECK-UNPARSED %s +// RUN: not %target-swift-frontend-verify -load-plugin-library %t/%target-library-name(UnstringifyMacroDefinition) -typecheck %t/escaped.swift 2>%t/output.txt -Rmacro-expansions +// RUN: %update-verify-tests < %t/output.txt +// RUN: %target-swift-frontend-verify -load-plugin-library %t/%target-library-name(UnstringifyMacroDefinition) -typecheck %t/escaped.swift -Rmacro-expansions +// RUN: %diff %t/escaped.swift %t/escaped.swift.expected + //--- single.swift @attached(peer, names: overloaded) macro unstringifyPeer(_ s: String) = @@ -260,3 +265,43 @@ func bar() { foo(a, &b) } +//--- escaped.swift +@attached(peer, names: overloaded) +macro unstringifyPeer(_ s: String) = + #externalMacro(module: "UnstringifyMacroDefinition", type: "UnstringifyPeerMacro") + +@unstringifyPeer(""" +func foo(_ x: Int) { + let a = "\\(x)" + let b = "\\(x)" +} +""") +// NB: DiagnosticVerifier interprets "\\(x)" as "\(x)" +// expected-expansion@+3:30{{ +// expected-remark@2{{macro content: |let a = "\\(x)"|}} +// }} +func foo() { let _ = "\(2)" } + +//--- escaped.swift.expected +@attached(peer, names: overloaded) +macro unstringifyPeer(_ s: String) = + #externalMacro(module: "UnstringifyMacroDefinition", type: "UnstringifyPeerMacro") + +// expected-note@+1 6{{in expansion of macro 'unstringifyPeer' on global function 'foo()' here}} +@unstringifyPeer(""" +func foo(_ x: Int) { + let a = "\\(x)" + let b = "\\(x)" +} +""") +// NB: DiagnosticVerifier interprets "\\(x)" as "\(x)" +// expected-expansion@+8:30{{ +// expected-remark@1{{macro content: |func foo(_ x: Int) {|}} +// expected-warning@2{{initialization of immutable value 'a' was never used; consider replacing with assignment to '_' or removing it}} +// expected-remark@2{{macro content: | let a = "\\(x)"|}} +// expected-warning@3{{initialization of immutable value 'b' was never used; consider replacing with assignment to '_' or removing it}} +// expected-remark@3{{macro content: | let b = "\\(x)"|}} +// expected-remark@4{{macro content: |}|}} +// }} +func foo() { let _ = "\(2)" } + diff --git a/utils/update_verify_tests/core.py b/utils/update_verify_tests/core.py index 79d6325bb0b..fe636deb4e3 100644 --- a/utils/update_verify_tests/core.py +++ b/utils/update_verify_tests/core.py @@ -1,5 +1,6 @@ import sys import re +from codecs import encode, decode DEBUG = False @@ -172,7 +173,9 @@ class Diag: if self.category == "expansion": return base_s + "{{" else: - return base_s + "{{" + self.diag_content + "}}" + # python trivia: raw strings can't end with a backslash + escaped_diag_s = self.diag_content.replace("\\", "\\\\") + return base_s + "{{" + escaped_diag_s + "}}" class ExpansionDiagClose: @@ -245,9 +248,12 @@ def parse_diag(line, filename, prefix): count = int(count_s) if count_s else 1 line.content = matched_re.sub("{{DIAG}}", s) + unescaped_diag_s = decode( + encode(diag_s, "utf-8", "backslashreplace"), "unicode-escape" + ) return Diag( check_prefix, - diag_s, + unescaped_diag_s, category_s, target_line_n, is_absolute,