1
Fork 0

Add applicability level to (nearly) every span_lint_and_sugg function

This commit is contained in:
flip1995 2018-11-27 15:13:57 +01:00
parent 0c6483bf21
commit 4e74eef6e9
No known key found for this signature in database
GPG key ID: E8E897A5870E41C2
29 changed files with 216 additions and 148 deletions

View file

@ -532,7 +532,7 @@ impl EarlyLintPass for CfgAttrPass {
"`cfg_attr` is deprecated for rustfmt and got replaced by tool_attributes", "`cfg_attr` is deprecated for rustfmt and got replaced by tool_attributes",
"use", "use",
format!("{}rustfmt::skip]", attr_style), format!("{}rustfmt::skip]", attr_style),
Applicability::Unspecified, Applicability::MachineApplicable,
); );
} }
} }

View file

@ -15,7 +15,8 @@ use crate::rustc::{declare_tool_lint, lint_array};
use crate::rustc_errors::Applicability; use crate::rustc_errors::Applicability;
use crate::syntax::ast::{Name, UintTy}; use crate::syntax::ast::{Name, UintTy};
use crate::utils::{ use crate::utils::{
contains_name, get_pat_name, match_type, paths, single_segment_path, snippet, span_lint_and_sugg, walk_ptrs_ty, contains_name, get_pat_name, match_type, paths, single_segment_path, snippet_with_applicability,
span_lint_and_sugg, walk_ptrs_ty,
}; };
use if_chain::if_chain; use if_chain::if_chain;
@ -91,6 +92,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount {
} else { } else {
&filter_args[0] &filter_args[0]
}; };
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
NAIVE_BYTECOUNT, NAIVE_BYTECOUNT,
@ -98,8 +100,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount {
"You appear to be counting bytes the naive way", "You appear to be counting bytes the naive way",
"Consider using the bytecount crate", "Consider using the bytecount crate",
format!("bytecount::count({}, {})", format!("bytecount::count({}, {})",
snippet(cx, haystack.span, ".."), snippet_with_applicability(cx, haystack.span, "..", &mut applicability),
snippet(cx, needle.span, "..")), snippet_with_applicability(cx, needle.span, "..", &mut applicability)),
Applicability::Unspecified, Applicability::Unspecified,
); );
} }

View file

@ -27,7 +27,7 @@ use crate::rustc::{declare_tool_lint, lint_array};
use if_chain::if_chain; use if_chain::if_chain;
use crate::syntax::ast; use crate::syntax::ast;
use crate::utils::{in_macro, snippet_block, span_lint_and_sugg, span_lint_and_then}; use crate::utils::{in_macro, snippet_block, snippet_block_with_applicability, span_lint_and_sugg, span_lint_and_then};
use crate::utils::sugg::Sugg; use crate::utils::sugg::Sugg;
use crate::rustc_errors::Applicability; use crate::rustc_errors::Applicability;
@ -128,14 +128,15 @@ fn check_collapsible_maybe_if_let(cx: &EarlyContext<'_>, else_: &ast::Expr) {
then { then {
match else_.node { match else_.node {
ast::ExprKind::If(..) | ast::ExprKind::IfLet(..) => { ast::ExprKind::If(..) | ast::ExprKind::IfLet(..) => {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
COLLAPSIBLE_IF, COLLAPSIBLE_IF,
block.span, block.span,
"this `else { if .. }` block can be collapsed", "this `else { if .. }` block can be collapsed",
"try", "try",
snippet_block(cx, else_.span, "..").into_owned(), snippet_block_with_applicability(cx, else_.span, "..", &mut applicability).into_owned(),
Applicability::Unspecified, applicability,
); );
} }
_ => (), _ => (),

View file

@ -82,7 +82,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DefaultTraitAccess {
&format!("Calling {} is more clear than this expression", replacement), &format!("Calling {} is more clear than this expression", replacement),
"try", "try",
replacement, replacement,
Applicability::Unspecified, Applicability::Unspecified, // First resolve the TODO above
); );
} }
}, },

View file

@ -16,7 +16,7 @@ use crate::rustc::{declare_tool_lint, lint_array};
use crate::rustc_errors::Applicability; use crate::rustc_errors::Applicability;
use crate::syntax::source_map::Span; use crate::syntax::source_map::Span;
use crate::utils::{snippet, span_lint_and_sugg, SpanlessEq}; use crate::utils::{snippet_with_applicability, span_lint_and_sugg, SpanlessEq};
/// **What it does:** Checks for double comparions that could be simpified to a single expression. /// **What it does:** Checks for double comparions that could be simpified to a single expression.
/// ///
@ -71,8 +71,9 @@ impl<'a, 'tcx> Pass {
} }
macro_rules! lint_double_comparison { macro_rules! lint_double_comparison {
($op:tt) => {{ ($op:tt) => {{
let lhs_str = snippet(cx, llhs.span, ""); let mut applicability = Applicability::MachineApplicable;
let rhs_str = snippet(cx, lrhs.span, ""); let lhs_str = snippet_with_applicability(cx, llhs.span, "", &mut applicability);
let rhs_str = snippet_with_applicability(cx, lrhs.span, "", &mut applicability);
let sugg = format!("{} {} {}", lhs_str, stringify!($op), rhs_str); let sugg = format!("{} {} {}", lhs_str, stringify!($op), rhs_str);
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
@ -81,7 +82,7 @@ impl<'a, 'tcx> Pass {
"This binary expression can be simplified", "This binary expression can be simplified",
"try", "try",
sugg, sugg,
Applicability::Unspecified, applicability,
); );
}} }}
} }

View file

@ -17,7 +17,7 @@ use if_chain::if_chain;
use crate::consts::{constant, Constant}; use crate::consts::{constant, Constant};
use crate::utils::paths; use crate::utils::paths;
use crate::utils::{match_type, snippet, span_lint_and_sugg, walk_ptrs_ty}; use crate::utils::{match_type, snippet_with_applicability, span_lint_and_sugg, walk_ptrs_ty};
/// **What it does:** Checks for calculation of subsecond microseconds or milliseconds /// **What it does:** Checks for calculation of subsecond microseconds or milliseconds
/// from other `Duration` methods. /// from other `Duration` methods.
@ -61,14 +61,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DurationSubsec {
("subsec_nanos", 1_000) => "subsec_micros", ("subsec_nanos", 1_000) => "subsec_micros",
_ => return, _ => return,
}; };
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
DURATION_SUBSEC, DURATION_SUBSEC,
expr.span, expr.span,
&format!("Calling `{}()` is more concise than this calculation", suggested_fn), &format!("Calling `{}()` is more concise than this calculation", suggested_fn),
"try", "try",
format!("{}.{}()", snippet(cx, args[0].span, "_"), suggested_fn), format!("{}.{}()", snippet_with_applicability(cx, args[0].span, "_", &mut applicability), suggested_fn),
Applicability::Unspecified, applicability,
); );
} }
} }

View file

@ -69,7 +69,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExcessivePrecision {
"float has excessive precision", "float has excessive precision",
"consider changing the type or truncating it to", "consider changing the type or truncating it to",
sugg, sugg,
Applicability::Unspecified, Applicability::MachineApplicable,
); );
} }
} }

View file

@ -8,7 +8,7 @@
// except according to those terms. // except according to those terms.
use super::utils::{get_arg_name, match_var, remove_blocks, snippet, span_lint_and_sugg}; use super::utils::{get_arg_name, match_var, remove_blocks, snippet_with_applicability, span_lint_and_sugg};
use crate::rustc::hir::*; use crate::rustc::hir::*;
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use crate::rustc::{declare_tool_lint, lint_array}; use crate::rustc::{declare_tool_lint, lint_array};
@ -72,6 +72,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
if match_var(body, arg); if match_var(body, arg);
then { then {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
INFALLIBLE_DESTRUCTURING_MATCH, INFALLIBLE_DESTRUCTURING_MATCH,
@ -81,11 +82,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
"try this", "try this",
format!( format!(
"let {}({}) = {};", "let {}({}) = {};",
snippet(cx, variant_name.span, ".."), snippet_with_applicability(cx, variant_name.span, "..", &mut applicability),
snippet(cx, local.pat.span, ".."), snippet_with_applicability(cx, local.pat.span, "..", &mut applicability),
snippet(cx, target.span, ".."), snippet_with_applicability(cx, target.span, "..", &mut applicability),
), ),
Applicability::Unspecified, applicability,
); );
} }
} }

