1
1
use clippy_utils:: diagnostics:: span_lint_and_then;
2
- use clippy_utils:: is_lint_allowed;
3
2
use clippy_utils:: source:: snippet;
4
3
use clippy_utils:: ty:: { implements_trait, is_copy} ;
4
+ use clippy_utils:: { is_lint_allowed, match_def_path, paths} ;
5
5
use rustc_ast:: ImplPolarity ;
6
6
use rustc_hir:: def_id:: DefId ;
7
7
use rustc_hir:: { FieldDef , Item , ItemKind , Node } ;
8
8
use rustc_lint:: { LateContext , LateLintPass } ;
9
+ use rustc_middle:: lint:: in_external_macro;
9
10
use rustc_middle:: ty:: { self , subst:: GenericArgKind , Ty } ;
10
11
use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
11
12
use rustc_span:: sym;
@@ -77,6 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy {
77
78
// single `AdtDef` may have multiple `Send` impls due to generic
78
79
// parameters, and the lint is much easier to implement in this way.
79
80
if_chain ! {
81
+ if !in_external_macro( cx. tcx. sess, item. span) ;
80
82
if let Some ( send_trait) = cx. tcx. get_diagnostic_item( sym:: Send ) ;
81
83
if let ItemKind :: Impl ( hir_impl) = & item. kind;
82
84
if let Some ( trait_ref) = & hir_impl. of_trait;
@@ -181,7 +183,7 @@ fn ty_allowed_without_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty
181
183
return true ;
182
184
}
183
185
184
- if is_copy ( cx, ty) && !contains_raw_pointer ( cx, ty) {
186
+ if is_copy ( cx, ty) && !contains_pointer_like ( cx, ty) {
185
187
return true ;
186
188
}
187
189
@@ -201,7 +203,7 @@ fn ty_allowed_with_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'t
201
203
. all ( |ty| ty_allowed_with_raw_pointer_heuristic ( cx, ty, send_trait) ) ,
202
204
ty:: Array ( ty, _) | ty:: Slice ( ty) => ty_allowed_with_raw_pointer_heuristic ( cx, ty, send_trait) ,
203
205
ty:: Adt ( _, substs) => {
204
- if contains_raw_pointer ( cx, ty) {
206
+ if contains_pointer_like ( cx, ty) {
205
207
// descends only if ADT contains any raw pointers
206
208
substs. iter ( ) . all ( |generic_arg| match generic_arg. unpack ( ) {
207
209
GenericArgKind :: Type ( ty) => ty_allowed_with_raw_pointer_heuristic ( cx, ty, send_trait) ,
@@ -218,14 +220,20 @@ fn ty_allowed_with_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'t
218
220
}
219
221
}
220
222
221
- /// Checks if the type contains any raw pointers in substs (including nested ones).
222
- fn contains_raw_pointer < ' tcx > ( cx : & LateContext < ' tcx > , target_ty : Ty < ' tcx > ) -> bool {
223
+ /// Checks if the type contains any pointer-like types in substs (including nested ones)
224
+ fn contains_pointer_like < ' tcx > ( cx : & LateContext < ' tcx > , target_ty : Ty < ' tcx > ) -> bool {
223
225
for ty_node in target_ty. walk ( cx. tcx ) {
224
- if_chain ! {
225
- if let GenericArgKind :: Type ( inner_ty) = ty_node. unpack( ) ;
226
- if let ty:: RawPtr ( _) = inner_ty. kind( ) ;
227
- then {
228
- return true ;
226
+ if let GenericArgKind :: Type ( inner_ty) = ty_node. unpack ( ) {
227
+ match inner_ty. kind ( ) {
228
+ ty:: RawPtr ( _) => {
229
+ return true ;
230
+ } ,
231
+ ty:: Adt ( adt_def, _) => {
232
+ if match_def_path ( cx, adt_def. did , & paths:: PTR_NON_NULL ) {
233
+ return true ;
234
+ }
235
+ } ,
236
+ _ => ( ) ,
229
237
}
230
238
}
231
239
}
0 commit comments