Skip to content

Commit af2d6a0

Browse files
authored
Merge pull request #3191 from vi/suggest_with_applicability
Use span_suggestion_with_applicability instead of span_suggestion
2 parents b5c4342 + 987b34d commit af2d6a0

35 files changed

+427
-106
lines changed

clippy_lints/src/assign_ops.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
66
use crate::rustc::{declare_tool_lint, lint_array};
77
use if_chain::if_chain;
88
use crate::syntax::ast;
9+
use crate::rustc_errors::Applicability;
910

1011
/// **What it does:** Checks for `a = a op b` or `a = b commutative_op a`
1112
/// patterns.
@@ -78,7 +79,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
7879
let r = &sugg::Sugg::hir(cx, rhs, "..");
7980
let long =
8081
format!("{} = {}", snip_a, sugg::make_binop(higher::binop(op.node), a, r));
81-
db.span_suggestion(
82+
db.span_suggestion_with_applicability(
8283
expr.span,
8384
&format!(
8485
"Did you mean {} = {} {} {} or {}? Consider replacing it with",
@@ -89,8 +90,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
8990
long
9091
),
9192
format!("{} {}= {}", snip_a, op.node.as_str(), snip_r),
93+
Applicability::MachineApplicable,
94+
);
95+
db.span_suggestion_with_applicability(
96+
expr.span,
97+
"or",
98+
long,
99+
Applicability::MachineApplicable, // snippet
92100
);
93-
db.span_suggestion(expr.span, "or", long);
94101
}
95102
},
96103
);
@@ -172,10 +179,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
172179
if let (Some(snip_a), Some(snip_r)) =
173180
(snippet_opt(cx, assignee.span), snippet_opt(cx, rhs.span))
174181
{
175-
db.span_suggestion(
182+
db.span_suggestion_with_applicability(
176183
expr.span,
177184
"replace it with",
178185
format!("{} {}= {}", snip_a, op.node.as_str(), snip_r),
186+
Applicability::MachineApplicable,
179187
);
180188
}
181189
},

clippy_lints/src/attrs.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::rustc::ty::{self, TyCtxt};
1313
use semver::Version;
1414
use crate::syntax::ast::{AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
1515
use crate::syntax::source_map::Span;
16+
use crate::rustc_errors::Applicability;
1617

1718
/// **What it does:** Checks for items annotated with `#[inline(always)]`,
1819
/// unless the annotated function is empty or simply panics.
@@ -203,7 +204,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
203204
"useless lint attribute",
204205
|db| {
205206
sugg = sugg.replacen("#[", "#![", 1);
206-
db.span_suggestion(line_span, "if you just forgot a `!`, use", sugg);
207+
db.span_suggestion_with_applicability(
208+
line_span,
209+
"if you just forgot a `!`, use",
210+
sugg,
211+
Applicability::MachineApplicable,
212+
);
207213
},
208214
);
209215
}

clippy_lints/src/bit_mask.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::syntax::source_map::Span;
77
use crate::utils::{span_lint, span_lint_and_then};
88
use crate::utils::sugg::Sugg;
99
use crate::consts::{constant, Constant};
10+
use crate::rustc_errors::Applicability;
1011

1112
/// **What it does:** Checks for incompatible bit masks in comparisons.
1213
///
@@ -138,7 +139,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BitMask {
138139
"bit mask could be simplified with a call to `trailing_zeros`",
139140
|db| {
140141
let sugg = Sugg::hir(cx, left1, "...").maybe_par();
141-
db.span_suggestion(e.span, "try", format!("{}.trailing_zeros() >= {}", sugg, n.count_ones()));
142+
db.span_suggestion_with_applicability(
143+
e.span,
144+
"try",
145+
format!("{}.trailing_zeros() >= {}", sugg, n.count_ones()),
146+
Applicability::MaybeIncorrect,
147+
);
142148
});
143149
}
144150
}

