|
1 |
| -use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then}; |
| 1 | +use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_then, span_lint_hir_and_then}; |
2 | 2 | use clippy_utils::ty::{implements_trait, implements_trait_with_env, is_copy};
|
3 | 3 | use clippy_utils::{has_non_exhaustive_attr, is_lint_allowed, match_def_path, paths};
|
4 | 4 | use rustc_errors::Applicability;
|
5 | 5 | use rustc_hir::def_id::DefId;
|
6 | 6 | use rustc_hir::intravisit::{walk_expr, walk_fn, walk_item, FnKind, Visitor};
|
7 | 7 | use rustc_hir::{
|
8 |
| - self as hir, BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, Safety, Impl, Item, ItemKind, UnsafeSource, |
| 8 | + self as hir, BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, Impl, Item, ItemKind, Safety, UnsafeSource, |
9 | 9 | };
|
10 | 10 | use rustc_lint::{LateContext, LateLintPass};
|
11 | 11 | use rustc_middle::hir::nested_filter;
|
12 | 12 | use rustc_middle::traits::Reveal;
|
13 | 13 | use rustc_middle::ty::{
|
14 |
| - self, ClauseKind, GenericArgKind, GenericParamDefKind, ParamEnv, Upcast, TraitPredicate, Ty, TyCtxt, |
| 14 | + self, ClauseKind, GenericArgKind, GenericParamDefKind, ParamEnv, TraitPredicate, Ty, TyCtxt, Upcast, |
15 | 15 | };
|
16 | 16 | use rustc_session::declare_lint_pass;
|
17 | 17 | use rustc_span::def_id::LocalDefId;
|
@@ -390,13 +390,17 @@ fn check_unsafe_derive_deserialize<'tcx>(
|
390 | 390 | .map(|imp_did| cx.tcx.hir().expect_item(imp_did.expect_local()))
|
391 | 391 | .any(|imp| has_unsafe(cx, imp))
|
392 | 392 | {
|
393 |
| - span_lint_and_help( |
| 393 | + span_lint_hir_and_then( |
394 | 394 | cx,
|
395 | 395 | UNSAFE_DERIVE_DESERIALIZE,
|
| 396 | + adt_hir_id, |
396 | 397 | item.span,
|
397 | 398 | "you are deriving `serde::Deserialize` on a type that has methods using `unsafe`",
|
398 |
| - None, |
399 |
| - "consider implementing `serde::Deserialize` manually. See https://serde.rs/impl-deserialize.html", |
| 399 | + |diag| { |
| 400 | + diag.help( |
| 401 | + "consider implementing `serde::Deserialize` manually. See https://serde.rs/impl-deserialize.html", |
| 402 | + ); |
| 403 | + }, |
400 | 404 | );
|
401 | 405 | }
|
402 | 406 | }
|
@@ -452,20 +456,27 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
|
452 | 456 | && !has_non_exhaustive_attr(cx.tcx, *adt)
|
453 | 457 | && !ty_implements_eq_trait(cx.tcx, ty, eq_trait_def_id)
|
454 | 458 | && let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id)
|
| 459 | + && let Some(local_def_id) = adt.did().as_local() |
455 | 460 | // If all of our fields implement `Eq`, we can implement `Eq` too
|
456 | 461 | && adt
|
457 | 462 | .all_fields()
|
458 | 463 | .map(|f| f.ty(cx.tcx, args))
|
459 | 464 | .all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, None, &[]))
|
460 | 465 | {
|
461 |
| - span_lint_and_sugg( |
| 466 | + span_lint_hir_and_then( |
462 | 467 | cx,
|
463 | 468 | DERIVE_PARTIAL_EQ_WITHOUT_EQ,
|
| 469 | + cx.tcx.local_def_id_to_hir_id(local_def_id), |
464 | 470 | span.ctxt().outer_expn_data().call_site,
|
465 | 471 | "you are deriving `PartialEq` and can implement `Eq`",
|
466 |
| - "consider deriving `Eq` as well", |
467 |
| - "PartialEq, Eq".to_string(), |
468 |
| - Applicability::MachineApplicable, |
| 472 | + |diag| { |
| 473 | + diag.span_suggestion( |
| 474 | + span.ctxt().outer_expn_data().call_site, |
| 475 | + "consider deriving `Eq` as well", |
| 476 | + "PartialEq, Eq", |
| 477 | + Applicability::MachineApplicable, |
| 478 | + ); |
| 479 | + }, |
469 | 480 | );
|
470 | 481 | }
|
471 | 482 | }
|
|
0 commit comments