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 3101015281b82..1c6a0f9cf4d4c 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 @@ -1124,7 +1124,10 @@ pub fn typeid_for_instance<'tcx>( .trait_item_def_id .expect("Part of a trait implementation, but not linked to the def_id?"); let trait_method = tcx.associated_item(method_id); - if traits::is_vtable_safe_method(tcx, trait_ref.skip_binder().def_id, trait_method) { + let trait_id = trait_ref.skip_binder().def_id; + if traits::is_vtable_safe_method(tcx, trait_id, trait_method) + && tcx.object_safety_violations(trait_id).is_empty() + { // Trait methods will have a Self polymorphic parameter, where the concreteized // implementatation will not. We need to walk back to the more general trait method let trait_ref = tcx.instantiate_and_normalize_erasing_regions( @@ -1152,8 +1155,8 @@ pub fn typeid_for_instance<'tcx>( let fn_abi = tcx .fn_abi_of_instance(tcx.param_env(instance.def_id()).and((instance, ty::List::empty()))) - .unwrap_or_else(|instance| { - bug!("typeid_for_instance: couldn't get fn_abi of instance {:?}", instance) + .unwrap_or_else(|error| { + bug!("typeid_for_instance: couldn't get fn_abi of instance {instance:?}: {error:?}") }); typeid_for_fnabi(tcx, fn_abi, options) @@ -1182,6 +1185,7 @@ fn strip_receiver_auto<'tcx>( tcx.mk_args_trait(new_rcvr, args.into_iter().skip(1)) } +#[instrument(skip(tcx), ret)] fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>) -> Ty<'tcx> { assert!(!poly_trait_ref.has_non_region_param()); let principal_pred = poly_trait_ref.map_bound(|trait_ref| { @@ -1199,6 +1203,7 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc ty::ParamEnv::reveal_all(), alias_ty.to_ty(tcx), ); + debug!("Resolved {:?} -> {resolved}", alias_ty.to_ty(tcx)); ty::ExistentialPredicate::Projection(ty::ExistentialProjection { def_id: assoc_ty.def_id, args: ty::ExistentialTraitRef::erase_self_ty(tcx, super_trait_ref).args, diff --git a/tests/ui/sanitizer/cfi-assoc-ty-lifetime-issue-123053.rs b/tests/ui/sanitizer/cfi-assoc-ty-lifetime-issue-123053.rs new file mode 100644 index 0000000000000..dd604b6bf7dcd --- /dev/null +++ b/tests/ui/sanitizer/cfi-assoc-ty-lifetime-issue-123053.rs @@ -0,0 +1,38 @@ +// Regression test for issue 123053, where associated types with lifetimes caused generation of the +// trait object type to fail, causing an ICE. +// +//@ needs-sanitizer-cfi +//@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi --edition=2021 +//@ no-prefer-dynamic +//@ only-x86_64-unknown-linux-gnu +//@ build-pass + +trait Iterable { + type Item<'a> + where + Self: 'a; + type Iter<'a>: Iterator> + where + Self: 'a; + + fn iter<'a>(&'a self) -> Self::Iter<'a>; +} + +impl Iterable for [T] { + type Item<'a> = as Iterator>::Item where T: 'a; + type Iter<'a> = std::slice::Iter<'a, T> where T: 'a; + + fn iter<'a>(&'a self) -> Self::Iter<'a> { + self.iter() + } +} + +fn get_first<'a, I: Iterable + ?Sized>(it: &'a I) -> Option> { + it.iter().next() +} + +fn main() { + let v = vec![1, 2, 3]; + + assert_eq!(Some(&1), get_first(&*v)); +}