aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2021-08-26 04:11:04 +0200
committerRobin Voetter <robin@voetter.nl>2021-09-20 02:29:03 +0200
commit497c0d3783c6a11cc64eaff72be050ce09a0ac13 (patch)
treee2de1b80aba62609c7ed3eb1beeb23323a2caae6 /src
parent64c328a71700608b4cf5a19644f96fe99fbac4dd (diff)
downloadzig-497c0d3783c6a11cc64eaff72be050ce09a0ac13.tar.gz
zig-497c0d3783c6a11cc64eaff72be050ce09a0ac13.zip
Allow x.y when x is a pointer
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig99
1 files changed, 61 insertions, 38 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index e0a085a010..9426c0caec 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -8424,21 +8424,32 @@ fn fieldVal(
}
},
.One => {
- const elem_ty = object_ty.elemType();
- if (elem_ty.zigTypeTag() == .Array) {
- if (mem.eql(u8, field_name, "len")) {
- return sema.addConstant(
- Type.initTag(.comptime_int),
- try Value.Tag.int_u64.create(arena, elem_ty.arrayLen()),
- );
- } else {
- return mod.fail(
- &block.base,
- field_name_src,
- "no member named '{s}' in '{}'",
- .{ field_name, object_ty },
- );
- }
+ const ptr_child = object_ty.elemType();
+ switch (ptr_child.zigTypeTag()) {
+ .Array => {
+ if (mem.eql(u8, field_name, "len")) {
+ return sema.addConstant(
+ Type.initTag(.comptime_int),
+ try Value.Tag.int_u64.create(arena, ptr_child.arrayLen()),
+ );
+ } else {
+ return mod.fail(
+ &block.base,
+ field_name_src,
+ "no member named '{s}' in '{}'",
+ .{ field_name, object_ty },
+ );
+ }
+ },
+ .Struct => {
+ const struct_ptr_deref = try sema.analyzeLoad(block, src, object, object_src);
+ return sema.unionFieldVal(block, src, struct_ptr_deref, field_name, field_name_src, ptr_child);
+ },
+ .Union => {
+ const union_ptr_deref = try sema.analyzeLoad(block, src, object, object_src);
+ return sema.unionFieldVal(block, src, union_ptr_deref, field_name, field_name_src, ptr_child);
+ },
+ else => {},
}
},
.Many, .C => {},
@@ -8562,9 +8573,8 @@ fn fieldPtr(
);
}
},
- .Pointer => {
- const ptr_child = object_ty.elemType();
- if (ptr_child.isSlice()) {
+ .Pointer => switch (object_ty.ptrSize()) {
+ .Slice => {
// Here for the ptr and len fields what we need to do is the situation
// when a temporary has its address taken, e.g. `&a[c..d].len`.
// This value may be known at compile-time or runtime. In the former
@@ -8594,26 +8604,39 @@ fn fieldPtr(
.{ field_name, object_ty },
);
}
- } else switch (ptr_child.zigTypeTag()) {
- .Array => {
- if (mem.eql(u8, field_name, "len")) {
- var anon_decl = try block.startAnonDecl();
- defer anon_decl.deinit();
- return sema.analyzeDeclRef(try anon_decl.finish(
- Type.initTag(.comptime_int),
- try Value.Tag.int_u64.create(anon_decl.arena(), ptr_child.arrayLen()),
- ));
- } else {
- return mod.fail(
- &block.base,
- field_name_src,
- "no member named '{s}' in '{}'",
- .{ field_name, object_ty },
- );
- }
- },
- else => {},
- }
+ },
+ .One => {
+ const ptr_child = object_ty.elemType();
+ switch (ptr_child.zigTypeTag()) {
+ .Array => {
+ if (mem.eql(u8, field_name, "len")) {
+ var anon_decl = try block.startAnonDecl();
+ defer anon_decl.deinit();
+ return sema.analyzeDeclRef(try anon_decl.finish(
+ Type.initTag(.comptime_int),
+ try Value.Tag.int_u64.create(anon_decl.arena(), ptr_child.arrayLen()),
+ ));
+ } else {
+ return mod.fail(
+ &block.base,
+ field_name_src,
+ "no member named '{s}' in '{}'",
+ .{ field_name, object_ty },
+ );
+ }
+ },
+ .Struct => {
+ const struct_ptr_deref = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src);
+ return sema.structFieldPtr(block, src, struct_ptr_deref, field_name, field_name_src, ptr_child);
+ },
+ .Union => {
+ const union_ptr_deref = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src);
+ return sema.unionFieldPtr(block, src, union_ptr_deref, field_name, field_name_src, ptr_child);
+ },
+ else => {},
+ }
+ },
+ .Many, .C => {},
},
.Type => {
_ = try sema.resolveConstValue(block, object_ptr_src, object_ptr);