Skip to content

Commit 1153b93

Browse files
committed
Update clippy
1 parent af96441 commit 1153b93

29 files changed

+604
-62
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
dist: xenial
2-
language: minimal
2+
language: bash
33

44
os:
55
- linux

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,7 @@ Released 2018-09-13
10331033
[`inconsistent_digit_grouping`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_digit_grouping
10341034
[`indexing_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing
10351035
[`ineffective_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#ineffective_bit_mask
1036+
[`inefficient_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#inefficient_to_string
10361037
[`infallible_destructuring_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#infallible_destructuring_match
10371038
[`infinite_iter`]: https://rust-lang.github.io/rust-clippy/master/index.html#infinite_iter
10381039
[`inherent_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#inherent_to_string
@@ -1128,6 +1129,7 @@ Released 2018-09-13
11281129
[`ok_expect`]: https://rust-lang.github.io/rust-clippy/master/index.html#ok_expect
11291130
[`op_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#op_ref
11301131
[`option_and_then_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_and_then_some
1132+
[`option_expect_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_expect_used
11311133
[`option_map_or_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_or_none
11321134
[`option_map_unit_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unit_fn
11331135
[`option_map_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unwrap_or
@@ -1137,6 +1139,7 @@ Released 2018-09-13
11371139
[`or_fun_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#or_fun_call
11381140
[`out_of_bounds_indexing`]: https://rust-lang.github.io/rust-clippy/master/index.html#out_of_bounds_indexing
11391141
[`overflow_check_conditional`]: https://rust-lang.github.io/rust-clippy/master/index.html#overflow_check_conditional
1142+
[`panic`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic
11401143
[`panic_params`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic_params
11411144
[`panicking_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#panicking_unwrap
11421145
[`partialeq_ne_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_ne_impl
@@ -1166,6 +1169,7 @@ Released 2018-09-13
11661169
[`ref_in_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_in_deref
11671170
[`regex_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#regex_macro
11681171
[`replace_consts`]: https://rust-lang.github.io/rust-clippy/master/index.html#replace_consts
1172+
[`result_expect_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_expect_used
11691173
[`result_map_unit_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_map_unit_fn
11701174
[`result_map_unwrap_or_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_map_unwrap_or_else
11711175
[`result_unwrap_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_unwrap_used
@@ -1197,6 +1201,7 @@ Released 2018-09-13
11971201
[`suspicious_unary_op_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_unary_op_formatting
11981202
[`temporary_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#temporary_assignment
11991203
[`temporary_cstring_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#temporary_cstring_as_ptr
1204+
[`todo`]: https://rust-lang.github.io/rust-clippy/master/index.html#todo
12001205
[`too_many_arguments`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments
12011206
[`too_many_lines`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines
12021207
[`toplevel_ref_arg`]: https://rust-lang.github.io/rust-clippy/master/index.html#toplevel_ref_arg
@@ -1226,6 +1231,7 @@ Released 2018-09-13
12261231
[`unnecessary_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap
12271232
[`unneeded_field_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_field_pattern
12281233
[`unneeded_wildcard_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_wildcard_pattern
1234+
[`unreachable`]: https://rust-lang.github.io/rust-clippy/master/index.html#unreachable
12291235
[`unreadable_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#unreadable_literal
12301236
[`unsafe_removed_from_name`]: https://rust-lang.github.io/rust-clippy/master/index.html#unsafe_removed_from_name
12311237
[`unsafe_vector_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#unsafe_vector_initialization

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
88

9-
[There are 325 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
9+
[There are 331 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
1010

1111
We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:
1212

appveyor.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ branches:
1515

1616
cache:
1717
- '%USERPROFILE%\.cargo'
18-
on_finish:
18+
after_test:
1919
- cargo install -Z install-upgrade cargo-cache --debug
2020
- cargo cache --autoclean
2121

@@ -24,7 +24,7 @@ install:
2424
- rustup-init.exe -y --default-host %TARGET% --default-toolchain nightly --profile=minimal
2525
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
2626
- del rust-toolchain
27-
- cargo install -Z install-upgrade rustup-toolchain-install-master --debug || echo "rustup-toolchain-install-master already installed"
27+
- cargo install -Z install-upgrade rustup-toolchain-install-master
2828
- rustup-toolchain-install-master -f -n master
2929
- rustup component add rustfmt --toolchain nightly & exit 0 # Format test handles missing rustfmt
3030
- rustup default master

clippy_lints/src/functions.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::utils::{
2-
iter_input_pats, match_def_path, qpath_res, return_ty, snippet, snippet_opt, span_help_and_lint, span_lint,
3-
span_lint_and_then, type_is_unsafe_function,
2+
attrs::is_proc_macro, iter_input_pats, match_def_path, qpath_res, return_ty, snippet, snippet_opt,
3+
span_help_and_lint, span_lint, span_lint_and_then, type_is_unsafe_function,
44
};
55
use matches::matches;
66
use rustc::hir::{self, def::Res, def_id::DefId, intravisit};
@@ -234,7 +234,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
234234
check_needless_must_use(cx, decl, item.hir_id, item.span, fn_header_span, attr);
235235
return;
236236
}
237-
if cx.access_levels.is_exported(item.hir_id) {
237+
if cx.access_levels.is_exported(item.hir_id) && !is_proc_macro(&item.attrs) {
238238
check_must_use_candidate(
239239
cx,
240240
decl,
@@ -254,7 +254,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
254254
if let Some(attr) = attr {
255255
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
256256
check_needless_must_use(cx, &sig.decl, item.hir_id, item.span, fn_header_span, attr);
257-
} else if cx.access_levels.is_exported(item.hir_id) {
257+
} else if cx.access_levels.is_exported(item.hir_id) && !is_proc_macro(&item.attrs) {
258258
check_must_use_candidate(
259259
cx,
260260
&sig.decl,
@@ -284,7 +284,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
284284
let body = cx.tcx.hir().body(eid);
285285
Self::check_raw_ptr(cx, sig.header.unsafety, &sig.decl, body, item.hir_id);
286286

287-
if attr.is_none() && cx.access_levels.is_exported(item.hir_id) {
287+
if attr.is_none() && cx.access_levels.is_exported(item.hir_id) && !is_proc_macro(&item.attrs) {
288288
check_must_use_candidate(
289289
cx,
290290
&sig.decl,
@@ -493,7 +493,7 @@ fn is_must_use_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
493493
},
494494
Tuple(ref substs) => substs.types().any(|ty| is_must_use_ty(cx, ty)),
495495
Opaque(ref def_id, _) => {
496-
for (predicate, _) in &cx.tcx.predicates_of(*def_id).predicates {
496+
for (predicate, _) in cx.tcx.predicates_of(*def_id).predicates {
497497
if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate {
498498
if must_use_attr(&cx.tcx.get_attrs(poly_trait_predicate.skip_binder().trait_ref.def_id)).is_some() {
499499
return true;

clippy_lints/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,13 +625,18 @@ pub fn register_plugins(reg: &mut rustc_driver::plugin::Registry<'_>, conf: &Con
625625
mem_forget::MEM_FORGET,
626626
methods::CLONE_ON_REF_PTR,
627627
methods::GET_UNWRAP,
628+
methods::OPTION_EXPECT_USED,
628629
methods::OPTION_UNWRAP_USED,
630+
methods::RESULT_EXPECT_USED,
629631
methods::RESULT_UNWRAP_USED,
630632
methods::WRONG_PUB_SELF_CONVENTION,
631633
misc::FLOAT_CMP_CONST,
632634
missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS,
633635
missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS,
636+
panic_unimplemented::PANIC,
637+
panic_unimplemented::TODO,
634638
panic_unimplemented::UNIMPLEMENTED,
639+
panic_unimplemented::UNREACHABLE,
635640
shadow::SHADOW_REUSE,
636641
shadow::SHADOW_SAME,
637642
strings::STRING_ADD,
@@ -808,6 +813,7 @@ pub fn register_plugins(reg: &mut rustc_driver::plugin::Registry<'_>, conf: &Con
808813
methods::EXPECT_FUN_CALL,
809814
methods::FILTER_NEXT,
810815
methods::FLAT_MAP_IDENTITY,
816+
methods::INEFFICIENT_TO_STRING,
811817
methods::INTO_ITER_ON_ARRAY,
812818
methods::INTO_ITER_ON_REF,
813819
methods::ITER_CLONED_COLLECT,
@@ -1184,6 +1190,7 @@ pub fn register_plugins(reg: &mut rustc_driver::plugin::Registry<'_>, conf: &Con
11841190
loops::MANUAL_MEMCPY,
11851191
loops::NEEDLESS_COLLECT,
11861192
methods::EXPECT_FUN_CALL,
1193+
methods::INEFFICIENT_TO_STRING,
11871194
methods::ITER_NTH,
11881195
methods::OR_FUN_CALL,
11891196
methods::SINGLE_CHAR_PATTERN,
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use super::INEFFICIENT_TO_STRING;
2+
use crate::utils::{match_def_path, paths, snippet_with_applicability, span_lint_and_then, walk_ptrs_ty_depth};
3+
use if_chain::if_chain;
4+
use rustc::hir;
5+
use rustc::lint::LateContext;
6+
use rustc::ty::{self, Ty};
7+
use rustc_errors::Applicability;
8+
9+
/// Checks for the `INEFFICIENT_TO_STRING` lint
10+
pub fn lint<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &hir::Expr, arg: &hir::Expr, arg_ty: Ty<'tcx>) {
11+
if_chain! {
12+
if let Some(to_string_meth_did) = cx.tables.type_dependent_def_id(expr.hir_id);
13+
if match_def_path(cx, to_string_meth_did, &paths::TO_STRING_METHOD);
14+
if let Some(substs) = cx.tables.node_substs_opt(expr.hir_id);
15+
let self_ty = substs.type_at(0);
16+
let (deref_self_ty, deref_count) = walk_ptrs_ty_depth(self_ty);
17+
if deref_count >= 1;
18+
if specializes_tostring(cx, deref_self_ty);
19+
then {
20+
span_lint_and_then(
21+
cx,
22+
INEFFICIENT_TO_STRING,
23+
expr.span,
24+
&format!("calling `to_string` on `{}`", arg_ty),
25+
|db| {
26+
db.help(&format!(
27+
"`{}` implements `ToString` through a slower blanket impl, but `{}` has a fast specialization of `ToString`",
28+
self_ty, deref_self_ty
29+
));
30+
let mut applicability = Applicability::MachineApplicable;
31+
let arg_snippet = snippet_with_applicability(cx, arg.span, "..", &mut applicability);
32+
db.span_suggestion(
33+
expr.span,
34+
"try dereferencing the receiver",
35+
format!("({}{}).to_string()", "*".repeat(deref_count), arg_snippet),
36+
applicability,
37+
);
38+
},
39+
);
40+
}
41+
}
42+
}
43+
44+
/// Returns whether `ty` specializes `ToString`.
45+
/// Currently, these are `str`, `String`, and `Cow<'_, str>`.
46+
fn specializes_tostring(cx: &LateContext<'_, '_>, ty: Ty<'_>) -> bool {
47+
match ty.kind {
48+
ty::Str => true,
49+
ty::Adt(adt, substs) => {
50+
match_def_path(cx, adt.did, &paths::STRING)
51+
|| (match_def_path(cx, adt.did, &paths::COW) && substs.type_at(1).is_str())
52+
},
53+
_ => false,
54+
}
55+
}

0 commit comments

Comments
 (0)