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 | 256 ++++++++++++++++++--------------- clippy_lints/src/utils/sugg.rs | 9 ++ 2 files changed, 150 insertions(+), 115 deletions(-) diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 457aa3f8500..43af5e393c8 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 crate::syntax::ast::{self, LitKind}; +use crate::syntax::attr; +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::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::symbol::{keywords, Symbol}; +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::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::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 90f48f0f83c..5bb35474403 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 | 9 ++-- 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 | 12 +++-- .../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 | 47 +++++++++++-------- 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, 207 insertions(+), 101 deletions(-) diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 58af069f1d9..19306b81e4a 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 a61e823f959..1e738b9afa1 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 a55ca04f706..2699ec0e7fd 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 66d94e00d0d..17dccf2adfb 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::{declare_tool_lint, lint_array}; -use if_chain::if_chain; 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::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 0171ac1e784..f4c340538a7 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 a679a97c2e7..5752968c1a2 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 26ffef9ebe4..99031dd2887 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 15a8d47337a..5f15f81205c 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::{declare_tool_lint, lint_array}; -use if_chain::if_chain; use crate::rustc::ty::TyKind; -use std::f32; -use std::f64; -use std::fmt; +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 std::f32; +use std::f64; +use std::fmt; /// **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 7bbbe72f91d..d212cf62390 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 789a569f4cd..33457bb7044 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 bd54c068486..ebcb773d6f2 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 0d1b960cc1f..e04fc6ea17f 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 b2c08e6ae8c..2fd5c6187c3 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 9e2dac8fef1..f96ab2f924e 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 ff57571a948..684f58a08ef 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 e3c704b77ad..dcee380f455 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 0019380a34c..8ed319c6736 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 289b5591edc..877cd5ab1e4 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 1c5e8fcb964..4376db5e9b3 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 58afdc351d1..e653ae2ff75 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 526232f7853..2acea17be26 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 79d30612cbd..aac3d09bfd3 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 ca17a032526..1c204912f17 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 e07b1649a46..74d5e304b87 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 2929752bbb2..467713694e1 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 d7adcd17981..4a9cb04a0ac 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 crate::syntax::ast::{FloatTy, IntTy, UintTy}; +use crate::syntax::errors::DiagnosticBuilder; +use crate::syntax::source_map::Span; +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, +}; +use if_chain::if_chain; +use std::borrow::Cow; 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::utils::paths; -use crate::consts::{constant, Constant}; /// 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 ad4ced995ba..ea9deb7a804 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 879157ec8a4..740da22ba1c 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 43af5e393c8..3c19cfe1805 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 21a33bd143f..0dd9af6db16 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 f84362fdbbc..c0161ecf532 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 99031dd2887..cb75d983683 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 dcee380f455..82c3274d43b 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 3c19cfe1805..0c6935d867d 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 5bb35474403..b4c9868bbd6 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 c0161ecf532..76e07a2d3b3 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 9eddd4ab30d..7c8afcf3ce1 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 19306b81e4a..88b61f07422 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 1e738b9afa1..0547837795d 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 2699ec0e7fd..206403791a1 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 17dccf2adfb..693b47f6fff 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 f4c340538a7..4d8345dadc3 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 5752968c1a2..fe4aea572e0 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 5f15f81205c..6043dd46ae7 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 d212cf62390..558d101d68e 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 33457bb7044..15c21d77698 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 ebcb773d6f2..8d7f549da39 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 e04fc6ea17f..0704246d450 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 2fd5c6187c3..4424143160c 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 f96ab2f924e..583cdee843f 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 684f58a08ef..f0310b87f69 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 82c3274d43b..dc939ad0815 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 8ed319c6736..37ccf28d572 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 877cd5ab1e4..72ed649c5d9 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 4376db5e9b3..d8f2645699d 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 e653ae2ff75..0d37d4d4b08 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 2acea17be26..b25ea1d5d38 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 aac3d09bfd3..7651c6f0a9f 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 1c204912f17..e3016b7259b 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 74d5e304b87..05d64fbcd04 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 467713694e1..836f84e8966 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 4a9cb04a0ac..61f294e1f3c 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 ea9deb7a804..564bdb0bb03 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 740da22ba1c..fd232e2a366 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 0dd9af6db16..d7e7de06355 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 76e07a2d3b3..c746815062b 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 8d7f549da39..1efacc4ccec 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 c746815062b..0119560ccd8 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 0547837795d..4f02b627e51 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, ); } };