@@ -647,6 +647,8 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
647
647
fn visit_ty ( & mut self , t : <TyCtxt < ' tcx > as ty:: Interner >:: Ty ) -> Self :: Result {
648
648
debug ! ( "wf bounds for t={:?} t.kind={:#?}" , t, t. kind( ) ) ;
649
649
650
+ let tcx = self . tcx ( ) ;
651
+
650
652
match * t. kind ( ) {
651
653
ty:: Bool
652
654
| ty:: Char
@@ -707,6 +709,16 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
707
709
}
708
710
709
711
ty:: FnDef ( did, args) => {
712
+ // HACK: Check the return type of function definitions for
713
+ // well-formedness to mostly fix #84533. This is still not
714
+ // perfect and there may be ways to abuse the fact that we
715
+ // ignore requirements with escaping bound vars. That's a
716
+ // more general issue however.
717
+ //
718
+ // FIXME(eddyb) add the type to `walker` instead of recursing.
719
+ let fn_sig = tcx. fn_sig ( did) . instantiate ( tcx, args) ;
720
+ fn_sig. output ( ) . skip_binder ( ) . visit_with ( self ) ;
721
+
710
722
let obligations = self . nominal_obligations ( did, args) ;
711
723
self . out . extend ( obligations) ;
712
724
}
@@ -716,7 +728,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
716
728
if !r. has_escaping_bound_vars ( ) && !rty. has_escaping_bound_vars ( ) {
717
729
let cause = self . cause ( traits:: ReferenceOutlivesReferent ( t) ) ;
718
730
self . out . push ( traits:: Obligation :: with_depth (
719
- self . tcx ( ) ,
731
+ tcx,
720
732
cause,
721
733
self . recursion_depth ,
722
734
self . param_env ,
@@ -805,12 +817,12 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
805
817
// obligations that don't refer to Self and
806
818
// checking those
807
819
808
- let defer_to_coercion = self . tcx ( ) . features ( ) . object_safe_for_dispatch ;
820
+ let defer_to_coercion = tcx. features ( ) . object_safe_for_dispatch ;
809
821
810
822
if !defer_to_coercion {
811
823
if let Some ( principal) = data. principal_def_id ( ) {
812
824
self . out . push ( traits:: Obligation :: with_depth (
813
- self . tcx ( ) ,
825
+ tcx,
814
826
self . cause ( traits:: WellFormed ( None ) ) ,
815
827
self . recursion_depth ,
816
828
self . param_env ,
@@ -835,7 +847,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
835
847
ty:: Infer ( _) => {
836
848
let cause = self . cause ( traits:: WellFormed ( None ) ) ;
837
849
self . out . push ( traits:: Obligation :: with_depth (
838
- self . tcx ( ) ,
850
+ tcx,
839
851
cause,
840
852
self . recursion_depth ,
841
853
self . param_env ,
@@ -850,6 +862,8 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
850
862
}
851
863
852
864
fn visit_const ( & mut self , c : <TyCtxt < ' tcx > as ty:: Interner >:: Const ) -> Self :: Result {
865
+ let tcx = self . tcx ( ) ;
866
+
853
867
match c. kind ( ) {
854
868
ty:: ConstKind :: Unevaluated ( uv) => {
855
869
if !c. has_escaping_bound_vars ( ) {
@@ -861,7 +875,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
861
875
) ) ;
862
876
let cause = self . cause ( traits:: WellFormed ( None ) ) ;
863
877
self . out . push ( traits:: Obligation :: with_depth (
864
- self . tcx ( ) ,
878
+ tcx,
865
879
cause,
866
880
self . recursion_depth ,
867
881
self . param_env ,
@@ -873,7 +887,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
873
887
let cause = self . cause ( traits:: WellFormed ( None ) ) ;
874
888
875
889
self . out . push ( traits:: Obligation :: with_depth (
876
- self . tcx ( ) ,
890
+ tcx,
877
891
cause,
878
892
self . recursion_depth ,
879
893
self . param_env ,
@@ -895,7 +909,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
895
909
) ) ;
896
910
let cause = self . cause ( traits:: WellFormed ( None ) ) ;
897
911
self . out . push ( traits:: Obligation :: with_depth (
898
- self . tcx ( ) ,
912
+ tcx,
899
913
cause,
900
914
self . recursion_depth ,
901
915
self . param_env ,
0 commit comments