View file

@ -17,7 +17,7 @@ use crate::rustc_data_structures::fx::FxHashSet;
use crate::rustc_errors::Applicability; use crate::rustc_errors::Applicability;
use crate::syntax::ast::{Lit, LitKind, Name}; use crate::syntax::ast::{Lit, LitKind, Name};
use crate::syntax::source_map::{Span, Spanned}; use crate::syntax::source_map::{Span, Spanned};
use crate::utils::{get_item_name, in_macro, snippet, span_lint, span_lint_and_sugg, walk_ptrs_ty}; use crate::utils::{get_item_name, in_macro, snippet_with_applicability, span_lint, span_lint_and_sugg, walk_ptrs_ty};
/// **What it does:** Checks for getting the length of something via `.len()` /// **What it does:** Checks for getting the length of something via `.len()`
/// just to compare to zero, and suggests using `.is_empty()` where applicable. /// just to compare to zero, and suggests using `.is_empty()` where applicable.
@ -224,7 +224,15 @@ fn check_cmp(cx: &LateContext<'_, '_>, span: Span, method: &Expr, lit: &Expr, op
} }
} }
fn check_len(cx: &LateContext<'_, '_>, span: Span, method_name: Name, args: &[Expr], lit: &Lit, op: &str, compare_to: u32) { fn check_len(
cx: &LateContext<'_, '_>,
span: Span,
method_name: Name,
args: &[Expr],
lit: &Lit,
op: &str,
compare_to: u32,
) {
if let Spanned { if let Spanned {
node: LitKind::Int(lit, _), node: LitKind::Int(lit, _),
.. ..
@ -236,14 +244,15 @@ fn check_len(cx: &LateContext<'_, '_>, span: Span, method_name: Name, args: &[Ex
} }
if method_name == "len" && args.len() == 1 && has_is_empty(cx, &args[0]) { if method_name == "len" && args.len() == 1 && has_is_empty(cx, &args[0]) {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
LEN_ZERO, LEN_ZERO,
span, span,
&format!("length comparison to {}", if compare_to == 0 { "zero" } else { "one" }), &format!("length comparison to {}", if compare_to == 0 { "zero" } else { "one" }),
"using `is_empty` is clearer and more explicit", "using `is_empty` is clearer and more explicit",
format!("{}{}.is_empty()", op, snippet(cx, args[0].span, "_")), format!("{}{}.is_empty()", op, snippet_with_applicability(cx, args[0].span, "_", &mut applicability)),
Applicability::Unspecified, applicability,
); );
} }
} }

View file

@ -301,7 +301,7 @@ impl WarningType {
"mistyped literal suffix", "mistyped literal suffix",
"did you mean to write", "did you mean to write",
grouping_hint.to_string(), grouping_hint.to_string(),
Applicability::Unspecified, Applicability::MachineApplicable,
), ),
WarningType::UnreadableLiteral => span_lint_and_sugg( WarningType::UnreadableLiteral => span_lint_and_sugg(
cx, cx,
@ -310,7 +310,7 @@ impl WarningType {
"long literal lacking separators", "long literal lacking separators",
"consider", "consider",
grouping_hint.to_owned(), grouping_hint.to_owned(),
Applicability::Unspecified, Applicability::MachineApplicable,
), ),
WarningType::LargeDigitGroups => span_lint_and_sugg( WarningType::LargeDigitGroups => span_lint_and_sugg(
cx, cx,
@ -319,7 +319,7 @@ impl WarningType {
"digit groups should be smaller", "digit groups should be smaller",
"consider", "consider",
grouping_hint.to_owned(), grouping_hint.to_owned(),
Applicability::Unspecified, Applicability::MachineApplicable,
), ),
WarningType::InconsistentDigitGrouping => span_lint_and_sugg( WarningType::InconsistentDigitGrouping => span_lint_and_sugg(
cx, cx,
@ -328,7 +328,7 @@ impl WarningType {
"digits grouped inconsistently by underscores", "digits grouped inconsistently by underscores",
"consider", "consider",
grouping_hint.to_owned(), grouping_hint.to_owned(),
Applicability::Unspecified, Applicability::MachineApplicable,
), ),
WarningType::DecimalRepresentation => span_lint_and_sugg( WarningType::DecimalRepresentation => span_lint_and_sugg(
cx, cx,
@ -337,7 +337,7 @@ impl WarningType {
"integer literal has a better hexadecimal representation", "integer literal has a better hexadecimal representation",
"consider", "consider",
grouping_hint.to_owned(), grouping_hint.to_owned(),
Applicability::Unspecified, Applicability::MachineApplicable,
), ),
}; };
} }

View file

