mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-10 22:13:27 +00:00
Change to just use first binders and add test
This commit is contained in:
parent
c34e7c60f5
commit
0daabbee2d
@ -485,38 +485,59 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
|
|||||||
mut self,
|
mut self,
|
||||||
predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
|
predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
|
||||||
) -> Result<Self::DynExistential, Self::Error> {
|
) -> Result<Self::DynExistential, Self::Error> {
|
||||||
let mut predicate_iter = predicates.iter().peekable();
|
// Okay, so this is a bit tricky. Imagine we have a trait object like
|
||||||
while let Some(predicate) = predicate_iter.next() {
|
// `dyn for<'a> Foo<'a, Bar = &'a ()>`. When we mangle this, the
|
||||||
match predicate.as_ref().skip_binder() {
|
// output looks really close to the syntax, where the `Bar = &'a ()` bit
|
||||||
ty::ExistentialPredicate::Trait(trait_ref) => {
|
// is under the same binders (`['a]`) as the `Foo<'a>` bit. However, we
|
||||||
self = self.in_binder(&predicate, |mut cx, _predicate| {
|
// actually desugar these into two separate `ExistentialPredicate`s. We
|
||||||
|
// can't enter/exit the "binder scope" twice though, because then we
|
||||||
|
// would mangle the binders twice. (Also, side note, we merging these
|
||||||
|
// two is kind of difficult, because of potential HRTBs in the Projection
|
||||||
|
// predicate.)
|
||||||
|
//
|
||||||
|
// Also worth mentioning: imagine that we instead had
|
||||||
|
// `dyn for<'a> Foo<'a, Bar = &'a ()> + Send`. In this case, `Send` is
|
||||||
|
// under the same binders as `Foo`. Currently, this doesn't matter,
|
||||||
|
// because only *auto traits* are allowed other than the principal trait
|
||||||
|
// and all auto traits don't have any generics. Two things could
|
||||||
|
// make this not an "okay" mangling:
|
||||||
|
// 1) Instead of mangling only *used*
|
||||||
|
// bound vars, we want to mangle *all* bound vars (`for<'b> Send` is a
|
||||||
|
// valid trait predicate);
|
||||||
|
// 2) We allow multiple "principal" traits in the future, or at least
|
||||||
|
// allow in any form another trait predicate that can take generics.
|
||||||
|
//
|
||||||
|
// Here we assume that predicates have the following structure:
|
||||||
|
// [<Trait> [{<Projection>}]] [{<Auto>}]
|
||||||
|
// Since any predicates after the first one shouldn't change the binders,
|
||||||
|
// just put them all in the binders of the first.
|
||||||
|
self = self.in_binder(&predicates[0], |mut cx, _| {
|
||||||
|
for predicate in predicates.iter() {
|
||||||
|
// It would be nice to be able to validate bound vars here, but
|
||||||
|
// projections can actually include bound vars from super traits
|
||||||
|
// because of HRTBs (only in the `Self` type). Also, auto traits
|
||||||
|
// could have different bound vars *anyways*.
|
||||||
|
match predicate.as_ref().skip_binder() {
|
||||||
|
ty::ExistentialPredicate::Trait(trait_ref) => {
|
||||||
// Use a type that can't appear in defaults of type parameters.
|
// Use a type that can't appear in defaults of type parameters.
|
||||||
let dummy_self = cx.tcx.mk_ty_infer(ty::FreshTy(0));
|
let dummy_self = cx.tcx.mk_ty_infer(ty::FreshTy(0));
|
||||||
let trait_ref = trait_ref.with_self_ty(cx.tcx, dummy_self);
|
let trait_ref = trait_ref.with_self_ty(cx.tcx, dummy_self);
|
||||||
cx = cx.print_def_path(trait_ref.def_id, trait_ref.substs)?;
|
cx = cx.print_def_path(trait_ref.def_id, trait_ref.substs)?;
|
||||||
while let Some(projection_pred) = predicate_iter.next_if(|p| {
|
}
|
||||||
matches!(p.skip_binder(), ty::ExistentialPredicate::Projection(_))
|
ty::ExistentialPredicate::Projection(projection) => {
|
||||||
}) {
|
let name = cx.tcx.associated_item(projection.item_def_id).ident;
|
||||||
let projection = match projection_pred.skip_binder() {
|
cx.push("p");
|
||||||
ty::ExistentialPredicate::Projection(projection) => projection,
|
cx.push_ident(&name.as_str());
|
||||||
_ => unreachable!(),
|
cx = projection.ty.print(cx)?;
|
||||||
};
|
}
|
||||||
let name = cx.tcx.associated_item(projection.item_def_id).ident;
|
ty::ExistentialPredicate::AutoTrait(def_id) => {
|
||||||
cx.push("p");
|
cx = cx.print_def_path(*def_id, &[])?;
|
||||||
cx.push_ident(&name.as_str());
|
}
|
||||||
cx = projection.ty.print(cx)?;
|
|
||||||
}
|
|
||||||
Ok(cx)
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
ty::ExistentialPredicate::Projection(_) => {
|
|
||||||
unreachable!("handled in trait predicate arm")
|
|
||||||
}
|
|
||||||
ty::ExistentialPredicate::AutoTrait(def_id) => {
|
|
||||||
self = self.print_def_path(*def_id, &[])?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
Ok(cx)
|
||||||
|
})?;
|
||||||
|
|
||||||
self.push("E");
|
self.push("E");
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
@ -1386,11 +1386,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
let auto_trait_predicates = auto_traits.into_iter().map(|trait_ref| {
|
let auto_trait_predicates = auto_traits.into_iter().map(|trait_ref| {
|
||||||
ty::Binder::dummy(ty::ExistentialPredicate::AutoTrait(trait_ref.trait_ref().def_id()))
|
ty::Binder::dummy(ty::ExistentialPredicate::AutoTrait(trait_ref.trait_ref().def_id()))
|
||||||
});
|
});
|
||||||
|
// N.b. principal, projections, auto traits
|
||||||
|
// FIXME: This is actually wrong with multiple principals in regards to symbol mangling
|
||||||
let mut v = regular_trait_predicates
|
let mut v = regular_trait_predicates
|
||||||
.chain(auto_trait_predicates)
|
|
||||||
.chain(
|
.chain(
|
||||||
existential_projections.map(|x| x.map_bound(ty::ExistentialPredicate::Projection)),
|
existential_projections.map(|x| x.map_bound(ty::ExistentialPredicate::Projection)),
|
||||||
)
|
)
|
||||||
|
.chain(auto_trait_predicates)
|
||||||
.collect::<SmallVec<[_; 8]>>();
|
.collect::<SmallVec<[_; 8]>>();
|
||||||
v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
|
v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
|
||||||
v.dedup();
|
v.dedup();
|
||||||
|
56
src/test/ui/symbol-names/trait-objects.legacy.stderr
Normal file
56
src/test/ui/symbol-names/trait-objects.legacy.stderr
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
error: symbol-name(_ZN136_$LT$$RF$dyn$u20$core..ops..function..FnMut$LT$$LP$$RF$u8$C$$RP$$GT$$u2b$Output$u20$$u3d$$u20$$LP$$RP$$u20$as$u20$trait_objects..Bar$GT$6method17h1e14a5f2d365272fE)
|
||||||
|
--> $DIR/trait-objects.rs:15:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_symbol_name]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: demangling(<&dyn core::ops::function::FnMut<(&u8,)>+Output = () as trait_objects::Bar>::method::h1e14a5f2d365272f)
|
||||||
|
--> $DIR/trait-objects.rs:15:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_symbol_name]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: demangling-alt(<&dyn core::ops::function::FnMut<(&u8,)>+Output = () as trait_objects::Bar>::method)
|
||||||
|
--> $DIR/trait-objects.rs:15:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_symbol_name]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: symbol-name(_ZN159_$LT$$RF$dyn$u20$core..ops..function..FnMut$LT$$LP$$RF$u8$C$$RP$$GT$$u2b$Output$u20$$u3d$$u20$$LP$$RP$$u2b$core..marker..Send$u20$as$u20$trait_objects..Foo$GT$6method17he7a07961c9aaa367E)
|
||||||
|
--> $DIR/trait-objects.rs:30:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_symbol_name]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: demangling(<&dyn core::ops::function::FnMut<(&u8,)>+Output = ()+core::marker::Send as trait_objects::Foo>::method::he7a07961c9aaa367)
|
||||||
|
--> $DIR/trait-objects.rs:30:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_symbol_name]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: demangling-alt(<&dyn core::ops::function::FnMut<(&u8,)>+Output = ()+core::marker::Send as trait_objects::Foo>::method)
|
||||||
|
--> $DIR/trait-objects.rs:30:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_symbol_name]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: symbol-name(_ZN159_$LT$$RF$dyn$u20$core..ops..function..FnMut$LT$$LP$$RF$u8$C$$RP$$GT$$u2b$Output$u20$$u3d$$u20$$LP$$RP$$u2b$core..marker..Send$u20$as$u20$trait_objects..Baz$GT$6method17ha53e6f99bf033f0bE)
|
||||||
|
--> $DIR/trait-objects.rs:45:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_symbol_name]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: demangling(<&dyn core::ops::function::FnMut<(&u8,)>+Output = ()+core::marker::Send as trait_objects::Baz>::method::ha53e6f99bf033f0b)
|
||||||
|
--> $DIR/trait-objects.rs:45:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_symbol_name]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: demangling-alt(<&dyn core::ops::function::FnMut<(&u8,)>+Output = ()+core::marker::Send as trait_objects::Baz>::method)
|
||||||
|
--> $DIR/trait-objects.rs:45:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_symbol_name]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 9 previous errors
|
||||||
|
|
56
src/test/ui/symbol-names/trait-objects.rs
Normal file
56
src/test/ui/symbol-names/trait-objects.rs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// Ensure that trait objects don't include more than one binder. See #83611
|
||||||
|
|
||||||
|
// build-fail
|
||||||
|
// revisions: legacy v0
|
||||||
|
//[legacy]compile-flags: -Z symbol-mangling-version=legacy
|
||||||
|
//[v0]compile-flags: -Z symbol-mangling-version=v0
|
||||||
|
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
|
trait Bar {
|
||||||
|
fn method(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Bar for &dyn FnMut(&u8) {
|
||||||
|
#[rustc_symbol_name]
|
||||||
|
//[legacy]~^ ERROR symbol-name
|
||||||
|
//[legacy]~| ERROR demangling
|
||||||
|
//[legacy]~| ERROR demangling-alt
|
||||||
|
//[v0]~^^^^ ERROR symbol-name
|
||||||
|
//[v0]~| ERROR demangling
|
||||||
|
//[v0]~| ERROR demangling-alt
|
||||||
|
fn method(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Foo {
|
||||||
|
fn method(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo for &(dyn FnMut(&u8) + for<'b> Send) {
|
||||||
|
#[rustc_symbol_name]
|
||||||
|
//[legacy]~^ ERROR symbol-name
|
||||||
|
//[legacy]~| ERROR demangling
|
||||||
|
//[legacy]~| ERROR demangling-alt
|
||||||
|
//[v0]~^^^^ ERROR symbol-name
|
||||||
|
//[v0]~| ERROR demangling
|
||||||
|
//[v0]~| ERROR demangling-alt
|
||||||
|
fn method(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Baz {
|
||||||
|
fn method(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Baz for &(dyn for<'b> Send + FnMut(&u8)) {
|
||||||
|
#[rustc_symbol_name]
|
||||||
|
//[legacy]~^ ERROR symbol-name
|
||||||
|
//[legacy]~| ERROR demangling
|
||||||
|
//[legacy]~| ERROR demangling-alt
|
||||||
|
//[v0]~^^^^ ERROR symbol-name
|
||||||
|
//[v0]~| ERROR demangling
|
||||||
|
//[v0]~| ERROR demangling-alt
|
||||||
|
fn method(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}
|
56
src/test/ui/symbol-names/trait-objects.v0.stderr
Normal file
56
src/test/ui/symbol-names/trait-objects.v0.stderr
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
error: symbol-name(_RNvXCs21hi0yVfW1J_13trait_objectsRDG_INtNtNtCs54lBhuwykzk_4core3ops8function5FnMutTRL0_hEEp6OutputuEL_NtB2_3Bar6method)
|
||||||
|
--> $DIR/trait-objects.rs:15:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_symbol_name]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: demangling(<&dyn for<'a> core[3b0e14d6e1ad42d0]::ops::function::FnMut<(&'a u8,), Output = ()> as trait_objects[17891616a171812d]::Bar>::method)
|
||||||
|
--> $DIR/trait-objects.rs:15:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_symbol_name]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: demangling-alt(<&dyn for<'a> core::ops::function::FnMut<(&'a u8,), Output = ()> as trait_objects::Bar>::method)
|
||||||
|
--> $DIR/trait-objects.rs:15:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_symbol_name]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: symbol-name(_RNvXs_Cs21hi0yVfW1J_13trait_objectsRDG_INtNtNtCs54lBhuwykzk_4core3ops8function5FnMutTRL0_hEEp6OutputuNtNtBI_6marker4SendEL_NtB4_3Foo6method)
|
||||||
|
--> $DIR/trait-objects.rs:30:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_symbol_name]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: demangling(<&dyn for<'a> core[3b0e14d6e1ad42d0]::ops::function::FnMut<(&'a u8,), Output = ()> + core[3b0e14d6e1ad42d0]::marker::Send as trait_objects[17891616a171812d]::Foo>::method)
|
||||||
|
--> $DIR/trait-objects.rs:30:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_symbol_name]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: demangling-alt(<&dyn for<'a> core::ops::function::FnMut<(&'a u8,), Output = ()> + core::marker::Send as trait_objects::Foo>::method)
|
||||||
|
--> $DIR/trait-objects.rs:30:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_symbol_name]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: symbol-name(_RNvXs0_Cs21hi0yVfW1J_13trait_objectsRDG_INtNtNtCs54lBhuwykzk_4core3ops8function5FnMutTRL0_hEEp6OutputuNtNtBJ_6marker4SendEL_NtB5_3Baz6method)
|
||||||
|
--> $DIR/trait-objects.rs:45:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_symbol_name]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: demangling(<&dyn for<'a> core[3b0e14d6e1ad42d0]::ops::function::FnMut<(&'a u8,), Output = ()> + core[3b0e14d6e1ad42d0]::marker::Send as trait_objects[17891616a171812d]::Baz>::method)
|
||||||
|
--> $DIR/trait-objects.rs:45:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_symbol_name]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: demangling-alt(<&dyn for<'a> core::ops::function::FnMut<(&'a u8,), Output = ()> + core::marker::Send as trait_objects::Baz>::method)
|
||||||
|
--> $DIR/trait-objects.rs:45:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_symbol_name]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 9 previous errors
|
||||||
|
|
Loading…
Reference in New Issue
Block a user