diff options
| author | Philipp Hansch <dev@phansch.net> | 2018-10-05 07:18:24 +0200 |
|---|---|---|
| committer | Philipp Hansch <dev@phansch.net> | 2018-10-05 07:18:24 +0200 |
| commit | 1544a1a681d4f7ab909f8e89c64d1b14bc7a7337 (patch) | |
| tree | 45c141cad594caf81486ea4d02caa7e328336a65 | |
| parent | 8b3d2073fa8b1f48a27081944c1a7010a8d7b7b1 (diff) | |
| parent | eb2cfe62b523c34dc2ec5990b0113001c936db7e (diff) | |
| download | rust-1544a1a681d4f7ab909f8e89c64d1b14bc7a7337.tar.gz rust-1544a1a681d4f7ab909f8e89c64d1b14bc7a7337.zip | |
Merge remote-tracking branch 'origin/master' into relicense-rewrite
| -rw-r--r-- | .travis.yml | 6 | ||||
| -rw-r--r-- | clippy_lints/src/format.rs | 35 | ||||
| -rw-r--r-- | clippy_lints/src/methods/mod.rs | 18 | ||||
| -rw-r--r-- | clippy_lints/src/utils/mod.rs | 3 | ||||
| -rw-r--r-- | src/driver.rs | 1 | ||||
| -rw-r--r-- | tests/ui/format.rs | 12 | ||||
| -rw-r--r-- | tests/ui/format.stderr | 38 | ||||
| -rw-r--r-- | tests/ui/wrong_self_convention.rs | 1 |
8 files changed, 79 insertions, 35 deletions
diff --git a/.travis.yml b/.travis.yml index 948eb23fe83..8aff93d480a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -57,11 +57,9 @@ script: export LD_LIBRARY_PATH=$(rustc --print sysroot)/lib - | if [ -z ${INTEGRATION} ]; then - ./ci/base-tests.sh - sleep 5 + ./ci/base-tests.sh && sleep 5 else - ./ci/integration-tests.sh - sleep 5 + ./ci/integration-tests.sh && sleep 5 fi after_success: | diff --git a/clippy_lints/src/format.rs b/clippy_lints/src/format.rs index 2eb95ebffbf..7e2e355c251 100644 --- a/clippy_lints/src/format.rs +++ b/clippy_lints/src/format.rs @@ -4,7 +4,6 @@ use crate::rustc::{declare_tool_lint, lint_array}; use if_chain::if_chain; use crate::rustc::ty; use crate::syntax::ast::LitKind; -use crate::syntax_pos::Span; use crate::utils::paths; use crate::utils::{in_macro, is_expn_of, last_path_segment, match_def_path, match_type, opt_def_id, resolve_node, snippet, span_lint_and_then, walk_ptrs_ty}; use crate::rustc_errors::Applicability; @@ -47,7 +46,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { return; } match expr.node { - // `format!("{}", foo)` expansion ExprKind::Call(ref fun, ref args) => { if_chain! { @@ -58,12 +56,24 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { if check_single_piece(&args[0]); if let Some(format_arg) = get_single_string_arg(cx, &args[1]); if check_unformatted(&args[2]); + if let ExprKind::AddrOf(_, ref format_arg) = format_arg.node; then { - let sugg = format!("{}.to_string()", snippet(cx, format_arg, "<arg>").into_owned()); + let (message, sugg) = if_chain! { + if let ExprKind::MethodCall(ref path, _, _) = format_arg.node; + if path.ident.as_interned_str() == "to_string"; + then { + ("`to_string()` is enough", + snippet(cx, format_arg.span, "<arg>").to_string()) + } else { + ("consider using .to_string()", + format!("{}.to_string()", snippet(cx, format_arg.span, "<arg>"))) + } + }; + span_lint_and_then(cx, USELESS_FORMAT, span, "useless use of `format!`", |db| { db.span_suggestion_with_applicability( expr.span, - "consider using .to_string()", + message, sugg, Applicability::MachineApplicable, ); @@ -114,9 +124,9 @@ fn check_single_piece(expr: &Expr) -> bool { /// ::std::fmt::Display::fmt)], /// } /// ``` -/// and that type of `__arg0` is `&str` or `String` -/// then returns the span of first element of the matched tuple -fn get_single_string_arg(cx: &LateContext<'_, '_>, expr: &Expr) -> Option<Span> { +/// and that the type of `__arg0` is `&str` or `String`, +/// then returns the span of first element of the matched tuple. +fn get_single_string_arg<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr) -> Option<&'a Expr> { if_chain! { if let ExprKind::AddrOf(_, ref expr) = expr.node; if let ExprKind::Match(ref match_expr, ref arms, _) = expr.node; @@ -135,7 +145,7 @@ fn get_single_string_arg(cx: &LateContext<'_, '_>, expr: &Expr) -> Option<Span> let ty = walk_ptrs_ty(cx.tables.pat_ty(&pat[0])); if ty.sty == ty::Str || match_type(cx, ty, &paths::STRING) { if let ExprKind::Tup(ref values) = match_expr.node { - return Some(values[0].span); + return Some(&values[0]); } } } @@ -162,9 +172,12 @@ fn check_unformatted(expr: &Expr) -> bool { if let ExprKind::Struct(_, ref fields, _) = exprs[0].node; if let Some(format_field) = fields.iter().find(|f| f.ident.name == "format"); if let ExprKind::Struct(_, ref fields, _) = format_field.expr.node; - if let Some(align_field) = fields.iter().find(|f| f.ident.name == "width"); - if let ExprKind::Path(ref qpath) = align_field.expr.node; - if last_path_segment(qpath).ident.name == "Implied"; + if let Some(width_field) = fields.iter().find(|f| f.ident.name == "width"); + if let ExprKind::Path(ref width_qpath) = width_field.expr.node; + if last_path_segment(width_qpath).ident.name == "Implied"; + if let Some(precision_field) = fields.iter().find(|f| f.ident.name == "precision"); + if let ExprKind::Path(ref precision_path) = precision_field.expr.node; + if last_path_segment(precision_path).ident.name == "Implied"; then { return true; } diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 2524152a120..e0d858bd270 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -882,12 +882,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { let ty = cx.tcx.type_of(def_id); let is_copy = is_copy(cx, ty); for &(ref conv, self_kinds) in &CONVENTIONS { - if_chain! { - if conv.check(&name.as_str()); + if conv.check(&name.as_str()) { if !self_kinds - .iter() - .any(|k| k.matches(cx, first_arg_ty, first_arg, self_ty, is_copy, &implitem.generics)); - then { + .iter() + .any(|k| k.matches(cx, first_arg_ty, first_arg, self_ty, is_copy, &implitem.generics)) { let lint = if item.vis.node.is_pub() { WRONG_PUB_SELF_CONVENTION } else { @@ -904,6 +902,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { .collect::<Vec<_>>() .join(" or "))); } + + // Only check the first convention to match (CONVENTIONS should be listed from most to least specific) + break; } } @@ -1183,8 +1184,8 @@ fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr, arg: &hir::Exp Applicability::MaybeIncorrect, ); db.span_suggestion_with_applicability( - expr.span, - "or try being explicit about what type to clone", + expr.span, + "or try being explicit about what type to clone", explicit, Applicability::MaybeIncorrect, ); @@ -2067,12 +2068,13 @@ enum Convention { } #[rustfmt::skip] -const CONVENTIONS: [(Convention, &[SelfKind]); 6] = [ +const CONVENTIONS: [(Convention, &[SelfKind]); 7] = [ (Convention::Eq("new"), &[SelfKind::No]), (Convention::StartsWith("as_"), &[SelfKind::Ref, SelfKind::RefMut]), (Convention::StartsWith("from_"), &[SelfKind::No]), (Convention::StartsWith("into_"), &[SelfKind::Value]), (Convention::StartsWith("is_"), &[SelfKind::Ref, SelfKind::No]), + (Convention::Eq("to_mut"), &[SelfKind::RefMut]), (Convention::StartsWith("to_"), &[SelfKind::Ref]), ]; diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 0011065db67..fa3c72dbb7d 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -72,6 +72,7 @@ pub fn in_macro(span: Span) -> bool { pub fn match_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, path: &[&str]) -> bool { use crate::syntax::symbol; + #[derive(Debug)] struct AbsolutePathBuffer { names: Vec<symbol::LocalInternedString>, } @@ -89,7 +90,7 @@ pub fn match_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, path: &[&str]) -> let mut apb = AbsolutePathBuffer { names: vec![] }; - tcx.push_item_path(&mut apb, def_id); + tcx.push_item_path(&mut apb, def_id, false); apb.names.len() == path.len() && apb.names diff --git a/src/driver.rs b/src/driver.rs index 99f8bc610ff..6c442e42d95 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -21,6 +21,7 @@ fn show_version() { } pub fn main() { + rustc_driver::init_rustc_env_logger(); exit(rustc_driver::run(move || { use std::env; diff --git a/tests/ui/format.rs b/tests/ui/format.rs index 8f31d92ac3c..858c9fc8de5 100644 --- a/tests/ui/format.rs +++ b/tests/ui/format.rs @@ -14,6 +14,7 @@ fn main() { format!("{}", "foo"); format!("{:?}", "foo"); // don't warn about debug format!("{:8}", "foo"); + format!("{:width$}", "foo", width = 8); format!("{:+}", "foo"); // warn when the format makes no difference format!("{:<}", "foo"); // warn when the format makes no difference format!("foo {}", "bar"); @@ -23,6 +24,7 @@ fn main() { format!("{}", arg); format!("{:?}", arg); // don't warn about debug format!("{:8}", arg); + format!("{:width$}", arg, width = 8); format!("{:+}", arg); // warn when the format makes no difference format!("{:<}", arg); // warn when the format makes no difference format!("foo {}", arg); @@ -44,4 +46,14 @@ fn main() { // A format! inside a macro should not trigger a warning foo!("should not warn"); + + // precision on string means slicing without panicking on size: + format!("{:.1}", "foo"); // could be "foo"[..1] + format!("{:.10}", "foo"); // could not be "foo"[..10] + format!("{:.prec$}", "foo", prec = 1); + format!("{:.prec$}", "foo", prec = 10); + + format!("{}", 42.to_string()); + let x = std::path::PathBuf::from("/bar/foo/qux"); + format!("{}", x.display().to_string()); } diff --git a/tests/ui/format.stderr b/tests/ui/format.stderr index ca6ef905396..520c1b79433 100644 --- a/tests/ui/format.stderr +++ b/tests/ui/format.stderr @@ -15,44 +15,60 @@ error: useless use of `format!` = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: useless use of `format!` - --> $DIR/format.rs:17:5 + --> $DIR/format.rs:18:5 | -17 | format!("{:+}", "foo"); // warn when the format makes no difference +18 | format!("{:+}", "foo"); // warn when the format makes no difference | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `"foo".to_string()` | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: useless use of `format!` - --> $DIR/format.rs:18:5 + --> $DIR/format.rs:19:5 | -18 | format!("{:<}", "foo"); // warn when the format makes no difference +19 | format!("{:<}", "foo"); // warn when the format makes no difference | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `"foo".to_string()` | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: useless use of `format!` - --> $DIR/format.rs:23:5 + --> $DIR/format.rs:24:5 | -23 | format!("{}", arg); +24 | format!("{}", arg); | ^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `arg.to_string()` | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: useless use of `format!` - --> $DIR/format.rs:26:5 + --> $DIR/format.rs:28:5 | -26 | format!("{:+}", arg); // warn when the format makes no difference +28 | format!("{:+}", arg); // warn when the format makes no difference | ^^^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `arg.to_string()` | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: useless use of `format!` - --> $DIR/format.rs:27:5 + --> $DIR/format.rs:29:5 | -27 | format!("{:<}", arg); // warn when the format makes no difference +29 | format!("{:<}", arg); // warn when the format makes no difference | ^^^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `arg.to_string()` | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) -error: aborting due to 7 previous errors +error: useless use of `format!` + --> $DIR/format.rs:56:5 + | +56 | format!("{}", 42.to_string()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `to_string()` is enough: `42.to_string()` + | + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +error: useless use of `format!` + --> $DIR/format.rs:58:5 + | +58 | format!("{}", x.display().to_string()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `to_string()` is enough: `x.display().to_string()` + | + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +error: aborting due to 9 previous errors diff --git a/tests/ui/wrong_self_convention.rs b/tests/ui/wrong_self_convention.rs index 1e718c1c648..2fb33d08619 100644 --- a/tests/ui/wrong_self_convention.rs +++ b/tests/ui/wrong_self_convention.rs @@ -59,4 +59,5 @@ impl Bar { fn is_(self) {} fn to_(self) {} fn from_(self) {} + fn to_mut(&mut self) {} } |