@ -35,10 +35,12 @@ use crate::utils::{in_macro, sugg, sext};
use crate::utils::usage::mutated_variables; use crate::utils::usage::mutated_variables;
use crate::consts::{constant, Constant}; use crate::consts::{constant, Constant};
use crate::utils::{get_enclosing_block, get_parent_expr, higher, is_integer_literal, is_refutable,
last_path_segment, match_trait_method, match_type, match_var, multispan_sugg, snippet, snippet_opt,
span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, SpanlessEq};
use crate::utils::paths; use crate::utils::paths;
use crate::utils::{
get_enclosing_block, get_parent_expr, higher, is_integer_literal, is_refutable, last_path_segment,
match_trait_method, match_type, match_var, multispan_sugg, snippet, snippet_opt, snippet_with_applicability,
span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, SpanlessEq,
};
/// **What it does:** Checks for for-loops that manually copy items between /// **What it does:** Checks for for-loops that manually copy items between
/// slices that could be optimized by having a memcpy. /// slices that could be optimized by having a memcpy.
@ -501,6 +503,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
// 1) it was ugly with big bodies; // 1) it was ugly with big bodies;
// 2) it was not indented properly; // 2) it was not indented properly;
// 3) it wasnt very smart (see #675). // 3) it wasnt very smart (see #675).
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
WHILE_LET_LOOP, WHILE_LET_LOOP,
@ -509,10 +512,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
"try", "try",
format!( format!(
"while let {} = {} {{ .. }}", "while let {} = {} {{ .. }}",
snippet(cx, arms[0].pats[0].span, ".."), snippet_with_applicability(cx, arms[0].pats[0].span, "..", &mut applicability),
snippet(cx, matchexpr.span, "..") snippet_with_applicability(cx, matchexpr.span, "..", &mut applicability),
), ),
Applicability::Unspecified, applicability,
); );
} }
}, },
@ -550,7 +553,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
"this loop could be written as a `for` loop", "this loop could be written as a `for` loop",
"try", "try",
format!("for {} in {} {{ .. }}", loop_var, iterator), format!("for {} in {} {{ .. }}", loop_var, iterator),
Applicability::Unspecified, Applicability::HasPlaceholders,
); );
} }
} }
@ -1006,7 +1009,7 @@ fn detect_manual_memcpy<'a, 'tcx>(
let big_sugg = manual_copies let big_sugg = manual_copies
.into_iter() .into_iter()
.map(|(dst_var, src_var)| { .map(|(dst_var, src_var)| {
let start_str = Offset::positive(snippet_opt(cx, start.span).unwrap_or_else(|| "".into())); let start_str = Offset::positive(snippet(cx, start.span, "").to_string());
let dst_offset = print_sum(&start_str, &dst_var.offset); let dst_offset = print_sum(&start_str, &dst_var.offset);
let dst_limit = print_limit(end, dst_var.offset, &dst_var.var_name); let dst_limit = print_limit(end, dst_var.offset, &dst_var.var_name);
let src_offset = print_sum(&start_str, &src_var.offset); let src_offset = print_sum(&start_str, &src_var.offset);
@ -1305,7 +1308,8 @@ fn check_for_loop_reverse_range<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arg: &'tcx
} }
fn lint_iter_method(cx: &LateContext<'_, '_>, args: &[Expr], arg: &Expr, method_name: &str) { fn lint_iter_method(cx: &LateContext<'_, '_>, args: &[Expr], arg: &Expr, method_name: &str) {
let object = snippet(cx, args[0].span, "_"); let mut applicability = Applicability::MachineApplicable;
let object = snippet_with_applicability(cx, args[0].span, "_", &mut applicability);
let muta = if method_name == "iter_mut" { let muta = if method_name == "iter_mut" {
"mut " "mut "
} else { } else {
@ -1319,7 +1323,7 @@ fn lint_iter_method(cx: &LateContext<'_, '_>, args: &[Expr], arg: &Expr, method_
iteration methods", iteration methods",
"to write this more concisely, try", "to write this more concisely, try",
format!("&{}{}", muta, object), format!("&{}{}", muta, object),
Applicability::Unspecified, applicability,
) )
} }
@ -1349,7 +1353,8 @@ fn check_for_loop_arg(cx: &LateContext<'_, '_>, pat: &Pat, arg: &Expr, expr: &Ex
_ => lint_iter_method(cx, args, arg, method_name), _ => lint_iter_method(cx, args, arg, method_name),
}; };
} else { } else {
let object = snippet(cx, args[0].span, "_"); let mut applicability = Applicability::MachineApplicable;
let object = snippet_with_applicability(cx, args[0].span, "_", &mut applicability);
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
EXPLICIT_INTO_ITER_LOOP, EXPLICIT_INTO_ITER_LOOP,
@ -1358,7 +1363,7 @@ fn check_for_loop_arg(cx: &LateContext<'_, '_>, pat: &Pat, arg: &Expr, expr: &Ex
iteration methods`", iteration methods`",
"to write this more concisely, try", "to write this more concisely, try",
object.to_string(), object.to_string(),
Applicability::Unspecified, applicability,
); );
} }
} else if method_name == "next" && match_trait_method(cx, arg, &paths::ITERATOR) { } else if method_name == "next" && match_trait_method(cx, arg, &paths::ITERATOR) {

View file

@ -15,7 +15,7 @@ use crate::rustc_errors::Applicability;
use crate::syntax::ast::Ident; use crate::syntax::ast::Ident;
use crate::syntax::source_map::Span; use crate::syntax::source_map::Span;
use crate::utils::paths; use crate::utils::paths;
use crate::utils::{in_macro, match_trait_method, match_type, remove_blocks, snippet, span_lint_and_sugg}; use crate::utils::{in_macro, match_trait_method, match_type, remove_blocks, snippet_with_applicability, span_lint_and_sugg};
use if_chain::if_chain; use if_chain::if_chain;
#[derive(Clone)] #[derive(Clone)]
@ -92,14 +92,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
fn lint(cx: &LateContext<'_, '_>, replace: Span, root: Span, name: Ident, path: &hir::Expr) { fn lint(cx: &LateContext<'_, '_>, replace: Span, root: Span, name: Ident, path: &hir::Expr) {
if let hir::ExprKind::Path(hir::QPath::Resolved(None, ref path)) = path.node { if let hir::ExprKind::Path(hir::QPath::Resolved(None, ref path)) = path.node {
if path.segments.len() == 1 && path.segments[0].ident == name { if path.segments.len() == 1 && path.segments[0].ident == name {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
MAP_CLONE, MAP_CLONE,
replace, replace,
"You are using an explicit closure for cloning elements", "You are using an explicit closure for cloning elements",
"Consider calling the dedicated `cloned` method", "Consider calling the dedicated `cloned` method",
format!("{}.cloned()", snippet(cx, root, "..")), format!("{}.cloned()", snippet_with_applicability(cx, root, "..", &mut applicability)),
Applicability::Unspecified, applicability,
) )
} }
} }

View file

@ -19,7 +19,7 @@ use crate::syntax::ast::LitKind;
use crate::syntax::source_map::Span; use crate::syntax::source_map::Span;
use crate::utils::paths; use crate::utils::paths;
use crate::utils::{expr_block, in_macro, is_allowed, is_expn_of, match_qpath, match_type, use crate::utils::{expr_block, in_macro, is_allowed, is_expn_of, match_qpath, match_type,
multispan_sugg, remove_blocks, snippet, span_lint_and_sugg, span_lint_and_then, multispan_sugg, remove_blocks, snippet, snippet_with_applicability, span_lint_and_sugg, span_lint_and_then,
span_note_and_lint, walk_ptrs_ty}; span_note_and_lint, walk_ptrs_ty};
use crate::utils::sugg::Sugg; use crate::utils::sugg::Sugg;
use crate::consts::{constant, Constant}; use crate::consts::{constant, Constant};
@ -270,7 +270,7 @@ fn report_single_match_single_pattern(cx: &LateContext<'_, '_>, ex: &Expr, arms:
expr_block(cx, &arms[0].body, None, ".."), expr_block(cx, &arms[0].body, None, ".."),
els_str, els_str,
), ),
Applicability::Unspecified, Applicability::HasPlaceholders,
); );
} }
@ -478,14 +478,15 @@ fn check_match_as_ref(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &
}; };
if let Some(rb) = arm_ref { if let Some(rb) = arm_ref {
let suggestion = if rb == BindingAnnotation::Ref { "as_ref" } else { "as_mut" }; let suggestion = if rb == BindingAnnotation::Ref { "as_ref" } else { "as_mut" };
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
MATCH_AS_REF, MATCH_AS_REF,
expr.span, expr.span,
&format!("use {}() instead", suggestion), &format!("use {}() instead", suggestion),
"try this", "try this",
format!("{}.{}()", snippet(cx, ex.span, "_"), suggestion), format!("{}.{}()", snippet_with_applicability(cx, ex.span, "_", &mut applicability), suggestion),
Applicability::Unspecified, applicability,
) )
} }
} }

View file

@ -12,7 +12,7 @@ use crate::rustc::hir::{Expr, ExprKind, MutMutable, QPath};
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use crate::rustc::{declare_tool_lint, lint_array}; use crate::rustc::{declare_tool_lint, lint_array};
use crate::rustc_errors::Applicability; use crate::rustc_errors::Applicability;
use crate::utils::{match_def_path, match_qpath, opt_def_id, paths, snippet, span_lint_and_sugg}; use crate::utils::{match_def_path, match_qpath, opt_def_id, paths, snippet_with_applicability, span_lint_and_sugg};
use if_chain::if_chain; use if_chain::if_chain;
/// **What it does:** Checks for `mem::replace()` on an `Option` with /// **What it does:** Checks for `mem::replace()` on an `Option` with
@ -80,14 +80,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemReplace {
_ => return, _ => return,
}; };
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
MEM_REPLACE_OPTION_WITH_NONE, MEM_REPLACE_OPTION_WITH_NONE,
expr.span, expr.span,
"replacing an `Option` with `None`", "replacing an `Option` with `None`",
"consider `Option::take()` instead", "consider `Option::take()` instead",
format!("{}.take()", snippet(cx, replaced_path.span, "")), format!("{}.take()", snippet_with_applicability(cx, replaced_path.span, "", &mut applicability)),
Applicability::Unspecified, applicability,
); );
} }
} }

View file