clippy_lints/src/booleans.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::syntax::ast::{LitKind, NodeId, DUMMY_NODE_ID};
66
use crate::syntax::source_map::{dummy_spanned, Span, DUMMY_SP};
77
use crate::rustc_data_structures::thin_vec::ThinVec;
88
use crate::utils::{in_macro, paths, match_type, snippet_opt, span_lint_and_then, SpanlessEq, get_trait_def_id, implements_trait};
9+
use crate::rustc_errors::Applicability;
910

1011
/// **What it does:** Checks for boolean expressions that can be written more
1112
/// concisely.
@@ -390,10 +391,13 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
390391
"this expression can be optimized out by applying boolean operations to the \
391392
outer expression",
392393
);
393-
db.span_suggestion(
394+
db.span_suggestion_with_applicability(
394395
e.span,
395396
"it would look like the following",
396397
suggest(self.cx, suggestion, &h2q.terminals).0,
398+
// nonminimal_bool can produce minimal but
399+
// not human readable expressions (#3141)
400+
Applicability::Unspecified,
397401
);
398402
},
399403
);
@@ -416,7 +420,16 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
416420
NONMINIMAL_BOOL,
417421
e.span,
418422
"this boolean expression can be simplified",
419-
|db| { db.span_suggestions(e.span, "try", suggestions); },
423+
|db| {
424+
db.span_suggestions_with_applicability(
425+
e.span,
426+
"try",
427+
suggestions,
428+
// nonminimal_bool can produce minimal but
429+
// not human readable expressions (#3141)
430+
Applicability::Unspecified,
431+
);
432+
},
420433
);
421434
};
422435
if improvements.is_empty() {

clippy_lints/src/collapsible_if.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use crate::syntax::ast;
1919

2020
use crate::utils::{in_macro, snippet_block, span_lint_and_sugg, span_lint_and_then};
2121
use crate::utils::sugg::Sugg;
22+
use crate::rustc_errors::Applicability;
2223

2324
/// **What it does:** Checks for nested `if` statements which can be collapsed
2425
/// by `&&`-combining their conditions and for `else { if ... }` expressions
@@ -133,11 +134,16 @@ fn check_collapsible_no_if_let(cx: &EarlyContext<'_>, expr: &ast::Expr, check: &
133134
span_lint_and_then(cx, COLLAPSIBLE_IF, expr.span, "this if statement can be collapsed", |db| {
134135
let lhs = Sugg::ast(cx, check, "..");
135136
let rhs = Sugg::ast(cx, check_inner, "..");
136-
db.span_suggestion(expr.span,
137-
"try",
138-
format!("if {} {}",
139-
lhs.and(&rhs),
140-
snippet_block(cx, content.span, "..")));
137+
db.span_suggestion_with_applicability(
138+
expr.span,
139+
"try",
140+
format!(
141+
"if {} {}",
142+
lhs.and(&rhs),
143+
snippet_block(cx, content.span, ".."),
144+
),
145+
Applicability::MachineApplicable, // snippet
146+
);
141147
});
142148
}
143149
}

clippy_lints/src/const_static_lifetime.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::syntax::ast::*;
22
use crate::rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
33
use crate::rustc::{declare_tool_lint, lint_array};
44
use crate::utils::{in_macro, snippet, span_lint_and_then};
5+
use crate::rustc_errors::Applicability;
56

67
/// **What it does:** Checks for constants with an explicit `'static` lifetime.
78
///
@@ -60,7 +61,12 @@ impl StaticConst {
6061
lifetime.ident.span,
6162
"Constants have by default a `'static` lifetime",
6263
|db| {
63-
db.span_suggestion(ty.span, "consider removing `'static`", sugg);
64+
db.span_suggestion_with_applicability(
65+
ty.span,
66+
"consider removing `'static`",
67+
sugg,
68+
Applicability::MachineApplicable, //snippet
69+
);
6470
},
6571
);
6672
}

