Support ADT types in type info reflection#151142
Support ADT types in type info reflection#151142SpriteOvO wants to merge 5 commits intorust-lang:mainfrom
Conversation
|
|
1bd8449 to
0b20893
Compare
| sym::name => { | ||
| if let Some(name) = name { | ||
| let name_place = self.allocate_str_dedup(name.as_str())?; | ||
| let ptr = self.mplace_to_ref(&name_place)?; | ||
| self.write_immediate(*ptr, &field_place)? | ||
| } else { | ||
| let (variant, _) = self.downcast(&field_place, sym::None)?; | ||
| self.write_discriminant(variant, &field_place)?; | ||
| } | ||
| } |
There was a problem hiding this comment.
I feel like I should write sym::Some discriminant for name? 🤔 Writing ptr directly seems to work, but this relies on how Option<&'static str> is underlyingly represented IIUC.
But const eval interpreter doesn't complain about this -- perhaps it should?
There was a problem hiding this comment.
the interpreter doesn't care if the value is exactly the same as if it had its discriminant written. There is some talk about SetDiscriminant needing to happen always, but it's not really important for us here, this will be fixed by whoever changes it
also irrelevant if we make the field just always have a name (rendering the index)
This comment has been minimized.
This comment has been minimized.
| sym::name => { | ||
| if let Some(name) = name { | ||
| let name_place = self.allocate_str_dedup(name.as_str())?; | ||
| let ptr = self.mplace_to_ref(&name_place)?; | ||
| self.write_immediate(*ptr, &field_place)? | ||
| } else { | ||
| let (variant, _) = self.downcast(&field_place, sym::None)?; | ||
| self.write_discriminant(variant, &field_place)?; | ||
| } | ||
| } |
There was a problem hiding this comment.
the interpreter doesn't care if the value is exactly the same as if it had its discriminant written. There is some talk about SetDiscriminant needing to happen always, but it's not really important for us here, this will be fixed by whoever changes it
also irrelevant if we make the field just always have a name (rendering the index)
This comment has been minimized.
This comment has been minimized.
0b20893 to
e50e5d9
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
e50e5d9 to
0b7ff30
Compare
|
Is there anything missing from this PR / is there some way I could help? @SpriteOvO |
|
I've almost finished it locally, but there's still some cleanup and rebasing I need to do before it's ready for review. Just been a bit busy lately. |
|
@SpriteOvO Btw traits are already done in the other PR and unions / methods seem out of scope of ADTs so consider omiting them from this PR |
c5e6c84 to
f0ae098
Compare
This comment has been minimized.
This comment has been minimized.
f0ae098 to
ffabe32
Compare
| assert!(ty.fields[2].ty != TypeId::of::<&'static u16>()); // FIXME(type_info): should be == | ||
| assert!(ty.fields[2].offset == 0); // FIXME(type_info): should be == offset_of!(TestStruct, reference) | ||
| } |
There was a problem hiding this comment.
This is wrong. I'll look into it tomorrow.
The other parts is ready for review.
There was a problem hiding this comment.
Okay, so the offset == 0 is correct, since the fields are reordered for layout optimization.
It's still weird that the TypeId of &'static u16 are not equal. I made a debugging example:
let at_const_block = const {
struct TestStruct {
first: u8,
second: u16,
reference: &'static u16,
}
let Type { kind: Struct(ty), size, .. } = Type::of::<TestStruct>() else { panic!() };
assert!(size == Some(size_of::<TestStruct>()));
assert!(!ty.non_exhaustive);
assert!(ty.fields.len() == 3);
assert!(ty.fields[0].name == "first");
assert!(ty.fields[0].ty == TypeId::of::<u8>());
assert!(ty.fields[0].offset == offset_of!(TestStruct, first));
assert!(ty.fields[1].name == "second");
assert!(ty.fields[1].ty == TypeId::of::<u16>());
assert!(ty.fields[1].offset == offset_of!(TestStruct, second));
assert!(ty.fields[2].name == "reference");
assert!(ty.fields[2].ty != TypeId::of::<&'static u16>()); // FIXME(type_info): should be ==
assert!(ty.fields[2].offset == offset_of!(TestStruct, reference));
(ty.fields[2].ty, TypeId::of::<&'static u16>())
};
let at_runtime = TypeId::of::<&'static u16>();
eprintln!("runtime: {at_runtime:?}");
eprintln!("const: {at_const_block:?}");
assert_eq!(at_runtime, at_const_block.0);
assert_eq!(at_runtime, at_const_block.1);All assertions in this example are succeeded, no assertion failed, for both runtime and compile-time. Outputs:
runtime: TypeId(0x9e1edc294606897cc59b170c3a16c732)
const: (TypeId(0x9e1edc294606897cc59b170c3a16c732), TypeId(0x9e1edc294606897cc59b170c3a16c732))
I also add a debugging print to compiler when writing the type ID for fields, outputs:
u8 = 596b48cc04376e64d5c788c2aa46bdb
u16 = c50c4a8d8e150aa67101203f1fab1cd7
&'static u16 = 9e1edc294606897cc59b170c3a16c732
All outputs of &'static u16 type ID are the same, but the assertion ty.fields[2].ty != TypeId::of::<&'static u16>() passed in const block. I'm confused about what happened.
Any idea?
There was a problem hiding this comment.
More minimal:
struct TestStruct {
reference: &'static u16,
}
let ret = const {
let Type { kind: Struct(ty), .. } = Type::of::<TestStruct>() else { panic!() };
let ret = (ty.fields[0].ty, TypeId::of::<&'static u16>());
assert!(ret.0 != ret.1); // FIXME(type_info): should be ==
ret
};
assert_eq!(ret.0, ret.1);
This comment has been minimized.
This comment has been minimized.
ffabe32 to
5fb36fd
Compare
Tracking issue: #146922
#![feature(type_info)]This PR supports ADT types for feature
type_inforeflection.(It's still a draft PR, with implementation in progress)
Note that this PR does not take SemVer into consideration (I left a FIXME comment). As discussed earlier (comment), this requires further discussion. However, I hope we could get an initial implementation to land first, so we can start playing with it.
Progress / Checklist
MethodsImplemented and to be implemented in other PRsTraitsImplemented and to be implemented in other PRsmainbranch(It's currently based on PR Support primitives in type info reflection #151123, so here's an extra commit)r? @oli-obk