Rollup merge of #65592 - RalfJung:const-prop-comment, r=wesleywiser
clarify const_prop ICE protection comment This is based on discussion at https://github.com/rust-lang/rust/pull/64890/files#r334555787. That said, why are function arguments the only unsized locals that could remain uninitialized? Couldn't we also fail to initialize some local but still go on with const_prop, and then hit a line that takes a reference to that? Cc @wesleywiser @oli-obk ; I don't know enough about const-prop to understand why this can happen only for function arguments. ~~The PR includes https://github.com/rust-lang/rust/pull/64890; the only new commit is 05e4e6ba0d5.~~
This commit is contained in:
commit
f8d1c3589e
1 changed files with 14 additions and 11 deletions
|
@ -518,27 +518,30 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// Work around: avoid ICE in miri.
|
||||
// FIXME(wesleywiser) we don't currently handle the case where we try to make a ref
|
||||
// from a function argument that hasn't been assigned to in this function. The main
|
||||
// issue is if an arg is a fat-pointer, miri `expects()` to be able to read the value
|
||||
// of that pointer to get size info. However, since this is `ConstProp`, that argument
|
||||
// doesn't actually have a backing value and so this causes an ICE.
|
||||
// Work around: avoid ICE in miri. FIXME(wesleywiser)
|
||||
// The Miri engine ICEs when taking a reference to an uninitialized unsized
|
||||
// local. There's nothing it can do here: taking a reference needs an allocation
|
||||
// which needs to know the size. Normally that's okay as during execution
|
||||
// (e.g. for CTFE) it can never happen. But here in const_prop
|
||||
// unknown data is uninitialized, so if e.g. a function argument is unsized
|
||||
// and has a reference taken, we get an ICE.
|
||||
Rvalue::Ref(_, _, Place { base: PlaceBase::Local(local), projection: box [] }) => {
|
||||
trace!("checking Ref({:?})", place);
|
||||
let alive =
|
||||
if let LocalValue::Live(_) = self.ecx.frame().locals[*local].value {
|
||||
true
|
||||
} else { false };
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if local.as_usize() <= self.ecx.frame().body.arg_count && !alive {
|
||||
trace!("skipping Ref({:?})", place);
|
||||
if !alive {
|
||||
trace!("skipping Ref({:?}) to uninitialized local", place);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
// Work around: avoid extra unnecessary locals.
|
||||
// FIXME(wesleywiser): const eval will turn this into a `const Scalar(<ZST>)` that
|
||||
// Work around: avoid extra unnecessary locals. FIXME(wesleywiser)
|
||||
// Const eval will turn this into a `const Scalar(<ZST>)` that
|
||||
// `SimplifyLocals` doesn't know it can remove.
|
||||
Rvalue::Aggregate(_, operands) if operands.len() == 0 => {
|
||||
return None;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue