-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ty/print: pretty-print constant aggregates (arrays, tuples and ADTs). #71232
Conversation
src/test/mir-opt/match_false_edges/rustc.full_tested_match.PromoteTemps.after.mir
Show resolved
Hide resolved
How would |
@RalfJung Presumably |
|
@RalfJung There's no information loss, strictly speaking (it can only be If you want the full dump of the value, we could gate that on e.g. |
- _3 = std::option::Option::<bool>::Some(const true,); // bb0[3]: scope 0 at $DIR/discriminant.rs:6:34: 6:44 | ||
+ _3 = const {transmute(0x01): std::option::Option<bool>}; // bb0[3]: scope 0 at $DIR/discriminant.rs:6:34: 6:44 | ||
- _3 = std::option::Option::<bool>::Some(const true); // bb0[3]: scope 0 at $DIR/discriminant.rs:6:34: 6:44 | ||
+ _3 = const std::option::Option::<bool>::Some(true); // bb0[3]: scope 0 at $DIR/discriminant.rs:6:34: 6:44 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see, yeah I got confused by the double-diff here... makes sense.
Eh, what? 2 is an invalid value for |
@RalfJung You asked about |
Ah, maybe it was me. If we could test it somehow, I'd be glad to make |
Damn, somehow I thought 2 was an invalid value for this type. |
@RalfJung AFAIK, If we want to retain the |
I see. Miri itself won't ICE on bad discriminants, it will raise an |
// NB: the `has_param_types_or_consts` check ensures that we can use | ||
// the `destructure_const` query with an empty `ty::ParamEnv` without | ||
// introducing ICEs (e.g. via `layout_of`) from missing bounds. | ||
// E.g. `transmute([0usize; 2]): (u8, *mut T)` needs to know `T: Sized` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this happen at all? Const evaluation must already have had to know the type in order to produce a ConstValue
. While the type may still be generic, in case of polymorphic const eval working out because of e.g. PhantomData<T>
being a known ZST irrelevant of the type, any layout_of
calls we do during destructure_const
should also figure this out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*mut T
has a known layout irrespective of T
as long as T: Sized
is in the ParamEnv
, that's why I used it as an example. You can use size_of::<*mut T>()
as an explicit discriminant of an enum
, for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, but here we already have a ConstValue
, which must have gone through some monomorphic evaluation at some point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, there is nothing requiring monomorphic const-eval, and I have this example to prove it (I made that to prove a point in #70453).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess your point is that the constant's type can't have type parameters? Sorry, I was getting turned around. const
generics/array lengths shouldn't hit this.
So this could only be a problem with printing MIR after constant-folding something that uses type parameters but doesn't depend on them layout-wise.
Riiight, which is why I was thinking MIR printing could create a FmtPrinter
with a ParamEnv
.
We can't really end up with such broken constants via the The PR is pretty neat. Quite verbose when compared with normal debug printing of certain types (e.g. @bors r+ |
📌 Commit eccb28e has been approved by |
☀️ Test successful - checks-azure |
Oddly enough, we don't have any UI tests showing this off in types, only
mir-opt
tests.However, the pretty form should show up in the test output diff of #71018, if this PR is merged first.
Examples of before/after:
Option<bool>
{transmute(0x01): std::option::Option<bool>}
std::option::Option::<bool>::Some(true)
RawVec<u32>
ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), undef_mask: UndefMask { blocks: [65535], len: Size { raw: 16 } }, size: Size { raw: 16 }, align: Align { pow2: 3 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }: alloc::raw_vec::RawVec::<u32>
alloc::raw_vec::RawVec::<u32> { ptr: std::ptr::Unique::<u32> { pointer: {0x4 as *const u32}, _marker: std::marker::PhantomData::<u32> }, cap: 0usize, alloc: std::alloc::Global }
This PR is a prerequisite for #61486, sort of, in that we need to be able to pretty-print values in order to even consider how we might mangle them.
We still don't have pretty-printing for constants of reference types, @oli-obk has the necessary support logic in a PR but I didn't want to interfere with that.
Each commit should be reviewed separately, as I've fixed a couple deficiencies along the way.
r? @oli-obk cc @rust-lang/wg-mir-opt @varkor @yodaldevoid