static void TestStructCasts() { PromotedStruct a = new PromotedStruct(); // Addr-exposed, cannot be independent promoted. a.anotherField = 5; a.smallField = 6; Debug.Assert(PromotedStruct.AsNotPromotedStruct(ref a).anotherField == 0x5); // This access will ask LclVariable with type of `PromotedStruct` about the field with offset == 4, that doesn't exist there. Debug.Assert(PromotedStruct.AsNotPromotedStruct(ref a).overlappingField == 0x600000000); a.smallField = 6; Debug.Assert(PromotedStruct.AsNotPromotedStruct(ref a).overlappingField == 0x600000000); PromotedStruct.AsNotPromotedStruct(ref a).overlappingField = 0x700000000; Debug.Assert(a.smallField == 0x7); }
static void TestStructCasts() { PromotedStruct a = new PromotedStruct(); // Addr-exposed, cannot be promoted.promotedField. a.promotedField.pointerSizedField = 4; a.anotherField = 5; NotPromotedStruct b = PromotedStruct.AsNotPromotedStruct(ref a); // The cast can be inlined and the field handle will refer to the `PromotedStruct.pointerSizedField`, // in this case we can promote it because `NotPromotedStruct.notPromotedField.pointerSizedField` has // the same class handle. Debug.Assert(b.notPromotedField.pointerSizedField == 0x4); NotPromotedStruct c = PromotedStruct.AsNotPromotedStruct(ref a); // The cast can be inlined and the field handle will refer to the `PromotedStruct.pointerSizedField`, // in this case we cannot promote it because `NotPromotedStruct.anotherOverlappingStruct.a` has // a different class handle (`NotPromotedStruct.anotherOverlappingStruct`). Debug.Assert(c.anotherOverlappingStruct.a == 0x4); Debug.Assert(c.anotherOverlappingStruct.b == 0x5); }
public static ref NotPromotedStruct AsNotPromotedStruct(ref PromotedStruct d) => ref Unsafe.As <PromotedStruct, NotPromotedStruct>(ref d);