@ -22,8 +22,9 @@ use crate::utils::sugg;
use crate::utils::{ use crate::utils::{
get_arg_name, get_trait_def_id, implements_trait, in_macro, is_copy, is_expn_of, is_self, is_self_ty, get_arg_name, get_trait_def_id, implements_trait, in_macro, is_copy, is_expn_of, is_self, is_self_ty,
iter_input_pats, last_path_segment, match_def_path, match_path, match_qpath, match_trait_method, match_type, iter_input_pats, last_path_segment, match_def_path, match_path, match_qpath, match_trait_method, match_type,
match_var, method_calls, method_chain_args, remove_blocks, return_ty, same_tys, single_segment_path, snippet, snippet_with_macro_callsite, span_lint, match_var, method_calls, method_chain_args, remove_blocks, return_ty, same_tys, single_segment_path, snippet,
span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq, snippet_with_macro_callsite, snippet_with_applicability, span_lint, span_lint_and_sugg, span_lint_and_then,
span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq,
}; };
use if_chain::if_chain; use if_chain::if_chain;
use matches::matches; use matches::matches;
@ -1035,14 +1036,15 @@ fn lint_or_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: Spa
}; };
if implements_trait(cx, arg_ty, default_trait_id, &[]) { if implements_trait(cx, arg_ty, default_trait_id, &[]) {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
OR_FUN_CALL, OR_FUN_CALL,
span, span,
&format!("use of `{}` followed by a call to `{}`", name, path), &format!("use of `{}` followed by a call to `{}`", name, path),
"try this", "try this",
format!("{}.unwrap_or_default()", snippet(cx, self_expr.span, "_")), format!("{}.unwrap_or_default()", snippet_with_applicability(cx, self_expr.span, "_", &mut applicability)),
Applicability::Unspecified, applicability,
); );
return true; return true;
} }
@ -1112,7 +1114,7 @@ fn lint_or_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: Spa
&format!("use of `{}` followed by a function call", name), &format!("use of `{}` followed by a function call", name),
"try this", "try this",
format!("{}_{}({})", name, suffix, sugg), format!("{}_{}({})", name, suffix, sugg),
Applicability::Unspecified, Applicability::HasPlaceholders,
); );
} }
@ -1155,11 +1157,15 @@ fn lint_expect_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span:
None None
} }
fn generate_format_arg_snippet(cx: &LateContext<'_, '_>, a: &hir::Expr) -> String { fn generate_format_arg_snippet(
cx: &LateContext<'_, '_>,
a: &hir::Expr,
applicability: &mut Applicability,
) -> String {
if let hir::ExprKind::AddrOf(_, ref format_arg) = a.node { if let hir::ExprKind::AddrOf(_, ref format_arg) = a.node {
if let hir::ExprKind::Match(ref format_arg_expr, _, _) = format_arg.node { if let hir::ExprKind::Match(ref format_arg_expr, _, _) = format_arg.node {
if let hir::ExprKind::Tup(ref format_arg_expr_tup) = format_arg_expr.node { if let hir::ExprKind::Tup(ref format_arg_expr_tup) = format_arg_expr.node {
return snippet(cx, format_arg_expr_tup[0].span, "..").into_owned(); return snippet_with_applicability(cx, format_arg_expr_tup[0].span, "..", applicability).into_owned();
} }
} }
}; };
@ -1210,11 +1216,12 @@ fn lint_expect_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span:
let span_replace_word = method_span.with_hi(span.hi()); let span_replace_word = method_span.with_hi(span.hi());
if let Some(format_args) = extract_format_args(arg) { if let Some(format_args) = extract_format_args(arg) {
let mut applicability = Applicability::MachineApplicable;
let args_len = format_args.len(); let args_len = format_args.len();
let args: Vec<String> = format_args let args: Vec<String> = format_args
.into_iter() .into_iter()
.take(args_len - 1) .take(args_len - 1)
.map(|a| generate_format_arg_snippet(cx, a)) .map(|a| generate_format_arg_snippet(cx, a, &mut applicability))
.collect(); .collect();
let sugg = args.join(", "); let sugg = args.join(", ");
@ -1226,13 +1233,14 @@ fn lint_expect_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span:
&format!("use of `{}` followed by a function call", name), &format!("use of `{}` followed by a function call", name),
"try this", "try this",
format!("unwrap_or_else({} panic!({}))", closure, sugg), format!("unwrap_or_else({} panic!({}))", closure, sugg),
Applicability::Unspecified, applicability,
); );
return; return;
} }
let sugg: Cow<'_, _> = snippet(cx, arg.span, ".."); let mut applicability = Applicability::MachineApplicable;
let sugg: Cow<'_, _> = snippet_with_applicability(cx, arg.span, "..", &mut applicability);
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
@ -1241,7 +1249,7 @@ fn lint_expect_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span:
&format!("use of `{}` followed by a function call", name), &format!("use of `{}` followed by a function call", name),
"try this", "try this",
format!("unwrap_or_else({} {{ let msg = {}; panic!(msg) }}))", closure, sugg), format!("unwrap_or_else({} {{ let msg = {}; panic!(msg) }}))", closure, sugg),
Applicability::Unspecified, applicability,
); );
} }
@ -1358,7 +1366,7 @@ fn lint_clone_on_ref_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr, arg: &hir::
"using '.clone()' on a ref-counted pointer", "using '.clone()' on a ref-counted pointer",
"try this", "try this",
format!("{}::<{}>::clone(&{})", caller_type, subst.type_at(0), snippet(cx, arg.span, "_")), format!("{}::<{}>::clone(&{})", caller_type, subst.type_at(0), snippet(cx, arg.span, "_")),
Applicability::Unspecified, Applicability::Unspecified, // Sometimes unnecessary ::<_> after Rc/Arc/Weak
); );
} }
} }
@ -1377,6 +1385,7 @@ fn lint_string_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr, args: &[hir::E
return; return;
}; };
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
STRING_EXTEND_CHARS, STRING_EXTEND_CHARS,
@ -1385,11 +1394,11 @@ fn lint_string_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr, args: &[hir::E
"try this", "try this",
format!( format!(
"{}.push_str({}{})", "{}.push_str({}{})",
snippet(cx, args[0].span, "_"), snippet_with_applicability(cx, args[0].span, "_", &mut applicability),
ref_str, ref_str,
snippet(cx, target.span, "_") snippet_with_applicability(cx, target.span, "_", &mut applicability)
), ),
Applicability::Unspecified, applicability,
); );
} }
} }
@ -1466,12 +1475,13 @@ fn lint_unnecessary_fold(cx: &LateContext<'_, '_>, expr: &hir::Expr, fold_args:
let next_point = cx.sess().source_map().next_point(fold_args[0].span); let next_point = cx.sess().source_map().next_point(fold_args[0].span);
let fold_span = next_point.with_hi(fold_args[2].span.hi() + BytePos(1)); let fold_span = next_point.with_hi(fold_args[2].span.hi() + BytePos(1));
let mut applicability = Applicability::MachineApplicable;
let sugg = if replacement_has_args { let sugg = if replacement_has_args {
format!( format!(
".{replacement}(|{s}| {r})", ".{replacement}(|{s}| {r})",
replacement = replacement_method_name, replacement = replacement_method_name,
s = second_arg_ident, s = second_arg_ident,
r = snippet(cx, right_expr.span, "EXPR"), r = snippet_with_applicability(cx, right_expr.span, "EXPR", &mut applicability),
) )
} else { } else {
format!( format!(
@ -1488,7 +1498,7 @@ fn lint_unnecessary_fold(cx: &LateContext<'_, '_>, expr: &hir::Expr, fold_args:
"this `.fold` can be written more succinctly using another method", "this `.fold` can be written more succinctly using another method",
"try", "try",
sugg, sugg,
Applicability::Unspecified, applicability,
); );
} }
} }
@ -1552,9 +1562,10 @@ fn lint_iter_nth(cx: &LateContext<'_, '_>, expr: &hir::Expr, iter_args: &[hir::E
fn lint_get_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr, get_args: &[hir::Expr], is_mut: bool) { fn lint_get_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr, get_args: &[hir::Expr], is_mut: bool) {
// Note: we don't want to lint `get_mut().unwrap` for HashMap or BTreeMap, // Note: we don't want to lint `get_mut().unwrap` for HashMap or BTreeMap,
// because they do not implement `IndexMut` // because they do not implement `IndexMut`
let mut applicability = Applicability::MachineApplicable;
let expr_ty = cx.tables.expr_ty(&get_args[0]); let expr_ty = cx.tables.expr_ty(&get_args[0]);
let get_args_str = if get_args.len() > 1 { let get_args_str = if get_args.len() > 1 {
snippet(cx, get_args[1].span, "_") snippet_with_applicability(cx, get_args[1].span, "_", &mut applicability)
} else { } else {
return; // not linting on a .get().unwrap() chain or variant return; // not linting on a .get().unwrap() chain or variant
}; };
@ -1593,10 +1604,10 @@ fn lint_get_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr, get_args: &[hir::
format!( format!(
"{}{}[{}]", "{}{}[{}]",
borrow_str, borrow_str,
snippet(cx, get_args[0].span, "_"), snippet_with_applicability(cx, get_args[0].span, "_", &mut applicability),
get_args_str get_args_str
), ),
Applicability::Unspecified, applicability,
); );
} }
@ -2012,6 +2023,7 @@ fn lint_chars_cmp(
if let Some(segment) = single_segment_path(qpath); if let Some(segment) = single_segment_path(qpath);
if segment.ident.name == "Some"; if segment.ident.name == "Some";
then { then {
let mut applicability = Applicability::MachineApplicable;
let self_ty = walk_ptrs_ty(cx.tables.expr_ty_adjusted(&args[0][0])); let self_ty = walk_ptrs_ty(cx.tables.expr_ty_adjusted(&args[0][0]));
if self_ty.sty != ty::Str { if self_ty.sty != ty::Str {
@ -2026,10 +2038,10 @@ fn lint_chars_cmp(
"like this", "like this",
format!("{}{}.{}({})", format!("{}{}.{}({})",
if info.eq { "" } else { "!" }, if info.eq { "" } else { "!" },
snippet(cx, args[0][0].span, "_"), snippet_with_applicability(cx, args[0][0].span, "_", &mut applicability),
suggest, suggest,
snippet(cx, arg_char[0].span, "_")), snippet_with_applicability(cx, arg_char[0].span, "_", &mut applicability)),
Applicability::Unspecified, applicability,
); );
return true; return true;
@ -2066,6 +2078,7 @@ fn lint_chars_cmp_with_unwrap<'a, 'tcx>(
if let hir::ExprKind::Lit(ref lit) = info.other.node; if let hir::ExprKind::Lit(ref lit) = info.other.node;
if let ast::LitKind::Char(c) = lit.node; if let ast::LitKind::Char(c) = lit.node;
then { then {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
lint, lint,
@ -2074,10 +2087,10 @@ fn lint_chars_cmp_with_unwrap<'a, 'tcx>(
"like this", "like this",
format!("{}{}.{}('{}')", format!("{}{}.{}('{}')",
if info.eq { "" } else { "!" }, if info.eq { "" } else { "!" },
snippet(cx, args[0][0].span, "_"), snippet_with_applicability(cx, args[0][0].span, "_", &mut applicability),
suggest, suggest,
c), c),
Applicability::Unspecified, applicability,
); );
return true; return true;
@ -2108,7 +2121,8 @@ fn lint_single_char_pattern<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, _expr: &'tcx h
if let ast::LitKind::Str(r, _) = lit.node; if let ast::LitKind::Str(r, _) = lit.node;
if r.as_str().len() == 1; if r.as_str().len() == 1;
then { then {
let snip = snippet(cx, arg.span, ".."); let mut applicability = Applicability::MachineApplicable;
let snip = snippet_with_applicability(cx, arg.span, "..", &mut applicability);
let hint = format!("'{}'", &snip[1..snip.len() - 1]); let hint = format!("'{}'", &snip[1..snip.len() - 1]);
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
@ -2117,7 +2131,7 @@ fn lint_single_char_pattern<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, _expr: &'tcx h
"single-character string constant used as pattern", "single-character string constant used as pattern",
"try using a char instead", "try using a char instead",
hint, hint,
Applicability::Unspecified, applicability,
); );
} }
} }
@ -2135,14 +2149,15 @@ fn lint_asref(cx: &LateContext<'_, '_>, expr: &hir::Expr, call_name: &str, as_re
let (base_res_ty, res_depth) = walk_ptrs_ty_depth(res_ty); let (base_res_ty, res_depth) = walk_ptrs_ty_depth(res_ty);
let (base_rcv_ty, rcv_depth) = walk_ptrs_ty_depth(rcv_ty); let (base_rcv_ty, rcv_depth) = walk_ptrs_ty_depth(rcv_ty);
if base_rcv_ty == base_res_ty && rcv_depth >= res_depth { if base_rcv_ty == base_res_ty && rcv_depth >= res_depth {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
USELESS_ASREF, USELESS_ASREF,
expr.span, expr.span,
&format!("this call to `{}` does nothing", call_name), &format!("this call to `{}` does nothing", call_name),
"try this", "try this",
snippet(cx, recvr.span, "_").into_owned(), snippet_with_applicability(cx, recvr.span, "_", &mut applicability).to_string(),
Applicability::Unspecified, applicability,
); );
} }
} }
@ -2207,8 +2222,8 @@ fn lint_into_iter(cx: &LateContext<'_, '_>, expr: &hir::Expr, self_ref_ty: ty::T
kind, kind,
), ),
"call directly", "call directly",
method_name.to_owned(), method_name.to_string(),
Applicability::Unspecified, Applicability::MachineApplicable,
); );
} }
} }

