-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Update InterpCx::project_field
to take FieldIdx
#142103
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
Changes from 1 commit
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 |
---|---|---|
|
@@ -39,6 +39,13 @@ rustc_index::newtype_index! { | |
pub struct FieldIdx {} | ||
} | ||
|
||
impl FieldIdx { | ||
/// The second field. | ||
/// | ||
/// For use alongside [`FieldIdx::ZERO`], particularly with scalar pairs. | ||
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. Why is this not defined near 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. Because all rustc_newtype_index! types get a 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. 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. You can add a 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 generates it as a non-associated constant, though -- like the |
||
pub const ONE: FieldIdx = FieldIdx::from_u32(1); | ||
} | ||
|
||
rustc_index::newtype_index! { | ||
/// The *source-order* index of a variant in a type. | ||
/// | ||
|
@@ -274,7 +281,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { | |
|
||
/// Finds the one field that is not a 1-ZST. | ||
/// Returns `None` if there are multiple non-1-ZST fields or only 1-ZST-fields. | ||
pub fn non_1zst_field<C>(&self, cx: &C) -> Option<(usize, Self)> | ||
pub fn non_1zst_field<C>(&self, cx: &C) -> Option<(FieldIdx, Self)> | ||
where | ||
Ty: TyAbiInterface<'a, C> + Copy, | ||
{ | ||
|
@@ -288,7 +295,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { | |
// More than one non-1-ZST field. | ||
return None; | ||
} | ||
found = Some((field_idx, field)); | ||
found = Some((FieldIdx::from_usize(field_idx), field)); | ||
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 may be worth adding an 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. Yeah, most of the layout-related (Conveniently this one was obvious because a over-4-billion-length array clearly can't have exactly one non-ZST.) |
||
} | ||
found | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
// Not in interpret to make sure we do not use private implementation details | ||
|
||
use rustc_abi::VariantIdx; | ||
use rustc_abi::{FieldIdx, VariantIdx}; | ||
use rustc_middle::query::Key; | ||
use rustc_middle::ty::layout::LayoutOf; | ||
use rustc_middle::ty::{self, Ty, TyCtxt}; | ||
|
@@ -60,7 +60,7 @@ pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>( | |
|
||
let fields_iter = (0..field_count) | ||
.map(|i| { | ||
let field_op = ecx.project_field(&down, i).discard_err()?; | ||
let field_op = ecx.project_field(&down, FieldIdx::from_usize(i)).discard_err()?; | ||
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 could also use a typed field iterator |
||
let val = op_to_const(&ecx, &field_op, /* for diagnostics */ true); | ||
Some((val, field_op.layout.ty)) | ||
}) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
use rustc_abi::{BackendRepr, VariantIdx}; | ||
use rustc_abi::{BackendRepr, FieldIdx, VariantIdx}; | ||
use rustc_data_structures::stack::ensure_sufficient_stack; | ||
use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId, ReportedErrorInfo}; | ||
use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout}; | ||
|
@@ -40,7 +40,7 @@ fn branches<'tcx>( | |
} | ||
|
||
for i in 0..field_count { | ||
let field = ecx.project_field(&place, i).unwrap(); | ||
let field = ecx.project_field(&place, FieldIdx::from_usize(i)).unwrap(); | ||
let valtree = const_to_valtree_inner(ecx, &field, num_nodes)?; | ||
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. And more here (probably not worth pointing them all out) |
||
branches.push(valtree); | ||
} | ||
|
@@ -437,7 +437,7 @@ fn valtree_into_mplace<'tcx>( | |
ty::Str | ty::Slice(_) | ty::Array(..) => { | ||
ecx.project_index(place, i as u64).unwrap() | ||
} | ||
_ => ecx.project_field(&place_adjusted, i).unwrap(), | ||
_ => ecx.project_field(&place_adjusted, FieldIdx::from_usize(i)).unwrap(), | ||
}; | ||
|
||
debug!(?place_inner); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,7 @@ | |
use std::marker::PhantomData; | ||
use std::ops::Range; | ||
|
||
use rustc_abi::{self as abi, Size, VariantIdx}; | ||
use rustc_abi::{self as abi, FieldIdx, Size, VariantIdx}; | ||
use rustc_middle::ty::Ty; | ||
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; | ||
use rustc_middle::{bug, mir, span_bug, ty}; | ||
|
@@ -144,22 +144,22 @@ where | |
/// always possible without allocating, so it can take `&self`. Also return the field's layout. | ||
/// This supports both struct and array fields, but not slices! | ||
/// | ||
/// This also works for arrays, but then the `usize` index type is restricting. | ||
/// For indexing into arrays, use `mplace_index`. | ||
/// This also works for arrays, but then the `FieldIdx` index type is restricting. | ||
/// For indexing into arrays, use [`Self::project_index`]. | ||
pub fn project_field<P: Projectable<'tcx, M::Provenance>>( | ||
&self, | ||
base: &P, | ||
field: usize, | ||
field: FieldIdx, | ||
) -> InterpResult<'tcx, P> { | ||
// Slices nominally have length 0, so they will panic somewhere in `fields.offset`. | ||
debug_assert!( | ||
!matches!(base.layout().ty.kind(), ty::Slice(..)), | ||
"`field` projection called on a slice -- call `index` projection instead" | ||
); | ||
let offset = base.layout().fields.offset(field); | ||
let offset = base.layout().fields.offset(field.as_usize()); | ||
// Computing the layout does normalization, so we get a normalized type out of this | ||
// even if the field type is non-normalized (possible e.g. via associated types). | ||
let field_layout = base.layout().field(self, field); | ||
let field_layout = base.layout().field(self, field.as_usize()); | ||
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. Why does 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 https://doc.rust-lang.org/nightly/nightly-rustc/rustc_abi/struct.TyAndLayout.html#method.field, I think. And that's like I mentioned in #142005 (comment) something that takes |
||
|
||
// Offset may need adjustment for unsized fields. | ||
let (meta, offset) = if field_layout.is_unsized() { | ||
|
@@ -244,7 +244,7 @@ where | |
} | ||
_ => span_bug!( | ||
self.cur_span(), | ||
"`mplace_index` called on non-array type {:?}", | ||
"`project_index` called on non-array type {:?}", | ||
base.layout().ty | ||
), | ||
}; | ||
|
@@ -260,7 +260,7 @@ where | |
) -> InterpResult<'tcx, (P, u64)> { | ||
assert!(base.layout().ty.ty_adt_def().unwrap().repr().simd()); | ||
// SIMD types must be newtypes around arrays, so all we have to do is project to their only field. | ||
let array = self.project_field(base, 0)?; | ||
let array = self.project_field(base, FieldIdx::ZERO)?; | ||
let len = array.len(self)?; | ||
interp_ok((array, len)) | ||
} | ||
|
@@ -384,7 +384,7 @@ where | |
UnwrapUnsafeBinder(target) => base.transmute(self.layout_of(target)?, self)?, | ||
// We don't want anything happening here, this is here as a dummy. | ||
Subtype(_) => base.transmute(base.layout(), self)?, | ||
Field(field, _) => self.project_field(base, field.index())?, | ||
Field(field, _) => self.project_field(base, field)?, | ||
Downcast(_, variant) => self.project_downcast(base, variant)?, | ||
Deref => self.deref_pointer(&base.to_op(self)?)?.into(), | ||
Index(local) => { | ||
|
Uh oh!
There was an error while loading. Please reload this page.