@@ -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 ;
@@ -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,8 @@ 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 =
695
+ self . equate_trait_refs ( obligation. with ( tcx, placeholder_predicate) , trait_ref) ?;
702
696
let cause = obligation. derived_cause ( BuiltinDerivedObligation ) ;
703
697
704
698
// Confirm the `type Output: Sized;` bound that is present on `FnOnce`
@@ -746,10 +740,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
746
740
& mut self ,
747
741
obligation : & PolyTraitObligation < ' tcx > ,
748
742
) -> 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 ( ) ) ;
753
745
let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
754
746
bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
755
747
} ;
@@ -758,23 +750,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
758
750
759
751
let coroutine_sig = args. as_coroutine ( ) . sig ( ) ;
760
752
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
753
let ( trait_ref, _, _) = super :: util:: coroutine_trait_ref_and_outputs (
771
754
self . tcx ( ) ,
772
755
obligation. predicate . def_id ( ) ,
773
756
self_ty,
774
757
coroutine_sig,
775
758
) ;
776
759
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
+ ) ?;
778
764
debug ! ( ?trait_ref, ?nested, "coroutine candidate obligations" ) ;
779
765
780
766
Ok ( nested)
@@ -784,10 +770,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
784
770
& mut self ,
785
771
obligation : & PolyTraitObligation < ' tcx > ,
786
772
) -> 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 ( ) ) ;
791
775
let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
792
776
bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
793
777
} ;
@@ -799,11 +783,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
799
783
let ( trait_ref, _) = super :: util:: future_trait_ref_and_outputs (
800
784
self . tcx ( ) ,
801
785
obligation. predicate . def_id ( ) ,
802
- obligation . predicate . no_bound_vars ( ) . expect ( "future has no bound vars" ) . self_ty ( ) ,
786
+ self_ty,
803
787
coroutine_sig,
804
788
) ;
805
789
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
+ ) ?;
807
794
debug ! ( ?trait_ref, ?nested, "future candidate obligations" ) ;
808
795
809
796
Ok ( nested)
@@ -813,10 +800,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
813
800
& mut self ,
814
801
obligation : & PolyTraitObligation < ' tcx > ,
815
802
) -> 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 ( ) ) ;
820
805
let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
821
806
bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
822
807
} ;
@@ -828,11 +813,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
828
813
let ( trait_ref, _) = super :: util:: iterator_trait_ref_and_outputs (
829
814
self . tcx ( ) ,
830
815
obligation. predicate . def_id ( ) ,
831
- obligation . predicate . no_bound_vars ( ) . expect ( "iterator has no bound vars" ) . self_ty ( ) ,
816
+ self_ty,
832
817
gen_sig,
833
818
) ;
834
819
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
+ ) ?;
836
824
debug ! ( ?trait_ref, ?nested, "iterator candidate obligations" ) ;
837
825
838
826
Ok ( nested)
@@ -842,10 +830,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
842
830
& mut self ,
843
831
obligation : & PolyTraitObligation < ' tcx > ,
844
832
) -> 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 ( ) ) ;
849
835
let ty:: Coroutine ( coroutine_def_id, args) = * self_ty. kind ( ) else {
850
836
bug ! ( "closure candidate for non-closure {:?}" , obligation) ;
851
837
} ;
@@ -857,11 +843,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
857
843
let ( trait_ref, _) = super :: util:: async_iterator_trait_ref_and_outputs (
858
844
self . tcx ( ) ,
859
845
obligation. predicate . def_id ( ) ,
860
- obligation . predicate . no_bound_vars ( ) . expect ( "iterator has no bound vars" ) . self_ty ( ) ,
846
+ self_ty,
861
847
gen_sig,
862
848
) ;
863
849
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
+ ) ?;
865
854
debug ! ( ?trait_ref, ?nested, "iterator candidate obligations" ) ;
866
855
867
856
Ok ( nested)
@@ -872,14 +861,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
872
861
& mut self ,
873
862
obligation : & PolyTraitObligation < ' tcx > ,
874
863
) -> 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
+
879
867
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
+ ) ,
883
873
ty:: CoroutineClosure ( _, args) => {
884
874
args. as_coroutine_closure ( ) . coroutine_closure_sig ( ) . map_bound ( |sig| {
885
875
ty:: TraitRef :: new (
@@ -894,16 +884,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
894
884
}
895
885
} ;
896
886
897
- self . confirm_poly_trait_refs ( obligation, trait_ref)
887
+ self . equate_trait_refs ( obligation. with ( self . tcx ( ) , placeholder_predicate ) , trait_ref)
898
888
}
899
889
900
890
#[ instrument( skip( self ) , level = "debug" ) ]
901
891
fn confirm_async_closure_candidate (
902
892
& mut self ,
903
893
obligation : & PolyTraitObligation < ' tcx > ,
904
894
) -> 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
+
905
898
let tcx = self . tcx ( ) ;
906
- let self_ty = self . infcx . shallow_resolve ( obligation. self_ty ( ) . skip_binder ( ) ) ;
907
899
908
900
let mut nested = vec ! [ ] ;
909
901
let ( trait_ref, kind_ty) = match * self_ty. kind ( ) {
@@ -970,7 +962,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
970
962
_ => bug ! ( "expected callable type for AsyncFn candidate" ) ,
971
963
} ;
972
964
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
+ ) ;
974
968
975
969
let goal_kind =
976
970
self . tcx ( ) . async_fn_trait_kind_from_def_id ( obligation. predicate . def_id ( ) ) . unwrap ( ) ;
@@ -1023,42 +1017,40 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1023
1017
/// selection of the impl. Therefore, if there is a mismatch, we
1024
1018
/// report an error to the user.
1025
1019
#[ instrument( skip( self ) , level = "trace" ) ]
1026
- fn confirm_poly_trait_refs (
1020
+ fn equate_trait_refs (
1027
1021
& 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 > ,
1030
1024
) -> 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 (
1034
1026
obligation. cause . span ,
1035
1027
HigherRankedType ,
1036
- self_ty_trait_ref ,
1028
+ found_trait_ref ,
1037
1029
) ;
1038
1030
// 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 ) } =
1040
1032
ensure_sufficient_stack ( || {
1041
1033
normalize_with_depth (
1042
1034
self ,
1043
1035
obligation. param_env ,
1044
1036
obligation. cause . clone ( ) ,
1045
1037
obligation. recursion_depth + 1 ,
1046
- ( obligation_trait_ref , self_ty_trait_ref ) ,
1038
+ ( obligation . predicate . trait_ref , found_trait_ref ) ,
1047
1039
)
1048
1040
} ) ;
1049
1041
1050
1042
// needed to define opaque types for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs
1051
1043
self . infcx
1052
1044
. 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 )
1054
1046
. map ( |InferOk { mut obligations, .. } | {
1055
1047
obligations. extend ( nested) ;
1056
1048
obligations
1057
1049
} )
1058
1050
. map_err ( |terr| {
1059
1051
SignatureMismatch ( Box :: new ( SignatureMismatchData {
1060
1052
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 ) ,
1062
1054
terr,
1063
1055
} ) )
1064
1056
} )
0 commit comments