View file

@ -19,7 +19,7 @@ use crate::rustc_errors::Applicability;
use crate::syntax::ast::LitKind; use crate::syntax::ast::LitKind;
use crate::syntax::source_map::Spanned; use crate::syntax::source_map::Spanned;
use crate::utils::sugg::Sugg; use crate::utils::sugg::Sugg;
use crate::utils::{in_macro, snippet, span_lint, span_lint_and_sugg}; use crate::utils::{in_macro, snippet_with_applicability, span_lint, span_lint_and_sugg};
/// **What it does:** Checks for expressions of the form `if c { true } else { /// **What it does:** Checks for expressions of the form `if c { true } else {
/// false }` /// false }`
@ -74,7 +74,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool {
use self::Expression::*; use self::Expression::*;
if let ExprKind::If(ref pred, ref then_block, Some(ref else_expr)) = e.node { if let ExprKind::If(ref pred, ref then_block, Some(ref else_expr)) = e.node {
let reduce = |ret, not| { let reduce = |ret, not| {
let snip = Sugg::hir(cx, pred, "<predicate>"); let mut applicability = Applicability::MachineApplicable;
let snip = Sugg::hir_with_applicability(cx, pred, "<predicate>", &mut applicability);
let snip = if not { !snip } else { snip }; let snip = if not { !snip } else { snip };
let hint = if ret { let hint = if ret {
@ -90,7 +91,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool {
"this if-then-else expression returns a bool literal", "this if-then-else expression returns a bool literal",
"you can reduce it to", "you can reduce it to",
hint, hint,
Applicability::Unspecified, applicability,
); );
}; };
if let ExprKind::Block(ref then_block, _) = then_block.node { if let ExprKind::Block(ref then_block, _) = then_block.node {
@ -142,33 +143,34 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison {
} }
if let ExprKind::Binary(Spanned { node: BinOpKind::Eq, .. }, ref left_side, ref right_side) = e.node { if let ExprKind::Binary(Spanned { node: BinOpKind::Eq, .. }, ref left_side, ref right_side) = e.node {
let mut applicability = Applicability::MachineApplicable;
match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) { match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) {
(Bool(true), Other) => { (Bool(true), Other) => {
let hint = snippet(cx, right_side.span, "..").into_owned(); let hint = snippet_with_applicability(cx, right_side.span, "..", &mut applicability);
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
BOOL_COMPARISON, BOOL_COMPARISON,
e.span, e.span,
"equality checks against true are unnecessary", "equality checks against true are unnecessary",
"try simplifying it as shown", "try simplifying it as shown",
hint, hint.to_string(),
Applicability::Unspecified, applicability,
); );
}, },
(Other, Bool(true)) => { (Other, Bool(true)) => {
let hint = snippet(cx, left_side.span, "..").into_owned(); let hint = snippet_with_applicability(cx, left_side.span, "..", &mut applicability);
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
BOOL_COMPARISON, BOOL_COMPARISON,
e.span, e.span,
"equality checks against true are unnecessary", "equality checks against true are unnecessary",
"try simplifying it as shown", "try simplifying it as shown",
hint, hint.to_string(),
Applicability::Unspecified, applicability,
); );
}, },
(Bool(false), Other) => { (Bool(false), Other) => {
let hint = Sugg::hir(cx, right_side, ".."); let hint = Sugg::hir_with_applicability(cx, right_side, "..", &mut applicability);
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
BOOL_COMPARISON, BOOL_COMPARISON,
@ -176,11 +178,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison {
"equality checks against false can be replaced by a negation", "equality checks against false can be replaced by a negation",
"try simplifying it as shown", "try simplifying it as shown",
(!hint).to_string(), (!hint).to_string(),
Applicability::Unspecified, applicability,
); );
}, },
(Other, Bool(false)) => { (Other, Bool(false)) => {
let hint = Sugg::hir(cx, left_side, ".."); let hint = Sugg::hir_with_applicability(cx, left_side, "..", &mut applicability);
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
BOOL_COMPARISON, BOOL_COMPARISON,
@ -188,7 +190,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison {
"equality checks against false can be replaced by a negation", "equality checks against false can be replaced by a negation",
"try simplifying it as shown", "try simplifying it as shown",
(!hint).to_string(), (!hint).to_string(),
Applicability::Unspecified, applicability,
); );
}, },
_ => (), _ => (),

View file

@ -132,7 +132,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
"statement can be reduced", "statement can be reduced",
"replace it with", "replace it with",
snippet, snippet,
Applicability::Unspecified, Applicability::MachineApplicable,
); );
} }
} }

