| ... | @@ -2316,7 +2316,7 @@ fn validateStructInit( | ... | @@ -2316,7 +2316,7 @@ fn validateStructInit( |
| 2316 | const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data; | 2316 | const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data; |
| 2317 | const field_name = sema.code.nullTerminatedString(field_ptr_extra.field_name_start); | 2317 | const field_name = sema.code.nullTerminatedString(field_ptr_extra.field_name_start); |
| 2318 | const field_index = struct_obj.fields.getIndex(field_name) orelse | 2318 | const field_index = struct_obj.fields.getIndex(field_name) orelse |
| 2319 | return sema.failWithBadFieldAccess(block, struct_obj, field_src, field_name); | 2319 | return sema.failWithBadStructFieldAccess(block, struct_obj, field_src, field_name); |
| 2320 | if (found_fields[field_index] != 0) { | 2320 | if (found_fields[field_index] != 0) { |
| 2321 | const other_field_ptr = found_fields[field_index]; | 2321 | const other_field_ptr = found_fields[field_index]; |
| 2322 | const other_field_ptr_data = sema.code.instructions.items(.data)[other_field_ptr].pl_node; | 2322 | const other_field_ptr_data = sema.code.instructions.items(.data)[other_field_ptr].pl_node; |
| ... | @@ -2378,7 +2378,32 @@ fn zirValidateArrayInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil | ... | @@ -2378,7 +2378,32 @@ fn zirValidateArrayInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil |
| 2378 | } | 2378 | } |
| 2379 | } | 2379 | } |
| 2380 | | 2380 | |
| 2381 | fn failWithBadFieldAccess( | 2381 | fn failWithBadMemberAccess( |
| | 2382 | sema: *Sema, |
| | 2383 | block: *Block, |
| | 2384 | agg_ty: Type, |
| | 2385 | field_src: LazySrcLoc, |
| | 2386 | field_name: []const u8, |
| | 2387 | ) CompileError { |
| | 2388 | const kw_name = switch (agg_ty.zigTypeTag()) { |
| | 2389 | .Union => "union", |
| | 2390 | .Struct => "struct", |
| | 2391 | .Opaque => "opaque", |
| | 2392 | .Enum => "enum", |
| | 2393 | else => unreachable, |
| | 2394 | }; |
| | 2395 | const msg = msg: { |
| | 2396 | const msg = try sema.errMsg(block, field_src, "{s} '{}' has no member named '{s}'", .{ |
| | 2397 | kw_name, agg_ty, field_name, |
| | 2398 | }); |
| | 2399 | errdefer msg.destroy(sema.gpa); |
| | 2400 | try sema.addDeclaredHereNote(msg, agg_ty); |
| | 2401 | break :msg msg; |
| | 2402 | }; |
| | 2403 | return sema.failWithOwnedErrorMsg(msg); |
| | 2404 | } |
| | 2405 | |
| | 2406 | fn failWithBadStructFieldAccess( |
| 2382 | sema: *Sema, | 2407 | sema: *Sema, |
| 2383 | block: *Block, | 2408 | block: *Block, |
| 2384 | struct_obj: *Module.Struct, | 2409 | struct_obj: *Module.Struct, |
| ... | @@ -8828,7 +8853,7 @@ fn zirStructInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_ref: bool) | ... | @@ -8828,7 +8853,7 @@ fn zirStructInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_ref: bool) |
| 8828 | const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data; | 8853 | const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data; |
| 8829 | const field_name = sema.code.nullTerminatedString(field_type_extra.name_start); | 8854 | const field_name = sema.code.nullTerminatedString(field_type_extra.name_start); |
| 8830 | const field_index = struct_obj.fields.getIndex(field_name) orelse | 8855 | const field_index = struct_obj.fields.getIndex(field_name) orelse |
| 8831 | return sema.failWithBadFieldAccess(block, struct_obj, field_src, field_name); | 8856 | return sema.failWithBadStructFieldAccess(block, struct_obj, field_src, field_name); |
| 8832 | if (found_fields[field_index] != 0) { | 8857 | if (found_fields[field_index] != 0) { |
| 8833 | const other_field_type = found_fields[field_index]; | 8858 | const other_field_type = found_fields[field_index]; |
| 8834 | const other_field_type_data = zir_datas[other_field_type].pl_node; | 8859 | const other_field_type_data = zir_datas[other_field_type].pl_node; |
| ... | @@ -9037,7 +9062,7 @@ fn zirFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -9037,7 +9062,7 @@ fn zirFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 9037 | .Struct => { | 9062 | .Struct => { |
| 9038 | const struct_obj = resolved_ty.castTag(.@"struct").?.data; | 9063 | const struct_obj = resolved_ty.castTag(.@"struct").?.data; |
| 9039 | const field = struct_obj.fields.get(field_name) orelse | 9064 | const field = struct_obj.fields.get(field_name) orelse |
| 9040 | return sema.failWithBadFieldAccess(block, struct_obj, src, field_name); | 9065 | return sema.failWithBadStructFieldAccess(block, struct_obj, src, field_name); |
| 9041 | return sema.addType(field.ty); | 9066 | return sema.addType(field.ty); |
| 9042 | }, | 9067 | }, |
| 9043 | .Union => { | 9068 | .Union => { |
| ... | @@ -10859,7 +10884,7 @@ fn fieldVal( | ... | @@ -10859,7 +10884,7 @@ fn fieldVal( |
| 10859 | }, | 10884 | }, |
| 10860 | else => {}, | 10885 | else => {}, |
| 10861 | } | 10886 | } |
| 10862 | return sema.fail(block, src, "type '{}' does not support field access (fieldVal, {}.{s})", .{object_ty, object_ty, field_name}); | 10887 | return sema.fail(block, src, "type '{}' does not support field access (fieldVal, {}.{s})", .{ object_ty, object_ty, field_name }); |
| 10863 | } | 10888 | } |
| 10864 | | 10889 | |
| 10865 | fn fieldPtr( | 10890 | fn fieldPtr( |
| ... | @@ -11001,22 +11026,24 @@ fn fieldPtr( | ... | @@ -11001,22 +11026,24 @@ fn fieldPtr( |
| 11001 | try Value.Tag.@"error".create(anon_decl.arena(), .{ .name = name }), | 11026 | try Value.Tag.@"error".create(anon_decl.arena(), .{ .name = name }), |
| 11002 | )); | 11027 | )); |
| 11003 | }, | 11028 | }, |
| 11004 | .Struct, .Opaque, .Union => { | 11029 | .Union => { |
| 11005 | if (child_type.getNamespace()) |namespace| { | 11030 | if (child_type.getNamespace()) |namespace| { |
| 11006 | if (try sema.namespaceLookupRef(block, src, namespace, field_name)) |inst| { | 11031 | if (try sema.namespaceLookupRef(block, src, namespace, field_name)) |inst| { |
| 11007 | return inst; | 11032 | return inst; |
| 11008 | } | 11033 | } |
| 11009 | } | 11034 | } |
| 11010 | // TODO add note: declared here | 11035 | if (child_type.unionTagType()) |enum_ty| { |
| 11011 | const kw_name = switch (child_type.zigTypeTag()) { | 11036 | if (enum_ty.enumFieldIndex(field_name)) |field_index| { |
| 11012 | .Struct => "struct", | 11037 | const field_index_u32 = @intCast(u32, field_index); |
| 11013 | .Opaque => "opaque", | 11038 | var anon_decl = try block.startAnonDecl(); |
| 11014 | .Union => "union", | 11039 | defer anon_decl.deinit(); |
| 11015 | else => unreachable, | 11040 | return sema.analyzeDeclRef(try anon_decl.finish( |
| 11016 | }; | 11041 | try enum_ty.copy(anon_decl.arena()), |
| 11017 | return sema.fail(block, src, "{s} '{}' has no member named '{s}'", .{ | 11042 | try Value.Tag.enum_field_index.create(anon_decl.arena(), field_index_u32), |
| 11018 | kw_name, child_type, field_name, | 11043 | )); |
| 11019 | }); | 11044 | } |
| | 11045 | } |
| | 11046 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); |
| 11020 | }, | 11047 | }, |
| 11021 | .Enum => { | 11048 | .Enum => { |
| 11022 | if (child_type.getNamespace()) |namespace| { | 11049 | if (child_type.getNamespace()) |namespace| { |
| ... | @@ -11025,23 +11052,7 @@ fn fieldPtr( | ... | @@ -11025,23 +11052,7 @@ fn fieldPtr( |
| 11025 | } | 11052 | } |
| 11026 | } | 11053 | } |
| 11027 | const field_index = child_type.enumFieldIndex(field_name) orelse { | 11054 | const field_index = child_type.enumFieldIndex(field_name) orelse { |
| 11028 | const msg = msg: { | 11055 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); |
| 11029 | const msg = try sema.errMsg( | | |
| 11030 | block, | | |
| 11031 | src, | | |
| 11032 | "enum '{}' has no member named '{s}'", | | |
| 11033 | .{ child_type, field_name }, | | |
| 11034 | ); | | |
| 11035 | errdefer msg.destroy(sema.gpa); | | |
| 11036 | try sema.mod.errNoteNonLazy( | | |
| 11037 | child_type.declSrcLoc(), | | |
| 11038 | msg, | | |
| 11039 | "enum declared here", | | |
| 11040 | .{}, | | |
| 11041 | ); | | |
| 11042 | break :msg msg; | | |
| 11043 | }; | | |
| 11044 | return sema.failWithOwnedErrorMsg(msg); | | |
| 11045 | }; | 11056 | }; |
| 11046 | const field_index_u32 = @intCast(u32, field_index); | 11057 | const field_index_u32 = @intCast(u32, field_index); |
| 11047 | var anon_decl = try block.startAnonDecl(); | 11058 | var anon_decl = try block.startAnonDecl(); |
| ... | @@ -11051,6 +11062,14 @@ fn fieldPtr( | ... | @@ -11051,6 +11062,14 @@ fn fieldPtr( |
| 11051 | try Value.Tag.enum_field_index.create(anon_decl.arena(), field_index_u32), | 11062 | try Value.Tag.enum_field_index.create(anon_decl.arena(), field_index_u32), |
| 11052 | )); | 11063 | )); |
| 11053 | }, | 11064 | }, |
| | 11065 | .Struct, .Opaque => { |
| | 11066 | if (child_type.getNamespace()) |namespace| { |
| | 11067 | if (try sema.namespaceLookupRef(block, src, namespace, field_name)) |inst| { |
| | 11068 | return inst; |
| | 11069 | } |
| | 11070 | } |
| | 11071 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); |
| | 11072 | }, |
| 11054 | else => return sema.fail(block, src, "type '{}' has no members", .{child_type}), | 11073 | else => return sema.fail(block, src, "type '{}' has no members", .{child_type}), |
| 11055 | } | 11074 | } |
| 11056 | }, | 11075 | }, |
| ... | @@ -11070,7 +11089,7 @@ fn fieldPtr( | ... | @@ -11070,7 +11089,7 @@ fn fieldPtr( |
| 11070 | }, | 11089 | }, |
| 11071 | else => {}, | 11090 | else => {}, |
| 11072 | } | 11091 | } |
| 11073 | return sema.fail(block, src, "type '{}' does not support field access (fieldPtr, {}.{s})", .{object_ty, object_ptr_ty, field_name}); | 11092 | return sema.fail(block, src, "type '{}' does not support field access (fieldPtr, {}.{s})", .{ object_ty, object_ptr_ty, field_name }); |
| 11074 | } | 11093 | } |
| 11075 | | 11094 | |
| 11076 | fn fieldCallBind( | 11095 | fn fieldCallBind( |
| ... | @@ -11242,7 +11261,7 @@ fn structFieldPtr( | ... | @@ -11242,7 +11261,7 @@ fn structFieldPtr( |
| 11242 | const struct_obj = struct_ty.castTag(.@"struct").?.data; | 11261 | const struct_obj = struct_ty.castTag(.@"struct").?.data; |
| 11243 | | 11262 | |
| 11244 | const field_index_big = struct_obj.fields.getIndex(field_name) orelse | 11263 | const field_index_big = struct_obj.fields.getIndex(field_name) orelse |
| 11245 | return sema.failWithBadFieldAccess(block, struct_obj, field_name_src, field_name); | 11264 | return sema.failWithBadStructFieldAccess(block, struct_obj, field_name_src, field_name); |
| 11246 | const field_index = @intCast(u32, field_index_big); | 11265 | const field_index = @intCast(u32, field_index_big); |
| 11247 | const field = struct_obj.fields.values()[field_index]; | 11266 | const field = struct_obj.fields.values()[field_index]; |
| 11248 | const ptr_field_ty = try Type.ptr(arena, .{ | 11267 | const ptr_field_ty = try Type.ptr(arena, .{ |
| ... | @@ -11279,10 +11298,9 @@ fn structFieldVal( | ... | @@ -11279,10 +11298,9 @@ fn structFieldVal( |
| 11279 | const struct_ty = try sema.resolveTypeFields(block, src, unresolved_struct_ty); | 11298 | const struct_ty = try sema.resolveTypeFields(block, src, unresolved_struct_ty); |
| 11280 | const struct_obj = struct_ty.castTag(.@"struct").?.data; | 11299 | const struct_obj = struct_ty.castTag(.@"struct").?.data; |
| 11281 | | 11300 | |
| 11282 | const field_index_big = struct_obj.fields.getIndex(field_name) orelse | 11301 | const field_index_usize = struct_obj.fields.getIndex(field_name) orelse |
| 11283 | return sema.failWithBadFieldAccess(block, struct_obj, field_name_src, field_name); | 11302 | return sema.failWithBadStructFieldAccess(block, struct_obj, field_name_src, field_name); |
| 11284 | const field_index = @intCast(u32, field_index_big); | 11303 | const field_index = @intCast(u32, field_index_usize); |
| 11285 | | | |
| 11286 | const field = struct_obj.fields.values()[field_index]; | 11304 | const field = struct_obj.fields.values()[field_index]; |
| 11287 | | 11305 | |
| 11288 | if (try sema.resolveMaybeUndefVal(block, src, struct_byval)) |struct_val| { | 11306 | if (try sema.resolveMaybeUndefVal(block, src, struct_byval)) |struct_val| { |
| ... | @@ -13168,6 +13186,10 @@ pub fn resolveTypeLayout( | ... | @@ -13168,6 +13186,10 @@ pub fn resolveTypeLayout( |
| 13168 | } | 13186 | } |
| 13169 | union_obj.status = .have_layout; | 13187 | union_obj.status = .have_layout; |
| 13170 | }, | 13188 | }, |
| | 13189 | .Array => { |
| | 13190 | const elem_ty = ty.childType(); |
| | 13191 | return sema.resolveTypeLayout(block, src, elem_ty); |
| | 13192 | }, |
| 13171 | else => {}, | 13193 | else => {}, |
| 13172 | } | 13194 | } |
| 13173 | } | 13195 | } |