Skip to content

Commit 6ee0e22

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 65c3533 + f7bdf50 commit 6ee0e22

File tree

265 files changed

+5099
-5054
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

265 files changed

+5099
-5054
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,7 @@ All notable changes to this project will be documented in this file.
760760
[`mistyped_literal_suffixes`]: https://rust-lang.github.io/rust-clippy/master/index.html#mistyped_literal_suffixes
761761
[`mixed_case_hex_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_case_hex_literals
762762
[`module_inception`]: https://rust-lang.github.io/rust-clippy/master/index.html#module_inception
763+
[`module_name_repetitions`]: https://rust-lang.github.io/rust-clippy/master/index.html#module_name_repetitions
763764
[`modulo_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#modulo_one
764765
[`multiple_crate_versions`]: https://rust-lang.github.io/rust-clippy/master/index.html#multiple_crate_versions
765766
[`multiple_inherent_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#multiple_inherent_impl
@@ -850,7 +851,6 @@ All notable changes to this project will be documented in this file.
850851
[`string_extend_chars`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_extend_chars
851852
[`string_lit_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_lit_as_bytes
852853
[`string_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_to_string
853-
[`stutter`]: https://rust-lang.github.io/rust-clippy/master/index.html#stutter
854854
[`suspicious_arithmetic_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_arithmetic_impl
855855
[`suspicious_assignment_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_assignment_formatting
856856
[`suspicious_else_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_else_formatting

CONTRIBUTING.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ All contributors are expected to follow the [Rust Code of Conduct](http://www.ru
1919
* [Running test suite](#running-test-suite)
2020
* [Running rustfmt](#running-rustfmt)
2121
* [Testing manually](#testing-manually)
22-
* [How Clippy works](#how-clippy-works)
23-
* [Fixing nightly build failures](#fixing-build-failures-caused-by-rust)
22+
* [How Clippy works](#how-clippy-works)
23+
* [Fixing nightly build failures](#fixing-build-failures-caused-by-rust)
2424
* [Issue and PR Triage](#issue-and-pr-triage)
2525
* [Bors and Homu](#bors-and-homu)
2626
* [Contributions](#contributions)
@@ -42,6 +42,13 @@ Some issues are easier than others. The [`good first issue`](https://github.com/
4242
label can be used to find the easy issues. If you want to work on an issue, please leave a comment
4343
so that we can assign it to you!
4444

45+
There are also some abandoned PRs, marked with
46+
[`S-inactive-closed`](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Aclosed+label%3AS-inactive-closed).
47+
Pretty often these PRs are nearly completed and just need some extra steps
48+
(formatting, addressing review comments, ...) to be merged. If you want to
49+
complete such a PR, please leave a comment in the PR and open a new one based
50+
on it.
51+
4552
Issues marked [`T-AST`](https://github.com/rust-lang/rust-clippy/labels/T-AST) involve simple
4653
matching of the syntax tree structure, and are generally easier than
4754
[`T-middle`](https://github.com/rust-lang/rust-clippy/labels/T-middle) issues, which involve types
@@ -168,7 +175,7 @@ Manually testing against an example file is useful if you have added some
168175
local modifications, run `env CLIPPY_TESTS=true cargo run --bin clippy-driver -- -L ./target/debug input.rs`
169176
from the working copy root.
170177

171-
### How Clippy works
178+
## How Clippy works
172179

173180
Clippy is a [rustc compiler plugin][compiler_plugin]. The main entry point is at [`src/lib.rs`][main_entry]. In there, the lint registration is delegated to the [`clippy_lints`][lint_crate] crate.
174181

@@ -218,7 +225,7 @@ The difference between `EarlyLintPass` and `LateLintPass` is that the methods of
218225

219226
That's why the `else_if_without_else` example uses the `register_early_lint_pass` function. Because the [actual lint logic][else_if_without_else] does not depend on any type information.
220227

221-
### Fixing build failures caused by Rust
228+
## Fixing build failures caused by Rust
222229

223230
Clippy will sometimes fail to build from source because building it depends on unstable internal Rust features. Most of the times we have to adapt to the changes and only very rarely there's an actual bug in Rust. Fixing build failures caused by Rust updates, can be a good way to learn about Rust internals.
224231

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ To have cargo compile your crate with Clippy without Clippy installation
7979
in your code, you can use:
8080

8181
```terminal
82-
cargo run --bin cargo-clippy --manifest-path=path_to_clippys_Cargo.toml
82+
RUSTFLAGS=--sysroot=`rustc --print sysroot` cargo run --bin cargo-clippy --manifest-path=path_to_clippys_Cargo.toml
8383
```
8484

8585
*[Note](https://github.com/rust-lang/rust-clippy/wiki#a-word-of-warning):*
@@ -151,6 +151,10 @@ Note: `deny` produces errors instead of warnings.
151151

152152
If you do not want to include your lint levels in your code, you can globally enable/disable lints by passing extra flags to Clippy during the run: `cargo clippy -- -A clippy::lint_name` will run Clippy with `lint_name` disabled and `cargo clippy -- -W clippy::lint_name` will run it with that enabled. This also works with lint groups. For example you can run Clippy with warnings for all lints enabled: `cargo clippy -- -W clippy::pedantic`
153153

154+
## Contributing
155+
156+
If you want to contribute to Clippy, you can find more information in [CONTRIBUTING.md](https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md).
157+
154158
## License
155159

156160
Copyright 2014-2018 The Rust Project Developers

ci/base-tests.sh

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,38 @@ cd clippy_lints && cargo test && cd ..
2626
cd rustc_tools_util && cargo test && cd ..
2727
cd clippy_dev && cargo test && cd ..
2828

29+
# make sure clippy can be called via ./path/to/cargo-clippy
30+
cd clippy_workspace_tests
31+
../target/debug/cargo-clippy
32+
cd ..
33+
2934
# Perform various checks for lint registration
3035
./util/dev update_lints --check
3136
cargo +nightly fmt --all -- --check
3237

33-
34-
#avoid loop spam
35-
set +x
3638
# make sure tests are formatted
3739

3840
# some lints are sensitive to formatting, exclude some files
39-
needs_formatting=false
41+
tests_need_reformatting="false"
42+
# switch to nightly
43+
rustup default nightly
44+
# avoid loop spam and allow cmds with exit status != 0
45+
set +ex
46+
4047
for file in `find tests -not -path "tests/ui/methods.rs" -not -path "tests/ui/format.rs" -not -path "tests/ui/formatting.rs" -not -path "tests/ui/empty_line_after_outer_attribute.rs" -not -path "tests/ui/double_parens.rs" -not -path "tests/ui/doc.rs" -not -path "tests/ui/unused_unit.rs" | grep "\.rs$"` ; do
41-
rustfmt ${file} --check || echo "${file} needs reformatting!" ; needs_formatting=true
48+
rustfmt ${file} --check
49+
if [ $? -ne 0 ]; then
50+
echo "${file} needs reformatting!"
51+
tests_need_reformatting="true"
52+
fi
4253
done
4354

44-
if [ "${needs_reformatting}" = true ] ; then
55+
set -ex # reset
56+
57+
if [ "${tests_need_reformatting}" == "true" ] ; then
4558
echo "Tests need reformatting!"
4659
exit 2
4760
fi
48-
set -x
61+
62+
# switch back to master
63+
rustup default master

ci/integration-tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function check() {
2121
# run clippy on a project, try to be verbose and trigger as many warnings as possible for greater coverage
2222
RUST_BACKTRACE=full cargo clippy --all-targets --all-features -- --cap-lints warn -W clippy::pedantic -W clippy::nursery &> clippy_output
2323
cat clippy_output
24-
! cat clippy_output | grep -q "internal compiler error\|query stack during panic"
24+
! cat clippy_output | grep -q "internal compiler error\|query stack during panic\|E0463"
2525
if [[ $? != 0 ]]; then
2626
return 1
2727
fi

clippy_dev/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ fn test_gen_deprecated() {
432432
"should_assert_eq",
433433
"group1",
434434
"abc",
435-
Some("has been superseeded by should_assert_eq2"),
435+
Some("has been superseded by should_assert_eq2"),
436436
"module_name",
437437
),
438438
Lint::new(
@@ -447,7 +447,7 @@ fn test_gen_deprecated() {
447447
let expected: Vec<String> = vec![
448448
" store.register_removed(",
449449
" \"should_assert_eq\",",
450-
" \"has been superseeded by should_assert_eq2\",",
450+
" \"has been superseded by should_assert_eq2\",",
451451
" );",
452452
" store.register_removed(",
453453
" \"another_deprecated\",",

clippy_lints/src/attrs.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,9 @@ fn check_clippy_lint_names(cx: &LateContext<'_, '_>, items: &[NestedMetaItem]) {
337337
&name_lower,
338338
Some(tool_name.as_str())
339339
) {
340-
CheckLintNameResult::NoLint => (),
340+
// FIXME: can we suggest similar lint names here?
341+
// https://github.com/rust-lang/rust/pull/56992
342+
CheckLintNameResult::NoLint(None) => (),
341343
_ => {
342344
db.span_suggestion(lint.span,
343345
"lowercase the lint name",

clippy_lints/src/double_comparison.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::syntax::source_map::Span;
1717

1818
use crate::utils::{snippet_with_applicability, span_lint_and_sugg, SpanlessEq};
1919

20-
/// **What it does:** Checks for double comparions that could be simpified to a single expression.
20+
/// **What it does:** Checks for double comparions that could be simplified to a single expression.
2121
///
2222
///
2323
/// **Why is this bad?** Readability.

clippy_lints/src/enum_variants.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ declare_clippy_lint! {
7575
/// }
7676
/// ```
7777
declare_clippy_lint! {
78-
pub STUTTER,
78+
pub MODULE_NAME_REPETITIONS,
7979
pedantic,
8080
"type names prefixed/postfixed with their containing module's name"
8181
}
@@ -126,7 +126,12 @@ impl EnumVariantNames {
126126

127127
impl LintPass for EnumVariantNames {
128128
fn get_lints(&self) -> LintArray {
129-
lint_array!(ENUM_VARIANT_NAMES, PUB_ENUM_VARIANT_NAMES, STUTTER, MODULE_INCEPTION)
129+
lint_array!(
130+
ENUM_VARIANT_NAMES,
131+
PUB_ENUM_VARIANT_NAMES,
132+
MODULE_NAME_REPETITIONS,
133+
MODULE_INCEPTION
134+
)
130135
}
131136
}
132137

@@ -277,7 +282,7 @@ impl EarlyLintPass for EnumVariantNames {
277282
match item_camel.chars().nth(nchars) {
278283
Some(c) if is_word_beginning(c) => span_lint(
279284
cx,
280-
STUTTER,
285+
MODULE_NAME_REPETITIONS,
281286
item.span,
282287
"item name starts with its containing module's name",
283288
),
@@ -287,7 +292,7 @@ impl EarlyLintPass for EnumVariantNames {
287292
if rmatching == nchars {
288293
span_lint(
289294
cx,
290-
STUTTER,
295+
MODULE_NAME_REPETITIONS,
291296
item.span,
292297
"item name ends with its containing module's name",
293298
);

clippy_lints/src/formatting.rs

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ declare_clippy_lint! {
3131
"suspicious formatting of `*=`, `-=` or `!=`"
3232
}
3333

34-
/// **What it does:** Checks for formatting of `else if`. It lints if the `else`
35-
/// and `if` are not on the same line or the `else` seems to be missing.
34+
/// **What it does:** Checks for formatting of `else`. It lints if the `else`
35+
/// is followed immediately by a newline or the `else` seems to be missing.
3636
///
3737
/// **Why is this bad?** This is probably some refactoring remnant, even if the
3838
/// code is correct, it might look confusing.
@@ -42,19 +42,29 @@ declare_clippy_lint! {
4242
/// **Example:**
4343
/// ```rust,ignore
4444
/// if foo {
45+
/// } { // looks like an `else` is missing here
46+
/// }
47+
///
48+
/// if foo {
4549
/// } if bar { // looks like an `else` is missing here
4650
/// }
4751
///
4852
/// if foo {
4953
/// } else
5054
///
55+
/// { // this is the `else` block of the previous `if`, but should it be?
56+
/// }
57+
///
58+
/// if foo {
59+
/// } else
60+
///
5161
/// if bar { // this is the `else` block of the previous `if`, but should it be?
5262
/// }
5363
/// ```
5464
declare_clippy_lint! {
5565
pub SUSPICIOUS_ELSE_FORMATTING,
5666
style,
57-
"suspicious formatting of `else if`"
67+
"suspicious formatting of `else`"
5868
}
5969

6070
/// **What it does:** Checks for possible missing comma in an array. It lints if
@@ -96,7 +106,7 @@ impl EarlyLintPass for Formatting {
96106
match (&w[0].node, &w[1].node) {
97107
(&ast::StmtKind::Expr(ref first), &ast::StmtKind::Expr(ref second))
98108
| (&ast::StmtKind::Expr(ref first), &ast::StmtKind::Semi(ref second)) => {
99-
check_consecutive_ifs(cx, first, second);
109+
check_missing_else(cx, first, second);
100110
},
101111
_ => (),
102112
}
@@ -105,7 +115,7 @@ impl EarlyLintPass for Formatting {
105115

106116
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
107117
check_assign(cx, expr);
108-
check_else_if(cx, expr);
118+
check_else(cx, expr);
109119
check_array(cx, expr);
110120
}
111121
}
@@ -139,10 +149,18 @@ fn check_assign(cx: &EarlyContext<'_>, expr: &ast::Expr) {
139149
}
140150
}
141151

142-
/// Implementation of the `SUSPICIOUS_ELSE_FORMATTING` lint for weird `else if`.
143-
fn check_else_if(cx: &EarlyContext<'_>, expr: &ast::Expr) {
152+
/// Implementation of the `SUSPICIOUS_ELSE_FORMATTING` lint for weird `else`.
153+
fn check_else(cx: &EarlyContext<'_>, expr: &ast::Expr) {
144154
if let Some((then, &Some(ref else_))) = unsugar_if(expr) {
145-
if unsugar_if(else_).is_some() && !differing_macro_contexts(then.span, else_.span) && !in_macro(then.span) {
155+
if (is_block(else_) || unsugar_if(else_).is_some())
156+
&& !differing_macro_contexts(then.span, else_.span)
157+
&& !in_macro(then.span)
158+
{
159+
// workaround for rust-lang/rust#43081
160+
if expr.span.lo().0 == 0 && expr.span.hi().0 == 0 {
161+
return;
162+
}
163+
146164
// this will be a span from the closing ‘}’ of the “then” block (excluding) to
147165
// the
148166
// “if” of the “else if” block (excluding)
@@ -154,14 +172,19 @@ fn check_else_if(cx: &EarlyContext<'_>, expr: &ast::Expr) {
154172
let else_pos = else_snippet.find("else").expect("there must be a `else` here");
155173

156174
if else_snippet[else_pos..].contains('\n') {
175+
let else_desc = if unsugar_if(else_).is_some() { "if" } else { "{..}" };
176+
157177
span_note_and_lint(
158178
cx,
159179
SUSPICIOUS_ELSE_FORMATTING,
160180
else_span,
161-
"this is an `else if` but the formatting might hide it",
181+
&format!("this is an `else {}` but the formatting might hide it", else_desc),
162182
else_span,
163-
"to remove this lint, remove the `else` or remove the new line between `else` \
164-
and `if`",
183+
&format!(
184+
"to remove this lint, remove the `else` or remove the new line between \
185+
`else` and `{}`",
186+
else_desc,
187+
),
165188
);
166189
}
167190
}
@@ -200,32 +223,47 @@ fn check_array(cx: &EarlyContext<'_>, expr: &ast::Expr) {
200223
}
201224
}
202225

203-
/// Implementation of the `SUSPICIOUS_ELSE_FORMATTING` lint for consecutive ifs.
204-
fn check_consecutive_ifs(cx: &EarlyContext<'_>, first: &ast::Expr, second: &ast::Expr) {
226+
fn check_missing_else(cx: &EarlyContext<'_>, first: &ast::Expr, second: &ast::Expr) {
205227
if !differing_macro_contexts(first.span, second.span)
206228
&& !in_macro(first.span)
207229
&& unsugar_if(first).is_some()
208-
&& unsugar_if(second).is_some()
230+
&& (is_block(second) || unsugar_if(second).is_some())
209231
{
210232
// where the else would be
211233
let else_span = first.span.between(second.span);
212234

213235
if let Some(else_snippet) = snippet_opt(cx, else_span) {
214236
if !else_snippet.contains('\n') {
237+
let (looks_like, next_thing) = if unsugar_if(second).is_some() {
238+
("an `else if`", "the second `if`")
239+
} else {
240+
("an `else {..}`", "the next block")
241+
};
242+
215243
span_note_and_lint(
216244
cx,
217245
SUSPICIOUS_ELSE_FORMATTING,
218246
else_span,
219-
"this looks like an `else if` but the `else` is missing",
247+
&format!("this looks like {} but the `else` is missing", looks_like),
220248
else_span,
221-
"to remove this lint, add the missing `else` or add a new line before the second \
222-
`if`",
249+
&format!(
250+
"to remove this lint, add the missing `else` or add a new line before {}",
251+
next_thing,
252+
),
223253
);
224254
}
225255
}
226256
}
227257
}
228258

259+
fn is_block(expr: &ast::Expr) -> bool {
260+
if let ast::ExprKind::Block(..) = expr.node {
261+
true
262+
} else {
263+
false
264+
}
265+
}
266+
229267
/// Match `if` or `if let` expressions and return the `then` and `else` block.
230268
fn unsugar_if(expr: &ast::Expr) -> Option<(&P<ast::Block>, &Option<P<ast::Expr>>)> {
231269
match expr.node {

clippy_lints/src/implicit_return.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
1212
use crate::rustc::{declare_tool_lint, lint_array};
1313
use crate::rustc_errors::Applicability;
1414
use crate::syntax::{ast::NodeId, source_map::Span};
15-
use crate::utils::{snippet_opt, span_lint_and_then};
15+
use crate::utils::{in_macro, snippet_opt, span_lint_and_then};
1616

1717
/// **What it does:** Checks for missing return statements at the end of a block.
1818
///
@@ -116,14 +116,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
116116
_: FnKind<'tcx>,
117117
_: &'tcx FnDecl,
118118
body: &'tcx Body,
119-
_: Span,
119+
span: Span,
120120
_: NodeId,
121121
) {
122122
let def_id = cx.tcx.hir().body_owner_def_id(body.id());
123123
let mir = cx.tcx.optimized_mir(def_id);
124124

125125
// checking return type through MIR, HIR is not able to determine inferred closure return types
126-
if !mir.return_ty().is_unit() {
126+
// make sure it's not a macro
127+
if !mir.return_ty().is_unit() && !in_macro(span) {
127128
Self::expr_match(cx, &body.value);
128129
}
129130
}

0 commit comments

Comments
 (0)