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