fix catch handlers / match statements yielding past scope

This commit is contained in:
2026-06-30 23:21:47 +02:00
parent d6f9c24314
commit 7fe3552c01
6 changed files with 117 additions and 44 deletions
+30 -15
View File
@@ -2459,9 +2459,16 @@ bad_catch func() i32 {
_ = e
}
}
bad_nested_match func() i32 {
return fa() catch |e| {
match e {
.a: yield 3
}
}
}
main func() i32 {
_ = bad_error() catch 0
return bad_catch()
return bad_catch() + bad_nested_match()
}
`
source_file := source.Source{path="fallible_ergonomics.bro", text=text}
@@ -2478,12 +2485,15 @@ main func() i32 {
found_error := false
found_yield := false
found_misplaced_yield := false
for diagnostic in diagnostics.items {
found_error = found_error || strings.contains(diagnostic.message, "'try' error channel cannot be widened")
found_yield = found_yield || strings.contains(diagnostic.message, "a value block must end with an explicit 'yield'")
found_misplaced_yield = found_misplaced_yield || strings.contains(diagnostic.message, "'yield' is only valid as the final statement")
}
testing.expect(t, found_error)
testing.expect(t, found_yield)
testing.expect(t, found_misplaced_yield)
success_text := `A :: enum {
a
@@ -2540,10 +2550,11 @@ with_detail func(value i32) i32 ! DetailError {
main func() i32 {
e DetailError = .code{3}
recovered :: with_detail(0) catch |err| {
match err {
.code |n|: yield n
.empty: yield 9
result i32 :: match err {
.code |n|: n
.empty: 9
}
yield result
}
return accept(e) + accept(.code{4}) + accept(make_code(5)) + accept(.code{make_payload()}) + recovered - 24
}
@@ -2617,17 +2628,19 @@ main func() i32 {
a :: accept(e)
b :: accept(.wrapped{line = 4, path = 3})
c :: with_payload(0) catch |err| {
match err {
.not_found |info|: yield info.path + info.line
.wrapped |info|: yield info.path + info.line
.scalar |n|: yield n
.empty: yield 0
result i32 :: match err {
.not_found |info|: info.path + info.line
.wrapped |info|: info.path + info.line
.scalar |n|: n
.empty: 0
}
yield result
}
d :: inline_payload(0) catch |err| {
match err {
.inline_bad |info|: yield info.code + info.line
result i32 :: match err {
.inline_bad |info|: info.code + info.line
}
yield result
}
return a + b + c + d - 59
}
@@ -2672,17 +2685,19 @@ inline_union func(value i32) i32 ! union(enum) {
}
main func() i32 {
a :: inline_enum(0) catch |e| {
if (e == .inline_bad) {
result i32 :: if (e == .inline_bad) {
yield 10
} else {
yield 11
}
yield result
}
b :: inline_union(0) catch |e| {
match e {
.inline_code |n|: yield n
.inline_empty: yield 12
result i32 :: match e {
.inline_code |n|: n
.inline_empty: 12
}
yield result
}
return a + b - 16
}