@@ -583,27 +583,36 @@ fn receiver_is_dispatchable<'tcx>(
583
583
// create a modified param env, with `Self: Unsize<U>` and `U: Trait` (and all of
584
584
// its supertraits) added to caller bounds. `U: ?Sized` is already implied here.
585
585
let param_env = {
586
- let param_env = tcx. param_env ( method. def_id ) ;
586
+ // N.B. We generally want to emulate the construction of the `unnormalized_param_env`
587
+ // in the param-env query here. The fact that we don't just start with the clauses
588
+ // in the param-env of the method is because those are already normalized, and mixing
589
+ // normalized and unnormalized copies of predicates in `normalize_param_env_or_error`
590
+ // will cause ambiguity that the user can't really avoid.
591
+ //
592
+ // We leave out certain complexities of the param-env query here. Specifically, we:
593
+ // 1. Do not add `~const` bounds since there are no `dyn const Trait`s.
594
+ // 2. Do not add RPITIT self projection bounds for defaulted methods, since we
595
+ // are not constructing a param-env for "inside" of the body of the defaulted
596
+ // method, so we don't really care about projecting to a specific RPIT type,
597
+ // and because RPITITs are not dyn compatible (yet).
598
+ let mut predicates = tcx. predicates_of ( method. def_id ) . instantiate_identity ( tcx) . predicates ;
587
599
588
600
// Self: Unsize<U>
589
601
let unsize_predicate =
590
- ty:: TraitRef :: new ( tcx, unsize_did, [ tcx. types . self_param , unsized_self_ty] ) . upcast ( tcx) ;
602
+ ty:: TraitRef :: new ( tcx, unsize_did, [ tcx. types . self_param , unsized_self_ty] ) ;
603
+ predicates. push ( unsize_predicate. upcast ( tcx) ) ;
591
604
592
605
// U: Trait<Arg1, ..., ArgN>
593
- let trait_predicate = {
594
- let trait_def_id = method. trait_container ( tcx) . unwrap ( ) ;
595
- let args = GenericArgs :: for_item ( tcx, trait_def_id, |param, _| {
596
- if param. index == 0 { unsized_self_ty. into ( ) } else { tcx. mk_param_from_def ( param) }
597
- } ) ;
598
-
599
- ty:: TraitRef :: new_from_args ( tcx, trait_def_id, args) . upcast ( tcx)
600
- } ;
606
+ let trait_def_id = method. trait_container ( tcx) . unwrap ( ) ;
607
+ let args = GenericArgs :: for_item ( tcx, trait_def_id, |param, _| {
608
+ if param. index == 0 { unsized_self_ty. into ( ) } else { tcx. mk_param_from_def ( param) }
609
+ } ) ;
610
+ let trait_predicate = ty:: TraitRef :: new_from_args ( tcx, trait_def_id, args) ;
611
+ predicates. push ( trait_predicate. upcast ( tcx) ) ;
601
612
602
613
normalize_param_env_or_error (
603
614
tcx,
604
- ty:: ParamEnv :: new ( tcx. mk_clauses_from_iter (
605
- param_env. caller_bounds ( ) . iter ( ) . chain ( [ unsize_predicate, trait_predicate] ) ,
606
- ) ) ,
615
+ ty:: ParamEnv :: new ( tcx. mk_clauses ( & predicates) ) ,
607
616
ObligationCause :: dummy_with_span ( tcx. def_span ( method. def_id ) ) ,
608
617
)
609
618
} ;
0 commit comments