clippy_lints/src/copies.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ fn lint_match_arms(cx: &LateContext<'_, '_>, expr: &Expr) {
202202
|db| {
203203
db.span_note(i.body.span, "same as this");
204204

205-
// Note: this does not use `span_suggestion` on purpose: there is no clean way
205+
// Note: this does not use `span_suggestion_with_applicability` on purpose:
206+
// there is no clean way
206207
// to remove the other arm. Building a span and suggest to replace it to ""
207208
// makes an even more confusing error message. Also in order not to make up a
208209
// span for the whole pattern, the suggestion is only shown when there is only

clippy_lints/src/entry.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use if_chain::if_chain;
66
use crate::syntax::source_map::Span;
77
use crate::utils::SpanlessEq;
88
use crate::utils::{get_item_name, match_type, paths, snippet, span_lint_and_then, walk_ptrs_ty};
9+
use crate::rustc_errors::Applicability;
910

1011
/// **What it does:** Checks for uses of `contains_key` + `insert` on `HashMap`
1112
/// or `BTreeMap`.
@@ -139,14 +140,24 @@ impl<'a, 'tcx, 'b> Visitor<'tcx> for InsertVisitor<'a, 'tcx, 'b> {
139140
snippet(self.cx, params[1].span, ".."),
140141
snippet(self.cx, params[2].span, ".."));
141142

142-
db.span_suggestion(self.span, "consider using", help);
143+
db.span_suggestion_with_applicability(
144+
self.span,
145+
"consider using",
146+
help,
147+
Applicability::MachineApplicable, // snippet
148+
);
143149
}
144150
else {
145151
let help = format!("{}.entry({})",
146152
snippet(self.cx, self.map.span, "map"),
147153
snippet(self.cx, params[1].span, ".."));
148154

149-
db.span_suggestion(self.span, "consider using", help);
155+
db.span_suggestion_with_applicability(
156+
self.span,
157+
"consider using",
158+
help,
159+
Applicability::MachineApplicable, // snippet
160+
);
150161
}
151162
});
152163
}

clippy_lints/src/eq_op.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::rustc::hir::*;
22
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
33
use crate::rustc::{declare_tool_lint, lint_array};
44
use crate::utils::{in_macro, implements_trait, is_copy, multispan_sugg, snippet, span_lint, span_lint_and_then, SpanlessEq};
5+
use crate::rustc_errors::Applicability;
56

67
/// **What it does:** Checks for equal operands to comparison, logical and
78
/// bitwise, difference and division binary operators (`==`, `>`, etc., `&&`,
@@ -113,7 +114,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
113114
} else if lcpy && !rcpy && implements_trait(cx, lty, trait_id, &[cx.tables.expr_ty(right).into()]) {
114115
span_lint_and_then(cx, OP_REF, e.span, "needlessly taken reference of left operand", |db| {
115116
let lsnip = snippet(cx, l.span, "...").to_string();
116-
db.span_suggestion(left.span, "use the left value directly", lsnip);
117+
db.span_suggestion_with_applicability(
118+
left.span,
119+
"use the left value directly",
120+
lsnip,
121+
Applicability::MachineApplicable, // snippet
122+
);
117123
})
118124
} else if !lcpy && rcpy && implements_trait(cx, cx.tables.expr_ty(left), trait_id, &[rty.into()]) {
119125
span_lint_and_then(
@@ -123,7 +129,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
123129
"needlessly taken reference of right operand",
124130
|db| {
125131
let rsnip = snippet(cx, r.span, "...").to_string();
126-
db.span_suggestion(right.span, "use the right value directly", rsnip);
132+
db.span_suggestion_with_applicability(
133+
right.span,
134+
"use the right value directly",
135+
rsnip,
136+
Applicability::MachineApplicable, // snippet
137+
);
127138
},
128139
)
129140
}
@@ -135,7 +146,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
135146
if (requires_ref || lcpy) && implements_trait(cx, lty, trait_id, &[cx.tables.expr_ty(right).into()]) {
136147
span_lint_and_then(cx, OP_REF, e.span, "needlessly taken reference of left operand", |db| {
137148
let lsnip = snippet(cx, l.span, "...").to_string();
138-
db.span_suggestion(left.span, "use the left value directly", lsnip);
149+
db.span_suggestion_with_applicability(
150+
left.span,
151+
"use the left value directly",
152+
lsnip,
153+
Applicability::MachineApplicable, // snippet
154+
);
139155
})
140156
}
141157
},
@@ -146,7 +162,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
146162
if (requires_ref || rcpy) && implements_trait(cx, cx.tables.expr_ty(left), trait_id, &[rty.into()]) {
147163
span_lint_and_then(cx, OP_REF, e.span, "taken reference of right operand", |db| {
148164
let rsnip = snippet(cx, r.span, "...").to_string();
149-
db.span_suggestion(right.span, "use the right value directly", rsnip);
165+
db.span_suggestion_with_applicability(
166+
right.span,
167+
"use the right value directly",
168+
rsnip,
169+
Applicability::MachineApplicable, // snippet
170+
);
150171
})
151172
}
152173
},

