diff options
| author | Waffle Lapkin <waffle.lapkin@gmail.com> | 2025-08-04 09:41:08 +0200 |
|---|---|---|
| committer | Waffle Lapkin <waffle.lapkin@gmail.com> | 2025-08-04 11:34:46 +0200 |
| commit | cf7b67420b9927c6154b43bab17917183d931f93 (patch) | |
| tree | ce3978599cc739d615d954cd6848bcf269aaf460 /compiler/rustc_const_eval | |
| parent | e3ed3e0f1c8156b0958c7653f001a8d99d5990f6 (diff) | |
| download | rust-cf7b67420b9927c6154b43bab17917183d931f93.tar.gz rust-cf7b67420b9927c6154b43bab17917183d931f93.zip | |
add `project_fields` helper function
Diffstat (limited to 'compiler/rustc_const_eval')
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/projection.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/visitor.rs | 15 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/lib.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/util/caller_location.rs | 10 |
4 files changed, 22 insertions, 13 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index f72c4418081..d05871bfc77 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -199,6 +199,15 @@ where base.offset_with_meta(offset, OffsetMode::Inbounds, meta, field_layout, self) } + /// Projects multiple fields at once. See [`Self::project_field`] for details. + pub fn project_fields<P: Projectable<'tcx, M::Provenance>, const N: usize>( + &self, + base: &P, + fields: [FieldIdx; N], + ) -> InterpResult<'tcx, [P; N]> { + fields.try_map(|field| self.project_field(base, field)) + } + /// Downcasting to an enum variant. pub fn project_downcast<P: Projectable<'tcx, M::Provenance>>( &self, diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs index a27b6646131..82c50fac6c0 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -121,25 +121,24 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { // `Box` has two fields: the pointer we care about, and the allocator. assert_eq!(v.layout().fields.count(), 2, "`Box` must have exactly 2 fields"); - let (unique_ptr, alloc) = ( - self.ecx().project_field(v, FieldIdx::ZERO)?, - self.ecx().project_field(v, FieldIdx::ONE)?, - ); + let [unique_ptr, alloc] = + self.ecx().project_fields(v, [FieldIdx::ZERO, FieldIdx::ONE])?; + // Unfortunately there is some type junk in the way here: `unique_ptr` is a `Unique`... // (which means another 2 fields, the second of which is a `PhantomData`) assert_eq!(unique_ptr.layout().fields.count(), 2); - let (nonnull_ptr, phantom) = ( - self.ecx().project_field(&unique_ptr, FieldIdx::ZERO)?, - self.ecx().project_field(&unique_ptr, FieldIdx::ONE)?, - ); + let [nonnull_ptr, phantom] = + self.ecx().project_fields(&unique_ptr, [FieldIdx::ZERO, FieldIdx::ONE])?; assert!( phantom.layout().ty.ty_adt_def().is_some_and(|adt| adt.is_phantom_data()), "2nd field of `Unique` should be PhantomData but is {:?}", phantom.layout().ty, ); + // ... that contains a `NonNull`... (gladly, only a single field here) assert_eq!(nonnull_ptr.layout().fields.count(), 1); let raw_ptr = self.ecx().project_field(&nonnull_ptr, FieldIdx::ZERO)?; // the actual raw ptr + // ... whose only field finally is a raw ptr we can dereference. self.visit_box(ty, &raw_ptr)?; diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index bf7a79dcb20..3840cdf7575 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -2,6 +2,7 @@ #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![doc(rust_logo)] +#![feature(array_try_map)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(decl_macro)] diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs index c437934eaab..5249b32eca4 100644 --- a/compiler/rustc_const_eval/src/util/caller_location.rs +++ b/compiler/rustc_const_eval/src/util/caller_location.rs @@ -42,12 +42,12 @@ fn alloc_caller_location<'tcx>( let location = ecx.allocate(loc_layout, MemoryKind::CallerLocation).unwrap(); // Initialize fields. - ecx.write_immediate(filename, &ecx.project_field(&location, FieldIdx::from_u32(0)).unwrap()) - .expect("writing to memory we just allocated cannot fail"); - ecx.write_scalar(line, &ecx.project_field(&location, FieldIdx::from_u32(1)).unwrap()) - .expect("writing to memory we just allocated cannot fail"); - ecx.write_scalar(col, &ecx.project_field(&location, FieldIdx::from_u32(2)).unwrap()) + let [filename_field, line_field, col_field] = + ecx.project_fields(&location, [0, 1, 2].map(FieldIdx::from_u32)).unwrap(); + ecx.write_immediate(filename, &filename_field) .expect("writing to memory we just allocated cannot fail"); + ecx.write_scalar(line, &line_field).expect("writing to memory we just allocated cannot fail"); + ecx.write_scalar(col, &col_field).expect("writing to memory we just allocated cannot fail"); location } |
