Skip to content

Commit 1544a1a

Browse files
committed
Merge remote-tracking branch 'origin/master' into relicense-rewrite
2 parents 8b3d207 + eb2cfe6 commit 1544a1a

File tree

8 files changed

+79
-35
lines changed

8 files changed

+79
-35
lines changed

.travis.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,9 @@ script:
5757
export LD_LIBRARY_PATH=$(rustc --print sysroot)/lib
5858
- |
5959
if [ -z ${INTEGRATION} ]; then
60-
./ci/base-tests.sh
61-
sleep 5
60+
./ci/base-tests.sh && sleep 5
6261
else
63-
./ci/integration-tests.sh
64-
sleep 5
62+
./ci/integration-tests.sh && sleep 5
6563
fi
6664
6765
after_success: |

clippy_lints/src/format.rs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use crate::rustc::{declare_tool_lint, lint_array};
44
use if_chain::if_chain;
55
use crate::rustc::ty;
66
use crate::syntax::ast::LitKind;
7-
use crate::syntax_pos::Span;
87
use crate::utils::paths;
98
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};
109
use crate::rustc_errors::Applicability;
@@ -47,7 +46,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
4746
return;
4847
}
4948
match expr.node {
50-
5149
// `format!("{}", foo)` expansion
5250
ExprKind::Call(ref fun, ref args) => {
5351
if_chain! {
@@ -58,12 +56,24 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
5856
if check_single_piece(&args[0]);
5957
if let Some(format_arg) = get_single_string_arg(cx, &args[1]);
6058
if check_unformatted(&args[2]);
59+
if let ExprKind::AddrOf(_, ref format_arg) = format_arg.node;
6160
then {
62-
let sugg = format!("{}.to_string()", snippet(cx, format_arg, "<arg>").into_owned());
61+
let (message, sugg) = if_chain! {
62+
if let ExprKind::MethodCall(ref path, _, _) = format_arg.node;
63+
if path.ident.as_interned_str() == "to_string";
64+
then {
65+
("`to_string()` is enough",
66+
snippet(cx, format_arg.span, "<arg>").to_string())
67+
} else {
68+
("consider using .to_string()",
69+
format!("{}.to_string()", snippet(cx, format_arg.span, "<arg>")))
70+
}
71+
};
72+
6373
span_lint_and_then(cx, USELESS_FORMAT, span, "useless use of `format!`", |db| {
6474
db.span_suggestion_with_applicability(
6575
expr.span,
66-
"consider using .to_string()",
76+
message,
6777
sugg,
6878
Applicability::MachineApplicable,
6979
);
@@ -114,9 +124,9 @@ fn check_single_piece(expr: &Expr) -> bool {
114124
/// ::std::fmt::Display::fmt)],
115125
/// }
116126
/// ```
117-
/// and that type of `__arg0` is `&str` or `String`
118-
/// then returns the span of first element of the matched tuple
119-
fn get_single_string_arg(cx: &LateContext<'_, '_>, expr: &Expr) -> Option<Span> {
127+
/// and that the type of `__arg0` is `&str` or `String`,
128+
/// then returns the span of first element of the matched tuple.
129+
fn get_single_string_arg<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr) -> Option<&'a Expr> {
120130
if_chain! {
121131
if let ExprKind::AddrOf(_, ref expr) = expr.node;
122132
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>
135145
let ty = walk_ptrs_ty(cx.tables.pat_ty(&pat[0]));
136146
if ty.sty == ty::Str || match_type(cx, ty, &paths::STRING) {
137147
if let ExprKind::Tup(ref values) = match_expr.node {
138-
return Some(values[0].span);
148+
return Some(&values[0]);
139149
}
140150
}
141151
}
@@ -162,9 +172,12 @@ fn check_unformatted(expr: &Expr) -> bool {
162172
if let ExprKind::Struct(_, ref fields, _) = exprs[0].node;
163173
if let Some(format_field) = fields.iter().find(|f| f.ident.name == "format");
164174
if let ExprKind::Struct(_, ref fields, _) = format_field.expr.node;
165-
if let Some(align_field) = fields.iter().find(|f| f.ident.name == "width");
166-
if let ExprKind::Path(ref qpath) = align_field.expr.node;
167-
if last_path_segment(qpath).ident.name == "Implied";
175+
if let Some(width_field) = fields.iter().find(|f| f.ident.name == "width");
176+
if let ExprKind::Path(ref width_qpath) = width_field.expr.node;
177+
if last_path_segment(width_qpath).ident.name == "Implied";
178+
if let Some(precision_field) = fields.iter().find(|f| f.ident.name == "precision");
179+
if let ExprKind::Path(ref precision_path) = precision_field.expr.node;
180+
if last_path_segment(precision_path).ident.name == "Implied";
168181
then {
169182
return true;
170183
}

clippy_lints/src/methods/mod.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -882,12 +882,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
882882
let ty = cx.tcx.type_of(def_id);
883883
let is_copy = is_copy(cx, ty);
884884
for &(ref conv, self_kinds) in &CONVENTIONS {
885-
if_chain! {
886-
if conv.check(&name.as_str());
885+
if conv.check(&name.as_str()) {
887886
if !self_kinds
888-
.iter()
889-
.any(|k| k.matches(cx, first_arg_ty, first_arg, self_ty, is_copy, &implitem.generics));
890-
then {
887+
.iter()
888+
.any(|k| k.matches(cx, first_arg_ty, first_arg, self_ty, is_copy, &implitem.generics)) {
891889
let lint = if item.vis.node.is_pub() {
892890
WRONG_PUB_SELF_CONVENTION
893891
} else {
@@ -904,6 +902,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
904902
.collect::<Vec<_>>()
905903
.join(" or ")));
906904
}
905+
906+
// Only check the first convention to match (CONVENTIONS should be listed from most to least specific)
907+
break;
907908
}
908909
}
909910

@@ -1183,8 +1184,8 @@ fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr, arg: &hir::Exp
11831184
Applicability::MaybeIncorrect,
11841185
);
11851186
db.span_suggestion_with_applicability(
1186-
expr.span,
1187-
"or try being explicit about what type to clone",
1187+
expr.span,
1188+
"or try being explicit about what type to clone",
11881189
explicit,
11891190
Applicability::MaybeIncorrect,
11901191
);
@@ -2067,12 +2068,13 @@ enum Convention {
20672068
}
20682069

20692070
#[rustfmt::skip]
2070-
const CONVENTIONS: [(Convention, &[SelfKind]); 6] = [
2071+
const CONVENTIONS: [(Convention, &[SelfKind]); 7] = [
20712072
(Convention::Eq("new"), &[SelfKind::No]),
20722073
(Convention::StartsWith("as_"), &[SelfKind::Ref, SelfKind::RefMut]),
20732074
(Convention::StartsWith("from_"), &[SelfKind::No]),
20742075
(Convention::StartsWith("into_"), &[SelfKind::Value]),
20752076
(Convention::StartsWith("is_"), &[SelfKind::Ref, SelfKind::No]),
2077+
(Convention::Eq("to_mut"), &[SelfKind::RefMut]),
20762078
(Convention::StartsWith("to_"), &[SelfKind::Ref]),
20772079
];
20782080

clippy_lints/src/utils/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub fn in_macro(span: Span) -> bool {
7272
pub fn match_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, path: &[&str]) -> bool {
7373
use crate::syntax::symbol;
7474

75+
#[derive(Debug)]
7576
struct AbsolutePathBuffer {
7677
names: Vec<symbol::LocalInternedString>,
7778
}
@@ -89,7 +90,7 @@ pub fn match_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, path: &[&str]) ->
8990

9091
let mut apb = AbsolutePathBuffer { names: vec![] };
9192

92-
tcx.push_item_path(&mut apb, def_id);
93+
tcx.push_item_path(&mut apb, def_id, false);
9394

9495
apb.names.len() == path.len()
9596
&& apb.names

src/driver.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ fn show_version() {
2121
}
2222

2323
pub fn main() {
24+
rustc_driver::init_rustc_env_logger();
2425
exit(rustc_driver::run(move || {
2526
use std::env;
2627

tests/ui/format.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ fn main() {
1414
format!("{}", "foo");
1515
format!("{:?}", "foo"); // don't warn about debug
1616
format!("{:8}", "foo");
17+
format!("{:width$}", "foo", width = 8);
1718
format!("{:+}", "foo"); // warn when the format makes no difference
1819
format!("{:<}", "foo"); // warn when the format makes no difference
1920
format!("foo {}", "bar");
@@ -23,6 +24,7 @@ fn main() {
2324
format!("{}", arg);
2425
format!("{:?}", arg); // don't warn about debug
2526
format!("{:8}", arg);
27+
format!("{:width$}", arg, width = 8);
2628
format!("{:+}", arg); // warn when the format makes no difference
2729
format!("{:<}", arg); // warn when the format makes no difference
2830
format!("foo {}", arg);
@@ -44,4 +46,14 @@ fn main() {
4446

4547
// A format! inside a macro should not trigger a warning
4648
foo!("should not warn");
49+
50+
// precision on string means slicing without panicking on size:
51+
format!("{:.1}", "foo"); // could be "foo"[..1]
52+
format!("{:.10}", "foo"); // could not be "foo"[..10]
53+
format!("{:.prec$}", "foo", prec = 1);
54+
format!("{:.prec$}", "foo", prec = 10);
55+
56+
format!("{}", 42.to_string());
57+
let x = std::path::PathBuf::from("/bar/foo/qux");
58+
format!("{}", x.display().to_string());
4759
}

tests/ui/format.stderr

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,44 +15,60 @@ error: useless use of `format!`
1515
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
1616

1717
error: useless use of `format!`
18-
--> $DIR/format.rs:17:5
18+
--> $DIR/format.rs:18:5
1919
|
20-
17 | format!("{:+}", "foo"); // warn when the format makes no difference
20+
18 | format!("{:+}", "foo"); // warn when the format makes no difference
2121
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `"foo".to_string()`
2222
|
2323
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
2424

2525
error: useless use of `format!`
26-
--> $DIR/format.rs:18:5
26+
--> $DIR/format.rs:19:5
2727
|
28-
18 | format!("{:<}", "foo"); // warn when the format makes no difference
28+
19 | format!("{:<}", "foo"); // warn when the format makes no difference
2929
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `"foo".to_string()`
3030
|
3131
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
3232

3333
error: useless use of `format!`
34-
--> $DIR/format.rs:23:5
34+
--> $DIR/format.rs:24:5
3535
|
36-
23 | format!("{}", arg);
36+
24 | format!("{}", arg);
3737
| ^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `arg.to_string()`
3838
|
3939
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
4040

4141
error: useless use of `format!`
42-
--> $DIR/format.rs:26:5
42+
--> $DIR/format.rs:28:5
4343
|
44-
26 | format!("{:+}", arg); // warn when the format makes no difference
44+
28 | format!("{:+}", arg); // warn when the format makes no difference
4545
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `arg.to_string()`
4646
|
4747
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
4848

4949
error: useless use of `format!`
50-
--> $DIR/format.rs:27:5
50+
--> $DIR/format.rs:29:5
5151
|
52-
27 | format!("{:<}", arg); // warn when the format makes no difference
52+
29 | format!("{:<}", arg); // warn when the format makes no difference
5353
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `arg.to_string()`
5454
|
5555
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
5656

57-
error: aborting due to 7 previous errors
57+
error: useless use of `format!`
58+
--> $DIR/format.rs:56:5
59+
|
60+
56 | format!("{}", 42.to_string());
61+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `to_string()` is enough: `42.to_string()`
62+
|
63+
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
64+
65+
error: useless use of `format!`
66+
--> $DIR/format.rs:58:5
67+
|
68+
58 | format!("{}", x.display().to_string());
69+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `to_string()` is enough: `x.display().to_string()`
70+
|
71+
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
72+
73+
error: aborting due to 9 previous errors
5874

tests/ui/wrong_self_convention.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,5 @@ impl Bar {
5959
fn is_(self) {}
6060
fn to_(self) {}
6161
fn from_(self) {}
62+
fn to_mut(&mut self) {}
6263
}

0 commit comments

Comments
 (0)