diff options
| author | Ralf Jung <post@ralfj.de> | 2023-08-27 18:12:34 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2023-08-29 09:03:46 +0200 |
| commit | b2ebf1c23f93886ba7d3738878f04e275add4ead (patch) | |
| tree | 78fd882aab805988388cbb4d3ead89ba112b23c7 /compiler/rustc_const_eval/src | |
| parent | bf91321e0fc9cb9cd921263ac473c5255dc8cc14 (diff) | |
| download | rust-b2ebf1c23f93886ba7d3738878f04e275add4ead.tar.gz rust-b2ebf1c23f93886ba7d3738878f04e275add4ead.zip | |
const_eval and codegen: audit uses of is_zst
Diffstat (limited to 'compiler/rustc_const_eval/src')
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/cast.rs | 20 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/operand.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/terminator.rs | 8 |
3 files changed, 17 insertions, 12 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 98e853dc4d9..25c74b98611 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -410,21 +410,25 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.unsize_into_ptr(src, dest, *s, *c) } (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => { - assert_eq!(def_a, def_b); + assert_eq!(def_a, def_b); // implies same number of fields - // unsizing of generic struct with pointer fields - // Example: `Arc<T>` -> `Arc<Trait>` - // here we need to increase the size of every &T thin ptr field to a fat ptr + // Unsizing of generic struct with pointer fields, like `Arc<T>` -> `Arc<Trait>`. + // There can be extra fields as long as they don't change their type or are 1-ZST. + // There might also be no field that actually needs unsizing. + let mut found_cast_field = false; for i in 0..src.layout.fields.count() { let cast_ty_field = cast_ty.field(self, i); - if cast_ty_field.is_zst() { - continue; - } let src_field = self.project_field(src, i)?; let dst_field = self.project_field(dest, i)?; - if src_field.layout.ty == cast_ty_field.ty { + if src_field.layout.is_1zst() && cast_ty_field.is_1zst() { + // Skip 1-ZST fields. + } else if src_field.layout.ty == cast_ty_field.ty { self.copy_op(&src_field, &dst_field, /*allow_transmute*/ false)?; } else { + if found_cast_field { + span_bug!(self.cur_span(), "unsize_into: more than one field to cast"); + } + found_cast_field = true; self.unsize_into(&src_field, cast_ty_field, &dst_field)?; } } diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 6e57a56b445..443d3c10871 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -239,6 +239,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { // if the entire value is uninit, then so is the field (can happen in ConstProp) (Immediate::Uninit, _) => Immediate::Uninit, // the field contains no information, can be left uninit + // (Scalar/ScalarPair can contain even aligned ZST, not just 1-ZST) _ if layout.is_zst() => Immediate::Uninit, // some fieldless enum variants can have non-zero size but still `Aggregate` ABI... try // to detect those here and also give them no data diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 42a2fb0330c..f3c38e363de 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -684,15 +684,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } _ => { // Not there yet, search for the only non-ZST field. + // (The rules for `DispatchFromDyn` ensure there's exactly one such field.) let mut non_zst_field = None; for i in 0..receiver.layout.fields.count() { let field = self.project_field(&receiver, i)?; - let zst = - field.layout.is_zst() && field.layout.align.abi.bytes() == 1; + let zst = field.layout.is_1zst(); if !zst { assert!( non_zst_field.is_none(), - "multiple non-ZST fields in dyn receiver type {}", + "multiple non-1-ZST fields in dyn receiver type {}", receiver.layout.ty ); non_zst_field = Some(field); @@ -700,7 +700,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } receiver = non_zst_field.unwrap_or_else(|| { panic!( - "no non-ZST fields in dyn receiver type {}", + "no non-1-ZST fields in dyn receiver type {}", receiver.layout.ty ) }); |
