@@ -437,16 +437,16 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
437437 /// in the following way:
438438 /// - let `Receiver` be the type of the `self` argument, i.e `Self`, `&Self`, `Rc<Self>`
439439 /// - require the following bound:
440- /// forall(T: Trait) {
441- /// Receiver[Self => T]: DispatchFromDyn<Receiver[Self => dyn Trait]>
442- /// }
443- /// where `Foo[X => Y]` means "the same type as `Foo`, but with `X` replaced with `Y`"
440+ ///
441+ /// Receiver[Self => T]: DispatchFromDyn<Receiver[Self => dyn Trait]>
442+ ///
443+ /// where `Foo[X => Y]` means "the same type as `Foo`, but with `X` replaced with `Y`"
444444 /// (substitution notation).
445445 ///
446446 /// some examples of receiver types and their required obligation
447- /// - `&'a mut self` requires `&'a mut T : DispatchFromDyn<&'a mut dyn Trait>`
448- /// - `self: Rc<Self>` requires `Rc<T >: DispatchFromDyn<Rc<dyn Trait>>`
449- /// - `self: Pin<Box<Self>>` requires `Pin<Box<T >>: DispatchFromDyn<Pin<Box<dyn Trait>>>`
447+ /// - `&'a mut self` requires `&'a mut Self : DispatchFromDyn<&'a mut dyn Trait>`
448+ /// - `self: Rc<Self>` requires `Rc<Self >: DispatchFromDyn<Rc<dyn Trait>>`
449+ /// - `self: Pin<Box<Self>>` requires `Pin<Box<Self >>: DispatchFromDyn<Pin<Box<dyn Trait>>>`
450450 ///
451451 /// The only case where the receiver is not dispatchable, but is still a valid receiver
452452 /// type (just not object-safe), is when there is more than one level of pointer indirection.
@@ -456,14 +456,12 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
456456 /// contained by the trait object, because the object that needs to be coerced is behind
457457 /// a pointer.
458458 ///
459- /// In practice, there are issues with the above bound: `where` clauses that apply to `Self`
460- /// would have to apply to `T`, trait object types have a lot of parameters that need to
461- /// be filled in (lifetime and type parameters, and the lifetime of the actual object), and
462- /// I'm pretty sure using `dyn Trait` in the query causes another object-safety query for
463- /// `Trait`, resulting in cyclic queries. So in the implementation, we use the following,
464- /// more general bound:
459+ /// In practice, we cannot use `dyn Trait` explicitly in the obligation because it would result
460+ /// in a new check that `Trait` is object safe, creating a cycle. So instead, we fudge a little
461+ /// by introducing a new type parameter `U` such that `Self: Unsize<U>` and `U: Trait + ?Sized`,
462+ /// and use `U` in place of `dyn Trait`. Written as a chalk-style query:
465463 ///
466- /// forall (U: ?Sized) {
464+ /// forall (U: Trait + ?Sized) {
467465 /// if (Self: Unsize<U>) {
468466 /// Receiver: DispatchFromDyn<Receiver[Self => U]>
469467 /// }
@@ -493,6 +491,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
493491 return false ;
494492 } ;
495493
494+ // the type `U` in the query
496495 // use a bogus type parameter to mimick a forall(U) query using u32::MAX for now.
497496 // FIXME(mikeyhew) this is a total hack, and we should replace it when real forall queries
498497 // are implemented
@@ -501,34 +500,48 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
501500 Name :: intern ( "RustaceansAreAwesome" ) . as_interned_str ( ) ,
502501 ) ;
503502
504- // create a modified param env, with `Self: Unsize<U>` added to the caller bounds
503+ // `Receiver[Self => U]`
504+ let unsized_receiver_ty = self . receiver_for_self_ty (
505+ receiver_ty, unsized_self_ty, method. def_id
506+ ) ;
507+
508+ // create a modified param env, with `Self: Unsize<U>` and `U: Trait` added to caller bounds
509+ // `U: ?Sized` is already implied here
505510 let param_env = {
506511 let mut param_env = self . param_env ( method. def_id ) ;
507512
508- let predicate = ty:: TraitRef {
513+ // Self: Unsize<U>
514+ let unsize_predicate = ty:: TraitRef {
509515 def_id : unsize_did,
510516 substs : self . mk_substs_trait ( self . mk_self_type ( ) , & [ unsized_self_ty. into ( ) ] ) ,
511517 } . to_predicate ( ) ;
512518
519+ // U: Trait<Arg1, ..., ArgN>
520+ let trait_predicate = {
521+ let substs = Substs :: for_item ( self , method. container . assert_trait ( ) , |param, _| {
522+ if param. index == 0 {
523+ unsized_self_ty. into ( )
524+ } else {
525+ self . mk_param_from_def ( param)
526+ }
527+ } ) ;
528+
529+ ty:: TraitRef {
530+ def_id : unsize_did,
531+ substs,
532+ } . to_predicate ( )
533+ } ;
534+
513535 let caller_bounds: Vec < Predicate < ' tcx > > = param_env. caller_bounds . iter ( ) . cloned ( )
514- . chain ( iter:: once ( predicate) )
536+ . chain ( iter:: once ( unsize_predicate) )
537+ . chain ( iter:: once ( trait_predicate) )
515538 . collect ( ) ;
516539
517540 param_env. caller_bounds = self . intern_predicates ( & caller_bounds) ;
518541
519542 param_env
520543 } ;
521544
522- let receiver_substs = Substs :: for_item ( self , method. def_id , |param, _| {
523- if param. index == 0 {
524- unsized_self_ty. into ( )
525- } else {
526- self . mk_param_from_def ( param)
527- }
528- } ) ;
529- // the type `Receiver[Self => U]` in the query
530- let unsized_receiver_ty = receiver_ty. subst ( self , receiver_substs) ;
531-
532545 // Receiver: DispatchFromDyn<Receiver[Self => U]>
533546 let obligation = {
534547 let predicate = ty:: TraitRef {
0 commit comments