@@ -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 ;
@@ -676,17 +676,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
676676 fn_host_effect : ty:: Const < ' tcx > ,
677677 ) -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
678678 debug ! ( ?obligation, "confirm_fn_pointer_candidate" ) ;
679+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
680+ let self_ty = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
679681
680682 let tcx = self . tcx ( ) ;
681-
682- let Some ( self_ty) = self . infcx . shallow_resolve ( obligation. self_ty ( ) . no_bound_vars ( ) ) else {
683- // FIXME: Ideally we'd support `for<'a> fn(&'a ()): Fn(&'a ())`,
684- // but we do not currently. Luckily, such a bound is not
685- // particularly useful, so we don't expect users to write
686- // them often.
687- return Err ( SelectionError :: Unimplemented ) ;
688- } ;
689-
690683 let sig = self_ty. fn_sig ( tcx) ;
691684 let trait_ref = closure_trait_ref_and_return_type (
692685 tcx,
@@ -698,7 +691,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
698691 )
699692 . map_bound ( |( trait_ref, _) | trait_ref) ;
700693
701- let mut nested = self . confirm_poly_trait_refs ( obligation, trait_ref) ?;
694+ let mut nested =
695+ self . equate_trait_refs ( obligation. with ( tcx, placeholder_predicate) , trait_ref) ?;
702696 let cause = obligation. derived_cause ( BuiltinDerivedObligation ) ;
703697
704698 // Confirm the `type Output: Sized;` bound that is present on `FnOnce`
@@ -746,10 +740,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
746740 & mut self ,
747741 obligation : & PolyTraitObligation < ' tcx > ,
748742 ) -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
749- // Okay to skip binder because the args on coroutine types never
750- // touch bound regions, they just capture the in-scope
751- // type/region parameters.
752- let self_ty = self . infcx . shallow_resolve ( obligation. self_ty ( ) . skip_binder ( ) ) ;
743+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
744+ let self_ty = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
753745 let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
754746 bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
755747 } ;
@@ -758,23 +750,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
758750
759751 let coroutine_sig = args. as_coroutine ( ) . sig ( ) ;
760752
761- // NOTE: The self-type is a coroutine type and hence is
762- // in fact unparameterized (or at least does not reference any
763- // regions bound in the obligation).
764- let self_ty = obligation
765- . predicate
766- . self_ty ( )
767- . no_bound_vars ( )
768- . expect ( "unboxed closure type should not capture bound vars from the predicate" ) ;
769-
770753 let ( trait_ref, _, _) = super :: util:: coroutine_trait_ref_and_outputs (
771754 self . tcx ( ) ,
772755 obligation. predicate . def_id ( ) ,
773756 self_ty,
774757 coroutine_sig,
775758 ) ;
776759
777- let nested = self . confirm_poly_trait_refs ( obligation, ty:: Binder :: dummy ( trait_ref) ) ?;
760+ let nested = self . equate_trait_refs (
761+ obligation. with ( self . tcx ( ) , placeholder_predicate) ,
762+ ty:: Binder :: dummy ( trait_ref) ,
763+ ) ?;
778764 debug ! ( ?trait_ref, ?nested, "coroutine candidate obligations" ) ;
779765
780766 Ok ( nested)
@@ -784,10 +770,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
784770 & mut self ,
785771 obligation : & PolyTraitObligation < ' tcx > ,
786772 ) -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
787- // Okay to skip binder because the args on coroutine types never
788- // touch bound regions, they just capture the in-scope
789- // type/region parameters.
790- let self_ty = self . infcx . shallow_resolve ( obligation. self_ty ( ) . skip_binder ( ) ) ;
773+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
774+ let self_ty = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
791775 let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
792776 bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
793777 } ;
@@ -799,11 +783,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
799783 let ( trait_ref, _) = super :: util:: future_trait_ref_and_outputs (
800784 self . tcx ( ) ,
801785 obligation. predicate . def_id ( ) ,
802- obligation . predicate . no_bound_vars ( ) . expect ( "future has no bound vars" ) . self_ty ( ) ,
786+ self_ty,
803787 coroutine_sig,
804788 ) ;
805789
806- let nested = self . confirm_poly_trait_refs ( obligation, ty:: Binder :: dummy ( trait_ref) ) ?;
790+ let nested = self . equate_trait_refs (
791+ obligation. with ( self . tcx ( ) , placeholder_predicate) ,
792+ ty:: Binder :: dummy ( trait_ref) ,
793+ ) ?;
807794 debug ! ( ?trait_ref, ?nested, "future candidate obligations" ) ;
808795
809796 Ok ( nested)
@@ -813,10 +800,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
813800 & mut self ,
814801 obligation : & PolyTraitObligation < ' tcx > ,
815802 ) -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
816- // Okay to skip binder because the args on coroutine types never
817- // touch bound regions, they just capture the in-scope
818- // type/region parameters.
819- let self_ty = self . infcx . shallow_resolve ( obligation. self_ty ( ) . skip_binder ( ) ) ;
803+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
804+ let self_ty = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
820805 let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
821806 bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
822807 } ;
@@ -828,11 +813,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
828813 let ( trait_ref, _) = super :: util:: iterator_trait_ref_and_outputs (
829814 self . tcx ( ) ,
830815 obligation. predicate . def_id ( ) ,
831- obligation . predicate . no_bound_vars ( ) . expect ( "iterator has no bound vars" ) . self_ty ( ) ,
816+ self_ty,
832817 gen_sig,
833818 ) ;
834819
835- let nested = self . confirm_poly_trait_refs ( obligation, ty:: Binder :: dummy ( trait_ref) ) ?;
820+ let nested = self . equate_trait_refs (
821+ obligation. with ( self . tcx ( ) , placeholder_predicate) ,
822+ ty:: Binder :: dummy ( trait_ref) ,
823+ ) ?;
836824 debug ! ( ?trait_ref, ?nested, "iterator candidate obligations" ) ;
837825
838826 Ok ( nested)
@@ -842,10 +830,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
842830 & mut self ,
843831 obligation : & PolyTraitObligation < ' tcx > ,
844832 ) -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
845- // Okay to skip binder because the args on coroutine types never
846- // touch bound regions, they just capture the in-scope
847- // type/region parameters.
848- let self_ty = self . infcx . shallow_resolve ( obligation. self_ty ( ) . skip_binder ( ) ) ;
833+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
834+ let self_ty = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
849835 let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
850836 bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
851837 } ;
@@ -857,11 +843,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
857843 let ( trait_ref, _) = super :: util:: async_iterator_trait_ref_and_outputs (
858844 self . tcx ( ) ,
859845 obligation. predicate . def_id ( ) ,
860- obligation . predicate . no_bound_vars ( ) . expect ( "iterator has no bound vars" ) . self_ty ( ) ,
846+ self_ty,
861847 gen_sig,
862848 ) ;
863849
864- let nested = self . confirm_poly_trait_refs ( obligation, ty:: Binder :: dummy ( trait_ref) ) ?;
850+ let nested = self . equate_trait_refs (
851+ obligation. with ( self . tcx ( ) , placeholder_predicate) ,
852+ ty:: Binder :: dummy ( trait_ref) ,
853+ ) ?;
865854 debug ! ( ?trait_ref, ?nested, "iterator candidate obligations" ) ;
866855
867856 Ok ( nested)
@@ -872,14 +861,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
872861 & mut self ,
873862 obligation : & PolyTraitObligation < ' tcx > ,
874863 ) -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
875- // Okay to skip binder because the args on closure types never
876- // touch bound regions, they just capture the in-scope
877- // type/region parameters.
878- let self_ty = self . infcx . shallow_resolve ( obligation. self_ty ( ) . skip_binder ( ) ) ;
864+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
865+ let self_ty: Ty < ' _ > = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
866+
879867 let trait_ref = match * self_ty. kind ( ) {
880- ty:: Closure ( _, args) => {
881- self . closure_trait_ref_unnormalized ( obligation, args, self . tcx ( ) . consts . true_ )
882- }
868+ ty:: Closure ( ..) => self . closure_trait_ref_unnormalized (
869+ self_ty,
870+ obligation. predicate . def_id ( ) ,
871+ self . tcx ( ) . consts . true_ ,
872+ ) ,
883873 ty:: CoroutineClosure ( _, args) => {
884874 args. as_coroutine_closure ( ) . coroutine_closure_sig ( ) . map_bound ( |sig| {
885875 ty:: TraitRef :: new (
@@ -894,16 +884,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
894884 }
895885 } ;
896886
897- self . confirm_poly_trait_refs ( obligation, trait_ref)
887+ self . equate_trait_refs ( obligation. with ( self . tcx ( ) , placeholder_predicate ) , trait_ref)
898888 }
899889
900890 #[ instrument( skip( self ) , level = "debug" ) ]
901891 fn confirm_async_closure_candidate (
902892 & mut self ,
903893 obligation : & PolyTraitObligation < ' tcx > ,
904894 ) -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
895+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
896+ let self_ty = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
897+
905898 let tcx = self . tcx ( ) ;
906- let self_ty = self . infcx . shallow_resolve ( obligation. self_ty ( ) . skip_binder ( ) ) ;
907899
908900 let mut nested = vec ! [ ] ;
909901 let ( trait_ref, kind_ty) = match * self_ty. kind ( ) {
@@ -970,7 +962,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
970962 _ => bug ! ( "expected callable type for AsyncFn candidate" ) ,
971963 } ;
972964
973- nested. extend ( self . confirm_poly_trait_refs ( obligation, trait_ref) ?) ;
965+ nested. extend (
966+ self . equate_trait_refs ( obligation. with ( tcx, placeholder_predicate) , trait_ref) ?,
967+ ) ;
974968
975969 let goal_kind =
976970 self . tcx ( ) . async_fn_trait_kind_from_def_id ( obligation. predicate . def_id ( ) ) . unwrap ( ) ;
@@ -1023,42 +1017,40 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10231017 /// selection of the impl. Therefore, if there is a mismatch, we
10241018 /// report an error to the user.
10251019 #[ instrument( skip( self ) , level = "trace" ) ]
1026- fn confirm_poly_trait_refs (
1020+ fn equate_trait_refs (
10271021 & mut self ,
1028- obligation : & PolyTraitObligation < ' tcx > ,
1029- self_ty_trait_ref : ty:: PolyTraitRef < ' tcx > ,
1022+ obligation : TraitObligation < ' tcx > ,
1023+ found_trait_ref : ty:: PolyTraitRef < ' tcx > ,
10301024 ) -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
1031- let obligation_trait_ref =
1032- self . infcx . enter_forall_and_leak_universe ( obligation. predicate . to_poly_trait_ref ( ) ) ;
1033- let self_ty_trait_ref = self . infcx . instantiate_binder_with_fresh_vars (
1025+ let found_trait_ref = self . infcx . instantiate_binder_with_fresh_vars (
10341026 obligation. cause . span ,
10351027 HigherRankedType ,
1036- self_ty_trait_ref ,
1028+ found_trait_ref ,
10371029 ) ;
10381030 // Normalize the obligation and expected trait refs together, because why not
1039- let Normalized { obligations : nested, value : ( obligation_trait_ref, expected_trait_ref ) } =
1031+ let Normalized { obligations : nested, value : ( obligation_trait_ref, found_trait_ref ) } =
10401032 ensure_sufficient_stack ( || {
10411033 normalize_with_depth (
10421034 self ,
10431035 obligation. param_env ,
10441036 obligation. cause . clone ( ) ,
10451037 obligation. recursion_depth + 1 ,
1046- ( obligation_trait_ref , self_ty_trait_ref ) ,
1038+ ( obligation . predicate . trait_ref , found_trait_ref ) ,
10471039 )
10481040 } ) ;
10491041
10501042 // needed to define opaque types for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs
10511043 self . infcx
10521044 . at ( & obligation. cause , obligation. param_env )
1053- . eq ( DefineOpaqueTypes :: Yes , obligation_trait_ref, expected_trait_ref )
1045+ . eq ( DefineOpaqueTypes :: Yes , obligation_trait_ref, found_trait_ref )
10541046 . map ( |InferOk { mut obligations, .. } | {
10551047 obligations. extend ( nested) ;
10561048 obligations
10571049 } )
10581050 . map_err ( |terr| {
10591051 SignatureMismatch ( Box :: new ( SignatureMismatchData {
10601052 expected_trait_ref : ty:: Binder :: dummy ( obligation_trait_ref) ,
1061- found_trait_ref : ty:: Binder :: dummy ( expected_trait_ref ) ,
1053+ found_trait_ref : ty:: Binder :: dummy ( found_trait_ref ) ,
10621054 terr,
10631055 } ) )
10641056 } )
0 commit comments