aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-07-07 14:17:04 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-07-07 14:17:04 -0700
commit5816997ae79c6025d5f85aab0c9ab456fecadec9 (patch)
tree66e90395fe170f84e1567787538d4cbc67a63fe4 /src/Sema.zig
parent13f04e3012b6b2eee141923f9780fce55f7a999d (diff)
downloadzig-5816997ae79c6025d5f85aab0c9ab456fecadec9.tar.gz
zig-5816997ae79c6025d5f85aab0c9ab456fecadec9.zip
stage2: get tests passing
* implement enough of ret_err_value to pass wasm tests * only do the proper `@panic` implementation for the backends which support it, which is currently only the C backend. The other backends will see `@breakpoint(); unreachable;` same as before. - I plan to do AIR memory layout reworking as a prerequisite to fixing other backends, because that will help me put all the constants up front, which will allow the codegen to lower to memory without jumps. * `@panic` is implemented using anon decls for the message. Makes it easier on the backends. Might want to look into re-using decls for this in the future. * implement DWARF .debug_info for pointer-like optionals.
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig57
1 files changed, 46 insertions, 11 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 1538e54208..24c51bdc46 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -5423,11 +5423,22 @@ fn zirRetErrValue(
const src = inst_data.src();
// Add the error tag to the inferred error set of the in-scope function.
+ if (sema.func) |func| {
+ const fn_ty = func.owner_decl.ty;
+ const fn_ret_ty = fn_ty.fnReturnType();
+ if (fn_ret_ty.zigTypeTag() == .ErrorUnion and
+ fn_ret_ty.errorUnionSet().tag() == .error_set_inferred)
+ {
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirRetErrValue", .{});
+ }
+ }
// Return the error code from the function.
-
- _ = inst_data;
- _ = err_name;
- return sema.mod.fail(&block.base, src, "TODO: Sema.zirRetErrValueCode", .{});
+ const kv = try sema.mod.getErrorValue(err_name);
+ const result_inst = try sema.mod.constInst(sema.arena, src, .{
+ .ty = try Type.Tag.error_set_single.create(sema.arena, kv.key),
+ .val = try Value.Tag.@"error".create(sema.arena, .{ .name = kv.key }),
+ });
+ return sema.analyzeRet(block, result_inst, src, true);
}
fn zirRetCoerce(
@@ -6411,6 +6422,15 @@ fn panicWithMsg(
) !Zir.Inst.Index {
const mod = sema.mod;
const arena = sema.arena;
+
+ const this_feature_is_implemented_in_the_backend =
+ mod.comp.bin_file.options.object_format == .c;
+ if (!this_feature_is_implemented_in_the_backend) {
+ // TODO implement this feature in all the backends and then delete this branch
+ _ = try block.addNoOp(src, Type.initTag(.void), .breakpoint);
+ _ = try block.addNoOp(src, Type.initTag(.noreturn), .unreach);
+ return always_noreturn;
+ }
const panic_fn = try sema.getBuiltin(block, src, "panic");
const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace");
const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty);
@@ -6431,8 +6451,6 @@ fn safetyPanic(
src: LazySrcLoc,
panic_id: PanicId,
) !Zir.Inst.Index {
- const mod = sema.mod;
- const arena = sema.arena;
const msg = switch (panic_id) {
.unreach => "reached unreachable code",
.unwrap_null => "attempt to use null value",
@@ -6441,11 +6459,28 @@ fn safetyPanic(
.incorrect_alignment => "incorrect alignment",
.invalid_error_code => "invalid error code",
};
- const msg_inst = try mod.constInst(arena, src, .{
- .ty = Type.initTag(.const_slice_u8),
- .val = try Value.Tag.ref_val.create(arena, try Value.Tag.bytes.create(arena, msg)),
- });
- return sema.panicWithMsg(block, src, msg_inst);
+
+ const msg_inst = msg_inst: {
+ // TODO instead of making a new decl for every panic in the entire compilation,
+ // introduce the concept of a reference-counted decl for these
+ var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);
+ errdefer new_decl_arena.deinit();
+
+ const decl_ty = try Type.Tag.array_u8.create(&new_decl_arena.allocator, msg.len);
+ const decl_val = try Value.Tag.bytes.create(&new_decl_arena.allocator, msg);
+
+ const new_decl = try sema.mod.createAnonymousDecl(&block.base, .{
+ .ty = decl_ty,
+ .val = decl_val,
+ });
+ errdefer sema.mod.deleteAnonDecl(&block.base, new_decl);
+ try new_decl.finalizeNewArena(&new_decl_arena);
+ break :msg_inst try sema.analyzeDeclRef(block, .unneeded, new_decl);
+ };
+
+ const casted_msg_inst = try sema.coerce(block, Type.initTag(.const_slice_u8), msg_inst, src);
+
+ return sema.panicWithMsg(block, src, casted_msg_inst);
}
fn emitBackwardBranch(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void {