@@ -78,66 +78,65 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
78
78
if let ty:: Alias ( ty:: Opaque , AliasTy { def_id, args, .. } ) = * ret_ty. kind ( )
79
79
&& let Some ( future_trait) = cx. tcx . lang_items ( ) . future_trait ( )
80
80
&& 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
+ // If is a Future
83
+ && preds. iter_instantiated_copied ( cx. tcx , args) . any ( |( p, _) | {
84
84
p. as_trait_clause ( )
85
85
. 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 ( ) ;
86
+ } )
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 ( ) ;
94
94
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.
104
104
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
+ } ) ;
116
116
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
+ ) ) ;
137
136
}
138
- } ,
139
- ) ;
140
- }
137
+ }
138
+ } ,
139
+ ) ;
141
140
}
142
141
}
143
142
}
0 commit comments