11use clippy_utils:: diagnostics:: span_lint_and_then;
2- use clippy_utils:: is_lint_allowed;
32use clippy_utils:: source:: snippet;
43use clippy_utils:: ty:: { implements_trait, is_copy} ;
4+ use clippy_utils:: { is_lint_allowed, match_def_path, paths} ;
55use rustc_ast:: ImplPolarity ;
66use rustc_hir:: def_id:: DefId ;
77use rustc_hir:: { FieldDef , Item , ItemKind , Node } ;
88use rustc_lint:: { LateContext , LateLintPass } ;
9+ use rustc_middle:: lint:: in_external_macro;
910use rustc_middle:: ty:: { self , subst:: GenericArgKind , Ty } ;
1011use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
1112use rustc_span:: sym;
@@ -77,6 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy {
7778 // single `AdtDef` may have multiple `Send` impls due to generic
7879 // parameters, and the lint is much easier to implement in this way.
7980 if_chain ! {
81+ if !in_external_macro( cx. tcx. sess, item. span) ;
8082 if let Some ( send_trait) = cx. tcx. get_diagnostic_item( sym:: Send ) ;
8183 if let ItemKind :: Impl ( hir_impl) = & item. kind;
8284 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
181183 return true ;
182184 }
183185
184- if is_copy ( cx, ty) && !contains_raw_pointer ( cx, ty) {
186+ if is_copy ( cx, ty) && !contains_pointer_like ( cx, ty) {
185187 return true ;
186188 }
187189
@@ -201,7 +203,7 @@ fn ty_allowed_with_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'t
201203 . all ( |ty| ty_allowed_with_raw_pointer_heuristic ( cx, ty, send_trait) ) ,
202204 ty:: Array ( ty, _) | ty:: Slice ( ty) => ty_allowed_with_raw_pointer_heuristic ( cx, ty, send_trait) ,
203205 ty:: Adt ( _, substs) => {
204- if contains_raw_pointer ( cx, ty) {
206+ if contains_pointer_like ( cx, ty) {
205207 // descends only if ADT contains any raw pointers
206208 substs. iter ( ) . all ( |generic_arg| match generic_arg. unpack ( ) {
207209 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
218220 }
219221}
220222
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 {
223225 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+ _ => ( ) ,
229237 }
230238 }
231239 }
0 commit comments