diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/type.zig | 76 | ||||
| -rw-r--r-- | src/zir_sema.zig | 17 |
2 files changed, 90 insertions, 3 deletions
diff --git a/src/type.zig b/src/type.zig index bcce9d6edd..c22edaa561 100644 --- a/src/type.zig +++ b/src/type.zig @@ -441,7 +441,7 @@ pub const Type = extern union { }, .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet), .error_set_single => return self.copyPayloadShallow(allocator, Payload.ErrorSetSingle), - .empty_struct => return self.copyPayloadShallow(allocator, Payload.EmptyStruct), + .empty_struct => return self.copyPayloadShallow(allocator, Payload.EmptyStruct), } } @@ -2789,6 +2789,80 @@ pub const Type = extern union { (self.isSinglePointer() and self.elemType().zigTypeTag() == .Array); } + /// Asserts that the type is a container. (note: ErrorSet is not a container). + pub fn getContainerScope(self: Type) *Module.Scope.Container { + return switch (self.tag()) { + .f16, + .f32, + .f64, + .f128, + .c_longdouble, + .comptime_int, + .comptime_float, + .u8, + .i8, + .u16, + .i16, + .u32, + .i32, + .u64, + .i64, + .usize, + .isize, + .c_short, + .c_ushort, + .c_int, + .c_uint, + .c_long, + .c_ulong, + .c_longlong, + .c_ulonglong, + .bool, + .type, + .anyerror, + .fn_noreturn_no_args, + .fn_void_no_args, + .fn_naked_noreturn_no_args, + .fn_ccc_void_no_args, + .function, + .single_const_pointer_to_comptime_int, + .const_slice_u8, + .c_void, + .void, + .noreturn, + .@"null", + .@"undefined", + .int_unsigned, + .int_signed, + .array, + .array_sentinel, + .array_u8, + .array_u8_sentinel_0, + .single_const_pointer, + .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .const_slice, + .mut_slice, + .optional, + .optional_single_mut_pointer, + .optional_single_const_pointer, + .enum_literal, + .error_union, + .@"anyframe", + .anyframe_T, + .anyerror_void_error_union, + .error_set, + .error_set_single, + .c_const_pointer, + .c_mut_pointer, + .pointer, + => unreachable, + + .empty_struct => self.cast(Type.Payload.EmptyStruct).?.scope, + }; + } + /// This enum does not directly correspond to `std.builtin.TypeId` because /// it has extra enum tags in it, as a way of using less memory. For example, /// even though Zig recognizes `*align(10) i32` and `*i32` both as Pointer types diff --git a/src/zir_sema.zig b/src/zir_sema.zig index 4ba8d1e431..d02c21ec47 100644 --- a/src/zir_sema.zig +++ b/src/zir_sema.zig @@ -1048,6 +1048,19 @@ fn analyzeInstFieldPtr(mod: *Module, scope: *Scope, fieldptr: *zir.Inst.FieldPtr .val = Value.initPayload(&ref_payload.base), }); }, + .Struct => { + const container_scope = child_type.getContainerScope(); + if (mod.lookupDeclName(&container_scope.base, field_name)) |decl| { + // TODO if !decl.is_pub and inDifferentFiles() "{} is private" + return mod.analyzeDeclRef(scope, fieldptr.base.src, decl); + } + + if (&container_scope.file_scope.base == mod.root_scope) { + return mod.fail(scope, fieldptr.base.src, "root source file has no member called '{}'", .{field_name}); + } else { + return mod.fail(scope, fieldptr.base.src, "container '{}' has no member called '{}'", .{ child_type, field_name }); + } + }, else => return mod.fail(scope, fieldptr.base.src, "type '{}' does not support field access", .{child_type}), } }, @@ -1203,8 +1216,8 @@ fn analyzeInstImport(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerErr }, else => { // TODO user friendly error to string - return mod.fail(scope, inst.base.src, "unable to open '{}': {}", .{operand, @errorName(err)}); - } + return mod.fail(scope, inst.base.src, "unable to open '{}': {}", .{ operand, @errorName(err) }); + }, }; return mod.constType(scope, inst.base.src, file_scope.root_container.ty); } |
