@@ -518,6 +518,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
518
518
/// Pushes all the predicates needed to validate that `ty` is WF into `out`.
519
519
#[ instrument( level = "debug" , skip( self ) ) ]
520
520
fn compute ( & mut self , arg : GenericArg < ' tcx > ) {
521
+ let tcx = self . tcx ( ) ;
521
522
let mut walker = arg. walk ( ) ;
522
523
let param_env = self . param_env ;
523
524
let depth = self . recursion_depth ;
@@ -542,7 +543,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
542
543
) ) ;
543
544
let cause = self . cause ( traits:: WellFormed ( None ) ) ;
544
545
self . out . push ( traits:: Obligation :: with_depth (
545
- self . tcx ( ) ,
546
+ tcx,
546
547
cause,
547
548
self . recursion_depth ,
548
549
self . param_env ,
@@ -554,7 +555,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
554
555
let cause = self . cause ( traits:: WellFormed ( None ) ) ;
555
556
556
557
self . out . push ( traits:: Obligation :: with_depth (
557
- self . tcx ( ) ,
558
+ tcx,
558
559
cause,
559
560
self . recursion_depth ,
560
561
self . param_env ,
@@ -576,7 +577,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
576
577
) ) ;
577
578
let cause = self . cause ( traits:: WellFormed ( None ) ) ;
578
579
self . out . push ( traits:: Obligation :: with_depth (
579
- self . tcx ( ) ,
580
+ tcx,
580
581
cause,
581
582
self . recursion_depth ,
582
583
self . param_env ,
@@ -661,6 +662,16 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
661
662
}
662
663
663
664
ty:: FnDef ( did, args) => {
665
+ // HACK: Check the return type of function definitions for
666
+ // well-formedness to mostly fix #84533. This is still not
667
+ // perfect and there may be ways to abuse the fact that we
668
+ // ignore requirements with escaping bound vars. That's a
669
+ // more general issue however.
670
+ //
671
+ // FIXME(eddyb) add the type to `walker` instead of recursing.
672
+ let fn_sig = tcx. fn_sig ( did) . instantiate ( tcx, args) ;
673
+ self . compute ( fn_sig. output ( ) . skip_binder ( ) . into ( ) ) ;
674
+
664
675
let obligations = self . nominal_obligations ( did, args) ;
665
676
self . out . extend ( obligations) ;
666
677
}
@@ -670,7 +681,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
670
681
if !r. has_escaping_bound_vars ( ) && !rty. has_escaping_bound_vars ( ) {
671
682
let cause = self . cause ( traits:: ReferenceOutlivesReferent ( ty) ) ;
672
683
self . out . push ( traits:: Obligation :: with_depth (
673
- self . tcx ( ) ,
684
+ tcx,
674
685
cause,
675
686
depth,
676
687
param_env,
@@ -745,7 +756,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
745
756
// All of the requirements on type parameters
746
757
// have already been checked for `impl Trait` in
747
758
// return position. We do need to check type-alias-impl-trait though.
748
- if self . tcx ( ) . is_type_alias_impl_trait ( def_id) {
759
+ if tcx. is_type_alias_impl_trait ( def_id) {
749
760
let obligations = self . nominal_obligations ( def_id, args) ;
750
761
self . out . extend ( obligations) ;
751
762
}
@@ -767,12 +778,12 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
767
778
// obligations that don't refer to Self and
768
779
// checking those
769
780
770
- let defer_to_coercion = self . tcx ( ) . features ( ) . object_safe_for_dispatch ;
781
+ let defer_to_coercion = tcx. features ( ) . object_safe_for_dispatch ;
771
782
772
783
if !defer_to_coercion {
773
784
let cause = self . cause ( traits:: WellFormed ( None ) ) ;
774
785
let component_traits = data. auto_traits ( ) . chain ( data. principal_def_id ( ) ) ;
775
- let tcx = self . tcx ( ) ;
786
+ let tcx = tcx;
776
787
self . out . extend ( component_traits. map ( |did| {
777
788
traits:: Obligation :: with_depth (
778
789
tcx,
@@ -800,7 +811,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
800
811
ty:: Infer ( _) => {
801
812
let cause = self . cause ( traits:: WellFormed ( None ) ) ;
802
813
self . out . push ( traits:: Obligation :: with_depth (
803
- self . tcx ( ) ,
814
+ tcx,
804
815
cause,
805
816
self . recursion_depth ,
806
817
param_env,
0 commit comments