clippy_lints/src/eta_reduction.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::rustc::{declare_tool_lint, lint_array};
33
use crate::rustc::ty;
44
use crate::rustc::hir::*;
55
use crate::utils::{is_adjusted, iter_input_pats, snippet_opt, span_lint_and_then};
6+
use crate::rustc_errors::Applicability;
67

78
#[allow(missing_copy_implementations)]
89
pub struct EtaPass;
@@ -96,7 +97,12 @@ fn check_closure(cx: &LateContext<'_, '_>, expr: &Expr) {
9697
}
9798
span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure found", |db| {
9899
if let Some(snippet) = snippet_opt(cx, caller.span) {
99-
db.span_suggestion(expr.span, "remove closure as shown", snippet);
100+
db.span_suggestion_with_applicability(
101+
expr.span,
102+
"remove closure as shown",
103+
snippet,
104+
Applicability::MachineApplicable,
105+
);
100106
}
101107
});
102108
}

clippy_lints/src/format.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::syntax::ast::LitKind;
77
use crate::syntax_pos::Span;
88
use crate::utils::paths;
99
use crate::utils::{in_macro, is_expn_of, last_path_segment, match_def_path, match_type, opt_def_id, resolve_node, snippet, span_lint_and_then, walk_ptrs_ty};
10+
use crate::rustc_errors::Applicability;
1011

1112
/// **What it does:** Checks for the use of `format!("string literal with no
1213
/// argument")` and `format!("{}", foo)` where `foo` is a string.
@@ -60,7 +61,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
6061
then {
6162
let sugg = format!("{}.to_string()", snippet(cx, format_arg, "<arg>").into_owned());
6263
span_lint_and_then(cx, USELESS_FORMAT, span, "useless use of `format!`", |db| {
63-
db.span_suggestion(expr.span, "consider using .to_string()", sugg);
64+
db.span_suggestion_with_applicability(
65+
expr.span,
66+
"consider using .to_string()",
67+
sugg,
68+
Applicability::MachineApplicable,
69+
);
6470
});
6571
}
6672
}
@@ -70,7 +76,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
7076
if tup.is_empty() {
7177
let sugg = format!("{}.to_string()", snippet(cx, expr.span, "<expr>").into_owned());
7278
span_lint_and_then(cx, USELESS_FORMAT, span, "useless use of `format!`", |db| {
73-
db.span_suggestion(span, "consider using .to_string()", sugg);
79+
db.span_suggestion_with_applicability(
80+
span,
81+
"consider using .to_string()",
82+
sugg,
83+
Applicability::MachineApplicable, // snippet
84+
);
7485
});
7586
}
7687
},

0 commit comments

Comments
 (0)