diff --git a/compiler/rustc_codegen_llvm/src/gotoc/rvalue.rs b/compiler/rustc_codegen_llvm/src/gotoc/rvalue.rs index 3d4c4e87eee3..b176a19ba0eb 100644 --- a/compiler/rustc_codegen_llvm/src/gotoc/rvalue.rs +++ b/compiler/rustc_codegen_llvm/src/gotoc/rvalue.rs @@ -4,7 +4,7 @@ use super::cbmc::goto_program::{BuiltinFn, Expr, Location, Stmt, Symbol, Type}; use super::cbmc::utils::{aggr_name, BUG_REPORT_URL}; use super::cbmc::MachineModel; use super::metadata::*; -use super::typ::{is_dyn_trait_fat_pointer, is_pointer, pointee_type}; +use super::typ::{is_pointer, pointee_type}; use super::utils::{dynamic_fat_ptr, slice_fat_ptr}; use crate::btree_string_map; use num::bigint::BigInt; @@ -679,15 +679,18 @@ impl<'tcx> GotocCtx<'tcx> { ) -> Option { // Check if the cast is from a vtable fat pointer to another // vtable fat pointer (which can happen with auto trait fat pointers) - if is_dyn_trait_fat_pointer(src_mir_type) { + if self.is_vtable_fat_pointer(src_mir_type) { self.cast_unsized_dyn_trait_to_unsized_dyn_trait( src_goto_expr.clone(), src_mir_type, dst_mir_type, ) } else { - // Assert that the source is not a pointer or is a thin pointer - assert!(pointee_type(src_mir_type).map_or(true, |p| self.use_thin_pointer(p))); + // Check that the source is either not a pointer, or a thin or a slice pointer + assert!( + pointee_type(src_mir_type) + .map_or(true, |p| self.use_thin_pointer(p) || self.use_slice_fat_pointer(p)) + ); // Sized to unsized cast self.cast_sized_expr_to_unsized_expr(src_goto_expr.clone(), src_mir_type, dst_mir_type) @@ -923,8 +926,8 @@ impl<'tcx> GotocCtx<'tcx> { } // The source destination must be a fat pointers to a dyn trait object - assert!(is_dyn_trait_fat_pointer(src_mir_type)); - assert!(is_dyn_trait_fat_pointer(dst_mir_type)); + assert!(self.is_vtable_fat_pointer(src_mir_type)); + assert!(self.is_vtable_fat_pointer(dst_mir_type)); let dst_mir_dyn_ty = pointee_type(dst_mir_type).unwrap(); @@ -965,7 +968,7 @@ impl<'tcx> GotocCtx<'tcx> { // The src type cannot be a pointer to a dynamic trait object, otherwise // we should have called cast_unsized_dyn_trait_to_unsized_dyn_trait - assert!(!is_dyn_trait_fat_pointer(src_mir_type)); + assert!(!self.is_vtable_fat_pointer(src_mir_type)); match (src_mir_type.kind(), dst_mir_type.kind()) { (ty::Ref(..), ty::Ref(..)) => { diff --git a/compiler/rustc_codegen_llvm/src/gotoc/typ.rs b/compiler/rustc_codegen_llvm/src/gotoc/typ.rs index 8d4805f264cf..9cb59caa9824 100644 --- a/compiler/rustc_codegen_llvm/src/gotoc/typ.rs +++ b/compiler/rustc_codegen_llvm/src/gotoc/typ.rs @@ -1016,11 +1016,6 @@ pub fn pointee_type(pointer_type: Ty<'tcx>) -> Option> { } } -/// Check if the mir type already is a vtable fat pointer. -pub fn is_dyn_trait_fat_pointer(mir_type: Ty<'tcx>) -> bool { - if let Some(p) = pointee_type(mir_type) { p.is_trait() } else { false } -} - impl<'tcx> GotocCtx<'tcx> { /// A pointer to the mir type should be a thin pointer. pub fn use_thin_pointer(&self, mir_type: Ty<'tcx>) -> bool { @@ -1037,4 +1032,9 @@ impl<'tcx> GotocCtx<'tcx> { let metadata = mir_type.ptr_metadata_ty(self.tcx); return metadata != self.tcx.types.unit && metadata != self.tcx.types.usize; } + + /// Check if the mir type already is a vtable fat pointer. + pub fn is_vtable_fat_pointer(&self, mir_type: Ty<'tcx>) -> bool { + pointee_type(mir_type).map_or(false, |p| self.use_vtable_fat_pointer(p)) + } }