stage2: struct type field access

master
Vexu 2020-09-09 17:59:13 +03:00
parent 7d910b024b
commit e2cf2e015b
No known key found for this signature in database
GPG Key ID: 59AEB8936E16A6AC
2 changed files with 90 additions and 3 deletions

View File

@ -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

View File

@ -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);
}