-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Implement Valtree to ConstValue conversion #95976
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
Conversation
Some changes occured to the CTFE / Miri engine cc @rust-lang/miri Some changes occured to the CTFE / Miri engine cc @rust-lang/miri |
Will resolve the conflicts later. CI is irrelevant to this PR, since we don't yet use any of the functionality that is introduced here. |
Hm, the conversion is lossy so we have to be careful about when we do the round-trip. But I also cannot think of a good way to avoid having the back-conversion. :/ That is some unfortunate extra complexity... All non-trivial valtrees will have been constructed from a constant. So maybe we could remember that constant somewhere and just use that for the backconversion? But that sounds like a potentially bad side-channel circumventing query purity... |
I am surprised by |
That doesn't really mention the point that ConstValue is supposed to be removed. We currently already have too many types that all sound almost the same (Const, ConstS, ConstKind, ConstValue) -- valtrees shouldn't make that list any longer.^^ @lcnr wrote
However, I think if valtrees can be converted into a |
For now, moving to just ConstAlloc instead of ConstValue is a too big change to be in one step. We can either dynamically forbid it in MIR and convert everywhere to ConstAlloc as a test, or we can do this PR and add valtrees and then explore that possibility afterwards. I'm slightly in favour of the latter, as the amount of ConstValue is smaller aver valtrees, making such a change easier to review |
can miri also directly work with |
Wouldn't there be problems in the query system if we would convert |
But if this is just a stepping stone, and the plan is still to remove ConstValue later, and most of the work done here will be relevant even after ConstValue removal, then I am happy. :) |
yes, I still don't think we should cache the origin for valtrees so that we don't have to rebuild them later, that's prone to cause unstable query results, leading to ICE or unsoudness |
b66ed4d
to
ee31aaf
Compare
ee31aaf
to
1157dc7
Compare
@RalfJung Since Oli is on vacation, can you maybe review this, please? This is only code that is const-eval related. |
CI is failing... maybe we should teach CI to keep compiling on lint errors but fail only at the end |
This comment has been minimized.
This comment has been minimized.
Sorry, I am traveling for the next 2.5 weeks and won't have much Rust time at all. |
8829cf2
to
37856d4
Compare
@oli-obk Some tests involving statics still fail, this is due to |
This comment has been minimized.
This comment has been minimized.
afba722
to
5faf24f
Compare
Addressed the review and added another recursive call for unsized types that was necessary to correctly handle nested custom DSTs. I agree with your point that ideally we should only have on function for this, but I will try to fix this in a future PR. Also haven't included the depth limit on constants here yet, since this is called in |
This comment has been minimized.
This comment has been minimized.
5faf24f
to
1198729
Compare
Test suite results were as expected. Took the call of |
This comment has been minimized.
This comment has been minimized.
…ested unsized types correctly
1198729
to
ef5f072
Compare
While I was hoping we could leave it in, let's merge this and address the issue with statics in a separate PR @bors r+ |
📌 Commit ef5f072 has been approved by |
☀️ Test successful - checks-actions |
Finished benchmarking commit (b2c2a32): comparison url. Summary:
If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. @rustbot label: -perf-regression Footnotes |
@@ -115,6 +115,12 @@ impl<'tcx, Tag: Provenance> std::ops::Deref for MPlaceTy<'tcx, Tag> { | |||
} | |||
} | |||
|
|||
impl<'tcx, Tag: Provenance> std::ops::DerefMut for MPlaceTy<'tcx, Tag> { | |||
fn deref_mut(&mut self) -> &mut Self::Target { | |||
&mut self.mplace |
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.
Not having mutable access to these fields was a deliberate decision. Why is this needed?
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 think this is just leftover from previous refactorings. I missed that one :/
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.
this is currently made use of here: https://github.com/b-naber/rust/blob/ef5f07256cfa4e1f43a18acb45e0d8108f8471a4/compiler/rustc_const_eval/src/const_eval/valtrees.rs#L227
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 think it'd be better to construct a new MPlaceTy
than change the existing one.
if !ty.is_sized(ecx.tcx, ty::ParamEnv::empty()) { | ||
// We need to create `Allocation`s for custom DSTs | ||
|
||
let (unsized_inner_ty, num_elems) = get_info_on_unsized_field(ty, valtree, tcx); |
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.
If we only need all this to get the size, then maybe it'd make sense to alternatively have a type for a (ValTree, Option<Metadata>)
? That's often what our reference types end up looking like, so it probably makes sense here, too.
OTOH it is true that the valtree should already contain all the info we need, it's just a bit awkward to get it. Do we plan to ever have valtrees for dyn Trait
?
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.
Do we plan to ever have valtrees for
dyn Trait
?
Not at present.
If we only need all this to get the size, then maybe it'd make sense to alternatively have a type for a
(ValTree, Option<Metadata>)
?
you mean an additional variant on ValTree
? This is probably going in the same bucket as the string representation optimization that we'll look into. Until that happens (if ever) we could just add more convenience helpers
intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &place).unwrap(); | ||
|
||
let const_val = match ty.kind() { | ||
ty::Ref(_, _, _) => { |
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.
Given these two match
that special-case Ref
, it might make sense to just make this a separate arm in the top-level match
?
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.
😆 this was intentionally requested by me.
The three calls above and the opt_to_const
were shared and the difference between the arms wasn't very obvious to me, with this change the difference is very obvious.
The first match is actually unnecessary, we can just unconditionally call create_pointee_place
(though it should probably be renamed)
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.
Fair.^^ I wouldn't even expect a lot of commonalities between these arms so having them into one seems a bit forced to me. 🤷
|
||
// FIXME Needs a better/correct name | ||
#[instrument(skip(ecx), level = "debug")] | ||
fn fill_place_recursively<'tcx>( |
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.
This is basically the destination passing style version of valtree_to_const_value
. So what about something like valtree_into_mplace
?
I don't like that this duplicates logic from valtree_to_const_value
FWIW I am not surprised that something like this is required. It should not have a lot of duplication though; looks like that got improved since the comment has been written.
@@ -487,7 +494,8 @@ where | |||
} | |||
|
|||
/// Project into an mplace | |||
pub(super) fn mplace_projection( | |||
#[instrument(skip(self), level = "debug")] | |||
pub(crate) fn mplace_projection( |
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.
Looks like this is not even used after all, and could hence remain private?
Once we start to use
ValTree
s in the type system we will need to be able to convert them intoConstValue
instances, which we want to continue to use after MIR construction.r? @oli-obk
cc @RalfJung