stage2: basic inferred error set support

* Inferred error sets are stored in the return Type of the function,
   owned by the Module.Fn. So it cleans up that memory in deinit().
 * Sema: update the inferred error set in zirRetErrValue
   - Update relevant code in wrapErrorUnion
 * C backend: improve some some instructions to take advantage of
   liveness analysis to avoid being emitted when unused.
 * C backend: when an error union has a payload type with no runtime
   bits, emit the error union as the same type as the error set.
This commit is contained in:
Andrew Kelley
2021-07-07 20:47:21 -07:00
parent 5c8bd443d9
commit c2e66d9bab
5 changed files with 113 additions and 21 deletions

View File

@@ -777,8 +777,19 @@ pub const Fn = struct {
}
pub fn deinit(func: *Fn, gpa: *Allocator) void {
_ = func;
_ = gpa;
if (func.getInferredErrorSet()) |map| {
map.deinit(gpa);
}
}
pub fn getInferredErrorSet(func: *Fn) ?*std.StringHashMapUnmanaged(void) {
const ret_ty = func.owner_decl.ty.fnReturnType();
if (ret_ty.zigTypeTag() == .ErrorUnion) {
if (ret_ty.errorUnionSet().castTag(.error_set_inferred)) |payload| {
return &payload.data.map;
}
}
return null;
}
};