Skip to content

Commit 486300b

Browse files
bors[bot]sinkuu
andcommitted
3400: Fix a false-positive of needless_borrow r=phansch a=sinkuu Co-authored-by: Shotaro Yamada <[email protected]>
2 parents ebcea40 + d4370f8 commit 486300b

File tree

3 files changed

+36
-22
lines changed

3 files changed

+36
-22
lines changed

Diff for: clippy_lints/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
367367
reg.register_late_lint_pass(box zero_div_zero::Pass);
368368
reg.register_late_lint_pass(box mutex_atomic::MutexAtomic);
369369
reg.register_late_lint_pass(box needless_update::Pass);
370-
reg.register_late_lint_pass(box needless_borrow::NeedlessBorrow);
370+
reg.register_late_lint_pass(box needless_borrow::NeedlessBorrow::default());
371371
reg.register_late_lint_pass(box needless_borrowed_ref::NeedlessBorrowedRef);
372372
reg.register_late_lint_pass(box no_effect::Pass);
373373
reg.register_late_lint_pass(box temporary_assignment::Pass);

Diff for: clippy_lints/src/needless_borrow.rs

+28-21
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,15 @@
1212
//!
1313
//! This lint is **warn** by default
1414
15+
use crate::rustc::hir::{BindingAnnotation, Expr, ExprKind, Item, MutImmutable, Pat, PatKind};
1516
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
16-
use crate::rustc::{declare_tool_lint, lint_array};
17-
use if_chain::if_chain;
18-
use crate::rustc::hir::{BindingAnnotation, Expr, ExprKind, MutImmutable, Pat, PatKind};
1917
use crate::rustc::ty;
2018
use crate::rustc::ty::adjustment::{Adjust, Adjustment};
21-
use crate::utils::{in_macro, snippet_opt, span_lint_and_then};
19+
use crate::rustc::{declare_tool_lint, lint_array};
2220
use crate::rustc_errors::Applicability;
21+
use crate::utils::{in_macro, snippet_opt, span_lint_and_then};
22+
use crate::syntax::ast::NodeId;
23+
use if_chain::if_chain;
2324

2425
/// **What it does:** Checks for address of operations (`&`) that are going to
2526
/// be dereferenced immediately by the compiler.
@@ -32,26 +33,17 @@ use crate::rustc_errors::Applicability;
3233
/// let x: &i32 = &&&&&&5;
3334
/// ```
3435
///
35-
/// **Known problems:** This will cause false positives in code generated by `derive`.
36-
/// For instance in the following snippet:
37-
/// ```rust
38-
/// #[derive(Debug)]
39-
/// pub enum Error {
40-
/// Type(
41-
/// &'static str,
42-
/// ),
43-
/// }
44-
/// ```
45-
/// A warning will be emitted that `&'static str` should be replaced with `&'static str`,
46-
/// however there is nothing that can or should be done to fix this.
36+
/// **Known problems:** None.
4737
declare_clippy_lint! {
4838
pub NEEDLESS_BORROW,
4939
nursery,
5040
"taking a reference that is going to be automatically dereferenced"
5141
}
5242

53-
#[derive(Copy, Clone)]
54-
pub struct NeedlessBorrow;
43+
#[derive(Default)]
44+
pub struct NeedlessBorrow {
45+
derived_item: Option<NodeId>,
46+
}
5547

5648
impl LintPass for NeedlessBorrow {
5749
fn get_lints(&self) -> LintArray {
@@ -61,7 +53,7 @@ impl LintPass for NeedlessBorrow {
6153

6254
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow {
6355
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
64-
if in_macro(e.span) {
56+
if in_macro(e.span) || self.derived_item.is_some() {
6557
return;
6658
}
6759
if let ExprKind::AddrOf(MutImmutable, ref inner) = e.node {
@@ -87,7 +79,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow {
8779
|db| {
8880
if let Some(snippet) = snippet_opt(cx, inner.span) {
8981
db.span_suggestion_with_applicability(
90-
e.span,
82+
e.span,
9183
"change this to",
9284
snippet,
9385
Applicability::MachineApplicable,
@@ -101,7 +93,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow {
10193
}
10294
}
10395
fn check_pat(&mut self, cx: &LateContext<'a, 'tcx>, pat: &'tcx Pat) {
104-
if in_macro(pat.span) {
96+
if in_macro(pat.span) || self.derived_item.is_some() {
10597
return;
10698
}
10799
if_chain! {
@@ -131,4 +123,19 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow {
131123
}
132124
}
133125
}
126+
127+
fn check_item(&mut self, _: &LateContext<'a, 'tcx>, item: &'tcx Item) {
128+
if item.attrs.iter().any(|a| a.check_name("automatically_derived")) {
129+
debug_assert!(self.derived_item.is_none());
130+
self.derived_item = Some(item.id);
131+
}
132+
}
133+
134+
fn check_item_post(&mut self, _: &LateContext<'a, 'tcx>, item: &'tcx Item) {
135+
if let Some(id) = self.derived_item {
136+
if item.id == id {
137+
self.derived_item = None;
138+
}
139+
}
140+
}
134141
}

Diff for: tests/ui/needless_borrow.rs

+7
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,10 @@ fn issue_1432() {
6363

6464
let _ = v.iter().filter(|&a| a.is_empty());
6565
}
66+
67+
#[allow(dead_code)]
68+
#[warn(clippy::needless_borrow)]
69+
#[derive(Debug)]
70+
enum Foo<'a> {
71+
Str(&'a str),
72+
}

0 commit comments

Comments
 (0)