-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Fix an ICE encountered in clippy that will be possible to trigger in rustc in the future #61041
Changes from 2 commits
16911bd
d38fb10
b535090
e849b83
600d679
27320e3
b84ed30
7fac3a1
8ac4cb5
fe2013c
1d26fda
b917c43
5a8c9d3
faa342f
51e1343
034939b
685e0e5
fdf5450
3afcb1e
f0a16c4
3aa550a
82db274
70124ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -291,8 +291,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |
ty.is_freeze(*self.tcx, self.param_env, DUMMY_SP) | ||
} | ||
|
||
/// Call this whenever you have a value that `needs_subst`. Not guaranteed to actually | ||
/// monomorphize the value. If we are e.g. const propagating inside a generic function, some | ||
/// Call this whenever you have a value that you took from the current frame's `mir::Body`. | ||
/// Not guaranteed to actually monomorphize the value. | ||
/// If we are e.g. const propagating inside a generic function, some | ||
/// things may depend on a generic parameter and thus can never be monomorphized. | ||
pub(super) fn subst_and_normalize_erasing_regions_in_frame<T: TypeFoldable<'tcx>>( | ||
&self, | ||
|
@@ -304,7 +305,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |
/// Same thing as `subst_and_normalize_erasing_regions_in_frame` but not taking its substs | ||
/// from the top stack frame, but requiring you to pass specific substs. | ||
/// | ||
/// Only call this function if you want to compute the substs of a specific frame (that is | ||
/// Only call this function if you want to apply the substs of a specific frame (that is | ||
/// definitely not the frame currently being evaluated). You need to make sure to pass correct | ||
/// substs. | ||
fn subst_and_normalize_erasing_regions<T: TypeFoldable<'tcx>>( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function shouldn't be needed (as a separate thing). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's needed for layout_of_local There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd inline it there. |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ | |
|
||
use std::convert::TryInto; | ||
|
||
use rustc::{mir, ty}; | ||
use rustc::{mir, ty::{self, Ty}}; | ||
use rustc::ty::layout::{ | ||
self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt, VariantIdx, | ||
}; | ||
|
@@ -511,7 +511,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |
Move(ref place) => | ||
self.eval_place_to_op(place, layout)?, | ||
|
||
Constant(ref constant) => self.eval_const_to_op(constant.literal, layout)?, | ||
Constant(ref constant) => { | ||
let val = self.subst_and_normalize_erasing_regions_in_frame(constant.literal.val)?; | ||
let ty = self.subst_and_normalize_erasing_regions_in_frame(constant.ty)?; | ||
self.eval_const_to_op(val, ty, layout)? | ||
}, | ||
}; | ||
trace!("{:?}: {:?}", mir_op, *op); | ||
Ok(op) | ||
|
@@ -531,14 +535,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |
// in patterns via the `const_eval` module | ||
crate fn eval_const_to_op( | ||
&self, | ||
val: &'tcx ty::Const<'tcx>, | ||
value: ConstValue<'tcx>, | ||
ty: Ty<'tcx>, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a HACK/FIXME comment. Or even better, wait for #56137 to be fixed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is, rebase this on top of #63495. |
||
layout: Option<TyLayout<'tcx>>, | ||
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { | ||
let tag_scalar = |scalar| match scalar { | ||
Scalar::Ptr(ptr) => Scalar::Ptr(self.tag_static_base_pointer(ptr)), | ||
Scalar::Raw { data, size } => Scalar::Raw { data, size }, | ||
}; | ||
let value = self.subst_and_normalize_erasing_regions_in_frame(val.val)?; | ||
// Early-return cases. | ||
match value { | ||
ConstValue::Param(_) => throw_inval!(TooGeneric), | ||
|
@@ -552,13 +556,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |
_ => {} | ||
} | ||
// Other cases need layout. | ||
let layout = from_known_layout(layout, || { | ||
// Substituting is not a cached or O(1) operation. Substituting the type happens here, | ||
// which may not happen if we already have a layout. Or if we use the early abort above. | ||
// Thus we do not substitute and normalize `val` above, but only `val.val` and then | ||
// substitute `val.ty` here. | ||
self.layout_of(self.subst_and_normalize_erasing_regions_in_frame(val.ty)?) | ||
})?; | ||
let layout = from_known_layout(layout, || self.layout_of(ty))?; | ||
let op = match value { | ||
ConstValue::ByRef { alloc, offset } => { | ||
let id = self.tcx.alloc_map.lock().create_memory_alloc(alloc); | ||
|
@@ -586,7 +584,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |
ConstValue::Infer(..) | | ||
ConstValue::Placeholder(..) | | ||
ConstValue::Unevaluated(..) => | ||
bug!("eval_const_to_op: Unexpected ConstValue {:?}", val), | ||
bug!("eval_const_to_op: Unexpected ConstValue {:?}", value), | ||
}; | ||
Ok(OpTy { op, layout }) | ||
} | ||
|
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.
@RalfJung came up with
subst_from_frame_and_normalize_erasing_regions
, I kinda like that more?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.
In particular this finally made it click for me in terms of: we need this when taking something from the current frame to move it into the
InterpCx
"universe".Also see the comments I wrote for my own experiments here and here; I think it would be useful to carry those over.