@@ -676,17 +676,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
676
676
fn_host_effect : ty:: Const < ' tcx > ,
677
677
) -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
678
678
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 ( ) ) ;
679
681
680
682
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
-
690
683
let sig = self_ty. fn_sig ( tcx) ;
691
684
let trait_ref = closure_trait_ref_and_return_type (
692
685
tcx,
@@ -698,7 +691,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
698
691
)
699
692
. map_bound ( |( trait_ref, _) | trait_ref) ;
700
693
701
- let mut nested = self . confirm_poly_trait_refs ( obligation, trait_ref) ?;
694
+ let mut nested = self . equate_trait_refs (
695
+ & obligation. cause ,
696
+ obligation. param_env ,
697
+ placeholder_predicate. trait_ref ,
698
+ trait_ref,
699
+ ) ?;
702
700
let cause = obligation. derived_cause ( BuiltinDerivedObligation ) ;
703
701
704
702
// Confirm the `type Output: Sized;` bound that is present on `FnOnce`
@@ -746,10 +744,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
746
744
& mut self ,
747
745
obligation : & PolyTraitObligation < ' tcx > ,
748
746
) -> 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 ( ) ) ;
747
+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
748
+ let self_ty = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
753
749
let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
754
750
bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
755
751
} ;
@@ -758,23 +754,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
758
754
759
755
let coroutine_sig = args. as_coroutine ( ) . sig ( ) ;
760
756
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
-
770
757
let ( trait_ref, _, _) = super :: util:: coroutine_trait_ref_and_outputs (
771
758
self . tcx ( ) ,
772
759
obligation. predicate . def_id ( ) ,
773
760
self_ty,
774
761
coroutine_sig,
775
762
) ;
776
763
777
- let nested = self . confirm_poly_trait_refs ( obligation, ty:: Binder :: dummy ( trait_ref) ) ?;
764
+ let nested = self . equate_trait_refs (
765
+ & obligation. cause ,
766
+ obligation. param_env ,
767
+ placeholder_predicate. trait_ref ,
768
+ ty:: Binder :: dummy ( trait_ref) ,
769
+ ) ?;
778
770
debug ! ( ?trait_ref, ?nested, "coroutine candidate obligations" ) ;
779
771
780
772
Ok ( nested)
@@ -784,10 +776,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
784
776
& mut self ,
785
777
obligation : & PolyTraitObligation < ' tcx > ,
786
778
) -> 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 ( ) ) ;
779
+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
780
+ let self_ty = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
791
781
let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
792
782
bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
793
783
} ;
@@ -799,11 +789,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
799
789
let ( trait_ref, _) = super :: util:: future_trait_ref_and_outputs (
800
790
self . tcx ( ) ,
801
791
obligation. predicate . def_id ( ) ,
802
- obligation . predicate . no_bound_vars ( ) . expect ( "future has no bound vars" ) . self_ty ( ) ,
792
+ self_ty,
803
793
coroutine_sig,
804
794
) ;
805
795
806
- let nested = self . confirm_poly_trait_refs ( obligation, ty:: Binder :: dummy ( trait_ref) ) ?;
796
+ let nested = self . equate_trait_refs (
797
+ & obligation. cause ,
798
+ obligation. param_env ,
799
+ placeholder_predicate. trait_ref ,
800
+ ty:: Binder :: dummy ( trait_ref) ,
801
+ ) ?;
807
802
debug ! ( ?trait_ref, ?nested, "future candidate obligations" ) ;
808
803
809
804
Ok ( nested)
@@ -813,10 +808,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
813
808
& mut self ,
814
809
obligation : & PolyTraitObligation < ' tcx > ,
815
810
) -> 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 ( ) ) ;
811
+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
812
+ let self_ty = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
820
813
let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
821
814
bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
822
815
} ;
@@ -828,11 +821,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
828
821
let ( trait_ref, _) = super :: util:: iterator_trait_ref_and_outputs (
829
822
self . tcx ( ) ,
830
823
obligation. predicate . def_id ( ) ,
831
- obligation . predicate . no_bound_vars ( ) . expect ( "iterator has no bound vars" ) . self_ty ( ) ,
824
+ self_ty,
832
825
gen_sig,
833
826
) ;
834
827
835
- let nested = self . confirm_poly_trait_refs ( obligation, ty:: Binder :: dummy ( trait_ref) ) ?;
828
+ let nested = self . equate_trait_refs (
829
+ & obligation. cause ,
830
+ obligation. param_env ,
831
+ placeholder_predicate. trait_ref ,
832
+ ty:: Binder :: dummy ( trait_ref) ,
833
+ ) ?;
836
834
debug ! ( ?trait_ref, ?nested, "iterator candidate obligations" ) ;
837
835
838
836
Ok ( nested)
@@ -842,10 +840,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
842
840
& mut self ,
843
841
obligation : & PolyTraitObligation < ' tcx > ,
844
842
) -> 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 ( ) ) ;
843
+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
844
+ let self_ty = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
849
845
let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
850
846
bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
851
847
} ;
@@ -857,11 +853,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
857
853
let ( trait_ref, _) = super :: util:: async_iterator_trait_ref_and_outputs (
858
854
self . tcx ( ) ,
859
855
obligation. predicate . def_id ( ) ,
860
- obligation . predicate . no_bound_vars ( ) . expect ( "iterator has no bound vars" ) . self_ty ( ) ,
856
+ self_ty,
861
857
gen_sig,
862
858
) ;
863
859
864
- let nested = self . confirm_poly_trait_refs ( obligation, ty:: Binder :: dummy ( trait_ref) ) ?;
860
+ let nested = self . equate_trait_refs (
861
+ & obligation. cause ,
862
+ obligation. param_env ,
863
+ placeholder_predicate. trait_ref ,
864
+ ty:: Binder :: dummy ( trait_ref) ,
865
+ ) ?;
865
866
debug ! ( ?trait_ref, ?nested, "iterator candidate obligations" ) ;
866
867
867
868
Ok ( nested)
@@ -872,14 +873,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
872
873
& mut self ,
873
874
obligation : & PolyTraitObligation < ' tcx > ,
874
875
) -> 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 ( ) ) ;
876
+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
877
+ let self_ty: Ty < ' _ > = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
878
+
879
879
let trait_ref = match * self_ty. kind ( ) {
880
- ty:: Closure ( _, args) => {
881
- self . closure_trait_ref_unnormalized ( obligation, args, self . tcx ( ) . consts . true_ )
882
- }
880
+ ty:: Closure ( ..) => self . closure_trait_ref_unnormalized (
881
+ self_ty,
882
+ obligation. predicate . def_id ( ) ,
883
+ self . tcx ( ) . consts . true_ ,
884
+ ) ,
883
885
ty:: CoroutineClosure ( _, args) => {
884
886
args. as_coroutine_closure ( ) . coroutine_closure_sig ( ) . map_bound ( |sig| {
885
887
ty:: TraitRef :: new (
@@ -894,16 +896,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
894
896
}
895
897
} ;
896
898
897
- self . confirm_poly_trait_refs ( obligation, trait_ref)
899
+ self . equate_trait_refs (
900
+ & obligation. cause ,
901
+ obligation. param_env ,
902
+ placeholder_predicate. trait_ref ,
903
+ trait_ref,
904
+ )
898
905
}
899
906
900
907
#[ instrument( skip( self ) , level = "debug" ) ]
901
908
fn confirm_async_closure_candidate (
902
909
& mut self ,
903
910
obligation : & PolyTraitObligation < ' tcx > ,
904
911
) -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
912
+ let placeholder_predicate = self . infcx . enter_forall_and_leak_universe ( obligation. predicate ) ;
913
+ let self_ty = self . infcx . shallow_resolve ( placeholder_predicate. self_ty ( ) ) ;
914
+
905
915
let tcx = self . tcx ( ) ;
906
- let self_ty = self . infcx . shallow_resolve ( obligation. self_ty ( ) . skip_binder ( ) ) ;
907
916
908
917
let mut nested = vec ! [ ] ;
909
918
let ( trait_ref, kind_ty) = match * self_ty. kind ( ) {
@@ -970,7 +979,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
970
979
_ => bug ! ( "expected callable type for AsyncFn candidate" ) ,
971
980
} ;
972
981
973
- nested. extend ( self . confirm_poly_trait_refs ( obligation, trait_ref) ?) ;
982
+ nested. extend ( self . equate_trait_refs (
983
+ & obligation. cause ,
984
+ obligation. param_env ,
985
+ placeholder_predicate. trait_ref ,
986
+ trait_ref,
987
+ ) ?) ;
974
988
975
989
let goal_kind =
976
990
self . tcx ( ) . async_fn_trait_kind_from_def_id ( obligation. predicate . def_id ( ) ) . unwrap ( ) ;
@@ -1023,42 +1037,42 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1023
1037
/// selection of the impl. Therefore, if there is a mismatch, we
1024
1038
/// report an error to the user.
1025
1039
#[ instrument( skip( self ) , level = "trace" ) ]
1026
- fn confirm_poly_trait_refs (
1040
+ fn equate_trait_refs (
1027
1041
& mut self ,
1028
- obligation : & PolyTraitObligation < ' tcx > ,
1029
- self_ty_trait_ref : ty:: PolyTraitRef < ' tcx > ,
1042
+ cause : & ObligationCause < ' tcx > ,
1043
+ param_env : ty:: ParamEnv < ' tcx > ,
1044
+ obligation_trait_ref : ty:: TraitRef < ' tcx > ,
1045
+ found_trait_ref : ty:: PolyTraitRef < ' tcx > ,
1030
1046
) -> 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 (
1034
- obligation. cause . span ,
1047
+ let found_trait_ref = self . infcx . instantiate_binder_with_fresh_vars (
1048
+ cause. span ,
1035
1049
HigherRankedType ,
1036
- self_ty_trait_ref ,
1050
+ found_trait_ref ,
1037
1051
) ;
1038
1052
// Normalize the obligation and expected trait refs together, because why not
1039
- let Normalized { obligations : nested, value : ( obligation_trait_ref, expected_trait_ref ) } =
1053
+ let Normalized { obligations : nested, value : ( obligation_trait_ref, found_trait_ref ) } =
1040
1054
ensure_sufficient_stack ( || {
1041
1055
normalize_with_depth (
1042
1056
self ,
1043
- obligation . param_env ,
1044
- obligation . cause . clone ( ) ,
1045
- obligation . recursion_depth + 1 ,
1046
- ( obligation_trait_ref, self_ty_trait_ref ) ,
1057
+ param_env,
1058
+ cause. clone ( ) ,
1059
+ 0 ,
1060
+ ( obligation_trait_ref, found_trait_ref ) ,
1047
1061
)
1048
1062
} ) ;
1049
1063
1050
1064
// needed to define opaque types for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs
1051
1065
self . infcx
1052
- . at ( & obligation . cause , obligation . param_env )
1053
- . eq ( DefineOpaqueTypes :: Yes , obligation_trait_ref, expected_trait_ref )
1066
+ . at ( & cause, param_env)
1067
+ . eq ( DefineOpaqueTypes :: Yes , obligation_trait_ref, found_trait_ref )
1054
1068
. map ( |InferOk { mut obligations, .. } | {
1055
1069
obligations. extend ( nested) ;
1056
1070
obligations
1057
1071
} )
1058
1072
. map_err ( |terr| {
1059
1073
SignatureMismatch ( Box :: new ( SignatureMismatchData {
1060
1074
expected_trait_ref : ty:: Binder :: dummy ( obligation_trait_ref) ,
1061
- found_trait_ref : ty:: Binder :: dummy ( expected_trait_ref ) ,
1075
+ found_trait_ref : ty:: Binder :: dummy ( found_trait_ref ) ,
1062
1076
terr,
1063
1077
} ) )
1064
1078
} )
0 commit comments