authorgravatar for gabeuehlein@gmail.comgabeuehlein <gabeuehlein@gmail.com> 2024-10-14 08:02:14-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-10-14 15:02:14+03:00
log7b8fc18c666ba6952ad1571fbed4cc48e81f647d
treea9ec04b57aa063f899bce4a65cb7aa4419d9b21b
parent9fd61f7460950a4124f8a9d6eb31a40f03ecd5a7
signaturebadge-check Signed by PGP key B5690EEEBB952194

Sema: fail if analyzing return in `noreturn`-declared function before coercing `undefined`

Just switches logic around in coerceExtra to check for returning in a noreturn function before coercing undefined to anything

2 files changed, 15 insertions(+), 5 deletions(-)

src/Sema.zig+5-5
...@@ -30346,11 +30346,6 @@ fn coerceExtra(...@@ -30346,11 +30346,6 @@ fn coerceExtra(
30346 else => {},30346 else => {},
30347 }30347 }
3034830348
30349 // undefined to anything. We do this after the big switch above so that
30350 // special logic has a chance to run first, such as `*[N]T` to `[]T` which
30351 // should initialize the length field of the slice.
30352 if (maybe_inst_val) |val| if (val.toIntern() == .undef) return pt.undefRef(dest_ty);
30353
30354 if (!opts.report_err) return error.NotCoercible;30349 if (!opts.report_err) return error.NotCoercible;
3035530350
30356 if (opts.is_ret and dest_ty.zigTypeTag(zcu) == .noreturn) {30351 if (opts.is_ret and dest_ty.zigTypeTag(zcu) == .noreturn) {
...@@ -30368,6 +30363,11 @@ fn coerceExtra(...@@ -30368,6 +30363,11 @@ fn coerceExtra(
30368 return sema.failWithOwnedErrorMsg(block, msg);30363 return sema.failWithOwnedErrorMsg(block, msg);
30369 }30364 }
3037030365
30366 // undefined to anything. We do this after the big switch above so that
30367 // special logic has a chance to run first, such as `*[N]T` to `[]T` which
30368 // should initialize the length field of the slice.
30369 if (maybe_inst_val) |val| if (val.toIntern() == .undef) return pt.undefRef(dest_ty);
30370
30371 const msg = msg: {30371 const msg = msg: {
30372 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(pt), inst_ty.fmt(pt) });30372 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(pt), inst_ty.fmt(pt) });
30373 errdefer msg.destroy(sema.gpa);30373 errdefer msg.destroy(sema.gpa);
test/cases/compile_errors/return_undefined_from_noreturn.zig created+10
...@@ -0,0 +1,10 @@
1export fn entry() noreturn {
2 return undefined;
3}
4
5// error
6// backend=stage2
7// target=native
8//
9// :2:12: error: function declared 'noreturn' returns
10// :1:19: note: 'noreturn' declared here