incremental: fix adding/removing aggregate fields

I don't recall why I put these checks here -- they aren't correct. We
can freely recreate a type even if its fields have changed, because we
are going to re-do all type resolution.

The only conditions for recreations are (a) the ZIR index must not be
lost and (b) the number of captures must be the same. These conditions
are permissible because if either is violated, we can guarantee that
analysis of a valid `zirStructDecl` (etc) will never reference this
type (since the ZIR index has just been tracked, and the captures have
just been created based on the ZIR).

Adds a corresponding test case.

Resolves: #21185
This commit is contained in:
mlugg 2024-08-24 13:44:41 +01:00 committed by Matthew Lugg
parent 2d7c26cc66
commit 7d54c62c8a
2 changed files with 23 additions and 3 deletions

View File

@ -3378,7 +3378,6 @@ fn recreateStructType(
} else 0; } else 0;
if (captures_len != key.captures.owned.len) return error.AnalysisFail; if (captures_len != key.captures.owned.len) return error.AnalysisFail;
if (fields_len != struct_obj.field_types.len) return error.AnalysisFail;
// The old type will be unused, so drop its dependency information. // The old type will be unused, so drop its dependency information.
ip.removeDependenciesForDepender(gpa, AnalUnit.wrap(.{ .cau = struct_obj.cau.unwrap().? })); ip.removeDependenciesForDepender(gpa, AnalUnit.wrap(.{ .cau = struct_obj.cau.unwrap().? }));
@ -3466,7 +3465,6 @@ fn recreateUnionType(
} else 0; } else 0;
if (captures_len != key.captures.owned.len) return error.AnalysisFail; if (captures_len != key.captures.owned.len) return error.AnalysisFail;
if (fields_len != union_obj.field_types.len) return error.AnalysisFail;
// The old type will be unused, so drop its dependency information. // The old type will be unused, so drop its dependency information.
ip.removeDependenciesForDepender(gpa, AnalUnit.wrap(.{ .cau = union_obj.cau })); ip.removeDependenciesForDepender(gpa, AnalUnit.wrap(.{ .cau = union_obj.cau }));
@ -3577,7 +3575,6 @@ fn recreateEnumType(
} else 0; } else 0;
if (captures_len != key.captures.owned.len) return error.AnalysisFail; if (captures_len != key.captures.owned.len) return error.AnalysisFail;
if (fields_len != enum_obj.names.len) return error.AnalysisFail;
extra_index += captures_len; extra_index += captures_len;
extra_index += decls_len; extra_index += decls_len;

View File

@ -0,0 +1,23 @@
#target=x86_64-linux
#update=initial version
#file=main.zig
const MyEnum = enum(u8) {
foo = 1,
bar = 2,
};
pub fn main() !void {
try std.io.getStdOut().writer().print("{}\n", .{@intFromEnum(MyEnum.foo)});
}
const std = @import("std");
#expect_stdout="1\n"
#update=remove enum field
#file=main.zig
const MyEnum = enum(u8) {
//foo = 1,
bar = 2,
};
pub fn main() !void {
try std.io.getStdOut().writer().print("{}\n", .{@intFromEnum(MyEnum.foo)});
}
const std = @import("std");
#expect_error=ignored