View file

@ -13,7 +13,7 @@ use crate::rustc::{declare_tool_lint, lint_array};
use crate::rustc_errors::Applicability; use crate::rustc_errors::Applicability;
use crate::syntax::ast::*; use crate::syntax::ast::*;
use crate::syntax::source_map::Spanned; use crate::syntax::source_map::Spanned;
use crate::utils::{in_macro, snippet, span_lint_and_sugg}; use crate::utils::{in_macro, snippet_with_applicability, span_lint_and_sugg};
/// **What it does:** Checks for operations where precedence may be unclear /// **What it does:** Checks for operations where precedence may be unclear
/// and suggests to add parentheses. Currently it catches the following: /// and suggests to add parentheses. Currently it catches the following:
@ -54,7 +54,7 @@ impl EarlyLintPass for Precedence {
} }
if let ExprKind::Binary(Spanned { node: op, .. }, ref left, ref right) = expr.node { if let ExprKind::Binary(Spanned { node: op, .. }, ref left, ref right) = expr.node {
let span_sugg = |expr: &Expr, sugg| { let span_sugg = |expr: &Expr, sugg, appl| {
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
PRECEDENCE, PRECEDENCE,
@ -62,40 +62,41 @@ impl EarlyLintPass for Precedence {
"operator precedence can trip the unwary", "operator precedence can trip the unwary",
"consider parenthesizing your expression", "consider parenthesizing your expression",
sugg, sugg,
Applicability::Unspecified, appl,
); );
}; };
if !is_bit_op(op) { if !is_bit_op(op) {
return; return;
} }
let mut applicability = Applicability::MachineApplicable;
match (is_arith_expr(left), is_arith_expr(right)) { match (is_arith_expr(left), is_arith_expr(right)) {
(true, true) => { (true, true) => {
let sugg = format!( let sugg = format!(
"({}) {} ({})", "({}) {} ({})",
snippet(cx, left.span, ".."), snippet_with_applicability(cx, left.span, "..", &mut applicability),
op.to_string(), op.to_string(),
snippet(cx, right.span, "..") snippet_with_applicability(cx, right.span, "..", &mut applicability)
); );
span_sugg(expr, sugg); span_sugg(expr, sugg, applicability);
}, },
(true, false) => { (true, false) => {
let sugg = format!( let sugg = format!(
"({}) {} {}", "({}) {} {}",
snippet(cx, left.span, ".."), snippet_with_applicability(cx, left.span, "..", &mut applicability),
op.to_string(), op.to_string(),
snippet(cx, right.span, "..") snippet_with_applicability(cx, right.span, "..", &mut applicability)
); );
span_sugg(expr, sugg); span_sugg(expr, sugg, applicability);
}, },
(false, true) => { (false, true) => {
let sugg = format!( let sugg = format!(
"{} {} ({})", "{} {} ({})",
snippet(cx, left.span, ".."), snippet_with_applicability(cx, left.span, "..", &mut applicability),
op.to_string(), op.to_string(),
snippet(cx, right.span, "..") snippet_with_applicability(cx, right.span, "..", &mut applicability)
); );
span_sugg(expr, sugg); span_sugg(expr, sugg, applicability);
}, },
(false, false) => (), (false, false) => (),
} }
@ -107,14 +108,15 @@ impl EarlyLintPass for Precedence {
if let ExprKind::Lit(ref lit) = slf.node { if let ExprKind::Lit(ref lit) = slf.node {
match lit.node { match lit.node {
LitKind::Int(..) | LitKind::Float(..) | LitKind::FloatUnsuffixed(..) => { LitKind::Int(..) | LitKind::Float(..) | LitKind::FloatUnsuffixed(..) => {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
PRECEDENCE, PRECEDENCE,
expr.span, expr.span,
"unary minus has lower precedence than method call", "unary minus has lower precedence than method call",
"consider adding parentheses to clarify your intent", "consider adding parentheses to clarify your intent",
format!("-({})", snippet(cx, rhs.span, "..")), format!("-({})", snippet_with_applicability(cx, rhs.span, "..", &mut applicability)),
Applicability::Unspecified, applicability,
); );
}, },
_ => (), _ => (),

View file

@ -77,7 +77,7 @@ impl<'a, 'tcx> lint::LateLintPass<'a, 'tcx> for Pass {
&msg, &msg,
"try", "try",
sugg, sugg,
Applicability::Unspecified, Applicability::MachineApplicable,
); );
} else { } else {
utils::span_lint(cx, PTR_OFFSET_WITH_CAST, expr.span, &msg); utils::span_lint(cx, PTR_OFFSET_WITH_CAST, expr.span, &msg);

View file

@ -66,7 +66,7 @@ impl EarlyLintPass for RedundantFieldNames {
"redundant field names in struct initialization", "redundant field names in struct initialization",
"replace it with", "replace it with",
field.ident.to_string(), field.ident.to_string(),
Applicability::Unspecified, Applicability::MachineApplicable,
); );
} }
} }

View file

@ -12,7 +12,7 @@ use crate::rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
use crate::rustc::{declare_tool_lint, lint_array}; use crate::rustc::{declare_tool_lint, lint_array};
use crate::rustc_errors::Applicability; use crate::rustc_errors::Applicability;
use crate::syntax::ast::{Expr, ExprKind, UnOp}; use crate::syntax::ast::{Expr, ExprKind, UnOp};
use crate::utils::{snippet, span_lint_and_sugg}; use crate::utils::{snippet_with_applicability, span_lint_and_sugg};
use if_chain::if_chain; use if_chain::if_chain;
/// **What it does:** Checks for usage of `*&` and `*&mut` in expressions. /// **What it does:** Checks for usage of `*&` and `*&mut` in expressions.
@ -55,14 +55,15 @@ impl EarlyLintPass for Pass {
if let ExprKind::Unary(UnOp::Deref, ref deref_target) = e.node; if let ExprKind::Unary(UnOp::Deref, ref deref_target) = e.node;
if let ExprKind::AddrOf(_, ref addrof_target) = without_parens(deref_target).node; if let ExprKind::AddrOf(_, ref addrof_target) = without_parens(deref_target).node;
then { then {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
DEREF_ADDROF, DEREF_ADDROF,
e.span, e.span,
"immediately dereferencing a reference", "immediately dereferencing a reference",
"try this", "try this",
format!("{}", snippet(cx, addrof_target.span, "_")), format!("{}", snippet_with_applicability(cx, addrof_target.span, "_", &mut applicability)),
Applicability::Unspecified, applicability,
); );
} }
} }
@ -102,6 +103,7 @@ impl EarlyLintPass for DerefPass {
if let ExprKind::Paren(ref parened) = object.node; if let ExprKind::Paren(ref parened) = object.node;
if let ExprKind::AddrOf(_, ref inner) = parened.node; if let ExprKind::AddrOf(_, ref inner) = parened.node;
then { then {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
REF_IN_DEREF, REF_IN_DEREF,
@ -110,10 +112,10 @@ impl EarlyLintPass for DerefPass {
"try this", "try this",
format!( format!(
"{}.{}", "{}.{}",
snippet(cx, inner.span, "_"), snippet_with_applicability(cx, inner.span, "_", &mut applicability),
snippet(cx, field_name.span, "_") snippet_with_applicability(cx, field_name.span, "_", &mut applicability)
), ),
Applicability::Unspecified, applicability,
); );
} }
} }

