| ... | ... | @@ -13071,22 +13071,38 @@ fn fieldType( |
| 13071 | 13071 | ) CompileError!Air.Inst.Ref { |
| 13072 | 13072 | const resolved_ty = try sema.resolveTypeFields(block, ty_src, aggregate_ty); |
| 13073 | 13073 | const target = sema.mod.getTarget(); |
| 13074 | | switch (resolved_ty.zigTypeTag()) { |
| 13075 | | .Struct => { |
| 13076 | | const struct_obj = resolved_ty.castTag(.@"struct").?.data; |
| 13077 | | const field = struct_obj.fields.get(field_name) orelse |
| 13078 | | return sema.failWithBadStructFieldAccess(block, struct_obj, field_src, field_name); |
| 13079 | | return sema.addType(field.ty); |
| 13080 | | }, |
| 13081 | | .Union => { |
| 13082 | | const union_obj = resolved_ty.cast(Type.Payload.Union).?.data; |
| 13083 | | const field = union_obj.fields.get(field_name) orelse |
| 13084 | | return sema.failWithBadUnionFieldAccess(block, union_obj, field_src, field_name); |
| 13085 | | return sema.addType(field.ty); |
| 13086 | | }, |
| 13087 | | else => return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{ |
| 13074 | var cur_ty = resolved_ty; |
| 13075 | while (true) { |
| 13076 | switch (cur_ty.zigTypeTag()) { |
| 13077 | .Struct => { |
| 13078 | const struct_obj = cur_ty.castTag(.@"struct").?.data; |
| 13079 | const field = struct_obj.fields.get(field_name) orelse |
| 13080 | return sema.failWithBadStructFieldAccess(block, struct_obj, field_src, field_name); |
| 13081 | return sema.addType(field.ty); |
| 13082 | }, |
| 13083 | .Union => { |
| 13084 | const union_obj = cur_ty.cast(Type.Payload.Union).?.data; |
| 13085 | const field = union_obj.fields.get(field_name) orelse |
| 13086 | return sema.failWithBadUnionFieldAccess(block, union_obj, field_src, field_name); |
| 13087 | return sema.addType(field.ty); |
| 13088 | }, |
| 13089 | .Optional => { |
| 13090 | if (cur_ty.castTag(.optional)) |some| { |
| 13091 | // Struct/array init through optional requires the child type to not be a pointer. |
| 13092 | // If the child of .optional is a pointer it'll error on the next loop. |
| 13093 | cur_ty = some.data; |
| 13094 | continue; |
| 13095 | } |
| 13096 | }, |
| 13097 | .ErrorUnion => { |
| 13098 | cur_ty = cur_ty.errorUnionPayload(); |
| 13099 | continue; |
| 13100 | }, |
| 13101 | else => {}, |
| 13102 | } |
| 13103 | return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{ |
| 13088 | 13104 | resolved_ty.fmt(target), |
| 13089 | | }), |
| 13105 | }); |
| 13090 | 13106 | } |
| 13091 | 13107 | } |
| 13092 | 13108 | |