authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-08-26 04:11:04+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-09-20 02:29:03+02:00
log497c0d3783c6a11cc64eaff72be050ce09a0ac13
treee2de1b80aba62609c7ed3eb1beeb23323a2caae6
parent64c328a71700608b4cf5a19644f96fe99fbac4dd

Allow x.y when x is a pointer


1 files changed, 61 insertions(+), 38 deletions(-)

src/Sema.zig+61-38
......@@ -8424,21 +8424,32 @@ fn fieldVal(
84248424 }
84258425 },
84268426 .One => {
8427 const elem_ty = object_ty.elemType();
8428 if (elem_ty.zigTypeTag() == .Array) {
8429 if (mem.eql(u8, field_name, "len")) {
8430 return sema.addConstant(
8431 Type.initTag(.comptime_int),
8432 try Value.Tag.int_u64.create(arena, elem_ty.arrayLen()),
8433 );
8434 } else {
8435 return mod.fail(
8436 &block.base,
8437 field_name_src,
8438 "no member named '{s}' in '{}'",
8439 .{ field_name, object_ty },
8440 );
8441 }
8427 const ptr_child = object_ty.elemType();
8428 switch (ptr_child.zigTypeTag()) {
8429 .Array => {
8430 if (mem.eql(u8, field_name, "len")) {
8431 return sema.addConstant(
8432 Type.initTag(.comptime_int),
8433 try Value.Tag.int_u64.create(arena, ptr_child.arrayLen()),
8434 );
8435 } else {
8436 return mod.fail(
8437 &block.base,
8438 field_name_src,
8439 "no member named '{s}' in '{}'",
8440 .{ field_name, object_ty },
8441 );
8442 }
8443 },
8444 .Struct => {
8445 const struct_ptr_deref = try sema.analyzeLoad(block, src, object, object_src);
8446 return sema.unionFieldVal(block, src, struct_ptr_deref, field_name, field_name_src, ptr_child);
8447 },
8448 .Union => {
8449 const union_ptr_deref = try sema.analyzeLoad(block, src, object, object_src);
8450 return sema.unionFieldVal(block, src, union_ptr_deref, field_name, field_name_src, ptr_child);
8451 },
8452 else => {},
84428453 }
84438454 },
84448455 .Many, .C => {},
......@@ -8562,9 +8573,8 @@ fn fieldPtr(
85628573 );
85638574 }
85648575 },
8565 .Pointer => {
8566 const ptr_child = object_ty.elemType();
8567 if (ptr_child.isSlice()) {
8576 .Pointer => switch (object_ty.ptrSize()) {
8577 .Slice => {
85688578 // Here for the ptr and len fields what we need to do is the situation
85698579 // when a temporary has its address taken, e.g. `&a[c..d].len`.
85708580 // This value may be known at compile-time or runtime. In the former
......@@ -8594,26 +8604,39 @@ fn fieldPtr(
85948604 .{ field_name, object_ty },
85958605 );
85968606 }
8597 } else switch (ptr_child.zigTypeTag()) {
8598 .Array => {
8599 if (mem.eql(u8, field_name, "len")) {
8600 var anon_decl = try block.startAnonDecl();
8601 defer anon_decl.deinit();
8602 return sema.analyzeDeclRef(try anon_decl.finish(
8603 Type.initTag(.comptime_int),
8604 try Value.Tag.int_u64.create(anon_decl.arena(), ptr_child.arrayLen()),
8605 ));
8606 } else {
8607 return mod.fail(
8608 &block.base,
8609 field_name_src,
8610 "no member named '{s}' in '{}'",
8611 .{ field_name, object_ty },
8612 );
8613 }
8614 },
8615 else => {},
8616 }
8607 },
8608 .One => {
8609 const ptr_child = object_ty.elemType();
8610 switch (ptr_child.zigTypeTag()) {
8611 .Array => {
8612 if (mem.eql(u8, field_name, "len")) {
8613 var anon_decl = try block.startAnonDecl();
8614 defer anon_decl.deinit();
8615 return sema.analyzeDeclRef(try anon_decl.finish(
8616 Type.initTag(.comptime_int),
8617 try Value.Tag.int_u64.create(anon_decl.arena(), ptr_child.arrayLen()),
8618 ));
8619 } else {
8620 return mod.fail(
8621 &block.base,
8622 field_name_src,
8623 "no member named '{s}' in '{}'",
8624 .{ field_name, object_ty },
8625 );
8626 }
8627 },
8628 .Struct => {
8629 const struct_ptr_deref = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src);
8630 return sema.structFieldPtr(block, src, struct_ptr_deref, field_name, field_name_src, ptr_child);
8631 },
8632 .Union => {
8633 const union_ptr_deref = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src);
8634 return sema.unionFieldPtr(block, src, union_ptr_deref, field_name, field_name_src, ptr_child);
8635 },
8636 else => {},
8637 }
8638 },
8639 .Many, .C => {},
86178640 },
86188641 .Type => {
86198642 _ = try sema.resolveConstValue(block, object_ptr_src, object_ptr);