diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-02-03 23:57:05 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-02-03 23:59:32 -0700 |
| commit | 95fbce2b958395a367a82ce33170edd93e686173 (patch) | |
| tree | dae1e68036754591c53b71571d5b12b3b2f33539 /src | |
| parent | 64f7231f86d4b8a155f48087b3f173d8e41b620c (diff) | |
| download | zig-95fbce2b958395a367a82ce33170edd93e686173.tar.gz zig-95fbce2b958395a367a82ce33170edd93e686173.zip | |
Sema: fixes to fieldVal, resolveStructFully, Type.eql
fieldVal handles pointer to pointer to array. This can happen for
example, if a pointer to an array is used as the condition expression of
a for loop.
resolveStructFully handles tuples (by doing nothing).
fixed Type comparison for tuples to handle comptime fields properly.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Sema.zig | 62 | ||||
| -rw-r--r-- | src/type.zig | 14 |
2 files changed, 53 insertions, 23 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 7666b2c9ec..c4b3ad8c33 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -12998,7 +12998,7 @@ fn fieldVal( .Array => { if (mem.eql(u8, field_name, "len")) { return sema.addConstant( - Type.initTag(.comptime_int), + Type.comptime_int, try Value.Tag.int_u64.create(arena, inner_ty.arrayLen()), ); } else { @@ -13010,26 +13010,43 @@ fn fieldVal( ); } }, - .Pointer => if (inner_ty.isSlice()) { - if (mem.eql(u8, field_name, "ptr")) { - const slice = if (is_pointer_to) - try sema.analyzeLoad(block, src, object, object_src) - else - object; - return sema.analyzeSlicePtr(block, src, slice, inner_ty, object_src); - } else if (mem.eql(u8, field_name, "len")) { - const slice = if (is_pointer_to) - try sema.analyzeLoad(block, src, object, object_src) - else - object; - return sema.analyzeSliceLen(block, src, slice); - } else { - return sema.fail( - block, - field_name_src, - "no member named '{s}' in '{}'", - .{ field_name, object_ty }, - ); + .Pointer => { + const ptr_info = inner_ty.ptrInfo().data; + if (ptr_info.size == .Slice) { + if (mem.eql(u8, field_name, "ptr")) { + const slice = if (is_pointer_to) + try sema.analyzeLoad(block, src, object, object_src) + else + object; + return sema.analyzeSlicePtr(block, src, slice, inner_ty, object_src); + } else if (mem.eql(u8, field_name, "len")) { + const slice = if (is_pointer_to) + try sema.analyzeLoad(block, src, object, object_src) + else + object; + return sema.analyzeSliceLen(block, src, slice); + } else { + return sema.fail( + block, + field_name_src, + "no member named '{s}' in '{}'", + .{ field_name, object_ty }, + ); + } + } else if (ptr_info.pointee_type.zigTypeTag() == .Array) { + if (mem.eql(u8, field_name, "len")) { + return sema.addConstant( + Type.comptime_int, + try Value.Tag.int_u64.create(arena, ptr_info.pointee_type.arrayLen()), + ); + } else { + return sema.fail( + block, + field_name_src, + "no member named '{s}' in '{}'", + .{ field_name, ptr_info.pointee_type }, + ); + } } }, .Type => { @@ -16371,7 +16388,8 @@ fn resolveStructFully( try resolveStructLayout(sema, block, src, ty); const resolved_ty = try sema.resolveTypeFields(block, src, ty); - const struct_obj = resolved_ty.castTag(.@"struct").?.data; + const payload = resolved_ty.castTag(.@"struct") orelse return; + const struct_obj = payload.data; switch (struct_obj.status) { .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {}, .fully_resolved_wip, .fully_resolved => return, diff --git a/src/type.zig b/src/type.zig index 272d09a921..e3a4b3d60a 100644 --- a/src/type.zig +++ b/src/type.zig @@ -634,7 +634,19 @@ pub const Type = extern union { for (a_payload.data.values) |a_val, i| { const ty = a_payload.data.types[i]; const b_val = b_payload.data.values[i]; - if (!Value.eql(a_val, b_val, ty)) return false; + if (a_val.tag() == .unreachable_value) { + if (b_val.tag() == .unreachable_value) { + continue; + } else { + return false; + } + } else { + if (b_val.tag() == .unreachable_value) { + return false; + } else { + if (!Value.eql(a_val, b_val, ty)) return false; + } + } } return true; |
