@@ -727,9 +727,10 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
727727 self . out . extend ( obligations) ;
728728 }
729729
730- ty:: FnPtr ( _) => {
731- // let the loop iterate into the argument/return
732- // types appearing in the fn signature
730+ ty:: FnPtr ( fn_sig) => {
731+ // The loop iterates into the argument/return types appearing in the fn
732+ // signature, but we need to do some extra checks.
733+ self . compute_fn_sig_obligations ( fn_sig)
733734 }
734735
735736 ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, args, .. } ) => {
@@ -806,6 +807,22 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
806807 }
807808 }
808809
810+ /// Add the obligations for this signature to be well-formed to `out`.
811+ fn compute_fn_sig_obligations ( & mut self , sig : ty:: PolyFnSig < ' tcx > ) {
812+ // The return type must always be sized.
813+ // FIXME(RalfJung): is skip_binder right? It's what the type walker used in `compute` also does.
814+ self . require_sized ( sig. skip_binder ( ) . output ( ) , traits:: SizedReturnType ) ;
815+ // For non-Rust ABIs, the argument type must always be sized.
816+ // FIXME(RalfJung): we don't do the Rust ABI check here, since that depends on feature gates
817+ // and it's not clear to me whether WF depending on feature gates (which can differ across
818+ // crates) is possible or not.
819+ if !sig. skip_binder ( ) . abi . supports_unsized_args ( ) {
820+ for & arg in sig. skip_binder ( ) . inputs ( ) {
821+ self . require_sized ( arg, traits:: SizedArgumentType ( None ) ) ;
822+ }
823+ }
824+ }
825+
809826 #[ instrument( level = "debug" , skip( self ) ) ]
810827 fn nominal_obligations (
811828 & mut self ,
0 commit comments