diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 62822505fa5d2..4adbef103cfa9 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -290,7 +290,7 @@ impl<'tcx> ty::List> { /// have a "trivial" vtable consisting of just the size, alignment, /// and destructor. pub fn principal(&self) -> Option>> { - self[0] + self.get(0)? .map_bound(|this| match this { ExistentialPredicate::Trait(tr) => Some(tr), _ => None, diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index a69c80236e1e5..16eaf47125b9b 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -759,7 +759,11 @@ fn transform_predicates<'tcx>( ty::ExistentialPredicate::AutoTrait(..) => Some(predicate), }) .collect(); - tcx.mk_poly_existential_predicates(&predicates) + if predicates.len() == 0 { + List::empty() + } else { + tcx.mk_poly_existential_predicates(&predicates) + } } /// Transforms args for being encoded and used in the substitution dictionary. diff --git a/tests/ui/sanitizer/cfi-drop-no-principal.rs b/tests/ui/sanitizer/cfi-drop-no-principal.rs new file mode 100644 index 0000000000000..87f7029d30185 --- /dev/null +++ b/tests/ui/sanitizer/cfi-drop-no-principal.rs @@ -0,0 +1,16 @@ +// Check that dropping a trait object without a principal trait succeeds + +//@ needs-sanitizer-cfi +//@ compile-flags: --crate-type=bin -Cprefer-dynamic=off -Clto -Zsanitizer=cfi +//@ compile-flags: -C codegen-units=1 -C opt-level=0 +//@ run-pass +// Check that trait objects without a principal can be dropped. + +struct CustomDrop; +impl Drop for CustomDrop { + fn drop(&mut self) {} +} + +fn main() { + let _ = Box::new(CustomDrop) as Box; +}