@@ -437,16 +437,16 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
437
437
/// in the following way:
438
438
/// - let `Receiver` be the type of the `self` argument, i.e `Self`, `&Self`, `Rc<Self>`
439
439
/// - 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`"
444
444
/// (substitution notation).
445
445
///
446
446
/// 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>>>`
450
450
///
451
451
/// The only case where the receiver is not dispatchable, but is still a valid receiver
452
452
/// 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> {
456
456
/// contained by the trait object, because the object that needs to be coerced is behind
457
457
/// a pointer.
458
458
///
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:
465
463
///
466
- /// forall (U: ?Sized) {
464
+ /// forall (U: Trait + ?Sized) {
467
465
/// if (Self: Unsize<U>) {
468
466
/// Receiver: DispatchFromDyn<Receiver[Self => U]>
469
467
/// }
@@ -493,6 +491,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
493
491
return false ;
494
492
} ;
495
493
494
+ // the type `U` in the query
496
495
// use a bogus type parameter to mimick a forall(U) query using u32::MAX for now.
497
496
// FIXME(mikeyhew) this is a total hack, and we should replace it when real forall queries
498
497
// are implemented
@@ -501,34 +500,48 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
501
500
Name :: intern ( "RustaceansAreAwesome" ) . as_interned_str ( ) ,
502
501
) ;
503
502
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
505
510
let param_env = {
506
511
let mut param_env = self . param_env ( method. def_id ) ;
507
512
508
- let predicate = ty:: TraitRef {
513
+ // Self: Unsize<U>
514
+ let unsize_predicate = ty:: TraitRef {
509
515
def_id : unsize_did,
510
516
substs : self . mk_substs_trait ( self . mk_self_type ( ) , & [ unsized_self_ty. into ( ) ] ) ,
511
517
} . to_predicate ( ) ;
512
518
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
+
513
535
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) )
515
538
. collect ( ) ;
516
539
517
540
param_env. caller_bounds = self . intern_predicates ( & caller_bounds) ;
518
541
519
542
param_env
520
543
} ;
521
544
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
-
532
545
// Receiver: DispatchFromDyn<Receiver[Self => U]>
533
546
let obligation = {
534
547
let predicate = ty:: TraitRef {
0 commit comments