Skip to content

Commit 809e975

Browse files
authored
Rollup merge of #83767 - camelid:mangle-v0-fix, r=nikomatsakis
Fix v0 symbol mangling bug Fixes #83611. r? ``@jackh726``
2 parents 3c99dcd + 8345908 commit 809e975

File tree

4 files changed

+144
-7
lines changed

4 files changed

+144
-7
lines changed

compiler/rustc_symbol_mangling/src/v0.rs

+37-6
Original file line numberDiff line numberDiff line change
@@ -485,9 +485,39 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
485485
mut self,
486486
predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
487487
) -> Result<Self::DynExistential, Self::Error> {
488-
for predicate in predicates {
489-
self = self.in_binder(&predicate, |mut cx, predicate| {
490-
match predicate {
488+
// Okay, so this is a bit tricky. Imagine we have a trait object like
489+
// `dyn for<'a> Foo<'a, Bar = &'a ()>`. When we mangle this, the
490+
// output looks really close to the syntax, where the `Bar = &'a ()` bit
491+
// is under the same binders (`['a]`) as the `Foo<'a>` bit. However, we
492+
// actually desugar these into two separate `ExistentialPredicate`s. We
493+
// can't enter/exit the "binder scope" twice though, because then we
494+
// would mangle the binders twice. (Also, side note, we merging these
495+
// two is kind of difficult, because of potential HRTBs in the Projection
496+
// predicate.)
497+
//
498+
// Also worth mentioning: imagine that we instead had
499+
// `dyn for<'a> Foo<'a, Bar = &'a ()> + Send`. In this case, `Send` is
500+
// under the same binders as `Foo`. Currently, this doesn't matter,
501+
// because only *auto traits* are allowed other than the principal trait
502+
// and all auto traits don't have any generics. Two things could
503+
// make this not an "okay" mangling:
504+
// 1) Instead of mangling only *used*
505+
// bound vars, we want to mangle *all* bound vars (`for<'b> Send` is a
506+
// valid trait predicate);
507+
// 2) We allow multiple "principal" traits in the future, or at least
508+
// allow in any form another trait predicate that can take generics.
509+
//
510+
// Here we assume that predicates have the following structure:
511+
// [<Trait> [{<Projection>}]] [{<Auto>}]
512+
// Since any predicates after the first one shouldn't change the binders,
513+
// just put them all in the binders of the first.
514+
self = self.in_binder(&predicates[0], |mut cx, _| {
515+
for predicate in predicates.iter() {
516+
// It would be nice to be able to validate bound vars here, but
517+
// projections can actually include bound vars from super traits
518+
// because of HRTBs (only in the `Self` type). Also, auto traits
519+
// could have different bound vars *anyways*.
520+
match predicate.as_ref().skip_binder() {
491521
ty::ExistentialPredicate::Trait(trait_ref) => {
492522
// Use a type that can't appear in defaults of type parameters.
493523
let dummy_self = cx.tcx.mk_ty_infer(ty::FreshTy(0));
@@ -504,9 +534,10 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
504534
cx = cx.print_def_path(*def_id, &[])?;
505535
}
506536
}
507-
Ok(cx)
508-
})?;
509-
}
537+
}
538+
Ok(cx)
539+
})?;
540+
510541
self.push("E");
511542
Ok(self)
512543
}

compiler/rustc_typeck/src/astconv/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1394,11 +1394,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
13941394
let auto_trait_predicates = auto_traits.into_iter().map(|trait_ref| {
13951395
ty::Binder::dummy(ty::ExistentialPredicate::AutoTrait(trait_ref.trait_ref().def_id()))
13961396
});
1397+
// N.b. principal, projections, auto traits
1398+
// FIXME: This is actually wrong with multiple principals in regards to symbol mangling
13971399
let mut v = regular_trait_predicates
1398-
.chain(auto_trait_predicates)
13991400
.chain(
14001401
existential_projections.map(|x| x.map_bound(ty::ExistentialPredicate::Projection)),
14011402
)
1403+
.chain(auto_trait_predicates)
14021404
.collect::<SmallVec<[_; 8]>>();
14031405
v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
14041406
v.dedup();
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Ensure that trait objects don't include more than one binder. See #83611
2+
3+
// build-fail
4+
// revisions: v0
5+
//[v0]compile-flags: -Z symbol-mangling-version=v0
6+
//[v0]normalize-stderr-test: "Cs.*?_" -> "CRATE_HASH"
7+
//[v0]normalize-stderr-test: "core\[.*?\]" -> "core[HASH]"
8+
9+
#![feature(rustc_attrs)]
10+
11+
trait Bar {
12+
fn method(&self) {}
13+
}
14+
15+
impl Bar for &dyn FnMut(&u8) {
16+
#[rustc_symbol_name]
17+
//[v0]~^ ERROR symbol-name
18+
//[v0]~| ERROR demangling
19+
//[v0]~| ERROR demangling-alt
20+
fn method(&self) {}
21+
}
22+
23+
trait Foo {
24+
fn method(&self) {}
25+
}
26+
27+
impl Foo for &(dyn FnMut(&u8) + for<'b> Send) {
28+
#[rustc_symbol_name]
29+
//[v0]~^ ERROR symbol-name
30+
//[v0]~| ERROR demangling
31+
//[v0]~| ERROR demangling-alt
32+
fn method(&self) {}
33+
}
34+
35+
trait Baz {
36+
fn method(&self) {}
37+
}
38+
39+
impl Baz for &(dyn for<'b> Send + FnMut(&u8)) {
40+
#[rustc_symbol_name]
41+
//[v0]~^ ERROR symbol-name
42+
//[v0]~| ERROR demangling
43+
//[v0]~| ERROR demangling-alt
44+
fn method(&self) {}
45+
}
46+
47+
fn main() {
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
error: symbol-name(_RNvXCRATE_HASH13trait_objectsRDG_INtNtNtCRATE_HASH4core3ops8function5FnMutTRL0_hEEp6OutputuEL_NtB2_3Bar6method)
2+
--> $DIR/trait-objects.rs:16:5
3+
|
4+
LL | #[rustc_symbol_name]
5+
| ^^^^^^^^^^^^^^^^^^^^
6+
7+
error: demangling(<&dyn for<'a> core[HASH]::ops::function::FnMut<(&'a u8,), Output = ()> as trait_objects[17891616a171812d]::Bar>::method)
8+
--> $DIR/trait-objects.rs:16:5
9+
|
10+
LL | #[rustc_symbol_name]
11+
| ^^^^^^^^^^^^^^^^^^^^
12+
13+
error: demangling-alt(<&dyn for<'a> core::ops::function::FnMut<(&'a u8,), Output = ()> as trait_objects::Bar>::method)
14+
--> $DIR/trait-objects.rs:16:5
15+
|
16+
LL | #[rustc_symbol_name]
17+
| ^^^^^^^^^^^^^^^^^^^^
18+
19+
error: symbol-name(_RNvXs_CRATE_HASH13trait_objectsRDG_INtNtNtCRATE_HASH4core3ops8function5FnMutTRL0_hEEp6OutputuNtNtBI_6marker4SendEL_NtB4_3Foo6method)
20+
--> $DIR/trait-objects.rs:28:5
21+
|
22+
LL | #[rustc_symbol_name]
23+
| ^^^^^^^^^^^^^^^^^^^^
24+
25+
error: demangling(<&dyn for<'a> core[HASH]::ops::function::FnMut<(&'a u8,), Output = ()> + core[HASH]::marker::Send as trait_objects[17891616a171812d]::Foo>::method)
26+
--> $DIR/trait-objects.rs:28:5
27+
|
28+
LL | #[rustc_symbol_name]
29+
| ^^^^^^^^^^^^^^^^^^^^
30+
31+
error: demangling-alt(<&dyn for<'a> core::ops::function::FnMut<(&'a u8,), Output = ()> + core::marker::Send as trait_objects::Foo>::method)
32+
--> $DIR/trait-objects.rs:28:5
33+
|
34+
LL | #[rustc_symbol_name]
35+
| ^^^^^^^^^^^^^^^^^^^^
36+
37+
error: symbol-name(_RNvXs0_CRATE_HASH13trait_objectsRDG_INtNtNtCRATE_HASH4core3ops8function5FnMutTRL0_hEEp6OutputuNtNtBJ_6marker4SendEL_NtB5_3Baz6method)
38+
--> $DIR/trait-objects.rs:40:5
39+
|
40+
LL | #[rustc_symbol_name]
41+
| ^^^^^^^^^^^^^^^^^^^^
42+
43+
error: demangling(<&dyn for<'a> core[HASH]::ops::function::FnMut<(&'a u8,), Output = ()> + core[HASH]::marker::Send as trait_objects[17891616a171812d]::Baz>::method)
44+
--> $DIR/trait-objects.rs:40:5
45+
|
46+
LL | #[rustc_symbol_name]
47+
| ^^^^^^^^^^^^^^^^^^^^
48+
49+
error: demangling-alt(<&dyn for<'a> core::ops::function::FnMut<(&'a u8,), Output = ()> + core::marker::Send as trait_objects::Baz>::method)
50+
--> $DIR/trait-objects.rs:40:5
51+
|
52+
LL | #[rustc_symbol_name]
53+
| ^^^^^^^^^^^^^^^^^^^^
54+
55+
error: aborting due to 9 previous errors
56+

0 commit comments

Comments
 (0)