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(...@@ -13071,22 +13071,38 @@ fn fieldType(
13071) CompileError!Air.Inst.Ref {13071) CompileError!Air.Inst.Ref {
13072 const resolved_ty = try sema.resolveTypeFields(block, ty_src, aggregate_ty);13072 const resolved_ty = try sema.resolveTypeFields(block, ty_src, aggregate_ty);
13073 const target = sema.mod.getTarget();13073 const target = sema.mod.getTarget();
13074 switch (resolved_ty.zigTypeTag()) {13074 var cur_ty = resolved_ty;
13075 .Struct => {13075 while (true) {
13076 const struct_obj = resolved_ty.castTag(.@"struct").?.data;13076 switch (cur_ty.zigTypeTag()) {
13077 const field = struct_obj.fields.get(field_name) orelse13077 .Struct => {
13078 return sema.failWithBadStructFieldAccess(block, struct_obj, field_src, field_name);13078 const struct_obj = cur_ty.castTag(.@"struct").?.data;
13079 return sema.addType(field.ty);13079 const field = struct_obj.fields.get(field_name) orelse
13080 },13080 return sema.failWithBadStructFieldAccess(block, struct_obj, field_src, field_name);
13081 .Union => {13081 return sema.addType(field.ty);
13082 const union_obj = resolved_ty.cast(Type.Payload.Union).?.data;13082 },
13083 const field = union_obj.fields.get(field_name) orelse13083 .Union => {
13084 return sema.failWithBadUnionFieldAccess(block, union_obj, field_src, field_name);13084 const union_obj = cur_ty.cast(Type.Payload.Union).?.data;
13085 return sema.addType(field.ty);13085 const field = union_obj.fields.get(field_name) orelse
13086 },13086 return sema.failWithBadUnionFieldAccess(block, union_obj, field_src, field_name);
13087 else => return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{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 resolved_ty.fmt(target),13104 resolved_ty.fmt(target),
13089 }),13105 });
13090 }13106 }
13091}13107}
1309213108