@@ -28,7 +28,7 @@ use crate::traits::{
28
28
BuiltinDerivedObligation , ImplDerivedObligation , ImplDerivedObligationCause , ImplSource ,
29
29
ImplSourceUserDefinedData , Normalized , Obligation , ObligationCause , PolyTraitObligation ,
30
30
PredicateObligation , Selection , SelectionError , SignatureMismatch , TraitNotObjectSafe ,
31
- Unimplemented ,
31
+ TraitObligation , Unimplemented ,
32
32
} ;
33
33
34
34
use super :: BuiltinImplConditions ;
@@ -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,8 @@ 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 =
697
+ self . equate_trait_refs ( obligation. with ( tcx, placeholder_predicate) , trait_ref) ?;
704
698
let cause = obligation. derived_cause ( BuiltinDerivedObligation ) ;
705
699
706
700
// Confirm the `type Output: Sized;` bound that is present on `FnOnce`
@@ -748,10 +742,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
748
742
& mut self ,
749
743
obligation : & PolyTraitObligation < ' tcx > ,
750
744
) -> 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 ( ) ) ;
755
747
let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
756
748
bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
757
749
} ;
@@ -760,23 +752,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
760
752
761
753
let coroutine_sig = args. as_coroutine ( ) . sig ( ) ;
762
754
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
755
let ( trait_ref, _, _) = super :: util:: coroutine_trait_ref_and_outputs (
773
756
self . tcx ( ) ,
774
757
obligation. predicate . def_id ( ) ,
775
758
self_ty,
776
759
coroutine_sig,
777
760
) ;
778
761
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
+ ) ?;
780
766
debug ! ( ?trait_ref, ?nested, "coroutine candidate obligations" ) ;
781
767
782
768
Ok ( nested)
@@ -786,10 +772,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
786
772
& mut self ,
787
773
obligation : & PolyTraitObligation < ' tcx > ,
788
774
) -> 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 ( ) ) ;
793
777
let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
794
778
bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
795
779
} ;
@@ -801,11 +785,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
801
785
let ( trait_ref, _) = super :: util:: future_trait_ref_and_outputs (
802
786
self . tcx ( ) ,
803
787
obligation. predicate . def_id ( ) ,
804
- obligation . predicate . no_bound_vars ( ) . expect ( "future has no bound vars" ) . self_ty ( ) ,
788
+ self_ty,
805
789
coroutine_sig,
806
790
) ;
807
791
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
+ ) ?;
809
796
debug ! ( ?trait_ref, ?nested, "future candidate obligations" ) ;
810
797
811
798
Ok ( nested)
@@ -815,10 +802,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
815
802
& mut self ,
816
803
obligation : & PolyTraitObligation < ' tcx > ,
817
804
) -> 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 ( ) ) ;
822
807
let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
823
808
bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
824
809
} ;
@@ -830,11 +815,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
830
815
let ( trait_ref, _) = super :: util:: iterator_trait_ref_and_outputs (
831
816
self . tcx ( ) ,
832
817
obligation. predicate . def_id ( ) ,
833
- obligation . predicate . no_bound_vars ( ) . expect ( "iterator has no bound vars" ) . self_ty ( ) ,
818
+ self_ty,
834
819
gen_sig,
835
820
) ;
836
821
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
+ ) ?;
838
826
debug ! ( ?trait_ref, ?nested, "iterator candidate obligations" ) ;
839
827
840
828
Ok ( nested)
@@ -844,10 +832,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
844
832
& mut self ,
845
833
obligation : & PolyTraitObligation < ' tcx > ,
846
834
) -> 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 ( ) ) ;
851
837
let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
852
838
bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
853
839
} ;
@@ -859,11 +845,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
859
845
let ( trait_ref, _) = super :: util:: async_iterator_trait_ref_and_outputs (
860
846
self . tcx ( ) ,
861
847
obligation. predicate . def_id ( ) ,
862
- obligation . predicate . no_bound_vars ( ) . expect ( "iterator has no bound vars" ) . self_ty ( ) ,
848
+ self_ty,
863
849
gen_sig,
864
850
) ;
865
851
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
+ ) ?;
867
856
debug ! ( ?trait_ref, ?nested, "iterator candidate obligations" ) ;
868
857
869
858
Ok ( nested)
@@ -874,14 +863,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
874
863
& mut self ,
875
864
obligation : & PolyTraitObligation < ' tcx > ,
876
865
) -> 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
+
881
869
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
+ ) ,
885
875
ty:: CoroutineClosure ( _, args) => {
886
876
args. as_coroutine_closure ( ) . coroutine_closure_sig ( ) . map_bound ( |sig| {
887
877
ty:: TraitRef :: new (
@@ -896,16 +886,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
896
886
}
897
887
} ;
898
888
899
- self . confirm_poly_trait_refs ( obligation, trait_ref)
889
+ self . equate_trait_refs ( obligation. with ( self . tcx ( ) , placeholder_predicate ) , trait_ref)
900
890
}
901
891
902
892
#[ instrument( skip( self ) , level = "debug" ) ]
903
893
fn confirm_async_closure_candidate (
904
894
& mut self ,
905
895
obligation : & PolyTraitObligation < ' tcx > ,
906
896
) -> 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
+
907
900
let tcx = self . tcx ( ) ;
908
- let self_ty = self . infcx . shallow_resolve ( obligation. self_ty ( ) . skip_binder ( ) ) ;
909
901
910
902
let mut nested = vec ! [ ] ;
911
903
let ( trait_ref, kind_ty) = match * self_ty. kind ( ) {
@@ -972,7 +964,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
972
964
_ => bug ! ( "expected callable type for AsyncFn candidate" ) ,
973
965
} ;
974
966
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
+ ) ;
976
970
977
971
let goal_kind =
978
972
self . tcx ( ) . async_fn_trait_kind_from_def_id ( obligation. predicate . def_id ( ) ) . unwrap ( ) ;
@@ -1025,42 +1019,40 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1025
1019
/// selection of the impl. Therefore, if there is a mismatch, we
1026
1020
/// report an error to the user.
1027
1021
#[ instrument( skip( self ) , level = "trace" ) ]
1028
- fn confirm_poly_trait_refs (
1022
+ fn equate_trait_refs (
1029
1023
& 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 > ,
1032
1026
) -> 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 (
1036
1028
obligation. cause . span ,
1037
1029
HigherRankedType ,
1038
- self_ty_trait_ref ,
1030
+ found_trait_ref ,
1039
1031
) ;
1040
1032
// 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 ) } =
1042
1034
ensure_sufficient_stack ( || {
1043
1035
normalize_with_depth (
1044
1036
self ,
1045
1037
obligation. param_env ,
1046
1038
obligation. cause . clone ( ) ,
1047
1039
obligation. recursion_depth + 1 ,
1048
- ( obligation_trait_ref , self_ty_trait_ref ) ,
1040
+ ( obligation . predicate . trait_ref , found_trait_ref ) ,
1049
1041
)
1050
1042
} ) ;
1051
1043
1052
1044
// needed to define opaque types for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs
1053
1045
self . infcx
1054
1046
. 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 )
1056
1048
. map ( |InferOk { mut obligations, .. } | {
1057
1049
obligations. extend ( nested) ;
1058
1050
obligations
1059
1051
} )
1060
1052
. map_err ( |terr| {
1061
1053
SignatureMismatch ( Box :: new ( SignatureMismatchData {
1062
1054
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 ) ,
1064
1056
terr,
1065
1057
} ) )
1066
1058
} )
0 commit comments