@@ -92,66 +92,65 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
9292 if let ty:: Alias ( ty:: Opaque , AliasTy { def_id, args, .. } ) = * ret_ty. kind ( )
9393 && let Some ( future_trait) = self . future_trait
9494 && let Some ( send_trait) = self . send_trait
95- {
96- let preds = cx. tcx . explicit_item_self_bounds ( def_id) ;
97- let is_future = preds. iter_instantiated_copied ( cx. tcx , args) . any ( |( p, _) | {
95+ && let preds = cx. tcx . explicit_item_self_bounds ( def_id)
96+ && let is_future = preds. iter_instantiated_copied ( cx. tcx , args) . any ( |( p, _) | {
9897 p. as_trait_clause ( )
9998 . is_some_and ( |trait_pred| trait_pred. skip_binder ( ) . trait_ref . def_id == future_trait)
100- } ) ;
101- if is_future {
102- let span = decl. output . span ( ) ;
103- let infcx = cx. tcx . infer_ctxt ( ) . build ( cx. typing_mode ( ) ) ;
104- let ocx = ObligationCtxt :: new_with_diagnostics ( & infcx) ;
105- let cause = traits:: ObligationCause :: misc ( span, fn_def_id) ;
106- ocx. register_bound ( cause, cx. param_env , ret_ty, send_trait) ;
107- let send_errors = ocx. select_all_or_error ( ) ;
99+ } )
100+ && is_future
101+ {
102+ let span = decl. output . span ( ) ;
103+ let infcx = cx. tcx . infer_ctxt ( ) . build ( cx. typing_mode ( ) ) ;
104+ let ocx = ObligationCtxt :: new_with_diagnostics ( & infcx) ;
105+ let cause = traits:: ObligationCause :: misc ( span, fn_def_id) ;
106+ ocx. register_bound ( cause, cx. param_env , ret_ty, send_trait) ;
107+ let send_errors = ocx. select_all_or_error ( ) ;
108108
109- // Allow errors that try to prove `Send` for types that "mention" a generic parameter at the "top
110- // level".
111- // For example, allow errors that `T: Send` can't be proven, but reject `Rc<T>: Send` errors,
112- // which is always unconditionally `!Send` for any possible type `T`.
113- //
114- // We also allow associated type projections if the self type is either itself a projection or a
115- // type parameter.
116- // This is to prevent emitting warnings for e.g. holding a `<Fut as Future>::Output` across await
117- // points, where `Fut` is a type parameter.
109+ // Allow errors that try to prove `Send` for types that "mention" a generic parameter at the "top
110+ // level".
111+ // For example, allow errors that `T: Send` can't be proven, but reject `Rc<T>: Send` errors,
112+ // which is always unconditionally `!Send` for any possible type `T`.
113+ //
114+ // We also allow associated type projections if the self type is either itself a projection or a
115+ // type parameter.
116+ // This is to prevent emitting warnings for e.g. holding a `<Fut as Future>::Output` across await
117+ // points, where `Fut` is a type parameter.
118118
119- let is_send = send_errors. iter ( ) . all ( |err| {
120- err. obligation
121- . predicate
122- . as_trait_clause ( )
123- . map ( Binder :: skip_binder)
124- . is_some_and ( |pred| {
125- pred. def_id ( ) == send_trait
126- && pred. self_ty ( ) . has_param ( )
127- && TyParamAtTopLevelVisitor . visit_ty ( pred. self_ty ( ) ) == ControlFlow :: Break ( true )
128- } )
129- } ) ;
119+ let is_send = send_errors. iter ( ) . all ( |err| {
120+ err. obligation
121+ . predicate
122+ . as_trait_clause ( )
123+ . map ( Binder :: skip_binder)
124+ . is_some_and ( |pred| {
125+ pred. def_id ( ) == send_trait
126+ && pred. self_ty ( ) . has_param ( )
127+ && TyParamAtTopLevelVisitor . visit_ty ( pred. self_ty ( ) ) == ControlFlow :: Break ( true )
128+ } )
129+ } ) ;
130130
131- if !is_send {
132- span_lint_and_then (
133- cx,
134- FUTURE_NOT_SEND ,
135- span,
136- "future cannot be sent between threads safely" ,
137- |db| {
138- for FulfillmentError { obligation, .. } in send_errors {
139- infcx
140- . err_ctxt ( )
141- . maybe_note_obligation_cause_for_async_await ( db, & obligation) ;
142- if let PredicateKind :: Clause ( ClauseKind :: Trait ( trait_pred) ) =
143- obligation. predicate . kind ( ) . skip_binder ( )
144- {
145- db. note ( format ! (
146- "`{}` doesn't implement `{}`" ,
147- trait_pred. self_ty( ) ,
148- trait_pred. trait_ref. print_only_trait_path( ) ,
149- ) ) ;
150- }
131+ if !is_send {
132+ span_lint_and_then (
133+ cx,
134+ FUTURE_NOT_SEND ,
135+ span,
136+ "future cannot be sent between threads safely" ,
137+ |db| {
138+ for FulfillmentError { obligation, .. } in send_errors {
139+ infcx
140+ . err_ctxt ( )
141+ . maybe_note_obligation_cause_for_async_await ( db, & obligation) ;
142+ if let PredicateKind :: Clause ( ClauseKind :: Trait ( trait_pred) ) =
143+ obligation. predicate . kind ( ) . skip_binder ( )
144+ {
145+ db. note ( format ! (
146+ "`{}` doesn't implement `{}`" ,
147+ trait_pred. self_ty( ) ,
148+ trait_pred. trait_ref. print_only_trait_path( ) ,
149+ ) ) ;
151150 }
152- } ,
153- ) ;
154- }
151+ }
152+ } ,
153+ ) ;
155154 }
156155 }
157156 }
0 commit comments