authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-04-15 10:24:18+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-04-15 10:24:18+03:00
log4ef1c1c705ceb2d89d0bf93d7a2403c165ae9dc0
treeb6dd27838bc132121570fe81f4dbbe9b6bcb61f4
parentd66c61a2cf69665223815a1a12a1f93b30b99571

Sema: allow fieldType on optionals and error unions


1 files changed, 31 insertions(+), 15 deletions(-)

src/Sema.zig+31-15
......@@ -13071,22 +13071,38 @@ fn fieldType(
1307113071) CompileError!Air.Inst.Ref {
1307213072 const resolved_ty = try sema.resolveTypeFields(block, ty_src, aggregate_ty);
1307313073 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 '{}'", .{
1308813104 resolved_ty.fmt(target),
13089 }),
13105 });
1309013106 }
1309113107}
1309213108