Skip to content

Commit 3014ac3

Browse files
authored
Rollup merge of #123003 - maurer:dyn-empty, r=compiler-errors
CFI: Handle dyn with no principal In user-facing Rust, `dyn` always has at least one predicate following it. Unfortunately, because we filter out marker traits from receivers at callsites and `dyn Sync` is, for example, legal, this results in us having `dyn` types with no predicates on occasion in our alias set encoding. This patch handles cases where there are no predicates in a `dyn` type which are relevant to its alias set. Fixes #122998 r? workingjubilee
2 parents 4f9ab98 + ea45185 commit 3014ac3

File tree

2 files changed

+35
-13
lines changed

2 files changed

+35
-13
lines changed

compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs

+14-13
Original file line numberDiff line numberDiff line change
@@ -747,9 +747,8 @@ fn transform_predicates<'tcx>(
747747
tcx: TyCtxt<'tcx>,
748748
predicates: &List<ty::PolyExistentialPredicate<'tcx>>,
749749
) -> &'tcx List<ty::PolyExistentialPredicate<'tcx>> {
750-
let predicates: Vec<ty::PolyExistentialPredicate<'tcx>> = predicates
751-
.iter()
752-
.filter_map(|predicate| match predicate.skip_binder() {
750+
tcx.mk_poly_existential_predicates_from_iter(predicates.iter().filter_map(|predicate| {
751+
match predicate.skip_binder() {
753752
ty::ExistentialPredicate::Trait(trait_ref) => {
754753
let trait_ref = ty::TraitRef::identity(tcx, trait_ref.def_id);
755754
Some(ty::Binder::dummy(ty::ExistentialPredicate::Trait(
@@ -758,9 +757,8 @@ fn transform_predicates<'tcx>(
758757
}
759758
ty::ExistentialPredicate::Projection(..) => None,
760759
ty::ExistentialPredicate::AutoTrait(..) => Some(predicate),
761-
})
762-
.collect();
763-
tcx.mk_poly_existential_predicates(&predicates)
760+
}
761+
}))
764762
}
765763

766764
/// Transforms args for being encoded and used in the substitution dictionary.
@@ -1171,14 +1169,17 @@ fn strip_receiver_auto<'tcx>(
11711169
let ty::Dynamic(preds, lifetime, kind) = ty.kind() else {
11721170
bug!("Tried to strip auto traits from non-dynamic type {ty}");
11731171
};
1174-
let filtered_preds =
1175-
if preds.principal().is_some() {
1172+
let new_rcvr = if preds.principal().is_some() {
1173+
let filtered_preds =
11761174
tcx.mk_poly_existential_predicates_from_iter(preds.into_iter().filter(|pred| {
11771175
!matches!(pred.skip_binder(), ty::ExistentialPredicate::AutoTrait(..))
1178-
}))
1179-
} else {
1180-
ty::List::empty()
1181-
};
1182-
let new_rcvr = Ty::new_dynamic(tcx, filtered_preds, *lifetime, *kind);
1176+
}));
1177+
Ty::new_dynamic(tcx, filtered_preds, *lifetime, *kind)
1178+
} else {
1179+
// If there's no principal type, re-encode it as a unit, since we don't know anything
1180+
// about it. This technically discards the knowledge that it was a type that was made
1181+
// into a trait object at some point, but that's not a lot.
1182+
tcx.types.unit
1183+
};
11831184
tcx.mk_args_trait(new_rcvr, args.into_iter().skip(1))
11841185
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Check that dropping a trait object without a principal trait succeeds
2+
3+
//@ needs-sanitizer-cfi
4+
// FIXME(#122848) Remove only-linux once OSX CFI binaries works
5+
//@ only-linux
6+
//@ compile-flags: --crate-type=bin -Cprefer-dynamic=off -Clto -Zsanitizer=cfi
7+
//@ compile-flags: -C target-feature=-crt-static -C codegen-units=1 -C opt-level=0
8+
// FIXME(#118761) Should be run-pass once the labels on drop are compatible.
9+
// This test is being landed ahead of that to test that the compiler doesn't ICE while labeling the
10+
// callsite for a drop, but the vtable doesn't have the correct label yet.
11+
//@ build-pass
12+
13+
struct CustomDrop;
14+
15+
impl Drop for CustomDrop {
16+
fn drop(&mut self) {}
17+
}
18+
19+
fn main() {
20+
let _ = Box::new(CustomDrop) as Box<dyn Send>;
21+
}

0 commit comments

Comments
 (0)