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(...@@ -8424,21 +8424,32 @@ fn fieldVal(
8424 }8424 }
8425 },8425 },
8426 .One => {8426 .One => {
8427 const elem_ty = object_ty.elemType();8427 const ptr_child = object_ty.elemType();
8428 if (elem_ty.zigTypeTag() == .Array) {8428 switch (ptr_child.zigTypeTag()) {
8429 if (mem.eql(u8, field_name, "len")) {8429 .Array => {
8430 return sema.addConstant(8430 if (mem.eql(u8, field_name, "len")) {
8431 Type.initTag(.comptime_int),8431 return sema.addConstant(
8432 try Value.Tag.int_u64.create(arena, elem_ty.arrayLen()),8432 Type.initTag(.comptime_int),
8433 );8433 try Value.Tag.int_u64.create(arena, ptr_child.arrayLen()),
8434 } else {8434 );
8435 return mod.fail(8435 } else {
8436 &block.base,8436 return mod.fail(
8437 field_name_src,8437 &block.base,
8438 "no member named '{s}' in '{}'",8438 field_name_src,
8439 .{ field_name, object_ty },8439 "no member named '{s}' in '{}'",
8440 );8440 .{ field_name, object_ty },
8441 }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 => {},
8442 }8453 }
8443 },8454 },
8444 .Many, .C => {},8455 .Many, .C => {},
...@@ -8562,9 +8573,8 @@ fn fieldPtr(...@@ -8562,9 +8573,8 @@ fn fieldPtr(
8562 );8573 );
8563 }8574 }
8564 },8575 },
8565 .Pointer => {8576 .Pointer => switch (object_ty.ptrSize()) {
8566 const ptr_child = object_ty.elemType();8577 .Slice => {
8567 if (ptr_child.isSlice()) {
8568 // Here for the ptr and len fields what we need to do is the situation8578 // Here for the ptr and len fields what we need to do is the situation
8569 // when a temporary has its address taken, e.g. `&a[c..d].len`.8579 // when a temporary has its address taken, e.g. `&a[c..d].len`.
8570 // This value may be known at compile-time or runtime. In the former8580 // This value may be known at compile-time or runtime. In the former
...@@ -8594,26 +8604,39 @@ fn fieldPtr(...@@ -8594,26 +8604,39 @@ fn fieldPtr(
8594 .{ field_name, object_ty },8604 .{ field_name, object_ty },
8595 );8605 );
8596 }8606 }
8597 } else switch (ptr_child.zigTypeTag()) {8607 },
8598 .Array => {8608 .One => {
8599 if (mem.eql(u8, field_name, "len")) {8609 const ptr_child = object_ty.elemType();
8600 var anon_decl = try block.startAnonDecl();8610 switch (ptr_child.zigTypeTag()) {
8601 defer anon_decl.deinit();8611 .Array => {
8602 return sema.analyzeDeclRef(try anon_decl.finish(8612 if (mem.eql(u8, field_name, "len")) {
8603 Type.initTag(.comptime_int),8613 var anon_decl = try block.startAnonDecl();
8604 try Value.Tag.int_u64.create(anon_decl.arena(), ptr_child.arrayLen()),8614 defer anon_decl.deinit();
8605 ));8615 return sema.analyzeDeclRef(try anon_decl.finish(
8606 } else {8616 Type.initTag(.comptime_int),
8607 return mod.fail(8617 try Value.Tag.int_u64.create(anon_decl.arena(), ptr_child.arrayLen()),
8608 &block.base,8618 ));
8609 field_name_src,8619 } else {
8610 "no member named '{s}' in '{}'",8620 return mod.fail(
8611 .{ field_name, object_ty },8621 &block.base,
8612 );8622 field_name_src,
8613 }8623 "no member named '{s}' in '{}'",
8614 },8624 .{ field_name, object_ty },
8615 else => {},8625 );
8616 }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 => {},
8617 },8640 },
8618 .Type => {8641 .Type => {
8619 _ = try sema.resolveConstValue(block, object_ptr_src, object_ptr);8642 _ = try sema.resolveConstValue(block, object_ptr_src, object_ptr);