Skip to content

frontend: make fn calls byval; fix false positive isNonErr #16576

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions src/AstGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9536,16 +9536,19 @@ fn nodeMayNeedMemoryLocation(tree: *const Ast, start_node: Ast.Node.Index, have_
.@"for", // This variant always has an else expression.
.@"switch",
.switch_comma,
.call_one,
.call_one_comma,
.async_call_one,
.async_call_one_comma,
.call,
.call_comma,
.async_call,
.async_call_comma,
=> return true,

// https://github.com/ziglang/zig/issues/2765 would change this.
.call_one,
.call_one_comma,
.call,
.call_comma,
=> return false,

.block_two,
.block_two_semicolon,
.block,
Expand Down
32 changes: 8 additions & 24 deletions src/Sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -30732,18 +30732,10 @@ fn analyzeIsNonErrComptimeOnly(
else => return .none,
},
}
for (ies.inferred_error_sets.keys()) |other_ies_index| {
if (set_ty == other_ies_index) continue;
const other_resolved =
try sema.resolveInferredErrorSet(block, src, other_ies_index);
if (other_resolved == .anyerror_type) {
ies.resolved = .anyerror_type;
return .none;
}
if (ip.indexToKey(other_resolved).error_set_type.names.len != 0)
return .none;
}
return .bool_true;
// We do not have a comptime answer because this inferred error
// set is not resolved, and an instruction later in this function
// body may or may not cause an error to be added to this set.
return .none;
},
else => switch (ip.indexToKey(set_ty)) {
.error_set_type => |error_set_type| {
Expand Down Expand Up @@ -30771,18 +30763,10 @@ fn analyzeIsNonErrComptimeOnly(
else => return .none,
},
}
for (ies.inferred_error_sets.keys()) |other_ies_index| {
if (set_ty == other_ies_index) continue;
const other_resolved =
try sema.resolveInferredErrorSet(block, src, other_ies_index);
if (other_resolved == .anyerror_type) {
ies.resolved = .anyerror_type;
return .none;
}
if (ip.indexToKey(other_resolved).error_set_type.names.len != 0)
return .none;
}
return .bool_true;
// We do not have a comptime answer because this inferred error
// set is not resolved, and an instruction later in this function
// body may or may not cause an error to be added to this set.
return .none;
}
}
const resolved_ty = try sema.resolveInferredErrorSet(block, src, set_ty);
Expand Down
25 changes: 25 additions & 0 deletions test/behavior/error.zig
Original file line number Diff line number Diff line change
Expand Up @@ -938,3 +938,28 @@ test "returning an error union containing a type with no runtime bits" {
var zero_byte: ZeroByteType = undefined;
(&zero_byte).* = try ZeroByteType.init();
}

test "try used in recursive function with inferred error set" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO

const Value = union(enum) {
values: []const @This(),
b,

fn x(value: @This()) !void {
switch (value.values[0]) {
.values => return try x(value.values[0]),
.b => return error.a,
}
}
};
const a = Value{
.values = &[1]Value{
.{
.values = &[1]Value{.{ .b = {} }},
},
},
};
try expectError(error.a, Value.x(a));
}