Skip to content

Commit 7d8cdf6

Browse files
committed
frontend: make fn calls byval; fix false positive isNonErr
This commit does two things which seem unrelated at first, but, together, solve a miscompilation, and potentially slightly speed up compiler perf, at the expense of making #2765 trickier to implement in the future. Sema: avoid returning a false positive for whether an inferred error set is comptime-known to be empty. AstGen: mark function calls as not being interested in a result location. This prevents the test case "ret_ptr doesn't cause own inferred error set to be resolved" from being regressed. If we want to accept and implement #2765 in the future, it will require solving this problem a different way, but the principle of YAGNI tells us to go ahead with this change. Old ZIR looks like this: %97 = ret_ptr() %101 = store_node(%97, %100) %102 = load(%97) %103 = ret_is_non_err(%102) New ZIR looks like this: %97 = ret_type() %101 = as_node(%97, %100) %102 = ret_is_non_err(%101) closes #15669
1 parent 7201e69 commit 7d8cdf6

File tree

3 files changed

+40
-28
lines changed

3 files changed

+40
-28
lines changed

src/AstGen.zig

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9536,16 +9536,19 @@ fn nodeMayNeedMemoryLocation(tree: *const Ast, start_node: Ast.Node.Index, have_
95369536
.@"for", // This variant always has an else expression.
95379537
.@"switch",
95389538
.switch_comma,
9539-
.call_one,
9540-
.call_one_comma,
95419539
.async_call_one,
95429540
.async_call_one_comma,
9543-
.call,
9544-
.call_comma,
95459541
.async_call,
95469542
.async_call_comma,
95479543
=> return true,
95489544

9545+
// https://github.com/ziglang/zig/issues/2765 would change this.
9546+
.call_one,
9547+
.call_one_comma,
9548+
.call,
9549+
.call_comma,
9550+
=> return false,
9551+
95499552
.block_two,
95509553
.block_two_semicolon,
95519554
.block,

src/Sema.zig

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -30732,18 +30732,10 @@ fn analyzeIsNonErrComptimeOnly(
3073230732
else => return .none,
3073330733
},
3073430734
}
30735-
for (ies.inferred_error_sets.keys()) |other_ies_index| {
30736-
if (set_ty == other_ies_index) continue;
30737-
const other_resolved =
30738-
try sema.resolveInferredErrorSet(block, src, other_ies_index);
30739-
if (other_resolved == .anyerror_type) {
30740-
ies.resolved = .anyerror_type;
30741-
return .none;
30742-
}
30743-
if (ip.indexToKey(other_resolved).error_set_type.names.len != 0)
30744-
return .none;
30745-
}
30746-
return .bool_true;
30735+
// We do not have a comptime answer because this inferred error
30736+
// set is not resolved, and an instruction later in this function
30737+
// body may or may not cause an error to be added to this set.
30738+
return .none;
3074730739
},
3074830740
else => switch (ip.indexToKey(set_ty)) {
3074930741
.error_set_type => |error_set_type| {
@@ -30771,18 +30763,10 @@ fn analyzeIsNonErrComptimeOnly(
3077130763
else => return .none,
3077230764
},
3077330765
}
30774-
for (ies.inferred_error_sets.keys()) |other_ies_index| {
30775-
if (set_ty == other_ies_index) continue;
30776-
const other_resolved =
30777-
try sema.resolveInferredErrorSet(block, src, other_ies_index);
30778-
if (other_resolved == .anyerror_type) {
30779-
ies.resolved = .anyerror_type;
30780-
return .none;
30781-
}
30782-
if (ip.indexToKey(other_resolved).error_set_type.names.len != 0)
30783-
return .none;
30784-
}
30785-
return .bool_true;
30766+
// We do not have a comptime answer because this inferred error
30767+
// set is not resolved, and an instruction later in this function
30768+
// body may or may not cause an error to be added to this set.
30769+
return .none;
3078630770
}
3078730771
}
3078830772
const resolved_ty = try sema.resolveInferredErrorSet(block, src, set_ty);

test/behavior/error.zig

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,3 +938,28 @@ test "returning an error union containing a type with no runtime bits" {
938938
var zero_byte: ZeroByteType = undefined;
939939
(&zero_byte).* = try ZeroByteType.init();
940940
}
941+
942+
test "try used in recursive function with inferred error set" {
943+
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
944+
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
945+
946+
const Value = union(enum) {
947+
values: []const @This(),
948+
b,
949+
950+
fn x(value: @This()) !void {
951+
switch (value.values[0]) {
952+
.values => return try x(value.values[0]),
953+
.b => return error.a,
954+
}
955+
}
956+
};
957+
const a = Value{
958+
.values = &[1]Value{
959+
.{
960+
.values = &[1]Value{.{ .b = {} }},
961+
},
962+
},
963+
};
964+
try expectError(error.a, Value.x(a));
965+
}

0 commit comments

Comments
 (0)