@@ -78,66 +78,65 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
7878 if let ty:: Alias ( ty:: Opaque , AliasTy { def_id, args, .. } ) = * ret_ty. kind ( )
7979 && let Some ( future_trait) = cx. tcx . lang_items ( ) . future_trait ( )
8080 && let Some ( send_trait) = cx. tcx . get_diagnostic_item ( sym:: Send )
81- {
82- let preds = cx. tcx . explicit_item_self_bounds ( def_id) ;
83- let is_future = preds. iter_instantiated_copied ( cx. tcx , args) . any ( |( p, _) | {
81+ && let preds = cx. tcx . explicit_item_self_bounds ( def_id)
82+ && let is_future = preds. iter_instantiated_copied ( cx. tcx , args) . any ( |( p, _) | {
8483 p. as_trait_clause ( )
8584 . is_some_and ( |trait_pred| trait_pred. skip_binder ( ) . trait_ref . def_id == future_trait)
86- } ) ;
87- if is_future {
88- let span = decl. output . span ( ) ;
89- let infcx = cx. tcx . infer_ctxt ( ) . build ( cx. typing_mode ( ) ) ;
90- let ocx = ObligationCtxt :: new_with_diagnostics ( & infcx) ;
91- let cause = traits:: ObligationCause :: misc ( span, fn_def_id) ;
92- ocx. register_bound ( cause, cx. param_env , ret_ty, send_trait) ;
93- let send_errors = ocx. select_all_or_error ( ) ;
85+ } )
86+ && is_future
87+ {
88+ let span = decl. output . span ( ) ;
89+ let infcx = cx. tcx . infer_ctxt ( ) . build ( cx. typing_mode ( ) ) ;
90+ let ocx = ObligationCtxt :: new_with_diagnostics ( & infcx) ;
91+ let cause = traits:: ObligationCause :: misc ( span, fn_def_id) ;
92+ ocx. register_bound ( cause, cx. param_env , ret_ty, send_trait) ;
93+ let send_errors = ocx. select_all_or_error ( ) ;
9494
95- // Allow errors that try to prove `Send` for types that "mention" a generic parameter at the "top
96- // level".
97- // For example, allow errors that `T: Send` can't be proven, but reject `Rc<T>: Send` errors,
98- // which is always unconditionally `!Send` for any possible type `T`.
99- //
100- // We also allow associated type projections if the self type is either itself a projection or a
101- // type parameter.
102- // This is to prevent emitting warnings for e.g. holding a `<Fut as Future>::Output` across await
103- // points, where `Fut` is a type parameter.
95+ // Allow errors that try to prove `Send` for types that "mention" a generic parameter at the "top
96+ // level".
97+ // For example, allow errors that `T: Send` can't be proven, but reject `Rc<T>: Send` errors,
98+ // which is always unconditionally `!Send` for any possible type `T`.
99+ //
100+ // We also allow associated type projections if the self type is either itself a projection or a
101+ // type parameter.
102+ // This is to prevent emitting warnings for e.g. holding a `<Fut as Future>::Output` across await
103+ // points, where `Fut` is a type parameter.
104104
105- let is_send = send_errors. iter ( ) . all ( |err| {
106- err. obligation
107- . predicate
108- . as_trait_clause ( )
109- . map ( Binder :: skip_binder)
110- . is_some_and ( |pred| {
111- pred. def_id ( ) == send_trait
112- && pred. self_ty ( ) . has_param ( )
113- && TyParamAtTopLevelVisitor . visit_ty ( pred. self_ty ( ) ) == ControlFlow :: Break ( true )
114- } )
115- } ) ;
105+ let is_send = send_errors. iter ( ) . all ( |err| {
106+ err. obligation
107+ . predicate
108+ . as_trait_clause ( )
109+ . map ( Binder :: skip_binder)
110+ . is_some_and ( |pred| {
111+ pred. def_id ( ) == send_trait
112+ && pred. self_ty ( ) . has_param ( )
113+ && TyParamAtTopLevelVisitor . visit_ty ( pred. self_ty ( ) ) == ControlFlow :: Break ( true )
114+ } )
115+ } ) ;
116116
117- if !is_send {
118- span_lint_and_then (
119- cx,
120- FUTURE_NOT_SEND ,
121- span,
122- "future cannot be sent between threads safely" ,
123- |db| {
124- for FulfillmentError { obligation, .. } in send_errors {
125- infcx
126- . err_ctxt ( )
127- . maybe_note_obligation_cause_for_async_await ( db, & obligation) ;
128- if let PredicateKind :: Clause ( ClauseKind :: Trait ( trait_pred) ) =
129- obligation. predicate . kind ( ) . skip_binder ( )
130- {
131- db. note ( format ! (
132- "`{}` doesn't implement `{}`" ,
133- trait_pred. self_ty( ) ,
134- trait_pred. trait_ref. print_only_trait_path( ) ,
135- ) ) ;
136- }
117+ if !is_send {
118+ span_lint_and_then (
119+ cx,
120+ FUTURE_NOT_SEND ,
121+ span,
122+ "future cannot be sent between threads safely" ,
123+ |db| {
124+ for FulfillmentError { obligation, .. } in send_errors {
125+ infcx
126+ . err_ctxt ( )
127+ . maybe_note_obligation_cause_for_async_await ( db, & obligation) ;
128+ if let PredicateKind :: Clause ( ClauseKind :: Trait ( trait_pred) ) =
129+ obligation. predicate . kind ( ) . skip_binder ( )
130+ {
131+ db. note ( format ! (
132+ "`{}` doesn't implement `{}`" ,
133+ trait_pred. self_ty( ) ,
134+ trait_pred. trait_ref. print_only_trait_path( ) ,
135+ ) ) ;
137136 }
138- } ,
139- ) ;
140- }
137+ }
138+ } ,
139+ ) ;
141140 }
142141 }
143142 }
0 commit comments