@@ -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 }
0 commit comments