about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs11
-rw-r--r--tests/ui/sanitizer/cfi-assoc-ty-lifetime-issue-123053.rs38
2 files changed, 46 insertions, 3 deletions
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 3101015281b..1c6a0f9cf4d 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 00000000000..dd604b6bf7d
--- /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<Item = Self::Item<'a>>
+    where
+        Self: 'a;
+
+    fn iter<'a>(&'a self) -> Self::Iter<'a>;
+}
+
+impl<T> Iterable for [T] {
+    type Item<'a> = <std::slice::Iter<'a, T> 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<I::Item<'a>> {
+    it.iter().next()
+}
+
+fn main() {
+    let v = vec![1, 2, 3];
+
+    assert_eq!(Some(&1), get_first(&*v));
+}