View file

@ -62,7 +62,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ReplaceConsts {
&format!("using `{}`", const_path.last().expect("empty path")), &format!("using `{}`", const_path.last().expect("empty path")),
"try this", "try this",
repl_snip.to_string(), repl_snip.to_string(),
Applicability::Unspecified, Applicability::MachineApplicable,
); );
return; return;
} }

View file

@ -165,7 +165,7 @@ impl LintPass for StringLitAsBytes {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
use crate::syntax::ast::{LitKind, StrStyle}; use crate::syntax::ast::{LitKind, StrStyle};
use crate::utils::{in_macro, snippet}; use crate::utils::{in_macro, snippet, snippet_with_applicability};
if let ExprKind::MethodCall(ref path, _, ref args) = e.node { if let ExprKind::MethodCall(ref path, _, ref args) = e.node {
if path.ident.name == "as_bytes" { if path.ident.name == "as_bytes" {
@ -178,6 +178,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes {
} else { } else {
format!("\"{}\"", lit_content.as_str()) format!("\"{}\"", lit_content.as_str())
}; };
let mut applicability = Applicability::MachineApplicable;
if callsite.starts_with("include_str!") { if callsite.starts_with("include_str!") {
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
@ -185,8 +186,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes {
e.span, e.span,
"calling `as_bytes()` on `include_str!(..)`", "calling `as_bytes()` on `include_str!(..)`",
"consider using `include_bytes!(..)` instead", "consider using `include_bytes!(..)` instead",
snippet(cx, args[0].span, r#""foo""#).replacen("include_str", "include_bytes", 1), snippet_with_applicability(cx, args[0].span, r#""foo""#, &mut applicability).replacen(
Applicability::Unspecified, "include_str",
"include_bytes",
1,
),
applicability,
); );
} else if callsite == expanded } else if callsite == expanded
&& lit_content.as_str().chars().all(|c| c.is_ascii()) && lit_content.as_str().chars().all(|c| c.is_ascii())
@ -198,8 +203,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes {
e.span, e.span,
"calling `as_bytes()` on a string literal", "calling `as_bytes()` on a string literal",
"consider using a byte string literal instead", "consider using a byte string literal instead",
format!("b{}", snippet(cx, args[0].span, r#""foo""#)), format!(
Applicability::Unspecified, "b{}",
snippet_with_applicability(cx, args[0].span, r#""foo""#, &mut applicability)
),
applicability,
); );
} }
} }

View file

@ -15,14 +15,14 @@ use crate::rustc::hir::intravisit::FnKind;
use crate::rustc::hir::*; use crate::rustc::hir::*;
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use crate::rustc::session::config::Config as SessionConfig; use crate::rustc::session::config::Config as SessionConfig;
use crate::rustc::ty::TyKind; use crate::rustc::ty::{FnSig, TyKind};
use crate::rustc::{declare_tool_lint, lint_array}; use crate::rustc::{declare_tool_lint, lint_array};
use crate::rustc_errors::Applicability; use crate::rustc_errors::Applicability;
use crate::rustc_target::abi::LayoutOf; use crate::rustc_target::abi::LayoutOf;
use crate::rustc_target::spec::abi::Abi; use crate::rustc_target::spec::abi::Abi;
use crate::syntax::ast::NodeId; use crate::syntax::ast::NodeId;
use crate::syntax_pos::Span; use crate::syntax_pos::Span;
use crate::utils::{in_macro, is_copy, is_self, snippet, span_lint_and_sugg}; use crate::utils::{in_macro, is_copy, is_self_ty, snippet, span_lint_and_sugg};
use if_chain::if_chain; use if_chain::if_chain;
use matches::matches; use matches::matches;
@ -141,7 +141,9 @@ impl<'a, 'tcx> TriviallyCopyPassByRef {
input.span, input.span,
"this argument is passed by reference, but would be more efficient if passed by value", "this argument is passed by reference, but would be more efficient if passed by value",
"consider passing by value instead", "consider passing by value instead",
value_type); value_type,
Applicability::Unspecified,
);
} }
} }
} }

View file

@ -29,7 +29,7 @@ use crate::utils::paths;
use crate::utils::{ use crate::utils::{
clip, comparisons, differing_macro_contexts, higher, in_constant, in_macro, int_bits, last_path_segment, clip, comparisons, differing_macro_contexts, higher, in_constant, in_macro, int_bits, last_path_segment,
match_def_path, match_path, match_type, multispan_sugg, opt_def_id, same_tys, sext, snippet, snippet_opt, match_def_path, match_path, match_type, multispan_sugg, opt_def_id, same_tys, sext, snippet, snippet_opt,
span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, unsext, snippet_with_applicability, span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, unsext,
}; };
use if_chain::if_chain; use if_chain::if_chain;
use std::borrow::Cow; use std::borrow::Cow;
@ -334,20 +334,21 @@ fn check_ty_rptr(cx: &LateContext<'_, '_>, ast_ty: &hir::Ty, is_local: bool, lt:
let ltopt = if lt.is_elided() { let ltopt = if lt.is_elided() {
String::new() String::new()
} else { } else {
format!("{} ", lt.name.ident().name.as_str()) format!("{} ", lt.name.ident().as_str())
}; };
let mutopt = if mut_ty.mutbl == Mutability::MutMutable { let mutopt = if mut_ty.mutbl == Mutability::MutMutable {
"mut " "mut "
} else { } else {
"" ""
}; };
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
BORROWED_BOX, BORROWED_BOX,
ast_ty.span, ast_ty.span,
"you seem to be trying to use `&Box<T>`. Consider using just `&T`", "you seem to be trying to use `&Box<T>`. Consider using just `&T`",
"try", "try",
format!("&{}{}{}", ltopt, mutopt, &snippet(cx, inner.span, "..")), format!("&{}{}{}", ltopt, mutopt, &snippet_with_applicability(cx, inner.span, "..", &mut applicability)),
Applicability::Unspecified, Applicability::Unspecified,
); );
return; // don't recurse into the type return; // don't recurse into the type
@ -542,7 +543,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitArg {
"passing a unit value to a function", "passing a unit value to a function",
"if you intended to pass a unit value, use a unit literal instead", "if you intended to pass a unit value, use a unit literal instead",
"()".to_string(), "()".to_string(),
Applicability::Unspecified, Applicability::MachineApplicable,
); );
} }
} }
@ -862,6 +863,7 @@ fn span_lossless_lint(cx: &LateContext<'_, '_>, expr: &Expr, op: &Expr, cast_fro
if in_constant(cx, expr.id) { return } if in_constant(cx, expr.id) { return }
// The suggestion is to use a function call, so if the original expression // The suggestion is to use a function call, so if the original expression
// has parens on the outside, they are no longer needed. // has parens on the outside, they are no longer needed.
let mut applicability = Applicability::MachineApplicable;
let opt = snippet_opt(cx, op.span); let opt = snippet_opt(cx, op.span);
let sugg = if let Some(ref snip) = opt { let sugg = if let Some(ref snip) = opt {
if should_strip_parens(op, snip) { if should_strip_parens(op, snip) {
@ -870,6 +872,7 @@ fn span_lossless_lint(cx: &LateContext<'_, '_>, expr: &Expr, op: &Expr, cast_fro
snip.as_str() snip.as_str()
} }
} else { } else {
applicability = Applicability::HasPlaceholders;
".." ".."
}; };
@ -880,7 +883,7 @@ fn span_lossless_lint(cx: &LateContext<'_, '_>, expr: &Expr, op: &Expr, cast_fro
&format!("casting {} to {} may become silently lossy if types change", cast_from, cast_to), &format!("casting {} to {} may become silently lossy if types change", cast_from, cast_to),
"try", "try",
format!("{}::from({})", cast_to, sugg), format!("{}::from({})", cast_to, sugg),
Applicability::Unspecified, applicability,
); );
} }
@ -1100,7 +1103,8 @@ fn lint_fn_to_numeric_cast(cx: &LateContext<'_, '_>, expr: &Expr, cast_expr: &Ex
} }
match cast_from.sty { match cast_from.sty {
ty::FnDef(..) | ty::FnPtr(_) => { ty::FnDef(..) | ty::FnPtr(_) => {
let from_snippet = snippet(cx, cast_expr.span, "x"); let mut applicability = Applicability::MachineApplicable;
let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability);
let to_nbits = int_ty_to_nbits(cast_to, cx.tcx); let to_nbits = int_ty_to_nbits(cast_to, cx.tcx);
if to_nbits < cx.tcx.data_layout.pointer_size.bits() { if to_nbits < cx.tcx.data_layout.pointer_size.bits() {
@ -1111,7 +1115,7 @@ fn lint_fn_to_numeric_cast(cx: &LateContext<'_, '_>, expr: &Expr, cast_expr: &Ex
&format!("casting function pointer `{}` to `{}`, which truncates the value", from_snippet, cast_to), &format!("casting function pointer `{}` to `{}`, which truncates the value", from_snippet, cast_to),
"try", "try",
format!("{} as usize", from_snippet), format!("{} as usize", from_snippet),
Applicability::Unspecified, applicability,
); );
} else if cast_to.sty != ty::Uint(UintTy::Usize) { } else if cast_to.sty != ty::Uint(UintTy::Usize) {
@ -1122,7 +1126,7 @@ fn lint_fn_to_numeric_cast(cx: &LateContext<'_, '_>, expr: &Expr, cast_expr: &Ex
&format!("casting function pointer `{}` to `{}`", from_snippet, cast_to), &format!("casting function pointer `{}` to `{}`", from_snippet, cast_to),
"try", "try",
format!("{} as usize", from_snippet), format!("{} as usize", from_snippet),
Applicability::Unspecified, applicability,
); );
} }
}, },

