From fad267c3b32895999f464c640d603f923fa0eeba Mon Sep 17 00:00:00 2001 From: flip1995 Date: Tue, 20 Nov 2018 10:33:40 +0100 Subject: [PATCH 1/8] Introduce snippet_with_applicability and hir_with_applicability functions --- clippy_lints/src/utils/mod.rs | 258 ++++++++++++++++++--------------- clippy_lints/src/utils/sugg.rs | 9 ++ 2 files changed, 151 insertions(+), 116 deletions(-) diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 457aa3f85003..43af5e393c8a 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -7,44 +7,48 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - use crate::reexport::*; -use matches::matches; -use if_chain::if_chain; use crate::rustc::hir; -use crate::rustc::hir::*; -use crate::rustc::hir::def_id::{DefId, CRATE_DEF_INDEX}; use crate::rustc::hir::def::Def; +use crate::rustc::hir::def_id::{DefId, CRATE_DEF_INDEX}; use crate::rustc::hir::intravisit::{NestedVisitorMap, Visitor}; use crate::rustc::hir::Node; +use crate::rustc::hir::*; use crate::rustc::lint::{LateContext, Level, Lint, LintContext}; use crate::rustc::session::Session; use crate::rustc::traits; -use crate::rustc::ty::{self, Binder, Ty, TyCtxt, layout::{self, IntegerExt}, subst::Kind}; +use crate::rustc::ty::{ + self, + layout::{self, IntegerExt}, + subst::Kind, + Binder, Ty, TyCtxt, +}; use crate::rustc_errors::{Applicability, CodeSuggestion, Substitution, SubstitutionPart}; -use std::borrow::Cow; -use std::env; -use std::mem; -use std::str::FromStr; -use std::rc::Rc; use crate::syntax::ast::{self, LitKind}; use crate::syntax::attr; -use crate::syntax::source_map::{Span, DUMMY_SP}; use crate::syntax::errors::DiagnosticBuilder; +use crate::syntax::source_map::{Span, DUMMY_SP}; use crate::syntax::symbol::{keywords, Symbol}; +use if_chain::if_chain; +use matches::matches; +use std::borrow::Cow; +use std::env; +use std::mem; +use std::rc::Rc; +use std::str::FromStr; pub mod camel_case; +pub mod author; pub mod comparisons; pub mod conf; pub mod constants; mod hir_utils; -pub mod paths; -pub mod sugg; pub mod inspector; pub mod internal_lints; -pub mod author; +pub mod paths; pub mod ptr; +pub mod sugg; pub mod usage; pub use self::hir_utils::{SpanlessEq, SpanlessHash}; @@ -101,11 +105,7 @@ pub fn match_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, path: &[&str]) -> tcx.push_item_path(&mut apb, def_id, false); - apb.names.len() == path.len() - && apb.names - .into_iter() - .zip(path.iter()) - .all(|(a, &b)| *a == *b) + apb.names.len() == path.len() && apb.names.into_iter().zip(path.iter()).all(|(a, &b)| *a == *b) } /// Check if type is struct, enum or union type with given def path. @@ -137,12 +137,9 @@ pub fn match_var(expr: &Expr, var: Name) -> bool { false } - pub fn last_path_segment(path: &QPath) -> &PathSegment { match *path { - QPath::Resolved(_, ref path) => path.segments - .last() - .expect("A path must have at least one segment"), + QPath::Resolved(_, ref path) => path.segments.last().expect("A path must have at least one segment"), QPath::TypeRelative(_, ref seg) => seg, } } @@ -166,7 +163,8 @@ pub fn match_qpath(path: &QPath, segments: &[&str]) -> bool { QPath::Resolved(_, ref path) => match_path(path, segments), QPath::TypeRelative(ref ty, ref segment) => match ty.node { TyKind::Path(ref inner_path) => { - !segments.is_empty() && match_qpath(inner_path, &segments[..(segments.len() - 1)]) + !segments.is_empty() + && match_qpath(inner_path, &segments[..(segments.len() - 1)]) && segment.ident.name == segments[segments.len() - 1] }, _ => false, @@ -199,9 +197,7 @@ pub fn match_path_ast(path: &ast::Path, segments: &[&str]) -> bool { /// Get the definition associated to a path. pub fn path_to_def(cx: &LateContext<'_, '_>, path: &[&str]) -> Option { let crates = cx.tcx.crates(); - let krate = crates - .iter() - .find(|&&krate| cx.tcx.crate_name(krate) == path[0]); + let krate = crates.iter().find(|&&krate| cx.tcx.crate_name(krate) == path[0]); if let Some(krate) = krate { let krate = DefId { krate: *krate, @@ -254,10 +250,17 @@ pub fn implements_trait<'a, 'tcx>( ty_params: &[Kind<'tcx>], ) -> bool { let ty = cx.tcx.erase_regions(&ty); - let obligation = - cx.tcx - .predicate_for_trait_def(cx.param_env, traits::ObligationCause::dummy(), trait_id, 0, ty, ty_params); - cx.tcx.infer_ctxt().enter(|infcx| infcx.predicate_must_hold(&obligation)) + let obligation = cx.tcx.predicate_for_trait_def( + cx.param_env, + traits::ObligationCause::dummy(), + trait_id, + 0, + ty, + ty_params, + ); + cx.tcx + .infer_ctxt() + .enter(|infcx| infcx.predicate_must_hold(&obligation)) } /// Check whether this type implements Drop. @@ -326,14 +329,14 @@ pub fn method_chain_args<'a>(expr: &'a Expr, methods: &[&str]) -> Option, expr: &Expr) -> Option { let parent_id = cx.tcx.hir.get_parent(expr.id); match cx.tcx.hir.find(parent_id) { Some(Node::Item(&Item { ref name, .. })) => Some(*name), - Some(Node::TraitItem(&TraitItem { ident, .. })) | - Some(Node::ImplItem(&ImplItem { ident, .. })) => Some(ident.name), + Some(Node::TraitItem(&TraitItem { ident, .. })) | Some(Node::ImplItem(&ImplItem { ident, .. })) => { + Some(ident.name) + }, _ => None, } } @@ -366,15 +369,11 @@ impl<'tcx> Visitor<'tcx> for ContainsName { /// check if an `Expr` contains a certain name pub fn contains_name(name: Name, expr: &Expr) -> bool { - let mut cn = ContainsName { - name, - result: false, - }; + let mut cn = ContainsName { name, result: false }; cn.visit_expr(expr); cn.result } - /// Convert a span to a code snippet if available, otherwise use default. /// /// # Example @@ -385,6 +384,31 @@ pub fn snippet<'a, 'b, T: LintContext<'b>>(cx: &T, span: Span, default: &'a str) snippet_opt(cx, span).map_or_else(|| Cow::Borrowed(default), From::from) } +pub fn snippet_with_applicability<'a, 'b, T: LintContext<'b>>( + cx: &T, + span: Span, + default: &'a str, + applicability: &mut Applicability, +) -> Cow<'a, str> { + snippet_opt(cx, span).map_or_else( + || { + // If the applicability is already `HasPlaceholders` or `MaybeIncorrect` don't change it. + // Also `Unspecified` shouldn't be changed + // Only if the applicability level is originally `MachineApplicable` and the default value + // has to be used change it to `HasPlaceholders` + if *applicability == Applicability::MachineApplicable { + if in_macro(span) { + *applicability = Applicability::MaybeIncorrect; + } else { + *applicability = Applicability::HasPlaceholders; + } + } + Cow::Borrowed(default) + }, + From::from, + ) +} + /// Same as `snippet`, but should only be used when it's clear that the input span is /// not a macro argument. pub fn snippet_with_macro_callsite<'a, 'b, T: LintContext<'b>>(cx: &T, span: Span, default: &'a str) -> Cow<'a, str> { @@ -431,8 +455,7 @@ pub fn expr_block<'a, 'b, T: LintContext<'b>>( let string = option.unwrap_or_default(); if in_macro(expr.span) { Cow::Owned(format!("{{ {} }}", snippet_with_macro_callsite(cx, expr.span, default))) - } - else if let ExprKind::Block(_, _) = expr.node { + } else if let ExprKind::Block(_, _) = expr.node { Cow::Owned(format!("{}{}", code, string)) } else if string.is_empty() { Cow::Owned(format!("{{ {} }}", code)) @@ -450,19 +473,15 @@ pub fn trim_multiline(s: Cow<'_, str>, ignore_first: bool) -> Cow<'_, str> { } fn trim_multiline_inner(s: Cow<'_, str>, ignore_first: bool, ch: char) -> Cow<'_, str> { - let x = s.lines() + let x = s + .lines() .skip(ignore_first as usize) .filter_map(|l| { if l.is_empty() { None } else { // ignore empty lines - Some( - l.char_indices() - .find(|&(_, x)| x != ch) - .unwrap_or((l.len(), ch)) - .0, - ) + Some(l.char_indices().find(|&(_, x)| x != ch).unwrap_or((l.len(), ch)).0) } }) .min() @@ -505,7 +524,8 @@ pub fn get_parent_expr<'c>(cx: &'c LateContext<'_, '_>, e: &Expr) -> Option<&'c pub fn get_enclosing_block<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, node: NodeId) -> Option<&'tcx Block> { let map = &cx.tcx.hir; - let enclosing_node = map.get_enclosing_scope(node) + let enclosing_node = map + .get_enclosing_scope(node) .and_then(|enclosing_id| map.find(enclosing_id)); if let Some(node) = enclosing_node { match node { @@ -513,7 +533,8 @@ pub fn get_enclosing_block<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, node: NodeI Node::Item(&Item { node: ItemKind::Fn(_, _, _, eid), .. - }) | Node::ImplItem(&ImplItem { + }) + | Node::ImplItem(&ImplItem { node: ImplItemKind::Method(_, eid), .. }) => match cx.tcx.hir.body(eid).value.node { @@ -617,7 +638,8 @@ pub fn span_lint_node_and_then( /// Add a span lint with a suggestion on how to fix it. /// /// These suggestions can be parsed by rustfix to allow it to automatically fix your code. -/// In the example below, `help` is `"try"` and `sugg` is the suggested replacement `".any(|x| x > 2)"`. +/// In the example below, `help` is `"try"` and `sugg` is the suggested replacement `".any(|x| x > +/// 2)"`. /// /// ```ignore /// error: This `.fold` can be more succinctly expressed as `.any` @@ -652,18 +674,12 @@ where I: IntoIterator, { let sugg = CodeSuggestion { - substitutions: vec![ - Substitution { - parts: sugg.into_iter() - .map(|(span, snippet)| { - SubstitutionPart { - snippet, - span, - } - }) - .collect(), - } - ], + substitutions: vec![Substitution { + parts: sugg + .into_iter() + .map(|(span, snippet)| SubstitutionPart { snippet, span }) + .collect(), + }], msg: help_msg, show_code_when_inline: true, applicability: Applicability::Unspecified, @@ -729,9 +745,7 @@ impl LimitStack { Self { stack: vec![limit] } } pub fn limit(&self) -> u64 { - *self.stack - .last() - .expect("there should always be a value in the stack") + *self.stack.last().expect("there should always be a value in the stack") } pub fn push_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) { let stack = &mut self.stack; @@ -744,10 +758,11 @@ impl LimitStack { } pub fn get_attr<'a>(attrs: &'a [ast::Attribute], name: &'static str) -> impl Iterator { - attrs.iter().filter(move |attr| - attr.path.segments.len() == 2 && - attr.path.segments[0].ident.to_string() == "clippy" && - attr.path.segments[1].ident.to_string() == name) + attrs.iter().filter(move |attr| { + attr.path.segments.len() == 2 + && attr.path.segments[0].ident.to_string() == "clippy" + && attr.path.segments[1].ident.to_string() == name + }) } fn parse_attrs(sess: &Session, attrs: &[ast::Attribute], name: &'static str, mut f: F) { @@ -769,7 +784,8 @@ fn parse_attrs(sess: &Session, attrs: &[ast::Attribute], name: &' /// See also `is_direct_expn_of`. pub fn is_expn_of(mut span: Span, name: &str) -> Option { loop { - let span_name_span = span.ctxt() + let span_name_span = span + .ctxt() .outer() .expn_info() .map(|ei| (ei.format.name(), ei.call_site)); @@ -792,7 +808,8 @@ pub fn is_expn_of(mut span: Span, name: &str) -> Option { /// `bar!` by /// `is_direct_expn_of`. pub fn is_direct_expn_of(span: Span, name: &str) -> Option { - let span_name_span = span.ctxt() + let span_name_span = span + .ctxt() .outer() .expn_info() .map(|ei| (ei.format.name(), ei.call_site)); @@ -855,23 +872,23 @@ pub fn is_refutable(cx: &LateContext<'_, '_>, pat: &Pat) -> bool { PatKind::Lit(..) | PatKind::Range(..) => true, PatKind::Path(ref qpath) => is_enum_variant(cx, qpath, pat.hir_id), PatKind::Tuple(ref pats, _) => are_refutable(cx, pats.iter().map(|pat| &**pat)), - PatKind::Struct(ref qpath, ref fields, _) => if is_enum_variant(cx, qpath, pat.hir_id) { - true - } else { - are_refutable(cx, fields.iter().map(|field| &*field.node.pat)) + PatKind::Struct(ref qpath, ref fields, _) => { + if is_enum_variant(cx, qpath, pat.hir_id) { + true + } else { + are_refutable(cx, fields.iter().map(|field| &*field.node.pat)) + } }, - PatKind::TupleStruct(ref qpath, ref pats, _) => if is_enum_variant(cx, qpath, pat.hir_id) { - true - } else { - are_refutable(cx, pats.iter().map(|pat| &**pat)) + PatKind::TupleStruct(ref qpath, ref pats, _) => { + if is_enum_variant(cx, qpath, pat.hir_id) { + true + } else { + are_refutable(cx, pats.iter().map(|pat| &**pat)) + } + }, + PatKind::Slice(ref head, ref middle, ref tail) => { + are_refutable(cx, head.iter().chain(middle).chain(tail.iter()).map(|pat| &**pat)) }, - PatKind::Slice(ref head, ref middle, ref tail) => are_refutable( - cx, - head.iter() - .chain(middle) - .chain(tail.iter()) - .map(|pat| &**pat), - ), } } @@ -903,32 +920,37 @@ pub fn remove_blocks(expr: &Expr) -> &Expr { pub fn opt_def_id(def: Def) -> Option { match def { - Def::Fn(id) | - Def::Mod(id) | - Def::Static(id, _) | - Def::Variant(id) | - Def::VariantCtor(id, ..) | - Def::Enum(id) | - Def::TyAlias(id) | - Def::AssociatedTy(id) | - Def::TyParam(id) | - Def::ForeignTy(id) | - Def::Struct(id) | - Def::StructCtor(id, ..) | - Def::Union(id) | - Def::Trait(id) | - Def::TraitAlias(id) | - Def::Method(id) | - Def::Const(id) | - Def::AssociatedConst(id) | - Def::Macro(id, ..) | - Def::Existential(id) | - Def::AssociatedExistential(id) | - Def::SelfCtor(id) - => Some(id), - - Def::Upvar(..) | Def::Local(_) | Def::Label(..) | Def::PrimTy(..) | Def::SelfTy(..) | - Def::ToolMod | Def::NonMacroAttr{..} | Def::Err => None, + Def::Fn(id) + | Def::Mod(id) + | Def::Static(id, _) + | Def::Variant(id) + | Def::VariantCtor(id, ..) + | Def::Enum(id) + | Def::TyAlias(id) + | Def::AssociatedTy(id) + | Def::TyParam(id) + | Def::ForeignTy(id) + | Def::Struct(id) + | Def::StructCtor(id, ..) + | Def::Union(id) + | Def::Trait(id) + | Def::TraitAlias(id) + | Def::Method(id) + | Def::Const(id) + | Def::AssociatedConst(id) + | Def::Macro(id, ..) + | Def::Existential(id) + | Def::AssociatedExistential(id) + | Def::SelfCtor(id) => Some(id), + + Def::Upvar(..) + | Def::Local(_) + | Def::Label(..) + | Def::PrimTy(..) + | Def::SelfTy(..) + | Def::ToolMod + | Def::NonMacroAttr { .. } + | Def::Err => None, } } @@ -1019,7 +1041,9 @@ pub fn get_arg_name(pat: &Pat) -> Option { } pub fn int_bits(tcx: TyCtxt<'_, '_, '_>, ity: ast::IntTy) -> u64 { - layout::Integer::from_attr(&tcx, attr::IntType::SignedInt(ity)).size().bits() + layout::Integer::from_attr(&tcx, attr::IntType::SignedInt(ity)) + .size() + .bits() } #[allow(clippy::cast_possible_wrap)] @@ -1038,7 +1062,9 @@ pub fn unsext(tcx: TyCtxt<'_, '_, '_>, u: i128, ity: ast::IntTy) -> u128 { /// clip unused bytes pub fn clip(tcx: TyCtxt<'_, '_, '_>, u: u128, ity: ast::UintTy) -> u128 { - let bits = layout::Integer::from_attr(&tcx, attr::IntType::UnsignedInt(ity)).size().bits(); + let bits = layout::Integer::from_attr(&tcx, attr::IntType::UnsignedInt(ity)) + .size() + .bits(); let amt = 128 - bits; (u << amt) >> amt } diff --git a/clippy_lints/src/utils/sugg.rs b/clippy_lints/src/utils/sugg.rs index 90f48f0f83c7..5bb35474403a 100644 --- a/clippy_lints/src/utils/sugg.rs +++ b/clippy_lints/src/utils/sugg.rs @@ -96,6 +96,15 @@ impl<'a> Sugg<'a> { Self::hir_opt(cx, expr).unwrap_or_else(|| Sugg::NonParen(Cow::Borrowed(default))) } + pub fn hir_with_applicability(cx: &LateContext<'_, '_>, expr: &hir::Expr, default: &'a str, applicability: &mut Applicability) -> Self { + Self::hir_opt(cx, expr).unwrap_or_else(|| { + if *applicability == Applicability::MachineApplicable { + *applicability = Applicability::HasPlaceholders; + } + Sugg::NonParen(Cow::Borrowed(default)) + }) + } + /// Prepare a suggestion from an expression. pub fn ast(cx: &EarlyContext<'_>, expr: &ast::Expr, default: &'a str) -> Self { use crate::syntax::ast::RangeLimits; From 9096269610fcfc5cdc719dbe7d817de4cbb75201 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Tue, 20 Nov 2018 14:06:29 +0100 Subject: [PATCH 2/8] Add Applicability::Unspecified to span_lint_and_sugg functions --- clippy_lints/src/attrs.rs | 1 + clippy_lints/src/bytecount.rs | 29 +++++++----- clippy_lints/src/collapsible_if.rs | 15 ++++--- clippy_lints/src/default_trait_access.rs | 7 ++- clippy_lints/src/double_comparison.rs | 13 ++++-- clippy_lints/src/duration_subsec.rs | 4 +- clippy_lints/src/else_if_without_else.rs | 4 +- clippy_lints/src/excessive_precision.rs | 10 +++-- .../src/infallible_destructuring_match.rs | 2 + clippy_lints/src/len_zero.rs | 4 +- clippy_lints/src/literal_representation.rs | 6 +++ clippy_lints/src/loops.rs | 5 +++ clippy_lints/src/map_clone.rs | 10 ++--- clippy_lints/src/matches.rs | 6 ++- clippy_lints/src/mem_replace.rs | 4 +- clippy_lints/src/methods/mod.rs | 37 ++++++++++----- clippy_lints/src/needless_bool.rs | 10 ++++- clippy_lints/src/no_effect.rs | 6 ++- clippy_lints/src/precedence.rs | 3 ++ clippy_lints/src/ptr_offset_with_cast.rs | 11 ++++- clippy_lints/src/redundant_field_names.rs | 6 ++- clippy_lints/src/reference.rs | 9 ++-- clippy_lints/src/replace_consts.rs | 8 ++-- clippy_lints/src/strings.rs | 3 ++ .../src/trivially_copy_pass_by_ref.rs | 16 +++---- clippy_lints/src/types.rs | 45 +++++++++++-------- clippy_lints/src/use_self.rs | 8 ++-- clippy_lints/src/utils/internal_lints.rs | 2 + clippy_lints/src/utils/mod.rs | 3 +- clippy_lints/src/vec.rs | 8 ++-- clippy_lints/src/write.rs | 7 ++- 31 files changed, 204 insertions(+), 98 deletions(-) diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 58af069f1d9e..19306b81e4ad 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -532,6 +532,7 @@ impl EarlyLintPass for CfgAttrPass { "`cfg_attr` is deprecated for rustfmt and got replaced by tool_attributes", "use", format!("{}rustfmt::skip]", attr_style), + Applicability::Unspecified, ); } } diff --git a/clippy_lints/src/bytecount.rs b/clippy_lints/src/bytecount.rs index a61e823f9591..1e738b9afa1e 100644 --- a/clippy_lints/src/bytecount.rs +++ b/clippy_lints/src/bytecount.rs @@ -10,12 +10,14 @@ use crate::rustc::hir::*; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; -use crate::rustc::{declare_tool_lint, lint_array}; -use if_chain::if_chain; use crate::rustc::ty; +use crate::rustc::{declare_tool_lint, lint_array}; +use crate::rustc_errors::Applicability; use crate::syntax::ast::{Name, UintTy}; -use crate::utils::{contains_name, get_pat_name, match_type, paths, single_segment_path, snippet, span_lint_and_sugg, - walk_ptrs_ty}; +use crate::utils::{ + contains_name, get_pat_name, match_type, paths, single_segment_path, snippet, span_lint_and_sugg, walk_ptrs_ty, +}; +use if_chain::if_chain; /// **What it does:** Checks for naive byte counts /// @@ -89,14 +91,17 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount { } else { &filter_args[0] }; - span_lint_and_sugg(cx, - NAIVE_BYTECOUNT, - expr.span, - "You appear to be counting bytes the naive way", - "Consider using the bytecount crate", - format!("bytecount::count({}, {})", - snippet(cx, haystack.span, ".."), - snippet(cx, needle.span, ".."))); + span_lint_and_sugg( + cx, + NAIVE_BYTECOUNT, + expr.span, + "You appear to be counting bytes the naive way", + "Consider using the bytecount crate", + format!("bytecount::count({}, {})", + snippet(cx, haystack.span, ".."), + snippet(cx, needle.span, "..")), + Applicability::Unspecified, + ); } }; } diff --git a/clippy_lints/src/collapsible_if.rs b/clippy_lints/src/collapsible_if.rs index a55ca04f706a..2699ec0e7fdd 100644 --- a/clippy_lints/src/collapsible_if.rs +++ b/clippy_lints/src/collapsible_if.rs @@ -128,12 +128,15 @@ fn check_collapsible_maybe_if_let(cx: &EarlyContext<'_>, else_: &ast::Expr) { then { match else_.node { ast::ExprKind::If(..) | ast::ExprKind::IfLet(..) => { - span_lint_and_sugg(cx, - COLLAPSIBLE_IF, - block.span, - "this `else { if .. }` block can be collapsed", - "try", - snippet_block(cx, else_.span, "..").into_owned()); + span_lint_and_sugg( + cx, + COLLAPSIBLE_IF, + block.span, + "this `else { if .. }` block can be collapsed", + "try", + snippet_block(cx, else_.span, "..").into_owned(), + Applicability::Unspecified, + ); } _ => (), } diff --git a/clippy_lints/src/default_trait_access.rs b/clippy_lints/src/default_trait_access.rs index 66d94e00d0d3..17dccf2adfbf 100644 --- a/clippy_lints/src/default_trait_access.rs +++ b/clippy_lints/src/default_trait_access.rs @@ -10,9 +10,10 @@ use crate::rustc::hir::*; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; +use crate::rustc::ty::TyKind; use crate::rustc::{declare_tool_lint, lint_array}; +use crate::rustc_errors::Applicability; use if_chain::if_chain; -use crate::rustc::ty::TyKind; use crate::utils::{any_parent_is_automatically_derived, match_def_path, opt_def_id, paths, span_lint_and_sugg}; @@ -80,7 +81,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DefaultTraitAccess { expr.span, &format!("Calling {} is more clear than this expression", replacement), "try", - replacement); + replacement, + Applicability::Unspecified, + ); } }, QPath::TypeRelative(..) => {}, diff --git a/clippy_lints/src/double_comparison.rs b/clippy_lints/src/double_comparison.rs index 0171ac1e784f..f4c340538a7c 100644 --- a/clippy_lints/src/double_comparison.rs +++ b/clippy_lints/src/double_comparison.rs @@ -13,6 +13,7 @@ use crate::rustc::hir::*; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use crate::rustc::{declare_tool_lint, lint_array}; +use crate::rustc_errors::Applicability; use crate::syntax::source_map::Span; use crate::utils::{snippet, span_lint_and_sugg, SpanlessEq}; @@ -73,9 +74,15 @@ impl<'a, 'tcx> Pass { let lhs_str = snippet(cx, llhs.span, ""); let rhs_str = snippet(cx, lrhs.span, ""); let sugg = format!("{} {} {}", lhs_str, stringify!($op), rhs_str); - span_lint_and_sugg(cx, DOUBLE_COMPARISONS, span, - "This binary expression can be simplified", - "try", sugg); + span_lint_and_sugg( + cx, + DOUBLE_COMPARISONS, + span, + "This binary expression can be simplified", + "try", + sugg, + Applicability::Unspecified, + ); }} } match (op, lkind, rkind) { diff --git a/clippy_lints/src/duration_subsec.rs b/clippy_lints/src/duration_subsec.rs index a679a97c2e78..5752968c1a22 100644 --- a/clippy_lints/src/duration_subsec.rs +++ b/clippy_lints/src/duration_subsec.rs @@ -11,8 +11,9 @@ use crate::rustc::hir::*; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use crate::rustc::{declare_tool_lint, lint_array}; -use if_chain::if_chain; +use crate::rustc_errors::Applicability; use crate::syntax::source_map::Spanned; +use if_chain::if_chain; use crate::consts::{constant, Constant}; use crate::utils::paths; @@ -67,6 +68,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DurationSubsec { &format!("Calling `{}()` is more concise than this calculation", suggested_fn), "try", format!("{}.{}()", snippet(cx, args[0].span, "_"), suggested_fn), + Applicability::Unspecified, ); } } diff --git a/clippy_lints/src/else_if_without_else.rs b/clippy_lints/src/else_if_without_else.rs index 26ffef9ebe44..99031dd28872 100644 --- a/clippy_lints/src/else_if_without_else.rs +++ b/clippy_lints/src/else_if_without_else.rs @@ -12,6 +12,7 @@ use crate::rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass, in_external_macro, LintContext}; use crate::rustc::{declare_tool_lint, lint_array}; +use crate::rustc_errors::Applicability; use crate::syntax::ast::*; use crate::utils::span_lint_and_sugg; @@ -72,7 +73,8 @@ impl EarlyLintPass for ElseIfWithoutElse { els.span, "if expression with an `else if`, but without a final `else`", "add an `else` block here", - String::new() + String::new(), + Applicability::Unspecified, ); } diff --git a/clippy_lints/src/excessive_precision.rs b/clippy_lints/src/excessive_precision.rs index 15a8d47337aa..5f15f81205c4 100644 --- a/clippy_lints/src/excessive_precision.rs +++ b/clippy_lints/src/excessive_precision.rs @@ -10,15 +10,16 @@ use crate::rustc::hir; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; +use crate::rustc::ty::TyKind; use crate::rustc::{declare_tool_lint, lint_array}; +use crate::rustc_errors::Applicability; +use crate::syntax::ast::*; +use crate::syntax_pos::symbol::Symbol; +use crate::utils::span_lint_and_sugg; use if_chain::if_chain; -use crate::rustc::ty::TyKind; use std::f32; use std::f64; use std::fmt; -use crate::syntax::ast::*; -use crate::syntax_pos::symbol::Symbol; -use crate::utils::span_lint_and_sugg; /// **What it does:** Checks for float literals with a precision greater /// than that supported by the underlying type @@ -68,6 +69,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExcessivePrecision { "float has excessive precision", "consider changing the type or truncating it to", sugg, + Applicability::Unspecified, ); } } diff --git a/clippy_lints/src/infallible_destructuring_match.rs b/clippy_lints/src/infallible_destructuring_match.rs index 7bbbe72f91d2..d212cf623905 100644 --- a/clippy_lints/src/infallible_destructuring_match.rs +++ b/clippy_lints/src/infallible_destructuring_match.rs @@ -12,6 +12,7 @@ use super::utils::{get_arg_name, match_var, remove_blocks, snippet, span_lint_an use crate::rustc::hir::*; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use crate::rustc::{declare_tool_lint, lint_array}; +use crate::rustc_errors::Applicability; use if_chain::if_chain; /// **What it does:** Checks for matches being used to destructure a single-variant enum @@ -84,6 +85,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { snippet(cx, local.pat.span, ".."), snippet(cx, target.span, ".."), ), + Applicability::Unspecified, ); } } diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index 789a569f4cd1..33457bb70447 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -11,9 +11,10 @@ use crate::rustc::hir::def_id::DefId; use crate::rustc::hir::*; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; -use crate::rustc::{declare_tool_lint, lint_array}; use crate::rustc::ty; +use crate::rustc::{declare_tool_lint, lint_array}; use crate::rustc_data_structures::fx::FxHashSet; +use crate::rustc_errors::Applicability; use crate::syntax::ast::{Lit, LitKind, Name}; 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}; @@ -242,6 +243,7 @@ fn check_len(cx: &LateContext<'_, '_>, span: Span, method_name: Name, args: &[Ex &format!("length comparison to {}", if compare_to == 0 { "zero" } else { "one" }), "using `is_empty` is clearer and more explicit", format!("{}{}.is_empty()", op, snippet(cx, args[0].span, "_")), + Applicability::Unspecified, ); } } diff --git a/clippy_lints/src/literal_representation.rs b/clippy_lints/src/literal_representation.rs index bd54c0684862..ebcb773d6f25 100644 --- a/clippy_lints/src/literal_representation.rs +++ b/clippy_lints/src/literal_representation.rs @@ -12,6 +12,7 @@ use crate::rustc::lint::{in_external_macro, EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass}; use crate::rustc::{declare_tool_lint, lint_array}; +use crate::rustc_errors::Applicability; use crate::syntax::ast::*; use crate::syntax_pos; use crate::utils::{snippet_opt, span_lint_and_sugg}; @@ -300,6 +301,7 @@ impl WarningType { "mistyped literal suffix", "did you mean to write", grouping_hint.to_string(), + Applicability::Unspecified, ), WarningType::UnreadableLiteral => span_lint_and_sugg( cx, @@ -308,6 +310,7 @@ impl WarningType { "long literal lacking separators", "consider", grouping_hint.to_owned(), + Applicability::Unspecified, ), WarningType::LargeDigitGroups => span_lint_and_sugg( cx, @@ -316,6 +319,7 @@ impl WarningType { "digit groups should be smaller", "consider", grouping_hint.to_owned(), + Applicability::Unspecified, ), WarningType::InconsistentDigitGrouping => span_lint_and_sugg( cx, @@ -324,6 +328,7 @@ impl WarningType { "digits grouped inconsistently by underscores", "consider", grouping_hint.to_owned(), + Applicability::Unspecified, ), WarningType::DecimalRepresentation => span_lint_and_sugg( cx, @@ -332,6 +337,7 @@ impl WarningType { "integer literal has a better hexadecimal representation", "consider", grouping_hint.to_owned(), + Applicability::Unspecified, ), }; } diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 0d1b960cc1f5..e04fc6ea17f1 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -512,6 +512,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { snippet(cx, arms[0].pats[0].span, ".."), snippet(cx, matchexpr.span, "..") ), + Applicability::Unspecified, ); } }, @@ -549,6 +550,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { "this loop could be written as a `for` loop", "try", format!("for {} in {} {{ .. }}", loop_var, iterator), + Applicability::Unspecified, ); } } @@ -1027,6 +1029,7 @@ fn detect_manual_memcpy<'a, 'tcx>( "it looks like you're manually copying between slices", "try replacing the loop by", big_sugg, + Applicability::Unspecified, ); } } @@ -1316,6 +1319,7 @@ fn lint_iter_method(cx: &LateContext<'_, '_>, args: &[Expr], arg: &Expr, method_ iteration methods", "to write this more concisely, try", format!("&{}{}", muta, object), + Applicability::Unspecified, ) } @@ -1354,6 +1358,7 @@ fn check_for_loop_arg(cx: &LateContext<'_, '_>, pat: &Pat, arg: &Expr, expr: &Ex iteration methods`", "to write this more concisely, try", object.to_string(), + Applicability::Unspecified, ); } } else if method_name == "next" && match_trait_method(cx, arg, &paths::ITERATOR) { diff --git a/clippy_lints/src/map_clone.rs b/clippy_lints/src/map_clone.rs index b2c08e6ae8cc..2fd5c6187c32 100644 --- a/clippy_lints/src/map_clone.rs +++ b/clippy_lints/src/map_clone.rs @@ -11,15 +11,12 @@ use crate::rustc::hir; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use crate::rustc::{declare_tool_lint, lint_array}; +use crate::rustc_errors::Applicability; +use crate::syntax::ast::Ident; use crate::syntax::source_map::Span; 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, span_lint_and_sugg}; use if_chain::if_chain; -use crate::syntax::ast::Ident; #[derive(Clone)] pub struct Pass; @@ -102,6 +99,7 @@ fn lint(cx: &LateContext<'_, '_>, replace: Span, root: Span, name: Ident, path: "You are using an explicit closure for cloning elements", "Consider calling the dedicated `cloned` method", format!("{}.cloned()", snippet(cx, root, "..")), + Applicability::Unspecified, ) } } diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index 9e2dac8fef11..f96ab2f924e1 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -268,8 +268,9 @@ fn report_single_match_single_pattern(cx: &LateContext<'_, '_>, ex: &Expr, arms: snippet(cx, arms[0].pats[0].span, ".."), snippet(cx, ex.span, ".."), expr_block(cx, &arms[0].body, None, ".."), - els_str + els_str, ), + Applicability::Unspecified, ); } @@ -483,7 +484,8 @@ fn check_match_as_ref(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: & expr.span, &format!("use {}() instead", suggestion), "try this", - format!("{}.{}()", snippet(cx, ex.span, "_"), suggestion) + format!("{}.{}()", snippet(cx, ex.span, "_"), suggestion), + Applicability::Unspecified, ) } } diff --git a/clippy_lints/src/mem_replace.rs b/clippy_lints/src/mem_replace.rs index ff57571a948c..684f58a08efb 100644 --- a/clippy_lints/src/mem_replace.rs +++ b/clippy_lints/src/mem_replace.rs @@ -11,6 +11,7 @@ use crate::rustc::hir::{Expr, ExprKind, MutMutable, QPath}; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use crate::rustc::{declare_tool_lint, lint_array}; +use crate::rustc_errors::Applicability; use crate::utils::{match_def_path, match_qpath, opt_def_id, paths, snippet, span_lint_and_sugg}; use if_chain::if_chain; @@ -85,7 +86,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemReplace { expr.span, "replacing an `Option` with `None`", "consider `Option::take()` instead", - format!("{}.take()", snippet(cx, replaced_path.span, "")) + format!("{}.take()", snippet(cx, replaced_path.span, "")), + Applicability::Unspecified, ); } } diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index e3c704b77adc..dcee380f4555 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -1042,6 +1042,7 @@ fn lint_or_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: Spa &format!("use of `{}` followed by a call to `{}`", name, path), "try this", format!("{}.unwrap_or_default()", snippet(cx, self_expr.span, "_")), + Applicability::Unspecified, ); return true; } @@ -1111,6 +1112,7 @@ fn lint_or_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: Spa &format!("use of `{}` followed by a function call", name), "try this", format!("{}_{}({})", name, suffix, sugg), + Applicability::Unspecified, ); } @@ -1224,6 +1226,7 @@ fn lint_expect_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: &format!("use of `{}` followed by a function call", name), "try this", format!("unwrap_or_else({} panic!({}))", closure, sugg), + Applicability::Unspecified, ); return; @@ -1238,6 +1241,7 @@ fn lint_expect_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: &format!("use of `{}` followed by a function call", name), "try this", format!("unwrap_or_else({} {{ let msg = {}; panic!(msg) }}))", closure, sugg), + Applicability::Unspecified, ); } @@ -1354,6 +1358,7 @@ fn lint_clone_on_ref_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr, arg: &hir:: "using '.clone()' on a ref-counted pointer", "try this", format!("{}::<{}>::clone(&{})", caller_type, subst.type_at(0), snippet(cx, arg.span, "_")), + Applicability::Unspecified, ); } } @@ -1384,6 +1389,7 @@ fn lint_string_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr, args: &[hir::E ref_str, snippet(cx, target.span, "_") ), + Applicability::Unspecified, ); } } @@ -1482,6 +1488,7 @@ fn lint_unnecessary_fold(cx: &LateContext<'_, '_>, expr: &hir::Expr, fold_args: "this `.fold` can be written more succinctly using another method", "try", sugg, + Applicability::Unspecified, ); } } @@ -1589,6 +1596,7 @@ fn lint_get_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr, get_args: &[hir:: snippet(cx, get_args[0].span, "_"), get_args_str ), + Applicability::Unspecified, ); } @@ -2010,16 +2018,19 @@ fn lint_chars_cmp( return false; } - span_lint_and_sugg(cx, - lint, - info.expr.span, - &format!("you should use the `{}` method", suggest), - "like this", - format!("{}{}.{}({})", - if info.eq { "" } else { "!" }, - snippet(cx, args[0][0].span, "_"), - suggest, - snippet(cx, arg_char[0].span, "_"))); + span_lint_and_sugg( + cx, + lint, + info.expr.span, + &format!("you should use the `{}` method", suggest), + "like this", + format!("{}{}.{}({})", + if info.eq { "" } else { "!" }, + snippet(cx, args[0][0].span, "_"), + suggest, + snippet(cx, arg_char[0].span, "_")), + Applicability::Unspecified, + ); return true; } @@ -2065,7 +2076,8 @@ fn lint_chars_cmp_with_unwrap<'a, 'tcx>( if info.eq { "" } else { "!" }, snippet(cx, args[0][0].span, "_"), suggest, - c) + c), + Applicability::Unspecified, ); return true; @@ -2105,6 +2117,7 @@ fn lint_single_char_pattern<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, _expr: &'tcx h "single-character string constant used as pattern", "try using a char instead", hint, + Applicability::Unspecified, ); } } @@ -2129,6 +2142,7 @@ fn lint_asref(cx: &LateContext<'_, '_>, expr: &hir::Expr, call_name: &str, as_re &format!("this call to `{}` does nothing", call_name), "try this", snippet(cx, recvr.span, "_").into_owned(), + Applicability::Unspecified, ); } } @@ -2194,6 +2208,7 @@ fn lint_into_iter(cx: &LateContext<'_, '_>, expr: &hir::Expr, self_ref_ty: ty::T ), "call directly", method_name.to_owned(), + Applicability::Unspecified, ); } } diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs index 0019380a34c2..8ed319c6736d 100644 --- a/clippy_lints/src/needless_bool.rs +++ b/clippy_lints/src/needless_bool.rs @@ -12,13 +12,14 @@ //! //! This lint is **warn** by default +use crate::rustc::hir::*; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use crate::rustc::{declare_tool_lint, lint_array}; -use crate::rustc::hir::*; +use crate::rustc_errors::Applicability; use crate::syntax::ast::LitKind; use crate::syntax::source_map::Spanned; -use crate::utils::{in_macro, snippet, span_lint, span_lint_and_sugg}; use crate::utils::sugg::Sugg; +use crate::utils::{in_macro, snippet, span_lint, span_lint_and_sugg}; /// **What it does:** Checks for expressions of the form `if c { true } else { /// false }` @@ -89,6 +90,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool { "this if-then-else expression returns a bool literal", "you can reduce it to", hint, + Applicability::Unspecified, ); }; if let ExprKind::Block(ref then_block, _) = then_block.node { @@ -150,6 +152,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison { "equality checks against true are unnecessary", "try simplifying it as shown", hint, + Applicability::Unspecified, ); }, (Other, Bool(true)) => { @@ -161,6 +164,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison { "equality checks against true are unnecessary", "try simplifying it as shown", hint, + Applicability::Unspecified, ); }, (Bool(false), Other) => { @@ -172,6 +176,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison { "equality checks against false can be replaced by a negation", "try simplifying it as shown", (!hint).to_string(), + Applicability::Unspecified, ); }, (Other, Bool(false)) => { @@ -183,6 +188,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison { "equality checks against false can be replaced by a negation", "try simplifying it as shown", (!hint).to_string(), + Applicability::Unspecified, ); }, _ => (), diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs index 289b5591edc6..877cd5ab1e4e 100644 --- a/clippy_lints/src/no_effect.rs +++ b/clippy_lints/src/no_effect.rs @@ -8,10 +8,11 @@ // except according to those terms. -use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; -use crate::rustc::{declare_tool_lint, lint_array}; use crate::rustc::hir::def::Def; use crate::rustc::hir::{BinOpKind, BlockCheckMode, Expr, ExprKind, Stmt, StmtKind, UnsafeSource}; +use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; +use crate::rustc::{declare_tool_lint, lint_array}; +use crate::rustc_errors::Applicability; use crate::utils::{has_drop, in_macro, snippet_opt, span_lint, span_lint_and_sugg}; use std::ops::Deref; @@ -131,6 +132,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { "statement can be reduced", "replace it with", snippet, + Applicability::Unspecified, ); } } diff --git a/clippy_lints/src/precedence.rs b/clippy_lints/src/precedence.rs index 1c5e8fcb9646..4376db5e9b3c 100644 --- a/clippy_lints/src/precedence.rs +++ b/clippy_lints/src/precedence.rs @@ -10,6 +10,7 @@ use crate::rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass}; use crate::rustc::{declare_tool_lint, lint_array}; +use crate::rustc_errors::Applicability; use crate::syntax::ast::*; use crate::syntax::source_map::Spanned; use crate::utils::{in_macro, snippet, span_lint_and_sugg}; @@ -61,6 +62,7 @@ impl EarlyLintPass for Precedence { "operator precedence can trip the unwary", "consider parenthesizing your expression", sugg, + Applicability::Unspecified, ); }; @@ -112,6 +114,7 @@ impl EarlyLintPass for Precedence { "unary minus has lower precedence than method call", "consider adding parentheses to clarify your intent", format!("-({})", snippet(cx, rhs.span, "..")), + Applicability::Unspecified, ); }, _ => (), diff --git a/clippy_lints/src/ptr_offset_with_cast.rs b/clippy_lints/src/ptr_offset_with_cast.rs index 58afdc351d19..e653ae2ff75e 100644 --- a/clippy_lints/src/ptr_offset_with_cast.rs +++ b/clippy_lints/src/ptr_offset_with_cast.rs @@ -9,6 +9,7 @@ use crate::rustc::{declare_tool_lint, hir, lint, lint_array}; +use crate::rustc_errors::Applicability; use crate::utils; use std::fmt; @@ -69,7 +70,15 @@ impl<'a, 'tcx> lint::LateLintPass<'a, 'tcx> for Pass { let msg = format!("use of `{}` with a `usize` casted to an `isize`", method); if let Some(sugg) = build_suggestion(cx, method, receiver_expr, cast_lhs_expr) { - utils::span_lint_and_sugg(cx, PTR_OFFSET_WITH_CAST, expr.span, &msg, "try", sugg); + utils::span_lint_and_sugg( + cx, + PTR_OFFSET_WITH_CAST, + expr.span, + &msg, + "try", + sugg, + Applicability::Unspecified, + ); } else { utils::span_lint(cx, PTR_OFFSET_WITH_CAST, expr.span, &msg); } diff --git a/clippy_lints/src/redundant_field_names.rs b/clippy_lints/src/redundant_field_names.rs index 526232f78535..2acea17be264 100644 --- a/clippy_lints/src/redundant_field_names.rs +++ b/clippy_lints/src/redundant_field_names.rs @@ -10,6 +10,7 @@ use crate::rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass}; use crate::rustc::{declare_tool_lint, lint_array}; +use crate::rustc_errors::Applicability; use crate::syntax::ast::*; use crate::utils::{span_lint_and_sugg}; @@ -58,13 +59,14 @@ impl EarlyLintPass for RedundantFieldNames { } if let ExprKind::Path(None, path) = &field.expr.node { if path.segments.len() == 1 && path.segments[0].ident == field.ident { - span_lint_and_sugg ( + span_lint_and_sugg( cx, REDUNDANT_FIELD_NAMES, field.span, "redundant field names in struct initialization", "replace it with", - field.ident.to_string() + field.ident.to_string(), + Applicability::Unspecified, ); } } diff --git a/clippy_lints/src/reference.rs b/clippy_lints/src/reference.rs index 79d30612cbdc..aac3d09bfd3e 100644 --- a/clippy_lints/src/reference.rs +++ b/clippy_lints/src/reference.rs @@ -8,11 +8,12 @@ // except according to those terms. -use crate::syntax::ast::{Expr, ExprKind, UnOp}; use crate::rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass}; use crate::rustc::{declare_tool_lint, lint_array}; -use if_chain::if_chain; +use crate::rustc_errors::Applicability; +use crate::syntax::ast::{Expr, ExprKind, UnOp}; use crate::utils::{snippet, span_lint_and_sugg}; +use if_chain::if_chain; /// **What it does:** Checks for usage of `*&` and `*&mut` in expressions. /// @@ -61,6 +62,7 @@ impl EarlyLintPass for Pass { "immediately dereferencing a reference", "try this", format!("{}", snippet(cx, addrof_target.span, "_")), + Applicability::Unspecified, ); } } @@ -110,7 +112,8 @@ impl EarlyLintPass for DerefPass { "{}.{}", snippet(cx, inner.span, "_"), snippet(cx, field_name.span, "_") - ) + ), + Applicability::Unspecified, ); } } diff --git a/clippy_lints/src/replace_consts.rs b/clippy_lints/src/replace_consts.rs index ca17a0325261..1c204912f17d 100644 --- a/clippy_lints/src/replace_consts.rs +++ b/clippy_lints/src/replace_consts.rs @@ -8,12 +8,13 @@ // except according to those terms. -use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; -use crate::rustc::{declare_tool_lint, lint_array}; -use if_chain::if_chain; use crate::rustc::hir; use crate::rustc::hir::def::Def; +use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; +use crate::rustc::{declare_tool_lint, lint_array}; +use crate::rustc_errors::Applicability; use crate::utils::{match_def_path, span_lint_and_sugg}; +use if_chain::if_chain; /// **What it does:** Checks for usage of `ATOMIC_X_INIT`, `ONCE_INIT`, and /// `uX/iX::MIN/MAX`. @@ -61,6 +62,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ReplaceConsts { &format!("using `{}`", const_path.last().expect("empty path")), "try this", repl_snip.to_string(), + Applicability::Unspecified, ); return; } diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index e07b1649a466..74d5e304b876 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -10,6 +10,7 @@ use crate::rustc::hir::*; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use crate::rustc::{declare_tool_lint, lint_array}; +use crate::rustc_errors::Applicability; use crate::syntax::source_map::Spanned; use crate::utils::SpanlessEq; use crate::utils::{get_parent_expr, is_allowed, match_type, paths, span_lint, span_lint_and_sugg, walk_ptrs_ty}; @@ -185,6 +186,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes { "calling `as_bytes()` on `include_str!(..)`", "consider using `include_bytes!(..)` instead", snippet(cx, args[0].span, r#""foo""#).replacen("include_str", "include_bytes", 1), + Applicability::Unspecified, ); } else if callsite == expanded && lit_content.as_str().chars().all(|c| c.is_ascii()) @@ -197,6 +199,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes { "calling `as_bytes()` on a string literal", "consider using a byte string literal instead", format!("b{}", snippet(cx, args[0].span, r#""foo""#)), + Applicability::Unspecified, ); } } diff --git a/clippy_lints/src/trivially_copy_pass_by_ref.rs b/clippy_lints/src/trivially_copy_pass_by_ref.rs index 2929752bbb2d..467713694e18 100644 --- a/clippy_lints/src/trivially_copy_pass_by_ref.rs +++ b/clippy_lints/src/trivially_copy_pass_by_ref.rs @@ -10,21 +10,21 @@ use std::cmp; -use matches::matches; use crate::rustc::hir; -use crate::rustc::hir::*; use crate::rustc::hir::intravisit::FnKind; +use crate::rustc::hir::*; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; -use crate::rustc::{declare_tool_lint, lint_array}; -use if_chain::if_chain; -use crate::rustc::ty::TyKind; -use crate::rustc::ty::FnSig; use crate::rustc::session::config::Config as SessionConfig; -use crate::rustc_target::spec::abi::Abi; +use crate::rustc::ty::TyKind; +use crate::rustc::{declare_tool_lint, lint_array}; +use crate::rustc_errors::Applicability; use crate::rustc_target::abi::LayoutOf; +use crate::rustc_target::spec::abi::Abi; use crate::syntax::ast::NodeId; use crate::syntax_pos::Span; -use crate::utils::{in_macro, is_copy, is_self_ty, span_lint_and_sugg, snippet}; +use crate::utils::{in_macro, is_copy, is_self, snippet, span_lint_and_sugg}; +use if_chain::if_chain; +use matches::matches; /// **What it does:** Checks for functions taking arguments by reference, where /// the argument type is `Copy` and small enough to be more efficient to always diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index d7adcd179816..4a9cb04a0ac4 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -10,28 +10,31 @@ #![allow(clippy::default_hash_types)] +use crate::consts::{constant, Constant}; use crate::reexport::*; use crate::rustc::hir; -use crate::rustc::hir::*; use crate::rustc::hir::intravisit::{walk_body, walk_expr, walk_ty, FnKind, NestedVisitorMap, Visitor}; -use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass, in_external_macro, LintContext}; -use crate::rustc::{declare_tool_lint, lint_array}; -use if_chain::if_chain; -use crate::rustc::ty::{self, Ty, TyCtxt, TypeckTables}; +use crate::rustc::hir::*; +use crate::rustc::lint::{in_external_macro, LateContext, LateLintPass, LintArray, LintContext, LintPass}; use crate::rustc::ty::layout::LayoutOf; +use crate::rustc::ty::{self, Ty, TyCtxt, TypeckTables}; +use crate::rustc::{declare_tool_lint, lint_array}; +use crate::rustc_errors::Applicability; +use crate::rustc_target::spec::abi::Abi; use crate::rustc_typeck::hir_ty_to_ty; -use std::cmp::Ordering; -use std::collections::BTreeMap; -use std::borrow::Cow; use crate::syntax::ast::{FloatTy, IntTy, UintTy}; -use crate::syntax::source_map::Span; use crate::syntax::errors::DiagnosticBuilder; -use crate::rustc_target::spec::abi::Abi; -use crate::utils::{comparisons, differing_macro_contexts, higher, in_constant, in_macro, last_path_segment, match_def_path, match_path, - match_type, multispan_sugg, opt_def_id, same_tys, snippet, snippet_opt, span_help_and_lint, span_lint, - span_lint_and_sugg, span_lint_and_then, clip, unsext, sext, int_bits}; +use crate::syntax::source_map::Span; use crate::utils::paths; -use crate::consts::{constant, Constant}; +use crate::utils::{ + 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, + span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, unsext, +}; +use if_chain::if_chain; +use std::borrow::Cow; +use std::cmp::Ordering; +use std::collections::BTreeMap; /// Handles all the linting of funky types pub struct TypePass; @@ -338,12 +341,14 @@ fn check_ty_rptr(cx: &LateContext<'_, '_>, ast_ty: &hir::Ty, is_local: bool, lt: } else { "" }; - span_lint_and_sugg(cx, + span_lint_and_sugg( + cx, BORROWED_BOX, ast_ty.span, "you seem to be trying to use `&Box`. Consider using just `&T`", "try", - format!("&{}{}{}", ltopt, mutopt, &snippet(cx, inner.span, "..")) + format!("&{}{}{}", ltopt, mutopt, &snippet(cx, inner.span, "..")), + Applicability::Unspecified, ); return; // don't recurse into the type } @@ -537,6 +542,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitArg { "passing a unit value to a function", "if you intended to pass a unit value, use a unit literal instead", "()".to_string(), + Applicability::Unspecified, ); } } @@ -874,6 +880,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), "try", format!("{}::from({})", cast_to, sugg), + Applicability::Unspecified, ); } @@ -1103,7 +1110,8 @@ fn lint_fn_to_numeric_cast(cx: &LateContext<'_, '_>, expr: &Expr, cast_expr: &Ex expr.span, &format!("casting function pointer `{}` to `{}`, which truncates the value", from_snippet, cast_to), "try", - format!("{} as usize", from_snippet) + format!("{} as usize", from_snippet), + Applicability::Unspecified, ); } else if cast_to.sty != ty::Uint(UintTy::Usize) { @@ -1113,7 +1121,8 @@ fn lint_fn_to_numeric_cast(cx: &LateContext<'_, '_>, expr: &Expr, cast_expr: &Ex expr.span, &format!("casting function pointer `{}` to `{}`", from_snippet, cast_to), "try", - format!("{} as usize", from_snippet) + format!("{} as usize", from_snippet), + Applicability::Unspecified, ); } }, diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index ad4ced995ba8..ea9deb7a8049 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -8,15 +8,16 @@ // except according to those terms. -use crate::utils::{in_macro, span_lint_and_sugg}; -use if_chain::if_chain; use crate::rustc::hir::intravisit::{walk_path, walk_ty, NestedVisitorMap, Visitor}; use crate::rustc::hir::*; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use crate::rustc::ty; use crate::rustc::{declare_tool_lint, lint_array}; -use crate::syntax_pos::symbol::keywords::SelfType; +use crate::rustc_errors::Applicability; use crate::syntax::ast::NodeId; +use crate::syntax_pos::symbol::keywords::SelfType; +use crate::utils::{in_macro, span_lint_and_sugg}; +use if_chain::if_chain; /// **What it does:** Checks for unnecessary repetition of structure name when a /// replacement with `Self` is applicable. @@ -70,6 +71,7 @@ fn span_use_self_lint(cx: &LateContext<'_, '_>, path: &Path) { "unnecessary structure name repetition", "use the applicable keyword", "Self".to_owned(), + Applicability::Unspecified, ); } diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs index 879157ec8a47..740da22ba1c9 100644 --- a/clippy_lints/src/utils/internal_lints.rs +++ b/clippy_lints/src/utils/internal_lints.rs @@ -18,6 +18,7 @@ use crate::rustc::hir::*; use crate::rustc::hir::def::Def; use crate::rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintPass}; use crate::rustc::{declare_tool_lint, lint_array}; +use crate::rustc_errors::Applicability; use crate::rustc_data_structures::fx::{FxHashMap, FxHashSet}; use crate::syntax::ast::{Crate as AstCrate, Ident, ItemKind, Name}; use crate::syntax::source_map::Span; @@ -281,6 +282,7 @@ impl EarlyLintPass for DefaultHashTypes { &msg, "use", replace.to_string(), + Applicability::Unspecified, ); } } diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 43af5e393c8a..3c19cfe18057 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -657,9 +657,10 @@ pub fn span_lint_and_sugg<'a, 'tcx: 'a, T: LintContext<'tcx>>( msg: &str, help: &str, sugg: String, + applicability: Applicability, ) { span_lint_and_then(cx, lint, sp, msg, |db| { - db.span_suggestion_with_applicability(sp, help, sugg, Applicability::Unspecified); + db.span_suggestion_with_applicability(sp, help, sugg, applicability); }); } diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index 21a33bd143fb..0dd9af6db164 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -8,14 +8,15 @@ // except according to those terms. +use crate::consts::constant; use crate::rustc::hir::*; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; -use crate::rustc::{declare_tool_lint, lint_array}; -use if_chain::if_chain; use crate::rustc::ty::{self, Ty}; +use crate::rustc::{declare_tool_lint, lint_array}; +use crate::rustc_errors::Applicability; use crate::syntax::source_map::Span; use crate::utils::{higher, is_copy, snippet, span_lint_and_sugg}; -use crate::consts::constant; +use if_chain::if_chain; /// **What it does:** Checks for usage of `&vec![..]` when using `&[..]` would /// be possible. @@ -100,6 +101,7 @@ fn check_vec_macro<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, vec_args: &higher::VecA "useless use of `vec!`", "you can use a slice directly", snippet, + Applicability::Unspecified, ); } diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs index f84362fdbbc6..c0161ecf5323 100644 --- a/clippy_lints/src/write.rs +++ b/clippy_lints/src/write.rs @@ -8,13 +8,14 @@ // except according to those terms. -use crate::utils::{snippet, span_lint, span_lint_and_sugg}; use crate::rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass}; use crate::rustc::{declare_tool_lint, lint_array}; -use std::borrow::Cow; +use crate::rustc_errors::Applicability; use crate::syntax::ast::*; use crate::syntax::parse::{parser, token}; use crate::syntax::tokenstream::{ThinTokenStream, TokenStream}; +use crate::utils::{snippet, span_lint, span_lint_and_sugg}; +use std::borrow::Cow; /// **What it does:** This lint warns when you use `println!("")` to /// print a newline. @@ -199,6 +200,7 @@ impl EarlyLintPass for Pass { "using `println!(\"\")`", "replace it with", "println!()".to_string(), + Applicability::Unspecified, ); } } @@ -248,6 +250,7 @@ impl EarlyLintPass for Pass { format!("using `writeln!({}, \"\")`", suggestion).as_str(), "replace it with", format!("writeln!({})", suggestion), + Applicability::Unspecified, ); } } From 3740da203b6e65f19b5075379c494616d60e5f80 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Tue, 27 Nov 2018 15:11:13 +0100 Subject: [PATCH 3/8] Fix bugs and improve documentation Some bugs and some documentation is unrelated to the Applicability change, but these bugs were serious and the documentation was kind of required to understand what's going on. --- clippy_lints/src/else_if_without_else.rs | 7 ++---- clippy_lints/src/methods/mod.rs | 4 +-- clippy_lints/src/utils/mod.rs | 31 +++++++++++++++++------- clippy_lints/src/utils/sugg.rs | 18 ++++++++++++-- clippy_lints/src/write.rs | 14 +++++++++++ 5 files changed, 56 insertions(+), 18 deletions(-) diff --git a/clippy_lints/src/else_if_without_else.rs b/clippy_lints/src/else_if_without_else.rs index 99031dd28872..cb75d9836830 100644 --- a/clippy_lints/src/else_if_without_else.rs +++ b/clippy_lints/src/else_if_without_else.rs @@ -12,10 +12,9 @@ use crate::rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass, in_external_macro, LintContext}; use crate::rustc::{declare_tool_lint, lint_array}; -use crate::rustc_errors::Applicability; use crate::syntax::ast::*; -use crate::utils::span_lint_and_sugg; +use crate::utils::span_help_and_lint; /// **What it does:** Checks for usage of if expressions with an `else if` branch, /// but without a final `else` branch. @@ -67,14 +66,12 @@ impl EarlyLintPass for ElseIfWithoutElse { while let ExprKind::If(_, _, Some(ref els)) = item.node { if let ExprKind::If(_, _, None) = els.node { - span_lint_and_sugg( + span_help_and_lint( cx, ELSE_IF_WITHOUT_ELSE, els.span, "if expression with an `else if`, but without a final `else`", "add an `else` block here", - String::new(), - Applicability::Unspecified, ); } diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index dcee380f4555..82c3274d43ba 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -2046,10 +2046,10 @@ fn lint_chars_next_cmp<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprIn /// Checks for the `CHARS_LAST_CMP` lint. fn lint_chars_last_cmp<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprInfo<'_>) -> bool { - if lint_chars_cmp(cx, info, &["chars", "last"], CHARS_NEXT_CMP, "ends_with") { + if lint_chars_cmp(cx, info, &["chars", "last"], CHARS_LAST_CMP, "ends_with") { true } else { - lint_chars_cmp(cx, info, &["chars", "next_back"], CHARS_NEXT_CMP, "ends_with") + lint_chars_cmp(cx, info, &["chars", "next_back"], CHARS_LAST_CMP, "ends_with") } } diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 3c19cfe18057..0c6935d867da 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -384,24 +384,25 @@ pub fn snippet<'a, 'b, T: LintContext<'b>>(cx: &T, span: Span, default: &'a str) snippet_opt(cx, span).map_or_else(|| Cow::Borrowed(default), From::from) } +/// Same as `snippet`, but it adapts the applicability level by following rules: +/// +/// - Applicability level `Unspecified` will never be changed. +/// - If the span is inside a macro, change the applicability level to `MaybeIncorrect`. +/// - If the default value is used and the applicability level is `MachineApplicable`, change it to +/// `HasPlaceholders` pub fn snippet_with_applicability<'a, 'b, T: LintContext<'b>>( cx: &T, span: Span, default: &'a str, applicability: &mut Applicability, ) -> Cow<'a, str> { + if *applicability != Applicability::Unspecified && in_macro(span) { + *applicability = Applicability::MaybeIncorrect; + } snippet_opt(cx, span).map_or_else( || { - // If the applicability is already `HasPlaceholders` or `MaybeIncorrect` don't change it. - // Also `Unspecified` shouldn't be changed - // Only if the applicability level is originally `MachineApplicable` and the default value - // has to be used change it to `HasPlaceholders` if *applicability == Applicability::MachineApplicable { - if in_macro(span) { - *applicability = Applicability::MaybeIncorrect; - } else { - *applicability = Applicability::HasPlaceholders; - } + *applicability = Applicability::HasPlaceholders; } Cow::Borrowed(default) }, @@ -435,6 +436,18 @@ pub fn snippet_block<'a, 'b, T: LintContext<'b>>(cx: &T, span: Span, default: &' trim_multiline(snip, true) } +/// Same as `snippet_block`, but adapts the applicability level by the rules of +/// `snippet_with_applicabiliy`. +pub fn snippet_block_with_applicability<'a, 'b, T: LintContext<'b>>( + cx: &T, + span: Span, + default: &'a str, + applicability: &mut Applicability, +) -> Cow<'a, str> { + let snip = snippet_with_applicability(cx, span, default, applicability); + trim_multiline(snip, true) +} + /// Returns a new Span that covers the full last line of the given Span pub fn last_line_of_span<'a, T: LintContext<'a>>(cx: &T, span: Span) -> Span { let source_map_and_line = cx.sess().source_map().lookup_line(span.lo()).unwrap(); diff --git a/clippy_lints/src/utils/sugg.rs b/clippy_lints/src/utils/sugg.rs index 5bb35474403a..b4c9868bbd6b 100644 --- a/clippy_lints/src/utils/sugg.rs +++ b/clippy_lints/src/utils/sugg.rs @@ -24,7 +24,7 @@ use crate::syntax::parse::token; use crate::syntax::print::pprust::token_to_string; use crate::syntax::util::parser::AssocOp; use crate::syntax::ast; -use crate::utils::{higher, snippet, snippet_opt}; +use crate::utils::{higher, in_macro, snippet, snippet_opt}; use crate::syntax_pos::{BytePos, Pos}; use crate::rustc_errors::Applicability; @@ -96,7 +96,21 @@ impl<'a> Sugg<'a> { Self::hir_opt(cx, expr).unwrap_or_else(|| Sugg::NonParen(Cow::Borrowed(default))) } - pub fn hir_with_applicability(cx: &LateContext<'_, '_>, expr: &hir::Expr, default: &'a str, applicability: &mut Applicability) -> Self { + /// Same as `hir`, but it adapts the applicability level by following rules: + /// + /// - Applicability level `Unspecified` will never be changed. + /// - If the span is inside a macro, change the applicability level to `MaybeIncorrect`. + /// - If the default value is used and the applicability level is `MachineApplicable`, change it to + /// `HasPlaceholders` + pub fn hir_with_applicability( + cx: &LateContext<'_, '_>, + expr: &hir::Expr, + default: &'a str, + applicability: &mut Applicability, + ) -> Self { + if *applicability != Applicability::Unspecified && in_macro(expr.span) { + *applicability = Applicability::MaybeIncorrect; + } Self::hir_opt(cx, expr).unwrap_or_else(|| { if *applicability == Applicability::MachineApplicable { *applicability = Applicability::HasPlaceholders; diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs index c0161ecf5323..76e07a2d3b3f 100644 --- a/clippy_lints/src/write.rs +++ b/clippy_lints/src/write.rs @@ -258,6 +258,20 @@ impl EarlyLintPass for Pass { } } +/// Checks the arguments of `print[ln]!` and `write[ln]!` calls. It will return a tuple of two +/// options. The first part of the tuple is format_str of the macros. The secund part of the tuple +/// is in the `write[ln]!` case the expression the format_str should be written to. +/// +/// Example: +/// +/// Calling this function on +/// ```rust,ignore +/// writeln!(buf, "string to write: {}", something) +/// ``` +/// will return +/// ```rust,ignore +/// (Some("string to write: {}"), Some(buf)) +/// ``` fn check_tts<'a>(cx: &EarlyContext<'a>, tts: &ThinTokenStream, is_write: bool) -> (Option, Option) { use crate::fmt_macros::*; let tts = TokenStream::from(tts.clone()); From 0c6483bf215245c190d7a47bc9f3067bbc887e63 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Tue, 27 Nov 2018 15:27:34 +0100 Subject: [PATCH 4/8] Update stderr file --- tests/ui/else_if_without_else.stderr | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/ui/else_if_without_else.stderr b/tests/ui/else_if_without_else.stderr index 9eddd4ab30d4..7c8afcf3ce17 100644 --- a/tests/ui/else_if_without_else.stderr +++ b/tests/ui/else_if_without_else.stderr @@ -5,9 +5,10 @@ error: if expression with an `else if`, but without a final `else` | ____________^ 52 | | println!("else if"); 53 | | } - | |_____^ help: add an `else` block here + | |_____^ | = note: `-D clippy::else-if-without-else` implied by `-D warnings` + = help: add an `else` block here error: if expression with an `else if`, but without a final `else` --> $DIR/else_if_without_else.rs:59:12 @@ -16,7 +17,9 @@ error: if expression with an `else if`, but without a final `else` | ____________^ 60 | | println!("else if 2"); 61 | | } - | |_____^ help: add an `else` block here + | |_____^ + | + = help: add an `else` block here error: aborting due to 2 previous errors From 4e74eef6e9225973c73c555c9a324791e8be3958 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Tue, 27 Nov 2018 15:13:57 +0100 Subject: [PATCH 5/8] Add applicability level to (nearly) every span_lint_and_sugg function --- clippy_lints/src/attrs.rs | 2 +- clippy_lints/src/bytecount.rs | 8 +- clippy_lints/src/collapsible_if.rs | 7 +- clippy_lints/src/default_trait_access.rs | 2 +- clippy_lints/src/double_comparison.rs | 9 ++- clippy_lints/src/duration_subsec.rs | 7 +- clippy_lints/src/excessive_precision.rs | 2 +- .../src/infallible_destructuring_match.rs | 11 +-- clippy_lints/src/len_zero.rs | 17 +++- clippy_lints/src/literal_representation.rs | 10 +-- clippy_lints/src/loops.rs | 29 ++++--- clippy_lints/src/map_clone.rs | 7 +- clippy_lints/src/matches.rs | 9 ++- clippy_lints/src/mem_replace.rs | 7 +- clippy_lints/src/methods/mod.rs | 77 +++++++++++-------- clippy_lints/src/needless_bool.rs | 28 +++---- clippy_lints/src/no_effect.rs | 2 +- clippy_lints/src/precedence.rs | 30 ++++---- clippy_lints/src/ptr_offset_with_cast.rs | 2 +- clippy_lints/src/redundant_field_names.rs | 2 +- clippy_lints/src/reference.rs | 14 ++-- clippy_lints/src/replace_consts.rs | 2 +- clippy_lints/src/strings.rs | 18 +++-- .../src/trivially_copy_pass_by_ref.rs | 8 +- clippy_lints/src/types.rs | 20 +++-- clippy_lints/src/use_self.rs | 2 +- clippy_lints/src/utils/internal_lints.rs | 2 +- clippy_lints/src/vec.rs | 13 +++- clippy_lints/src/write.rs | 17 ++-- 29 files changed, 216 insertions(+), 148 deletions(-) diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 19306b81e4ad..88b61f074224 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -532,7 +532,7 @@ impl EarlyLintPass for CfgAttrPass { "`cfg_attr` is deprecated for rustfmt and got replaced by tool_attributes", "use", format!("{}rustfmt::skip]", attr_style), - Applicability::Unspecified, + Applicability::MachineApplicable, ); } } diff --git a/clippy_lints/src/bytecount.rs b/clippy_lints/src/bytecount.rs index 1e738b9afa1e..0547837795dd 100644 --- a/clippy_lints/src/bytecount.rs +++ b/clippy_lints/src/bytecount.rs @@ -15,7 +15,8 @@ use crate::rustc::{declare_tool_lint, lint_array}; use crate::rustc_errors::Applicability; use crate::syntax::ast::{Name, UintTy}; 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; @@ -91,6 +92,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount { } else { &filter_args[0] }; + let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, NAIVE_BYTECOUNT, @@ -98,8 +100,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount { "You appear to be counting bytes the naive way", "Consider using the bytecount crate", format!("bytecount::count({}, {})", - snippet(cx, haystack.span, ".."), - snippet(cx, needle.span, "..")), + snippet_with_applicability(cx, haystack.span, "..", &mut applicability), + snippet_with_applicability(cx, needle.span, "..", &mut applicability)), Applicability::Unspecified, ); } diff --git a/clippy_lints/src/collapsible_if.rs b/clippy_lints/src/collapsible_if.rs index 2699ec0e7fdd..206403791a18 100644 --- a/clippy_lints/src/collapsible_if.rs +++ b/clippy_lints/src/collapsible_if.rs @@ -27,7 +27,7 @@ use crate::rustc::{declare_tool_lint, lint_array}; use if_chain::if_chain; 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::rustc_errors::Applicability; @@ -128,14 +128,15 @@ fn check_collapsible_maybe_if_let(cx: &EarlyContext<'_>, else_: &ast::Expr) { then { match else_.node { ast::ExprKind::If(..) | ast::ExprKind::IfLet(..) => { + let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, COLLAPSIBLE_IF, block.span, "this `else { if .. }` block can be collapsed", "try", - snippet_block(cx, else_.span, "..").into_owned(), - Applicability::Unspecified, + snippet_block_with_applicability(cx, else_.span, "..", &mut applicability).into_owned(), + applicability, ); } _ => (), diff --git a/clippy_lints/src/default_trait_access.rs b/clippy_lints/src/default_trait_access.rs index 17dccf2adfbf..693b47f6fff5 100644 --- a/clippy_lints/src/default_trait_access.rs +++ b/clippy_lints/src/default_trait_access.rs @@ -82,7 +82,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DefaultTraitAccess { &format!("Calling {} is more clear than this expression", replacement), "try", replacement, - Applicability::Unspecified, + Applicability::Unspecified, // First resolve the TODO above ); } }, diff --git a/clippy_lints/src/double_comparison.rs b/clippy_lints/src/double_comparison.rs index f4c340538a7c..4d8345dadc3a 100644 --- a/clippy_lints/src/double_comparison.rs +++ b/clippy_lints/src/double_comparison.rs @@ -16,7 +16,7 @@ use crate::rustc::{declare_tool_lint, lint_array}; use crate::rustc_errors::Applicability; 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. /// @@ -71,8 +71,9 @@ impl<'a, 'tcx> Pass { } macro_rules! lint_double_comparison { ($op:tt) => {{ - let lhs_str = snippet(cx, llhs.span, ""); - let rhs_str = snippet(cx, lrhs.span, ""); + let mut applicability = Applicability::MachineApplicable; + 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); span_lint_and_sugg( cx, @@ -81,7 +82,7 @@ impl<'a, 'tcx> Pass { "This binary expression can be simplified", "try", sugg, - Applicability::Unspecified, + applicability, ); }} } diff --git a/clippy_lints/src/duration_subsec.rs b/clippy_lints/src/duration_subsec.rs index 5752968c1a22..fe4aea572e05 100644 --- a/clippy_lints/src/duration_subsec.rs +++ b/clippy_lints/src/duration_subsec.rs @@ -17,7 +17,7 @@ use if_chain::if_chain; use crate::consts::{constant, Constant}; 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 /// from other `Duration` methods. @@ -61,14 +61,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DurationSubsec { ("subsec_nanos", 1_000) => "subsec_micros", _ => return, }; + let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, DURATION_SUBSEC, expr.span, &format!("Calling `{}()` is more concise than this calculation", suggested_fn), "try", - format!("{}.{}()", snippet(cx, args[0].span, "_"), suggested_fn), - Applicability::Unspecified, + format!("{}.{}()", snippet_with_applicability(cx, args[0].span, "_", &mut applicability), suggested_fn), + applicability, ); } } diff --git a/clippy_lints/src/excessive_precision.rs b/clippy_lints/src/excessive_precision.rs index 5f15f81205c4..6043dd46ae71 100644 --- a/clippy_lints/src/excessive_precision.rs +++ b/clippy_lints/src/excessive_precision.rs @@ -69,7 +69,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExcessivePrecision { "float has excessive precision", "consider changing the type or truncating it to", sugg, - Applicability::Unspecified, + Applicability::MachineApplicable, ); } } diff --git a/clippy_lints/src/infallible_destructuring_match.rs b/clippy_lints/src/infallible_destructuring_match.rs index d212cf623905..558d101d68ec 100644 --- a/clippy_lints/src/infallible_destructuring_match.rs +++ b/clippy_lints/src/infallible_destructuring_match.rs @@ -8,7 +8,7 @@ // 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::lint::{LateContext, LateLintPass, LintArray, LintPass}; 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); then { + let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, INFALLIBLE_DESTRUCTURING_MATCH, @@ -81,11 +82,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { "try this", format!( "let {}({}) = {};", - snippet(cx, variant_name.span, ".."), - snippet(cx, local.pat.span, ".."), - snippet(cx, target.span, ".."), + snippet_with_applicability(cx, variant_name.span, "..", &mut applicability), + snippet_with_applicability(cx, local.pat.span, "..", &mut applicability), + snippet_with_applicability(cx, target.span, "..", &mut applicability), ), - Applicability::Unspecified, + applicability, ); } } diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index 33457bb70447..15c21d776988 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -17,7 +17,7 @@ use crate::rustc_data_structures::fx::FxHashSet; use crate::rustc_errors::Applicability; use crate::syntax::ast::{Lit, LitKind, Name}; 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()` /// 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 { 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]) { + let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, LEN_ZERO, span, &format!("length comparison to {}", if compare_to == 0 { "zero" } else { "one" }), "using `is_empty` is clearer and more explicit", - format!("{}{}.is_empty()", op, snippet(cx, args[0].span, "_")), - Applicability::Unspecified, + format!("{}{}.is_empty()", op, snippet_with_applicability(cx, args[0].span, "_", &mut applicability)), + applicability, ); } } diff --git a/clippy_lints/src/literal_representation.rs b/clippy_lints/src/literal_representation.rs index ebcb773d6f25..8d7f549da39e 100644 --- a/clippy_lints/src/literal_representation.rs +++ b/clippy_lints/src/literal_representation.rs @@ -301,7 +301,7 @@ impl WarningType { "mistyped literal suffix", "did you mean to write", grouping_hint.to_string(), - Applicability::Unspecified, + Applicability::MachineApplicable, ), WarningType::UnreadableLiteral => span_lint_and_sugg( cx, @@ -310,7 +310,7 @@ impl WarningType { "long literal lacking separators", "consider", grouping_hint.to_owned(), - Applicability::Unspecified, + Applicability::MachineApplicable, ), WarningType::LargeDigitGroups => span_lint_and_sugg( cx, @@ -319,7 +319,7 @@ impl WarningType { "digit groups should be smaller", "consider", grouping_hint.to_owned(), - Applicability::Unspecified, + Applicability::MachineApplicable, ), WarningType::InconsistentDigitGrouping => span_lint_and_sugg( cx, @@ -328,7 +328,7 @@ impl WarningType { "digits grouped inconsistently by underscores", "consider", grouping_hint.to_owned(), - Applicability::Unspecified, + Applicability::MachineApplicable, ), WarningType::DecimalRepresentation => span_lint_and_sugg( cx, @@ -337,7 +337,7 @@ impl WarningType { "integer literal has a better hexadecimal representation", "consider", grouping_hint.to_owned(), - Applicability::Unspecified, + Applicability::MachineApplicable, ), }; } diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index e04fc6ea17f1..0704246d4502 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -35,10 +35,12 @@ use crate::utils::{in_macro, sugg, sext}; use crate::utils::usage::mutated_variables; 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::{ + 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 /// 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; // 2) it was not indented properly; // 3) it wasn’t very smart (see #675). + let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, WHILE_LET_LOOP, @@ -509,10 +512,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { "try", format!( "while let {} = {} {{ .. }}", - snippet(cx, arms[0].pats[0].span, ".."), - snippet(cx, matchexpr.span, "..") + snippet_with_applicability(cx, arms[0].pats[0].span, "..", &mut applicability), + 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", "try", 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 .into_iter() .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_limit = print_limit(end, dst_var.offset, &dst_var.var_name); 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) { - 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" { "mut " } else { @@ -1319,7 +1323,7 @@ fn lint_iter_method(cx: &LateContext<'_, '_>, args: &[Expr], arg: &Expr, method_ iteration methods", "to write this more concisely, try", 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), }; } 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( cx, EXPLICIT_INTO_ITER_LOOP, @@ -1358,7 +1363,7 @@ fn check_for_loop_arg(cx: &LateContext<'_, '_>, pat: &Pat, arg: &Expr, expr: &Ex iteration methods`", "to write this more concisely, try", object.to_string(), - Applicability::Unspecified, + applicability, ); } } else if method_name == "next" && match_trait_method(cx, arg, &paths::ITERATOR) { diff --git a/clippy_lints/src/map_clone.rs b/clippy_lints/src/map_clone.rs index 2fd5c6187c32..4424143160c5 100644 --- a/clippy_lints/src/map_clone.rs +++ b/clippy_lints/src/map_clone.rs @@ -15,7 +15,7 @@ use crate::rustc_errors::Applicability; use crate::syntax::ast::Ident; use crate::syntax::source_map::Span; 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; #[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) { if let hir::ExprKind::Path(hir::QPath::Resolved(None, ref path)) = path.node { if path.segments.len() == 1 && path.segments[0].ident == name { + let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, MAP_CLONE, replace, "You are using an explicit closure for cloning elements", "Consider calling the dedicated `cloned` method", - format!("{}.cloned()", snippet(cx, root, "..")), - Applicability::Unspecified, + format!("{}.cloned()", snippet_with_applicability(cx, root, "..", &mut applicability)), + applicability, ) } } diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index f96ab2f924e1..583cdee843f7 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -19,7 +19,7 @@ use crate::syntax::ast::LitKind; use crate::syntax::source_map::Span; use crate::utils::paths; 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}; use crate::utils::sugg::Sugg; 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, ".."), 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 { let suggestion = if rb == BindingAnnotation::Ref { "as_ref" } else { "as_mut" }; + let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, MATCH_AS_REF, expr.span, &format!("use {}() instead", suggestion), "try this", - format!("{}.{}()", snippet(cx, ex.span, "_"), suggestion), - Applicability::Unspecified, + format!("{}.{}()", snippet_with_applicability(cx, ex.span, "_", &mut applicability), suggestion), + applicability, ) } } diff --git a/clippy_lints/src/mem_replace.rs b/clippy_lints/src/mem_replace.rs index 684f58a08efb..f0310b87f691 100644 --- a/clippy_lints/src/mem_replace.rs +++ b/clippy_lints/src/mem_replace.rs @@ -12,7 +12,7 @@ use crate::rustc::hir::{Expr, ExprKind, MutMutable, QPath}; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use crate::rustc::{declare_tool_lint, lint_array}; 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; /// **What it does:** Checks for `mem::replace()` on an `Option` with @@ -80,14 +80,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemReplace { _ => return, }; + let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, MEM_REPLACE_OPTION_WITH_NONE, expr.span, "replacing an `Option` with `None`", "consider `Option::take()` instead", - format!("{}.take()", snippet(cx, replaced_path.span, "")), - Applicability::Unspecified, + format!("{}.take()", snippet_with_applicability(cx, replaced_path.span, "", &mut applicability)), + applicability, ); } } diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 82c3274d43ba..dc939ad08157 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -22,8 +22,9 @@ use crate::utils::sugg; use crate::utils::{ 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, - match_var, method_calls, method_chain_args, remove_blocks, return_ty, same_tys, single_segment_path, snippet, snippet_with_macro_callsite, span_lint, - span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq, + match_var, method_calls, method_chain_args, remove_blocks, return_ty, same_tys, single_segment_path, snippet, + 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 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, &[]) { + let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, OR_FUN_CALL, span, &format!("use of `{}` followed by a call to `{}`", name, path), "try this", - format!("{}.unwrap_or_default()", snippet(cx, self_expr.span, "_")), - Applicability::Unspecified, + format!("{}.unwrap_or_default()", snippet_with_applicability(cx, self_expr.span, "_", &mut applicability)), + applicability, ); 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), "try this", 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 } - 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::Match(ref format_arg_expr, _, _) = format_arg.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()); if let Some(format_args) = extract_format_args(arg) { + let mut applicability = Applicability::MachineApplicable; let args_len = format_args.len(); let args: Vec = format_args .into_iter() .take(args_len - 1) - .map(|a| generate_format_arg_snippet(cx, a)) + .map(|a| generate_format_arg_snippet(cx, a, &mut applicability)) .collect(); 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), "try this", format!("unwrap_or_else({} panic!({}))", closure, sugg), - Applicability::Unspecified, + applicability, ); 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( 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), "try this", 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", "try this", 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; }; + let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, STRING_EXTEND_CHARS, @@ -1385,11 +1394,11 @@ fn lint_string_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr, args: &[hir::E "try this", format!( "{}.push_str({}{})", - snippet(cx, args[0].span, "_"), + snippet_with_applicability(cx, args[0].span, "_", &mut applicability), 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 fold_span = next_point.with_hi(fold_args[2].span.hi() + BytePos(1)); + let mut applicability = Applicability::MachineApplicable; let sugg = if replacement_has_args { format!( ".{replacement}(|{s}| {r})", replacement = replacement_method_name, s = second_arg_ident, - r = snippet(cx, right_expr.span, "EXPR"), + r = snippet_with_applicability(cx, right_expr.span, "EXPR", &mut applicability), ) } else { 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", "try", 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) { // Note: we don't want to lint `get_mut().unwrap` for HashMap or BTreeMap, // because they do not implement `IndexMut` + let mut applicability = Applicability::MachineApplicable; let expr_ty = cx.tables.expr_ty(&get_args[0]); 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 { 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!( "{}{}[{}]", borrow_str, - snippet(cx, get_args[0].span, "_"), + snippet_with_applicability(cx, get_args[0].span, "_", &mut applicability), get_args_str ), - Applicability::Unspecified, + applicability, ); } @@ -2012,6 +2023,7 @@ fn lint_chars_cmp( if let Some(segment) = single_segment_path(qpath); if segment.ident.name == "Some"; then { + let mut applicability = Applicability::MachineApplicable; let self_ty = walk_ptrs_ty(cx.tables.expr_ty_adjusted(&args[0][0])); if self_ty.sty != ty::Str { @@ -2026,10 +2038,10 @@ fn lint_chars_cmp( "like this", format!("{}{}.{}({})", if info.eq { "" } else { "!" }, - snippet(cx, args[0][0].span, "_"), + snippet_with_applicability(cx, args[0][0].span, "_", &mut applicability), suggest, - snippet(cx, arg_char[0].span, "_")), - Applicability::Unspecified, + snippet_with_applicability(cx, arg_char[0].span, "_", &mut applicability)), + applicability, ); 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 ast::LitKind::Char(c) = lit.node; then { + let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, lint, @@ -2074,10 +2087,10 @@ fn lint_chars_cmp_with_unwrap<'a, 'tcx>( "like this", format!("{}{}.{}('{}')", if info.eq { "" } else { "!" }, - snippet(cx, args[0][0].span, "_"), + snippet_with_applicability(cx, args[0][0].span, "_", &mut applicability), suggest, c), - Applicability::Unspecified, + applicability, ); 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 r.as_str().len() == 1; 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]); span_lint_and_sugg( 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", "try using a char instead", 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_rcv_ty, rcv_depth) = walk_ptrs_ty_depth(rcv_ty); if base_rcv_ty == base_res_ty && rcv_depth >= res_depth { + let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, USELESS_ASREF, expr.span, &format!("this call to `{}` does nothing", call_name), "try this", - snippet(cx, recvr.span, "_").into_owned(), - Applicability::Unspecified, + snippet_with_applicability(cx, recvr.span, "_", &mut applicability).to_string(), + applicability, ); } } @@ -2207,8 +2222,8 @@ fn lint_into_iter(cx: &LateContext<'_, '_>, expr: &hir::Expr, self_ref_ty: ty::T kind, ), "call directly", - method_name.to_owned(), - Applicability::Unspecified, + method_name.to_string(), + Applicability::MachineApplicable, ); } } diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs index 8ed319c6736d..37ccf28d5725 100644 --- a/clippy_lints/src/needless_bool.rs +++ b/clippy_lints/src/needless_bool.rs @@ -19,7 +19,7 @@ use crate::rustc_errors::Applicability; use crate::syntax::ast::LitKind; use crate::syntax::source_map::Spanned; 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 { /// false }` @@ -74,7 +74,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool { use self::Expression::*; if let ExprKind::If(ref pred, ref then_block, Some(ref else_expr)) = e.node { let reduce = |ret, not| { - let snip = Sugg::hir(cx, pred, ""); + let mut applicability = Applicability::MachineApplicable; + let snip = Sugg::hir_with_applicability(cx, pred, "", &mut applicability); let snip = if not { !snip } else { snip }; 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", "you can reduce it to", hint, - Applicability::Unspecified, + applicability, ); }; 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 { + let mut applicability = Applicability::MachineApplicable; match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) { (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( cx, BOOL_COMPARISON, e.span, "equality checks against true are unnecessary", "try simplifying it as shown", - hint, - Applicability::Unspecified, + hint.to_string(), + applicability, ); }, (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( cx, BOOL_COMPARISON, e.span, "equality checks against true are unnecessary", "try simplifying it as shown", - hint, - Applicability::Unspecified, + hint.to_string(), + applicability, ); }, (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( cx, BOOL_COMPARISON, @@ -176,11 +178,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison { "equality checks against false can be replaced by a negation", "try simplifying it as shown", (!hint).to_string(), - Applicability::Unspecified, + applicability, ); }, (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( cx, BOOL_COMPARISON, @@ -188,7 +190,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison { "equality checks against false can be replaced by a negation", "try simplifying it as shown", (!hint).to_string(), - Applicability::Unspecified, + applicability, ); }, _ => (), diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs index 877cd5ab1e4e..72ed649c5d9e 100644 --- a/clippy_lints/src/no_effect.rs +++ b/clippy_lints/src/no_effect.rs @@ -132,7 +132,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { "statement can be reduced", "replace it with", snippet, - Applicability::Unspecified, + Applicability::MachineApplicable, ); } } diff --git a/clippy_lints/src/precedence.rs b/clippy_lints/src/precedence.rs index 4376db5e9b3c..d8f2645699d5 100644 --- a/clippy_lints/src/precedence.rs +++ b/clippy_lints/src/precedence.rs @@ -13,7 +13,7 @@ use crate::rustc::{declare_tool_lint, lint_array}; use crate::rustc_errors::Applicability; use crate::syntax::ast::*; 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 /// 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 { - let span_sugg = |expr: &Expr, sugg| { + let span_sugg = |expr: &Expr, sugg, appl| { span_lint_and_sugg( cx, PRECEDENCE, @@ -62,40 +62,41 @@ impl EarlyLintPass for Precedence { "operator precedence can trip the unwary", "consider parenthesizing your expression", sugg, - Applicability::Unspecified, + appl, ); }; if !is_bit_op(op) { return; } + let mut applicability = Applicability::MachineApplicable; match (is_arith_expr(left), is_arith_expr(right)) { (true, true) => { let sugg = format!( "({}) {} ({})", - snippet(cx, left.span, ".."), + snippet_with_applicability(cx, left.span, "..", &mut applicability), 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) => { let sugg = format!( "({}) {} {}", - snippet(cx, left.span, ".."), + snippet_with_applicability(cx, left.span, "..", &mut applicability), 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) => { let sugg = format!( "{} {} ({})", - snippet(cx, left.span, ".."), + snippet_with_applicability(cx, left.span, "..", &mut applicability), 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) => (), } @@ -107,14 +108,15 @@ impl EarlyLintPass for Precedence { if let ExprKind::Lit(ref lit) = slf.node { match lit.node { LitKind::Int(..) | LitKind::Float(..) | LitKind::FloatUnsuffixed(..) => { + let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, PRECEDENCE, expr.span, "unary minus has lower precedence than method call", "consider adding parentheses to clarify your intent", - format!("-({})", snippet(cx, rhs.span, "..")), - Applicability::Unspecified, + format!("-({})", snippet_with_applicability(cx, rhs.span, "..", &mut applicability)), + applicability, ); }, _ => (), diff --git a/clippy_lints/src/ptr_offset_with_cast.rs b/clippy_lints/src/ptr_offset_with_cast.rs index e653ae2ff75e..0d37d4d4b083 100644 --- a/clippy_lints/src/ptr_offset_with_cast.rs +++ b/clippy_lints/src/ptr_offset_with_cast.rs @@ -77,7 +77,7 @@ impl<'a, 'tcx> lint::LateLintPass<'a, 'tcx> for Pass { &msg, "try", sugg, - Applicability::Unspecified, + Applicability::MachineApplicable, ); } else { utils::span_lint(cx, PTR_OFFSET_WITH_CAST, expr.span, &msg); diff --git a/clippy_lints/src/redundant_field_names.rs b/clippy_lints/src/redundant_field_names.rs index 2acea17be264..b25ea1d5d380 100644 --- a/clippy_lints/src/redundant_field_names.rs +++ b/clippy_lints/src/redundant_field_names.rs @@ -66,7 +66,7 @@ impl EarlyLintPass for RedundantFieldNames { "redundant field names in struct initialization", "replace it with", field.ident.to_string(), - Applicability::Unspecified, + Applicability::MachineApplicable, ); } } diff --git a/clippy_lints/src/reference.rs b/clippy_lints/src/reference.rs index aac3d09bfd3e..7651c6f0a9f0 100644 --- a/clippy_lints/src/reference.rs +++ b/clippy_lints/src/reference.rs @@ -12,7 +12,7 @@ use crate::rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass}; use crate::rustc::{declare_tool_lint, lint_array}; use crate::rustc_errors::Applicability; 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; /// **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::AddrOf(_, ref addrof_target) = without_parens(deref_target).node; then { + let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, DEREF_ADDROF, e.span, "immediately dereferencing a reference", "try this", - format!("{}", snippet(cx, addrof_target.span, "_")), - Applicability::Unspecified, + format!("{}", snippet_with_applicability(cx, addrof_target.span, "_", &mut applicability)), + applicability, ); } } @@ -102,6 +103,7 @@ impl EarlyLintPass for DerefPass { if let ExprKind::Paren(ref parened) = object.node; if let ExprKind::AddrOf(_, ref inner) = parened.node; then { + let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, REF_IN_DEREF, @@ -110,10 +112,10 @@ impl EarlyLintPass for DerefPass { "try this", format!( "{}.{}", - snippet(cx, inner.span, "_"), - snippet(cx, field_name.span, "_") + snippet_with_applicability(cx, inner.span, "_", &mut applicability), + snippet_with_applicability(cx, field_name.span, "_", &mut applicability) ), - Applicability::Unspecified, + applicability, ); } } diff --git a/clippy_lints/src/replace_consts.rs b/clippy_lints/src/replace_consts.rs index 1c204912f17d..e3016b7259ba 100644 --- a/clippy_lints/src/replace_consts.rs +++ b/clippy_lints/src/replace_consts.rs @@ -62,7 +62,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ReplaceConsts { &format!("using `{}`", const_path.last().expect("empty path")), "try this", repl_snip.to_string(), - Applicability::Unspecified, + Applicability::MachineApplicable, ); return; } diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index 74d5e304b876..05d64fbcd04f 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -165,7 +165,7 @@ impl LintPass for StringLitAsBytes { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { 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 path.ident.name == "as_bytes" { @@ -178,6 +178,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes { } else { format!("\"{}\"", lit_content.as_str()) }; + let mut applicability = Applicability::MachineApplicable; if callsite.starts_with("include_str!") { span_lint_and_sugg( cx, @@ -185,8 +186,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes { e.span, "calling `as_bytes()` on `include_str!(..)`", "consider using `include_bytes!(..)` instead", - snippet(cx, args[0].span, r#""foo""#).replacen("include_str", "include_bytes", 1), - Applicability::Unspecified, + snippet_with_applicability(cx, args[0].span, r#""foo""#, &mut applicability).replacen( + "include_str", + "include_bytes", + 1, + ), + applicability, ); } else if callsite == expanded && lit_content.as_str().chars().all(|c| c.is_ascii()) @@ -198,8 +203,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes { e.span, "calling `as_bytes()` on a string literal", "consider using a byte string literal instead", - format!("b{}", snippet(cx, args[0].span, r#""foo""#)), - Applicability::Unspecified, + format!( + "b{}", + snippet_with_applicability(cx, args[0].span, r#""foo""#, &mut applicability) + ), + applicability, ); } } diff --git a/clippy_lints/src/trivially_copy_pass_by_ref.rs b/clippy_lints/src/trivially_copy_pass_by_ref.rs index 467713694e18..836f84e89668 100644 --- a/clippy_lints/src/trivially_copy_pass_by_ref.rs +++ b/clippy_lints/src/trivially_copy_pass_by_ref.rs @@ -15,14 +15,14 @@ use crate::rustc::hir::intravisit::FnKind; use crate::rustc::hir::*; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; 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_errors::Applicability; use crate::rustc_target::abi::LayoutOf; use crate::rustc_target::spec::abi::Abi; use crate::syntax::ast::NodeId; 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 matches::matches; @@ -141,7 +141,9 @@ impl<'a, 'tcx> TriviallyCopyPassByRef { input.span, "this argument is passed by reference, but would be more efficient if passed by value", "consider passing by value instead", - value_type); + value_type, + Applicability::Unspecified, + ); } } } diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index 4a9cb04a0ac4..61f294e1f3c2 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -29,7 +29,7 @@ use crate::utils::paths; use crate::utils::{ 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, - 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 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() { String::new() } else { - format!("{} ", lt.name.ident().name.as_str()) + format!("{} ", lt.name.ident().as_str()) }; let mutopt = if mut_ty.mutbl == Mutability::MutMutable { "mut " } else { "" }; + let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, BORROWED_BOX, ast_ty.span, "you seem to be trying to use `&Box`. Consider using just `&T`", "try", - format!("&{}{}{}", ltopt, mutopt, &snippet(cx, inner.span, "..")), + format!("&{}{}{}", ltopt, mutopt, &snippet_with_applicability(cx, inner.span, "..", &mut applicability)), Applicability::Unspecified, ); 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", "if you intended to pass a unit value, use a unit literal instead", "()".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 } // The suggestion is to use a function call, so if the original expression // has parens on the outside, they are no longer needed. + let mut applicability = Applicability::MachineApplicable; let opt = snippet_opt(cx, op.span); let sugg = if let Some(ref snip) = opt { 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() } } 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), "try", 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 { 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); 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), "try", format!("{} as usize", from_snippet), - Applicability::Unspecified, + applicability, ); } 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), "try", format!("{} as usize", from_snippet), - Applicability::Unspecified, + applicability, ); } }, diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index ea9deb7a8049..564bdb0bb035 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -71,7 +71,7 @@ fn span_use_self_lint(cx: &LateContext<'_, '_>, path: &Path) { "unnecessary structure name repetition", "use the applicable keyword", "Self".to_owned(), - Applicability::Unspecified, + Applicability::MachineApplicable, ); } diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs index 740da22ba1c9..fd232e2a3669 100644 --- a/clippy_lints/src/utils/internal_lints.rs +++ b/clippy_lints/src/utils/internal_lints.rs @@ -282,7 +282,7 @@ impl EarlyLintPass for DefaultHashTypes { &msg, "use", replace.to_string(), - Applicability::Unspecified, + Applicability::MaybeIncorrect, // FxHashMap, ... needs another import ); } } diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index 0dd9af6db164..d7e7de06355c 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -15,7 +15,7 @@ use crate::rustc::ty::{self, Ty}; use crate::rustc::{declare_tool_lint, lint_array}; use crate::rustc_errors::Applicability; 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; /// **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) { + let mut applicability = Applicability::MachineApplicable; let snippet = match *vec_args { higher::VecArgs::Repeat(elem, len) => { 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 { 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() { let span = args[0].span.to(last.span); - format!("&[{}]", snippet(cx, span, "..")) + format!("&[{}]", snippet_with_applicability(cx, span, "..", &mut applicability)) } else { "&[]".into() }, @@ -101,7 +106,7 @@ fn check_vec_macro<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, vec_args: &higher::VecA "useless use of `vec!`", "you can use a slice directly", snippet, - Applicability::Unspecified, + applicability, ); } diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs index 76e07a2d3b3f..c746815062b8 100644 --- a/clippy_lints/src/write.rs +++ b/clippy_lints/src/write.rs @@ -14,7 +14,7 @@ use crate::rustc_errors::Applicability; use crate::syntax::ast::*; use crate::syntax::parse::{parser, token}; 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; /// **What it does:** This lint warns when you use `println!("")` to @@ -200,7 +200,7 @@ impl EarlyLintPass for Pass { "using `println!(\"\")`", "replace it with", "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); if let Some(fmtstr) = check_tts.0 { if fmtstr == "" { - let suggestion = check_tts - .1 - .map_or(Cow::Borrowed("v"), |expr| snippet(cx, expr.span, "v")); + let mut applicability = Applicability::MachineApplicable; + let suggestion = check_tts.1.map_or_else( + move || { + applicability = Applicability::HasPlaceholders; + Cow::Borrowed("v") + }, + move |expr| snippet_with_applicability(cx, expr.span, "v", &mut applicability), + ); span_lint_and_sugg( cx, @@ -250,7 +255,7 @@ impl EarlyLintPass for Pass { format!("using `writeln!({}, \"\")`", suggestion).as_str(), "replace it with", format!("writeln!({})", suggestion), - Applicability::Unspecified, + applicability, ); } } From adc638ef334a9f34a16ebaee1c3430c3be04a790 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Tue, 27 Nov 2018 16:59:39 +0100 Subject: [PATCH 6/8] Change Applicability of MISTYPED_LITERAL_SUFFIX --- clippy_lints/src/literal_representation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/literal_representation.rs b/clippy_lints/src/literal_representation.rs index 8d7f549da39e..1efacc4ccec7 100644 --- a/clippy_lints/src/literal_representation.rs +++ b/clippy_lints/src/literal_representation.rs @@ -301,7 +301,7 @@ impl WarningType { "mistyped literal suffix", "did you mean to write", grouping_hint.to_string(), - Applicability::MachineApplicable, + Applicability::MaybeIncorrect, ), WarningType::UnreadableLiteral => span_lint_and_sugg( cx, From 6eb8e6d7c59ba1dfb4f1e8d669ac8d7a5db06b68 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Tue, 27 Nov 2018 16:59:52 +0100 Subject: [PATCH 7/8] Fix dogfood error --- clippy_lints/src/write.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs index c746815062b8..0119560ccd8c 100644 --- a/clippy_lints/src/write.rs +++ b/clippy_lints/src/write.rs @@ -264,8 +264,8 @@ impl EarlyLintPass for Pass { } /// Checks the arguments of `print[ln]!` and `write[ln]!` calls. It will return a tuple of two -/// options. The first part of the tuple is format_str of the macros. The secund part of the tuple -/// is in the `write[ln]!` case the expression the format_str should be written to. +/// options. The first part of the tuple is `format_str` of the macros. The secund part of the tuple +/// is in the `write[ln]!` case the expression the `format_str` should be written to. /// /// Example: /// From 87e72a58616ab2c17877cdcf56035642cbcc536b Mon Sep 17 00:00:00 2001 From: flip1995 Date: Tue, 27 Nov 2018 17:31:17 +0100 Subject: [PATCH 8/8] Fix NAIVE_BYTECOUNT applicability --- clippy_lints/src/bytecount.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/bytecount.rs b/clippy_lints/src/bytecount.rs index 0547837795dd..4f02b627e51d 100644 --- a/clippy_lints/src/bytecount.rs +++ b/clippy_lints/src/bytecount.rs @@ -102,7 +102,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount { format!("bytecount::count({}, {})", snippet_with_applicability(cx, haystack.span, "..", &mut applicability), snippet_with_applicability(cx, needle.span, "..", &mut applicability)), - Applicability::Unspecified, + applicability, ); } };