diff options
| author | Eduard-Mihai Burtescu <eddyb@lyken.rs> | 2021-08-25 18:05:10 +0300 |
|---|---|---|
| committer | Eduard-Mihai Burtescu <eddyb@lyken.rs> | 2021-08-30 00:44:09 +0300 |
| commit | 8e6d126b7d69281072f16dcc3cfff140e8947c58 (patch) | |
| tree | 293ebfbe26edb8e4baf22cec93eb517f2f1c6714 /compiler | |
| parent | 87d1fb747f8ed3dde3cd36c17d1ef735872a7bf9 (diff) | |
| download | rust-8e6d126b7d69281072f16dcc3cfff140e8947c58.tar.gz rust-8e6d126b7d69281072f16dcc3cfff140e8947c58.zip | |
rustc_target: `TyAndLayout::field` should never error.
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/block.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/layout.rs | 101 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/cast.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/eval_context.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/operand.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/place.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/terminator.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/mod.rs | 17 |
10 files changed, 77 insertions, 77 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs index c471da83de2..95216f1c3d7 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs @@ -160,12 +160,10 @@ impl<'tcx> DebugContext<'tcx> { for (field_idx, field_def) in variant.fields.iter().enumerate() { let field_offset = layout.fields.offset(field_idx); - let field_layout = layout - .field( - &layout::LayoutCx { tcx: self.tcx, param_env: ParamEnv::reveal_all() }, - field_idx, - ) - .unwrap(); + let field_layout = layout.field( + &layout::LayoutCx { tcx: self.tcx, param_env: ParamEnv::reveal_all() }, + field_idx, + ); let field_type = self.dwarf_ty(field_layout.ty); diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 1c4d307fc50..12f61e0c564 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -789,7 +789,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( return; } - if intrinsic == sym::assert_zero_valid && !layout.might_permit_raw_init(fx, /*zero:*/ true).unwrap() { + if intrinsic == sym::assert_zero_valid && !layout.might_permit_raw_init(fx, /*zero:*/ true) { with_no_trimmed_paths(|| crate::base::codegen_panic( fx, &format!("attempted to zero-initialize type `{}`, which is invalid", T), @@ -798,7 +798,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( return; } - if intrinsic == sym::assert_uninit_valid && !layout.might_permit_raw_init(fx, /*zero:*/ false).unwrap() { + if intrinsic == sym::assert_uninit_valid && !layout.might_permit_raw_init(fx, /*zero:*/ false) { with_no_trimmed_paths(|| crate::base::codegen_panic( fx, &format!("attempted to leave type `{}` uninitialized, which is invalid", T), diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 673d348a2a8..2a76ad0fb13 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -472,10 +472,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let layout = bx.layout_of(ty); let do_panic = match intrinsic { Inhabited => layout.abi.is_uninhabited(), - // We unwrap as the error type is `!`. - ZeroValid => !layout.might_permit_raw_init(bx, /*zero:*/ true).unwrap(), - // We unwrap as the error type is `!`. - UninitValid => !layout.might_permit_raw_init(bx, /*zero:*/ false).unwrap(), + ZeroValid => !layout.might_permit_raw_init(bx, /*zero:*/ true), + UninitValid => !layout.might_permit_raw_init(bx, /*zero:*/ false), }; if do_panic { let msg_str = with_no_trimmed_paths(|| { diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index df5e6b2da99..6822df0e50d 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1788,22 +1788,18 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let field_info: Vec<_> = flds .iter() .enumerate() - .map(|(i, &name)| match layout.field(self, i) { - Err(err) => { - bug!("no layout found for field {}: `{:?}`", name, err); + .map(|(i, &name)| { + let field_layout = layout.field(self, i); + let offset = layout.fields.offset(i); + let field_end = offset + field_layout.size; + if min_size < field_end { + min_size = field_end; } - Ok(field_layout) => { - let offset = layout.fields.offset(i); - let field_end = offset + field_layout.size; - if min_size < field_end { - min_size = field_end; - } - FieldInfo { - name: name.to_string(), - offset: offset.bytes(), - size: field_layout.size.bytes(), - align: field_layout.align.abi.bytes(), - } + FieldInfo { + name: name.to_string(), + offset: offset.bytes(), + size: field_layout.size.bytes(), + align: field_layout.align.abi.bytes(), } }) .collect(); @@ -2146,30 +2142,24 @@ where TyAndLayout { ty: this.ty, layout } } - fn ty_and_layout_field(this: TyAndLayout<'tcx>, cx: &C, i: usize) -> C::TyAndLayout { - enum TyMaybeWithLayout<'tcx, C: LayoutOf<'tcx>> { - Ty(C::Ty), - TyAndLayout(C::TyAndLayout), + fn ty_and_layout_field(this: TyAndLayout<'tcx>, cx: &C, i: usize) -> TyAndLayout<'tcx> { + enum TyMaybeWithLayout<'tcx> { + Ty(Ty<'tcx>), + TyAndLayout(TyAndLayout<'tcx>), } - fn ty_and_layout_kind< - C: LayoutOf<'tcx, Ty = Ty<'tcx>> + HasTyCtxt<'tcx> + HasParamEnv<'tcx>, - >( + fn field_ty_or_layout( this: TyAndLayout<'tcx>, - cx: &C, + cx: &(impl HasTyCtxt<'tcx> + HasParamEnv<'tcx>), i: usize, - ty: C::Ty, - ) -> TyMaybeWithLayout<'tcx, C> { + ) -> TyMaybeWithLayout<'tcx> { let tcx = cx.tcx(); - let tag_layout = |tag: &Scalar| -> C::TyAndLayout { + let tag_layout = |tag: &Scalar| -> TyAndLayout<'tcx> { let layout = Layout::scalar(cx, tag.clone()); - MaybeResult::from(Ok(TyAndLayout { - layout: tcx.intern_layout(layout), - ty: tag.value.to_ty(tcx), - })) + TyAndLayout { layout: tcx.intern_layout(layout), ty: tag.value.to_ty(tcx) } }; - match *ty.kind() { + match *this.ty.kind() { ty::Bool | ty::Char | ty::Int(_) @@ -2180,7 +2170,7 @@ where | ty::FnDef(..) | ty::GeneratorWitness(..) | ty::Foreign(..) - | ty::Dynamic(..) => bug!("TyAndLayout::field_type({:?}): not applicable", this), + | ty::Dynamic(..) => bug!("TyAndLayout::field({:?}): not applicable", this), // Potentially-fat pointers. ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => { @@ -2192,17 +2182,19 @@ where // as the `Abi` or `FieldsShape` is checked by users. if i == 0 { let nil = tcx.mk_unit(); - let ptr_ty = if ty.is_unsafe_ptr() { + let unit_ptr_ty = if this.ty.is_unsafe_ptr() { tcx.mk_mut_ptr(nil) } else { tcx.mk_mut_ref(tcx.lifetimes.re_static, nil) }; - return TyMaybeWithLayout::TyAndLayout(MaybeResult::from( - cx.layout_of(ptr_ty).to_result().map(|mut ptr_layout| { - ptr_layout.ty = ty; - ptr_layout - }), - )); + + // NOTE(eddyb) using an empty `ParamEnv`, and `unwrap`-ing + // the `Result` should always work because the type is + // always either `*mut ()` or `&'static mut ()`. + return TyMaybeWithLayout::TyAndLayout(TyAndLayout { + ty: this.ty, + ..tcx.layout_of(ty::ParamEnv::reveal_all().and(unit_ptr_ty)).unwrap() + }); } match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind() { @@ -2226,7 +2218,7 @@ where ]) */ } - _ => bug!("TyAndLayout::field_type({:?}): not applicable", this), + _ => bug!("TyAndLayout::field({:?}): not applicable", this), } } @@ -2235,9 +2227,11 @@ where ty::Str => TyMaybeWithLayout::Ty(tcx.types.u8), // Tuples, generators and closures. - ty::Closure(_, ref substs) => { - ty_and_layout_kind(this, cx, i, substs.as_closure().tupled_upvars_ty()) - } + ty::Closure(_, ref substs) => field_ty_or_layout( + TyAndLayout { ty: substs.as_closure().tupled_upvars_ty(), ..this }, + cx, + i, + ), ty::Generator(def_id, ref substs, _) => match this.variants { Variants::Single { index } => TyMaybeWithLayout::Ty( @@ -2280,14 +2274,25 @@ where | ty::Opaque(..) | ty::Param(_) | ty::Infer(_) - | ty::Error(_) => bug!("TyAndLayout::field_type: unexpected type `{}`", this.ty), + | ty::Error(_) => bug!("TyAndLayout::field: unexpected type `{}`", this.ty), } } - cx.layout_of(match ty_and_layout_kind(this, cx, i, this.ty) { - TyMaybeWithLayout::Ty(result) => result, - TyMaybeWithLayout::TyAndLayout(result) => return result, - }) + match field_ty_or_layout(this, cx, i) { + TyMaybeWithLayout::Ty(field_ty) => { + cx.tcx().layout_of(cx.param_env().and(field_ty)).unwrap_or_else(|e| { + bug!( + "failed to get layout for `{}`: {},\n\ + despite it being a field (#{}) of an existing layout: {:#?}", + field_ty, + e, + i, + this + ) + }) + } + TyMaybeWithLayout::TyAndLayout(field_layout) => field_layout, + } } fn ty_and_layout_pointee_info_at( diff --git a/compiler/rustc_mir/src/interpret/cast.rs b/compiler/rustc_mir/src/interpret/cast.rs index 697e98311e2..6f18009cf47 100644 --- a/compiler/rustc_mir/src/interpret/cast.rs +++ b/compiler/rustc_mir/src/interpret/cast.rs @@ -340,7 +340,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Example: `Arc<T>` -> `Arc<Trait>` // here we need to increase the size of every &T thin ptr field to a fat ptr for i in 0..src.layout.fields.count() { - let cast_ty_field = cast_ty.field(self, i)?; + let cast_ty_field = cast_ty.field(self, i); if cast_ty_field.is_zst() { continue; } diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index 347359e1456..bfb3de04c59 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -592,7 +592,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Recurse to get the size of the dynamically sized field (must be // the last field). Can't have foreign types here, how would we // adjust alignment and size for them? - let field = layout.field(self, layout.fields.count() - 1)?; + let field = layout.field(self, layout.fields.count() - 1); let (unsized_size, unsized_align) = match self.size_and_align_of(metadata, &field)? { Some(size_and_align) => size_and_align, @@ -645,7 +645,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ty::Slice(_) | ty::Str => { let len = metadata.unwrap_meta().to_machine_usize(self)?; - let elem = layout.field(self, 0)?; + let elem = layout.field(self, 0); // Make sure the slice is not too big. let size = elem.size.checked_mul(len, self).ok_or_else(|| { diff --git a/compiler/rustc_mir/src/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs index 403dc1b4793..4afce2b6b80 100644 --- a/compiler/rustc_mir/src/interpret/operand.rs +++ b/compiler/rustc_mir/src/interpret/operand.rs @@ -364,7 +364,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Err(value) => value, }; - let field_layout = op.layout.field(self, field)?; + let field_layout = op.layout.field(self, field); if field_layout.is_zst() { let immediate = Scalar::ZST.into(); return Ok(OpTy { op: Operand::Immediate(immediate), layout: field_layout }); diff --git a/compiler/rustc_mir/src/interpret/place.rs b/compiler/rustc_mir/src/interpret/place.rs index 91fcc3495b1..afad9716b3f 100644 --- a/compiler/rustc_mir/src/interpret/place.rs +++ b/compiler/rustc_mir/src/interpret/place.rs @@ -355,7 +355,7 @@ where field: usize, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { let offset = base.layout.fields.offset(field); - let field_layout = base.layout.field(self, field)?; + let field_layout = base.layout.field(self, field); // Offset may need adjustment for unsized fields. let (meta, offset) = if field_layout.is_unsized() { @@ -405,7 +405,7 @@ where } let offset = stride * index; // `Size` multiplication // All fields have the same layout. - let field_layout = base.layout.field(self, 0)?; + let field_layout = base.layout.field(self, 0); assert!(!field_layout.is_unsized()); base.offset(offset, MemPlaceMeta::None, field_layout, self) @@ -430,7 +430,7 @@ where FieldsShape::Array { stride, .. } => stride, _ => span_bug!(self.cur_span(), "mplace_array_fields: expected an array layout"), }; - let layout = base.layout.field(self, 0)?; + let layout = base.layout.field(self, 0); let dl = &self.tcx.data_layout; // `Size` multiplication Ok((0..len).map(move |i| base.offset(stride * i, MemPlaceMeta::None, layout, dl))) diff --git a/compiler/rustc_mir/src/interpret/terminator.rs b/compiler/rustc_mir/src/interpret/terminator.rs index d87aa4a6267..63496045e0d 100644 --- a/compiler/rustc_mir/src/interpret/terminator.rs +++ b/compiler/rustc_mir/src/interpret/terminator.rs @@ -461,7 +461,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // a thin pointer. assert!(receiver_place.layout.is_unsized()); let receiver_ptr_ty = self.tcx.mk_mut_ptr(receiver_place.layout.ty); - let this_receiver_ptr = self.layout_of(receiver_ptr_ty)?.field(self, 0)?; + let this_receiver_ptr = self.layout_of(receiver_ptr_ty)?.field(self, 0); // Adjust receiver argument. args[0] = OpTy::from(ImmTy::from_immediate( Scalar::from_maybe_pointer(receiver_place.ptr, self).into(), diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 367071926fe..19673ef3272 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -1244,7 +1244,7 @@ pub trait TyAbiInterface<'a, C: LayoutOf<'a, Ty = Self>>: Sized { cx: &C, variant_index: VariantIdx, ) -> TyAndLayout<'a, Self>; - fn ty_and_layout_field(this: TyAndLayout<'a, Self>, cx: &C, i: usize) -> C::TyAndLayout; + fn ty_and_layout_field(this: TyAndLayout<'a, Self>, cx: &C, i: usize) -> TyAndLayout<'a, Self>; fn ty_and_layout_pointee_info_at( this: TyAndLayout<'a, Self>, cx: &C, @@ -1261,7 +1261,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { Ty::ty_and_layout_for_variant(self, cx, variant_index) } - pub fn field<C>(self, cx: &C, i: usize) -> C::TyAndLayout + pub fn field<C>(self, cx: &C, i: usize) -> Self where Ty: TyAbiInterface<'a, C>, C: LayoutOf<'a, Ty = Ty>, @@ -1302,11 +1302,11 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { /// FIXME: Once we removed all the conservatism, we could alternatively /// create an all-0/all-undef constant and run the const value validator to see if /// this is a valid value for the given type. - pub fn might_permit_raw_init<C, E>(self, cx: &C, zero: bool) -> Result<bool, E> + pub fn might_permit_raw_init<C>(self, cx: &C, zero: bool) -> bool where Self: Copy, Ty: TyAbiInterface<'a, C>, - C: LayoutOf<'a, Ty = Ty, TyAndLayout: MaybeResult<Self, Error = E>> + HasDataLayout, + C: LayoutOf<'a, Ty = Ty> + HasDataLayout, { let scalar_allows_raw_init = move |s: &Scalar| -> bool { if zero { @@ -1331,7 +1331,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { }; if !valid { // This is definitely not okay. - return Ok(false); + return false; } // If we have not found an error yet, we need to recursively descend into fields. @@ -1342,16 +1342,15 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { } FieldsShape::Arbitrary { offsets, .. } => { for idx in 0..offsets.len() { - let field = self.field(cx, idx).to_result()?; - if !field.might_permit_raw_init(cx, zero)? { + if !self.field(cx, idx).might_permit_raw_init(cx, zero) { // We found a field that is unhappy with this kind of initialization. - return Ok(false); + return false; } } } } // FIXME(#66151): For now, we are conservative and do not check `self.variants`. - Ok(true) + true } } |