View file

@ -71,7 +71,7 @@ fn span_use_self_lint(cx: &LateContext<'_, '_>, path: &Path) {
"unnecessary structure name repetition", "unnecessary structure name repetition",
"use the applicable keyword", "use the applicable keyword",
"Self".to_owned(), "Self".to_owned(),
Applicability::Unspecified, Applicability::MachineApplicable,
); );
} }

View file

@ -282,7 +282,7 @@ impl EarlyLintPass for DefaultHashTypes {
&msg, &msg,
"use", "use",
replace.to_string(), replace.to_string(),
Applicability::Unspecified, Applicability::MaybeIncorrect, // FxHashMap, ... needs another import
); );
} }
} }

View file

@ -15,7 +15,7 @@ use crate::rustc::ty::{self, Ty};
use crate::rustc::{declare_tool_lint, lint_array}; use crate::rustc::{declare_tool_lint, lint_array};
use crate::rustc_errors::Applicability; use crate::rustc_errors::Applicability;
use crate::syntax::source_map::Span; use crate::syntax::source_map::Span;
use crate::utils::{higher, is_copy, snippet, span_lint_and_sugg}; use crate::utils::{higher, is_copy, snippet_with_applicability, span_lint_and_sugg};
use if_chain::if_chain; use if_chain::if_chain;
/// **What it does:** Checks for usage of `&vec![..]` when using `&[..]` would /// **What it does:** Checks for usage of `&vec![..]` when using `&[..]` would
@ -77,10 +77,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
} }
fn check_vec_macro<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, vec_args: &higher::VecArgs<'tcx>, span: Span) { fn check_vec_macro<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, vec_args: &higher::VecArgs<'tcx>, span: Span) {
let mut applicability = Applicability::MachineApplicable;
let snippet = match *vec_args { let snippet = match *vec_args {
higher::VecArgs::Repeat(elem, len) => { higher::VecArgs::Repeat(elem, len) => {
if constant(cx, cx.tables, len).is_some() { if constant(cx, cx.tables, len).is_some() {
format!("&[{}; {}]", snippet(cx, elem.span, "elem"), snippet(cx, len.span, "len")) format!(
"&[{}; {}]",
snippet_with_applicability(cx, elem.span, "elem", &mut applicability),
snippet_with_applicability(cx, len.span, "len", &mut applicability)
)
} else { } else {
return; return;
} }
@ -88,7 +93,7 @@ fn check_vec_macro<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, vec_args: &higher::VecA
higher::VecArgs::Vec(args) => if let Some(last) = args.iter().last() { higher::VecArgs::Vec(args) => if let Some(last) = args.iter().last() {
let span = args[0].span.to(last.span); let span = args[0].span.to(last.span);
format!("&[{}]", snippet(cx, span, "..")) format!("&[{}]", snippet_with_applicability(cx, span, "..", &mut applicability))
} else { } else {
"&[]".into() "&[]".into()
}, },
@ -101,7 +106,7 @@ fn check_vec_macro<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, vec_args: &higher::VecA
"useless use of `vec!`", "useless use of `vec!`",
"you can use a slice directly", "you can use a slice directly",
snippet, snippet,
Applicability::Unspecified, applicability,
); );
} }

View file

@ -14,7 +14,7 @@ use crate::rustc_errors::Applicability;
use crate::syntax::ast::*; use crate::syntax::ast::*;
use crate::syntax::parse::{parser, token}; use crate::syntax::parse::{parser, token};
use crate::syntax::tokenstream::{ThinTokenStream, TokenStream}; use crate::syntax::tokenstream::{ThinTokenStream, TokenStream};
use crate::utils::{snippet, span_lint, span_lint_and_sugg}; use crate::utils::{snippet_with_applicability, span_lint, span_lint_and_sugg};
use std::borrow::Cow; use std::borrow::Cow;
/// **What it does:** This lint warns when you use `println!("")` to /// **What it does:** This lint warns when you use `println!("")` to
@ -200,7 +200,7 @@ impl EarlyLintPass for Pass {
"using `println!(\"\")`", "using `println!(\"\")`",
"replace it with", "replace it with",
"println!()".to_string(), "println!()".to_string(),
Applicability::Unspecified, Applicability::MachineApplicable,
); );
} }
} }
@ -239,9 +239,14 @@ impl EarlyLintPass for Pass {
let check_tts = check_tts(cx, &mac.node.tts, true); let check_tts = check_tts(cx, &mac.node.tts, true);
if let Some(fmtstr) = check_tts.0 { if let Some(fmtstr) = check_tts.0 {
if fmtstr == "" { if fmtstr == "" {
let suggestion = check_tts let mut applicability = Applicability::MachineApplicable;
.1 let suggestion = check_tts.1.map_or_else(
.map_or(Cow::Borrowed("v"), |expr| snippet(cx, expr.span, "v")); move || {
applicability = Applicability::HasPlaceholders;
Cow::Borrowed("v")
},
move |expr| snippet_with_applicability(cx, expr.span, "v", &mut applicability),
);
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
@ -250,7 +255,7 @@ impl EarlyLintPass for Pass {
format!("using `writeln!({}, \"\")`", suggestion).as_str(), format!("using `writeln!({}, \"\")`", suggestion).as_str(),
"replace it with", "replace it with",
format!("writeln!({})", suggestion), format!("writeln!({})", suggestion),
Applicability::Unspecified, applicability,
); );
} }
} }