@@ -485,9 +485,39 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
485
485
mut self ,
486
486
predicates : & ' tcx ty:: List < ty:: Binder < ' tcx , ty:: ExistentialPredicate < ' tcx > > > ,
487
487
) -> 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 ( ) {
491
521
ty:: ExistentialPredicate :: Trait ( trait_ref) => {
492
522
// Use a type that can't appear in defaults of type parameters.
493
523
let dummy_self = cx. tcx . mk_ty_infer ( ty:: FreshTy ( 0 ) ) ;
@@ -504,9 +534,10 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
504
534
cx = cx. print_def_path ( * def_id, & [ ] ) ?;
505
535
}
506
536
}
507
- Ok ( cx)
508
- } ) ?;
509
- }
537
+ }
538
+ Ok ( cx)
539
+ } ) ?;
540
+
510
541
self . push ( "E" ) ;
511
542
Ok ( self )
512
543
}
0 commit comments