-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
const_eval: Consider array length constant even if array is not #99594
Conversation
Some changes occurred to the CTFE / Miri engine cc @rust-lang/miri |
r? @jackh726 (rust-highfive has picked a reviewer for you, use r? to override) |
250e961
to
c5b1678
Compare
So is this reasonable code now allowed? fn main() {
let a = [1_u32, 2, 3];
let b = [0; a.len()];
} |
No, this PR should only affect constant propagation for the purposes of optimization and lints. (Ok, maybe the title is a bit misleading.) In particular, your code already fails a step earlier: accessing fn main() {
let a = [1_u32, 2, 3];
let b = [0; { a; 3 }];
} |
let mplace = self.force_allocation(&src)?; | ||
let len = mplace.len(self)?; | ||
self.write_scalar(Scalar::from_machine_usize(len, self), &dest)?; | ||
if let &ty::Array(_, len) = src.layout.ty.kind() { |
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 doesn't look right. It is certainly not right without extensive comments explaining what is happening and why the old code is wrong.
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.
It's a fast path that does the right thing (codegen does this opt after all or mir opts do it for codegen).
I wonder if this has any effect on miri at all (the force alloc will just happen later?). If there is no benefit to miri, we should just teach const prop about the Len Rvalue
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.
Miri shouldn't usually have fast paths though. We want to catch all the UB, not take any shortcuts. ;)
However, OpTy
also has a len
method these days, so I think a patch could be made that avoids force_allocation
. That sounds like a good idea. I don't know if it helps ConstProp though.
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.
Miri shouldn't usually have fast paths though. We want to catch all the UB, not take any shortcuts. ;)
Ok, that makes sense.
However,
OpTy
also has alen
method these days, so I think a patch could be made that avoidsforce_allocation
. That sounds like a good idea. I don't know if it helps ConstProp though.
I did some testing, and using OpTy
doesn't seem to help ConstProp.
If there is no benefit to miri, we should just teach const prop about the Len Rvalue.
There's two ConstProps: const_prop
and const_prop_lint
(since #94934). I guess this should be added to both?
And should I force-push this PR, or open a new one? Changing this one might make the existing discussion a bit confusing for future readers.
(sorry for the delay)
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.
The issue you want to fix is about the lint, so const_prop_lint is the most relevant one.
I did some testing, and using OpTy doesn't seem to help ConstProp.
Ah, place_to_op will still want to read the local and that is where ConstProp bails.
Sorry, but I don't think we want to have changes in the @oli-obk has plans for making ConstProp independent of the interpreter. That is the right way to fix these problems. |
One may try to change the N.B. It may be not the only place where some information (type level constant in array's case) is lost |
@@ -251,9 +252,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |||
|
|||
Len(place) => { | |||
let src = self.eval_place(place)?; |
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.
You should be able to do src.place_to_op(src)?
, which will give you a OpTy
, and then call len
on that. That would avoid force_allocation
.
Closing in favour of #100160 (wow 6 digits). |
Fixes #98444.