authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-09-09 17:59:13+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-09-30 16:59:09+03:00
loge2cf2e015bf2afe816593458a3cad9e5baaab095
treecf9c4260ee35687362a4caae4d00ee9427505e0d
parent7d910b024bd47d005030f9f3351e4923b2e0edc0
signature Commit is signed but in an unrecognized format.

stage2: struct type field access


2 files changed, 90 insertions(+), 3 deletions(-)

src/type.zig+75-1
...@@ -441,7 +441,7 @@ pub const Type = extern union {...@@ -441,7 +441,7 @@ pub const Type = extern union {
441 },441 },
442 .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet),442 .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet),
443 .error_set_single => return self.copyPayloadShallow(allocator, Payload.ErrorSetSingle),443 .error_set_single => return self.copyPayloadShallow(allocator, Payload.ErrorSetSingle),
444 .empty_struct => return self.copyPayloadShallow(allocator, Payload.EmptyStruct),444 .empty_struct => return self.copyPayloadShallow(allocator, Payload.EmptyStruct),
445 }445 }
446 }446 }
447447
...@@ -2789,6 +2789,80 @@ pub const Type = extern union {...@@ -2789,6 +2789,80 @@ pub const Type = extern union {
2789 (self.isSinglePointer() and self.elemType().zigTypeTag() == .Array);2789 (self.isSinglePointer() and self.elemType().zigTypeTag() == .Array);
2790 }2790 }
27912791
2792 /// Asserts that the type is a container. (note: ErrorSet is not a container).
2793 pub fn getContainerScope(self: Type) *Module.Scope.Container {
2794 return switch (self.tag()) {
2795 .f16,
2796 .f32,
2797 .f64,
2798 .f128,
2799 .c_longdouble,
2800 .comptime_int,
2801 .comptime_float,
2802 .u8,
2803 .i8,
2804 .u16,
2805 .i16,
2806 .u32,
2807 .i32,
2808 .u64,
2809 .i64,
2810 .usize,
2811 .isize,
2812 .c_short,
2813 .c_ushort,
2814 .c_int,
2815 .c_uint,
2816 .c_long,
2817 .c_ulong,
2818 .c_longlong,
2819 .c_ulonglong,
2820 .bool,
2821 .type,
2822 .anyerror,
2823 .fn_noreturn_no_args,
2824 .fn_void_no_args,
2825 .fn_naked_noreturn_no_args,
2826 .fn_ccc_void_no_args,
2827 .function,
2828 .single_const_pointer_to_comptime_int,
2829 .const_slice_u8,
2830 .c_void,
2831 .void,
2832 .noreturn,
2833 .@"null",
2834 .@"undefined",
2835 .int_unsigned,
2836 .int_signed,
2837 .array,
2838 .array_sentinel,
2839 .array_u8,
2840 .array_u8_sentinel_0,
2841 .single_const_pointer,
2842 .single_mut_pointer,
2843 .many_const_pointer,
2844 .many_mut_pointer,
2845 .const_slice,
2846 .mut_slice,
2847 .optional,
2848 .optional_single_mut_pointer,
2849 .optional_single_const_pointer,
2850 .enum_literal,
2851 .error_union,
2852 .@"anyframe",
2853 .anyframe_T,
2854 .anyerror_void_error_union,
2855 .error_set,
2856 .error_set_single,
2857 .c_const_pointer,
2858 .c_mut_pointer,
2859 .pointer,
2860 => unreachable,
2861
2862 .empty_struct => self.cast(Type.Payload.EmptyStruct).?.scope,
2863 };
2864 }
2865
2792 /// This enum does not directly correspond to `std.builtin.TypeId` because2866 /// This enum does not directly correspond to `std.builtin.TypeId` because
2793 /// it has extra enum tags in it, as a way of using less memory. For example,2867 /// it has extra enum tags in it, as a way of using less memory. For example,
2794 /// even though Zig recognizes `*align(10) i32` and `*i32` both as Pointer types2868 /// even though Zig recognizes `*align(10) i32` and `*i32` both as Pointer types
src/zir_sema.zig+15-2
...@@ -1048,6 +1048,19 @@ fn analyzeInstFieldPtr(mod: *Module, scope: *Scope, fieldptr: *zir.Inst.FieldPtr...@@ -1048,6 +1048,19 @@ fn analyzeInstFieldPtr(mod: *Module, scope: *Scope, fieldptr: *zir.Inst.FieldPtr
1048 .val = Value.initPayload(&ref_payload.base),1048 .val = Value.initPayload(&ref_payload.base),
1049 });1049 });
1050 },1050 },
1051 .Struct => {
1052 const container_scope = child_type.getContainerScope();
1053 if (mod.lookupDeclName(&container_scope.base, field_name)) |decl| {
1054 // TODO if !decl.is_pub and inDifferentFiles() "{} is private"
1055 return mod.analyzeDeclRef(scope, fieldptr.base.src, decl);
1056 }
1057
1058 if (&container_scope.file_scope.base == mod.root_scope) {
1059 return mod.fail(scope, fieldptr.base.src, "root source file has no member called '{}'", .{field_name});
1060 } else {
1061 return mod.fail(scope, fieldptr.base.src, "container '{}' has no member called '{}'", .{ child_type, field_name });
1062 }
1063 },
1051 else => return mod.fail(scope, fieldptr.base.src, "type '{}' does not support field access", .{child_type}),1064 else => return mod.fail(scope, fieldptr.base.src, "type '{}' does not support field access", .{child_type}),
1052 }1065 }
1053 },1066 },
...@@ -1203,8 +1216,8 @@ fn analyzeInstImport(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerErr...@@ -1203,8 +1216,8 @@ fn analyzeInstImport(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerErr
1203 },1216 },
1204 else => {1217 else => {
1205 // TODO user friendly error to string1218 // TODO user friendly error to string
1206 return mod.fail(scope, inst.base.src, "unable to open '{}': {}", .{operand, @errorName(err)});1219 return mod.fail(scope, inst.base.src, "unable to open '{}': {}", .{ operand, @errorName(err) });
1207 }1220 },
1208 };1221 };
1209 return mod.constType(scope, inst.base.src, file_scope.root_container.ty);1222 return mod.constType(scope, inst.base.src, file_scope.root_container.ty);
1210}1223}