@@ -28,7 +28,7 @@ use crate::traits::{
2828 BuiltinDerivedObligation , ImplDerivedObligation , ImplDerivedObligationCause , ImplSource ,
2929 ImplSourceUserDefinedData , Normalized , Obligation , ObligationCause , PolyTraitObligation ,
3030 PredicateObligation , Selection , SelectionError , SignatureMismatch , TraitNotObjectSafe ,
31- Unimplemented ,
31+ TraitObligation , Unimplemented ,
3232} ;
3333
3434use super :: BuiltinImplConditions ;
@@ -678,17 +678,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
678678 fn_host_effect : ty:: Const < ' tcx > ,
679679 ) -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
680680 debug ! ( ?obligation, "confirm_fn_pointer_candidate" ) ;
681+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
682+ let self_ty = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
681683
682684 let tcx = self . tcx ( ) ;
683-
684- let Some ( self_ty) = self . infcx . shallow_resolve ( obligation. self_ty ( ) . no_bound_vars ( ) ) else {
685- // FIXME: Ideally we'd support `for<'a> fn(&'a ()): Fn(&'a ())`,
686- // but we do not currently. Luckily, such a bound is not
687- // particularly useful, so we don't expect users to write
688- // them often.
689- return Err ( SelectionError :: Unimplemented ) ;
690- } ;
691-
692685 let sig = self_ty. fn_sig ( tcx) ;
693686 let trait_ref = closure_trait_ref_and_return_type (
694687 tcx,
@@ -700,7 +693,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
700693 )
701694 . map_bound ( |( trait_ref, _) | trait_ref) ;
702695
703- let mut nested = self . confirm_poly_trait_refs ( obligation, trait_ref) ?;
696+ let mut nested =
697+ self . equate_trait_refs ( obligation. with ( tcx, placeholder_predicate) , trait_ref) ?;
704698 let cause = obligation. derived_cause ( BuiltinDerivedObligation ) ;
705699
706700 // Confirm the `type Output: Sized;` bound that is present on `FnOnce`
@@ -748,10 +742,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
748742 & mut self ,
749743 obligation : & PolyTraitObligation < ' tcx > ,
750744 ) -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
751- // Okay to skip binder because the args on coroutine types never
752- // touch bound regions, they just capture the in-scope
753- // type/region parameters.
754- let self_ty = self . infcx . shallow_resolve ( obligation. self_ty ( ) . skip_binder ( ) ) ;
745+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
746+ let self_ty = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
755747 let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
756748 bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
757749 } ;
@@ -760,23 +752,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
760752
761753 let coroutine_sig = args. as_coroutine ( ) . sig ( ) ;
762754
763- // NOTE: The self-type is a coroutine type and hence is
764- // in fact unparameterized (or at least does not reference any
765- // regions bound in the obligation).
766- let self_ty = obligation
767- . predicate
768- . self_ty ( )
769- . no_bound_vars ( )
770- . expect ( "unboxed closure type should not capture bound vars from the predicate" ) ;
771-
772755 let ( trait_ref, _, _) = super :: util:: coroutine_trait_ref_and_outputs (
773756 self . tcx ( ) ,
774757 obligation. predicate . def_id ( ) ,
775758 self_ty,
776759 coroutine_sig,
777760 ) ;
778761
779- let nested = self . confirm_poly_trait_refs ( obligation, ty:: Binder :: dummy ( trait_ref) ) ?;
762+ let nested = self . equate_trait_refs (
763+ obligation. with ( self . tcx ( ) , placeholder_predicate) ,
764+ ty:: Binder :: dummy ( trait_ref) ,
765+ ) ?;
780766 debug ! ( ?trait_ref, ?nested, "coroutine candidate obligations" ) ;
781767
782768 Ok ( nested)
@@ -786,10 +772,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
786772 & mut self ,
787773 obligation : & PolyTraitObligation < ' tcx > ,
788774 ) -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
789- // Okay to skip binder because the args on coroutine types never
790- // touch bound regions, they just capture the in-scope
791- // type/region parameters.
792- let self_ty = self . infcx . shallow_resolve ( obligation. self_ty ( ) . skip_binder ( ) ) ;
775+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
776+ let self_ty = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
793777 let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
794778 bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
795779 } ;
@@ -801,11 +785,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
801785 let ( trait_ref, _) = super :: util:: future_trait_ref_and_outputs (
802786 self . tcx ( ) ,
803787 obligation. predicate . def_id ( ) ,
804- obligation . predicate . no_bound_vars ( ) . expect ( "future has no bound vars" ) . self_ty ( ) ,
788+ self_ty,
805789 coroutine_sig,
806790 ) ;
807791
808- let nested = self . confirm_poly_trait_refs ( obligation, ty:: Binder :: dummy ( trait_ref) ) ?;
792+ let nested = self . equate_trait_refs (
793+ obligation. with ( self . tcx ( ) , placeholder_predicate) ,
794+ ty:: Binder :: dummy ( trait_ref) ,
795+ ) ?;
809796 debug ! ( ?trait_ref, ?nested, "future candidate obligations" ) ;
810797
811798 Ok ( nested)
@@ -815,10 +802,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
815802 & mut self ,
816803 obligation : & PolyTraitObligation < ' tcx > ,
817804 ) -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
818- // Okay to skip binder because the args on coroutine types never
819- // touch bound regions, they just capture the in-scope
820- // type/region parameters.
821- let self_ty = self . infcx . shallow_resolve ( obligation. self_ty ( ) . skip_binder ( ) ) ;
805+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
806+ let self_ty = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
822807 let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
823808 bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
824809 } ;
@@ -830,11 +815,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
830815 let ( trait_ref, _) = super :: util:: iterator_trait_ref_and_outputs (
831816 self . tcx ( ) ,
832817 obligation. predicate . def_id ( ) ,
833- obligation . predicate . no_bound_vars ( ) . expect ( "iterator has no bound vars" ) . self_ty ( ) ,
818+ self_ty,
834819 gen_sig,
835820 ) ;
836821
837- let nested = self . confirm_poly_trait_refs ( obligation, ty:: Binder :: dummy ( trait_ref) ) ?;
822+ let nested = self . equate_trait_refs (
823+ obligation. with ( self . tcx ( ) , placeholder_predicate) ,
824+ ty:: Binder :: dummy ( trait_ref) ,
825+ ) ?;
838826 debug ! ( ?trait_ref, ?nested, "iterator candidate obligations" ) ;
839827
840828 Ok ( nested)
@@ -844,10 +832,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
844832 & mut self ,
845833 obligation : & PolyTraitObligation < ' tcx > ,
846834 ) -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
847- // Okay to skip binder because the args on coroutine types never
848- // touch bound regions, they just capture the in-scope
849- // type/region parameters.
850- let self_ty = self . infcx . shallow_resolve ( obligation. self_ty ( ) . skip_binder ( ) ) ;
835+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
836+ let self_ty = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
851837 let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
852838 bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
853839 } ;
@@ -859,11 +845,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
859845 let ( trait_ref, _) = super :: util:: async_iterator_trait_ref_and_outputs (
860846 self . tcx ( ) ,
861847 obligation. predicate . def_id ( ) ,
862- obligation . predicate . no_bound_vars ( ) . expect ( "iterator has no bound vars" ) . self_ty ( ) ,
848+ self_ty,
863849 gen_sig,
864850 ) ;
865851
866- let nested = self . confirm_poly_trait_refs ( obligation, ty:: Binder :: dummy ( trait_ref) ) ?;
852+ let nested = self . equate_trait_refs (
853+ obligation. with ( self . tcx ( ) , placeholder_predicate) ,
854+ ty:: Binder :: dummy ( trait_ref) ,
855+ ) ?;
867856 debug ! ( ?trait_ref, ?nested, "iterator candidate obligations" ) ;
868857
869858 Ok ( nested)
@@ -874,14 +863,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
874863 & mut self ,
875864 obligation : & PolyTraitObligation < ' tcx > ,
876865 ) -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
877- // Okay to skip binder because the args on closure types never
878- // touch bound regions, they just capture the in-scope
879- // type/region parameters.
880- let self_ty = self . infcx . shallow_resolve ( obligation. self_ty ( ) . skip_binder ( ) ) ;
866+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
867+ let self_ty: Ty < ' _ > = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
868+
881869 let trait_ref = match * self_ty. kind ( ) {
882- ty:: Closure ( _, args) => {
883- self . closure_trait_ref_unnormalized ( obligation, args, self . tcx ( ) . consts . true_ )
884- }
870+ ty:: Closure ( ..) => self . closure_trait_ref_unnormalized (
871+ self_ty,
872+ obligation. predicate . def_id ( ) ,
873+ self . tcx ( ) . consts . true_ ,
874+ ) ,
885875 ty:: CoroutineClosure ( _, args) => {
886876 args. as_coroutine_closure ( ) . coroutine_closure_sig ( ) . map_bound ( |sig| {
887877 ty:: TraitRef :: new (
@@ -896,16 +886,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
896886 }
897887 } ;
898888
899- self . confirm_poly_trait_refs ( obligation, trait_ref)
889+ self . equate_trait_refs ( obligation. with ( self . tcx ( ) , placeholder_predicate ) , trait_ref)
900890 }
901891
902892 #[ instrument( skip( self ) , level = "debug" ) ]
903893 fn confirm_async_closure_candidate (
904894 & mut self ,
905895 obligation : & PolyTraitObligation < ' tcx > ,
906896 ) -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
897+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
898+ let self_ty = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
899+
907900 let tcx = self . tcx ( ) ;
908- let self_ty = self . infcx . shallow_resolve ( obligation. self_ty ( ) . skip_binder ( ) ) ;
909901
910902 let mut nested = vec ! [ ] ;
911903 let ( trait_ref, kind_ty) = match * self_ty. kind ( ) {
@@ -972,7 +964,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
972964 _ => bug ! ( "expected callable type for AsyncFn candidate" ) ,
973965 } ;
974966
975- nested. extend ( self . confirm_poly_trait_refs ( obligation, trait_ref) ?) ;
967+ nested. extend (
968+ self . equate_trait_refs ( obligation. with ( tcx, placeholder_predicate) , trait_ref) ?,
969+ ) ;
976970
977971 let goal_kind =
978972 self . tcx ( ) . async_fn_trait_kind_from_def_id ( obligation. predicate . def_id ( ) ) . unwrap ( ) ;
@@ -1025,42 +1019,40 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10251019 /// selection of the impl. Therefore, if there is a mismatch, we
10261020 /// report an error to the user.
10271021 #[ instrument( skip( self ) , level = "trace" ) ]
1028- fn confirm_poly_trait_refs (
1022+ fn equate_trait_refs (
10291023 & mut self ,
1030- obligation : & PolyTraitObligation < ' tcx > ,
1031- self_ty_trait_ref : ty:: PolyTraitRef < ' tcx > ,
1024+ obligation : TraitObligation < ' tcx > ,
1025+ found_trait_ref : ty:: PolyTraitRef < ' tcx > ,
10321026 ) -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
1033- let obligation_trait_ref =
1034- self . infcx . enter_forall_and_leak_universe ( obligation. predicate . to_poly_trait_ref ( ) ) ;
1035- let self_ty_trait_ref = self . infcx . instantiate_binder_with_fresh_vars (
1027+ let found_trait_ref = self . infcx . instantiate_binder_with_fresh_vars (
10361028 obligation. cause . span ,
10371029 HigherRankedType ,
1038- self_ty_trait_ref ,
1030+ found_trait_ref ,
10391031 ) ;
10401032 // Normalize the obligation and expected trait refs together, because why not
1041- let Normalized { obligations : nested, value : ( obligation_trait_ref, expected_trait_ref ) } =
1033+ let Normalized { obligations : nested, value : ( obligation_trait_ref, found_trait_ref ) } =
10421034 ensure_sufficient_stack ( || {
10431035 normalize_with_depth (
10441036 self ,
10451037 obligation. param_env ,
10461038 obligation. cause . clone ( ) ,
10471039 obligation. recursion_depth + 1 ,
1048- ( obligation_trait_ref , self_ty_trait_ref ) ,
1040+ ( obligation . predicate . trait_ref , found_trait_ref ) ,
10491041 )
10501042 } ) ;
10511043
10521044 // needed to define opaque types for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs
10531045 self . infcx
10541046 . at ( & obligation. cause , obligation. param_env )
1055- . eq ( DefineOpaqueTypes :: Yes , obligation_trait_ref, expected_trait_ref )
1047+ . eq ( DefineOpaqueTypes :: Yes , obligation_trait_ref, found_trait_ref )
10561048 . map ( |InferOk { mut obligations, .. } | {
10571049 obligations. extend ( nested) ;
10581050 obligations
10591051 } )
10601052 . map_err ( |terr| {
10611053 SignatureMismatch ( Box :: new ( SignatureMismatchData {
10621054 expected_trait_ref : ty:: Binder :: dummy ( obligation_trait_ref) ,
1063- found_trait_ref : ty:: Binder :: dummy ( expected_trait_ref ) ,
1055+ found_trait_ref : ty:: Binder :: dummy ( found_trait_ref ) ,
10641056 terr,
10651057 } ) )
10661058 } )
0 commit comments