From 4af20b25d59dd03f395d4e8ef5bb8486633ba2c3 Mon Sep 17 00:00:00 2001 From: "Henrik G. Olsson" Date: Fri, 7 Nov 2025 17:50:38 -0800 Subject: [PATCH 1/4] [utils] fix bug in diagnostic stealing logic When replacing expected diagnostic content, we should consider expected diagnostics targeting the same target, not targeting the line the expected diagnostic is on. --- .../update-verify-tests/update-existing.swift | 30 +++++++++++++++++++ utils/update_verify_tests/core.py | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 test/Utils/update-verify-tests/update-existing.swift diff --git a/test/Utils/update-verify-tests/update-existing.swift b/test/Utils/update-verify-tests/update-existing.swift new file mode 100644 index 0000000000000..05794800769dd --- /dev/null +++ b/test/Utils/update-verify-tests/update-existing.swift @@ -0,0 +1,30 @@ +// RUN: %empty-directory(%t) +// RUN: split-file %s %t + +// RUN: not %target-swift-frontend-verify -typecheck %t/test.swift 2>%t/output.txt +// RUN: %update-verify-tests < %t/output.txt +// RUN: %target-swift-frontend-verify -typecheck %t/test.swift +// RUN: %diff %t/test.swift %t/test.swift.expected + +//--- test.swift +func foo() { + let a = 2 // expected-error@+1{{asdf}} + b = a // expected-error@+1{{asdf}} +} + +func bar() { + a = 2 // expected-error@+1{{asdf}} +} + +//--- test.swift.expected +func foo() { + // expected-note@+1{{'a' declared here}} + let a = 2 // expected-error@+1{{cannot find 'b' in scope; did you mean 'a'?}} + b = a +} + +func bar() { + // expected-error@+1{{cannot find 'a' in scope}} + a = 2 +} + diff --git a/utils/update_verify_tests/core.py b/utils/update_verify_tests/core.py index 6ab365b080ff5..2364522671263 100644 --- a/utils/update_verify_tests/core.py +++ b/utils/update_verify_tests/core.py @@ -398,7 +398,7 @@ def remove_dead_diags(lines): remove_line(line, lines) else: assert line.diag.is_from_source_file - for other_diag in line.targeting_diags: + for other_diag in line.diag.target.targeting_diags: if ( other_diag.is_from_source_file or other_diag.count == 0 From 4d5844b723df133adb5cd0b616a834e89878b4ef Mon Sep 17 00:00:00 2001 From: "Henrik G. Olsson" Date: Fri, 7 Nov 2025 18:01:15 -0800 Subject: [PATCH 2/4] [utils] only steal 1 diagnostic This fixes a bug in the diagnostic stealing logic when multiple diagnostics target the same line, which would trigger an assert. --- .../update-verify-tests/update-existing.swift | 34 +++++++++++++++++++ utils/update_verify_tests/core.py | 1 + 2 files changed, 35 insertions(+) diff --git a/test/Utils/update-verify-tests/update-existing.swift b/test/Utils/update-verify-tests/update-existing.swift index 05794800769dd..49261ea9d429d 100644 --- a/test/Utils/update-verify-tests/update-existing.swift +++ b/test/Utils/update-verify-tests/update-existing.swift @@ -16,6 +16,21 @@ func bar() { a = 2 // expected-error@+1{{asdf}} } +func baz() { + // expected-error@+2{{cannot find 'a' in scope}} + // expected-error@+1{{cannot find 'a'}} + let b = a; let c = a; // expected-error{{asdf}} +} + +func qux() { + let b = a; let c = a; // expected-error{{asdf}} +} + +func foobar() { + var b = 1 + b = a; b = a; // expected-error{{asdf}} +} + //--- test.swift.expected func foo() { // expected-note@+1{{'a' declared here}} @@ -28,3 +43,22 @@ func bar() { a = 2 } +func baz() { + // expected-error@+3{{cannot find 'a' in scope}} + // expected-error@+2{{cannot find 'a'}} + // expected-note@+1{{'b' declared here}} + let b = a; let c = a; +} + +func qux() { + // expected-note@+2{{'b' declared here}} + // expected-error@+1{{cannot find 'a' in scope}} + let b = a; let c = a; // expected-error{{cannot find 'a' in scope; did you mean 'b'?}} +} + +func foobar() { + // expected-note@+1 2{{'b' declared here}} + var b = 1 + b = a; b = a; // expected-error 2{{cannot find 'a' in scope; did you mean 'b'?}} +} + diff --git a/utils/update_verify_tests/core.py b/utils/update_verify_tests/core.py index 2364522671263..5bd9bfc2aa22d 100644 --- a/utils/update_verify_tests/core.py +++ b/utils/update_verify_tests/core.py @@ -409,6 +409,7 @@ def remove_dead_diags(lines): continue line.diag.take(other_diag) remove_line(other_diag.line, lines) + break def fold_expansions(lines): From c246140d7fc0cbad90cab54d9a2434dea7f35a22 Mon Sep 17 00:00:00 2001 From: "Henrik G. Olsson" Date: Fri, 7 Nov 2025 18:07:56 -0800 Subject: [PATCH 3/4] [utils] remove trailing whitespace after removing diag --- test/Utils/update-verify-tests/update-existing.swift | 6 +++--- utils/update_verify_tests/core.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Utils/update-verify-tests/update-existing.swift b/test/Utils/update-verify-tests/update-existing.swift index 49261ea9d429d..29c892813903e 100644 --- a/test/Utils/update-verify-tests/update-existing.swift +++ b/test/Utils/update-verify-tests/update-existing.swift @@ -35,19 +35,19 @@ func foobar() { func foo() { // expected-note@+1{{'a' declared here}} let a = 2 // expected-error@+1{{cannot find 'b' in scope; did you mean 'a'?}} - b = a + b = a } func bar() { // expected-error@+1{{cannot find 'a' in scope}} - a = 2 + a = 2 } func baz() { // expected-error@+3{{cannot find 'a' in scope}} // expected-error@+2{{cannot find 'a'}} // expected-note@+1{{'b' declared here}} - let b = a; let c = a; + let b = a; let c = a; } func qux() { diff --git a/utils/update_verify_tests/core.py b/utils/update_verify_tests/core.py index 5bd9bfc2aa22d..a07573fc469b6 100644 --- a/utils/update_verify_tests/core.py +++ b/utils/update_verify_tests/core.py @@ -51,7 +51,7 @@ def render(self): res = self.content.replace("{{DIAG}}", self.diag.render()) if not res.strip(): return "" - return res + return res.rstrip() + "\n" class Diag: From 5db7926e091a619eb0f85fe55465aa5e83cd1168 Mon Sep 17 00:00:00 2001 From: "Henrik G. Olsson" Date: Fri, 7 Nov 2025 18:09:42 -0800 Subject: [PATCH 4/4] [utils] add support for expected-remarks to update-verify-tests.py --- test/Utils/update-verify-tests/remarks.swift | 21 ++++++++++++++++++++ utils/update_verify_tests/core.py | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 test/Utils/update-verify-tests/remarks.swift diff --git a/test/Utils/update-verify-tests/remarks.swift b/test/Utils/update-verify-tests/remarks.swift new file mode 100644 index 0000000000000..b9981e7dcdc57 --- /dev/null +++ b/test/Utils/update-verify-tests/remarks.swift @@ -0,0 +1,21 @@ +// RUN: %empty-directory(%t) +// RUN: split-file %s %t + +// RUN: not %target-swift-frontend-verify -typecheck %t/test.swift -Rmodule-api-import 2>%t/output.txt +// RUN: %update-verify-tests < %t/output.txt +// RUN: %target-swift-frontend-verify -typecheck %t/test.swift -Rmodule-api-import +// RUN: %diff %t/test.swift %t/test.swift.expected + +//--- test.swift +public typealias Foo = String + +public typealias Bar = Optional // expected-remark@+1{{asdf}} + +//--- test.swift.expected +// expected-remark@+1{{struct 'String' is imported via 'Swift'}} +public typealias Foo = String + +// expected-remark@+2{{struct 'Int' is imported via 'Swift'}} +// expected-remark@+1{{generic enum 'Optional' is imported via 'Swift'}} +public typealias Bar = Optional + diff --git a/utils/update_verify_tests/core.py b/utils/update_verify_tests/core.py index a07573fc469b6..f076374d871a5 100644 --- a/utils/update_verify_tests/core.py +++ b/utils/update_verify_tests/core.py @@ -185,7 +185,7 @@ def render(self): expected_diag_re = re.compile( - r"//(\s*)expected-([a-zA-Z-]*)(note|warning|error)(-re)?(@[+-]?\d+)?(:\d+)?(\s*)(\d+)?\{\{(.*)\}\}" + r"//(\s*)expected-([a-zA-Z-]*)(note|warning|error|remark)(-re)?(@[+-]?\d+)?(:\d+)?(\s*)(\d+)?\{\{(.*)\}\}" ) expected_expansion_diag_re = re.compile( r"//(\s*)expected-([a-zA-Z-]*)(expansion)(-re)?(@[+-]?\d+)(:\d+)(\s*)(\d+)?\{\{(.*)"