Skip to content

Commit c680602

Browse files
committed
Merge remote-tracking branch 'upstream/master' into rustup
2 parents 4b0e6d5 + 9360ca6 commit c680602

File tree

101 files changed

+2851
-846
lines changed

Some content is hidden

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

101 files changed

+2851
-846
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,6 +1690,7 @@ Released 2018-09-13
16901690
[`same_functions_in_if_condition`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_functions_in_if_condition
16911691
[`same_item_push`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push
16921692
[`search_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#search_is_some
1693+
[`self_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_assignment
16931694
[`serde_api_misuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#serde_api_misuse
16941695
[`shadow_reuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_reuse
16951696
[`shadow_same`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_same
@@ -1699,6 +1700,7 @@ Released 2018-09-13
16991700
[`should_implement_trait`]: https://rust-lang.github.io/rust-clippy/master/index.html#should_implement_trait
17001701
[`similar_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#similar_names
17011702
[`single_char_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_char_pattern
1703+
[`single_char_push_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_char_push_str
17021704
[`single_component_path_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_component_path_imports
17031705
[`single_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_match
17041706
[`single_match_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_match_else
@@ -1723,6 +1725,7 @@ Released 2018-09-13
17231725
[`temporary_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#temporary_assignment
17241726
[`temporary_cstring_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#temporary_cstring_as_ptr
17251727
[`to_digit_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_digit_is_some
1728+
[`to_string_in_display`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_string_in_display
17261729
[`todo`]: https://rust-lang.github.io/rust-clippy/master/index.html#todo
17271730
[`too_many_arguments`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments
17281731
[`too_many_lines`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines
@@ -1752,6 +1755,7 @@ Released 2018-09-13
17521755
[`unnecessary_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast
17531756
[`unnecessary_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_filter_map
17541757
[`unnecessary_fold`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_fold
1758+
[`unnecessary_lazy_evaluations`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations
17551759
[`unnecessary_mut_passed`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed
17561760
[`unnecessary_operation`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_operation
17571761
[`unnecessary_sort_by`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_sort_by

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ path = "src/driver.rs"
3131
# begin automatic update
3232
clippy_lints = { version = "0.0.212", path = "clippy_lints" }
3333
# end automatic update
34-
semver = "0.9"
34+
semver = "0.10"
3535
rustc_tools_util = { version = "0.2.0", path = "rustc_tools_util"}
3636
tempfile = { version = "3.1.0", optional = true }
3737
lazy_static = "1.0"
3838

3939
[dev-dependencies]
40-
cargo_metadata = "0.9.1"
40+
cargo_metadata = "0.11.1"
4141
compiletest_rs = { version = "0.5.0", features = ["tmp"] }
4242
tester = "0.7"
4343
lazy_static = "1.0"

clippy_lints/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ keywords = ["clippy", "lint", "plugin"]
1717
edition = "2018"
1818

1919
[dependencies]
20-
cargo_metadata = "0.9.1"
20+
cargo_metadata = "0.11.1"
2121
if_chain = "1.0.0"
2222
itertools = "0.9"
2323
lazy_static = "1.0.2"
@@ -28,7 +28,7 @@ serde = { version = "1.0", features = ["derive"] }
2828
smallvec = { version = "1", features = ["union"] }
2929
toml = "0.5.3"
3030
unicode-normalization = "0.1"
31-
semver = "0.9.0"
31+
semver = "0.10.0"
3232
# NOTE: cargo requires serde feat in its url dep
3333
# see <https://github.com/rust-lang/rust/pull/63587#issuecomment-522343864>
3434
url = { version = "2.1.0", features = ["serde"] }

clippy_lints/src/assign_ops.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::utils::{
2-
get_trait_def_id, implements_trait, snippet_opt, span_lint_and_then, trait_ref_of_method, SpanlessEq,
2+
eq_expr_value, get_trait_def_id, implements_trait, snippet_opt, span_lint_and_then, trait_ref_of_method,
33
};
44
use crate::utils::{higher, sugg};
55
use if_chain::if_chain;
@@ -70,11 +70,11 @@ impl<'tcx> LateLintPass<'tcx> for AssignOps {
7070
return;
7171
}
7272
// lhs op= l op r
73-
if SpanlessEq::new(cx).ignore_fn().eq_expr(lhs, l) {
73+
if eq_expr_value(cx, lhs, l) {
7474
lint_misrefactored_assign_op(cx, expr, *op, rhs, lhs, r);
7575
}
7676
// lhs op= l commutative_op r
77-
if is_commutative(op.node) && SpanlessEq::new(cx).ignore_fn().eq_expr(lhs, r) {
77+
if is_commutative(op.node) && eq_expr_value(cx, lhs, r) {
7878
lint_misrefactored_assign_op(cx, expr, *op, rhs, lhs, l);
7979
}
8080
}
@@ -161,14 +161,12 @@ impl<'tcx> LateLintPass<'tcx> for AssignOps {
161161

162162
if visitor.counter == 1 {
163163
// a = a op b
164-
if SpanlessEq::new(cx).ignore_fn().eq_expr(assignee, l) {
164+
if eq_expr_value(cx, assignee, l) {
165165
lint(assignee, r);
166166
}
167167
// a = b commutative_op a
168168
// Limited to primitive type as these ops are know to be commutative
169-
if SpanlessEq::new(cx).ignore_fn().eq_expr(assignee, r)
170-
&& cx.typeck_results().expr_ty(assignee).is_primitive_ty()
171-
{
169+
if eq_expr_value(cx, assignee, r) && cx.typeck_results().expr_ty(assignee).is_primitive_ty() {
172170
match op.node {
173171
hir::BinOpKind::Add
174172
| hir::BinOpKind::Mul
@@ -253,7 +251,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ExprVisitor<'a, 'tcx> {
253251
type Map = Map<'tcx>;
254252

255253
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'_>) {
256-
if SpanlessEq::new(self.cx).ignore_fn().eq_expr(self.assignee, expr) {
254+
if eq_expr_value(self.cx, self.assignee, expr) {
257255
self.counter += 1;
258256
}
259257

clippy_lints/src/attrs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use crate::utils::{
55
span_lint_and_sugg, span_lint_and_then, without_block_comments,
66
};
77
use if_chain::if_chain;
8-
use rustc_ast::{AttrKind, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
98
use rustc_ast::util::lev_distance::find_best_match_for_name;
9+
use rustc_ast::{AttrKind, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
1010
use rustc_errors::Applicability;
1111
use rustc_hir::{
1212
Block, Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, StmtKind, TraitFn, TraitItem, TraitItemKind,

clippy_lints/src/booleans.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::utils::{
2-
get_trait_def_id, implements_trait, in_macro, is_type_diagnostic_item, paths, snippet_opt, span_lint_and_sugg,
3-
span_lint_and_then, SpanlessEq,
2+
eq_expr_value, get_trait_def_id, implements_trait, in_macro, is_type_diagnostic_item, paths, snippet_opt,
3+
span_lint_and_sugg, span_lint_and_then,
44
};
55
use if_chain::if_chain;
66
use rustc_ast::ast::LitKind;
@@ -128,7 +128,7 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
128128
}
129129
}
130130
for (n, expr) in self.terminals.iter().enumerate() {
131-
if SpanlessEq::new(self.cx).ignore_fn().eq_expr(e, expr) {
131+
if eq_expr_value(self.cx, e, expr) {
132132
#[allow(clippy::cast_possible_truncation)]
133133
return Ok(Bool::Term(n as u8));
134134
}
@@ -138,8 +138,8 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
138138
if implements_ord(self.cx, e_lhs);
139139
if let ExprKind::Binary(expr_binop, expr_lhs, expr_rhs) = &expr.kind;
140140
if negate(e_binop.node) == Some(expr_binop.node);
141-
if SpanlessEq::new(self.cx).ignore_fn().eq_expr(e_lhs, expr_lhs);
142-
if SpanlessEq::new(self.cx).ignore_fn().eq_expr(e_rhs, expr_rhs);
141+
if eq_expr_value(self.cx, e_lhs, expr_lhs);
142+
if eq_expr_value(self.cx, e_rhs, expr_rhs);
143143
then {
144144
#[allow(clippy::cast_possible_truncation)]
145145
return Ok(Bool::Not(Box::new(Bool::Term(n as u8))));

clippy_lints/src/copies.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
use crate::utils::{eq_expr_value, SpanlessEq, SpanlessHash};
12
use crate::utils::{get_parent_expr, higher, if_sequence, snippet, span_lint_and_note, span_lint_and_then};
2-
use crate::utils::{SpanlessEq, SpanlessHash};
33
use rustc_data_structures::fx::FxHashMap;
44
use rustc_hir::{Arm, Block, Expr, ExprKind, MatchSource, Pat, PatKind};
55
use rustc_lint::{LateContext, LateLintPass};
@@ -197,8 +197,7 @@ fn lint_same_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>]) {
197197
h.finish()
198198
};
199199

200-
let eq: &dyn Fn(&&Expr<'_>, &&Expr<'_>) -> bool =
201-
&|&lhs, &rhs| -> bool { SpanlessEq::new(cx).ignore_fn().eq_expr(lhs, rhs) };
200+
let eq: &dyn Fn(&&Expr<'_>, &&Expr<'_>) -> bool = &|&lhs, &rhs| -> bool { eq_expr_value(cx, lhs, rhs) };
202201

203202
for (i, j) in search_same(conds, hash, eq) {
204203
span_lint_and_note(
@@ -222,7 +221,7 @@ fn lint_same_fns_in_if_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>]) {
222221

223222
let eq: &dyn Fn(&&Expr<'_>, &&Expr<'_>) -> bool = &|&lhs, &rhs| -> bool {
224223
// Do not spawn warning if `IFS_SAME_COND` already produced it.
225-
if SpanlessEq::new(cx).ignore_fn().eq_expr(lhs, rhs) {
224+
if eq_expr_value(cx, lhs, rhs) {
226225
return false;
227226
}
228227
SpanlessEq::new(cx).eq_expr(lhs, rhs)

clippy_lints/src/doc.rs

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
use crate::utils::{implements_trait, is_entrypoint_fn, is_type_diagnostic_item, return_ty, span_lint};
22
use if_chain::if_chain;
33
use itertools::Itertools;
4-
use rustc_ast::ast::{AttrKind, Attribute};
4+
use rustc_ast::ast::{Async, AttrKind, Attribute, FnRetTy, ItemKind};
55
use rustc_ast::token::CommentKind;
66
use rustc_data_structures::fx::FxHashSet;
7+
use rustc_data_structures::sync::Lrc;
8+
use rustc_errors::emitter::EmitterWriter;
9+
use rustc_errors::Handler;
710
use rustc_hir as hir;
811
use rustc_lint::{LateContext, LateLintPass};
912
use rustc_middle::lint::in_external_macro;
1013
use rustc_middle::ty;
14+
use rustc_parse::maybe_new_parser_from_source_str;
15+
use rustc_session::parse::ParseSess;
1116
use rustc_session::{declare_tool_lint, impl_lint_pass};
12-
use rustc_span::source_map::{BytePos, MultiSpan, Span};
13-
use rustc_span::Pos;
17+
use rustc_span::source_map::{BytePos, FilePathMapping, MultiSpan, SourceMap, Span};
18+
use rustc_span::{FileName, Pos};
19+
use std::io;
1420
use std::ops::Range;
1521
use url::Url;
1622

@@ -431,10 +437,67 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
431437
headers
432438
}
433439

434-
static LEAVE_MAIN_PATTERNS: &[&str] = &["static", "fn main() {}", "extern crate", "async fn main() {"];
435-
436440
fn check_code(cx: &LateContext<'_>, text: &str, span: Span) {
437-
if text.contains("fn main() {") && !LEAVE_MAIN_PATTERNS.iter().any(|p| text.contains(p)) {
441+
fn has_needless_main(code: &str) -> bool {
442+
let filename = FileName::anon_source_code(code);
443+
444+
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
445+
let emitter = EmitterWriter::new(box io::sink(), None, false, false, false, None, false);
446+
let handler = Handler::with_emitter(false, None, box emitter);
447+
let sess = ParseSess::with_span_handler(handler, sm);
448+
449+
let mut parser = match maybe_new_parser_from_source_str(&sess, filename, code.into()) {
450+
Ok(p) => p,
451+
Err(errs) => {
452+
for mut err in errs {
453+
err.cancel();
454+
}
455+
return false;
456+
},
457+
};
458+
459+
let mut relevant_main_found = false;
460+
loop {
461+
match parser.parse_item() {
462+
Ok(Some(item)) => match &item.kind {
463+
// Tests with one of these items are ignored
464+
ItemKind::Static(..)
465+
| ItemKind::Const(..)
466+
| ItemKind::ExternCrate(..)
467+
| ItemKind::ForeignMod(..) => return false,
468+
// We found a main function ...
469+
ItemKind::Fn(_, sig, _, Some(block)) if item.ident.name == sym!(main) => {
470+
let is_async = matches!(sig.header.asyncness, Async::Yes{..});
471+
let returns_nothing = match &sig.decl.output {
472+
FnRetTy::Default(..) => true,
473+
FnRetTy::Ty(ty) if ty.kind.is_unit() => true,
474+
_ => false,
475+
};
476+
477+
if returns_nothing && !is_async && !block.stmts.is_empty() {
478+
// This main function should be linted, but only if there are no other functions
479+
relevant_main_found = true;
480+
} else {
481+
// This main function should not be linted, we're done
482+
return false;
483+
}
484+
},
485+
// Another function was found; this case is ignored too
486+
ItemKind::Fn(..) => return false,
487+
_ => {},
488+
},
489+
Ok(None) => break,
490+
Err(mut e) => {
491+
e.cancel();
492+
return false;
493+
},
494+
}
495+
}
496+
497+
relevant_main_found
498+
}
499+
500+
if has_needless_main(text) {
438501
span_lint(cx, NEEDLESS_DOCTEST_MAIN, span, "needless `fn main` in doctest");
439502
}
440503
}

clippy_lints/src/double_comparison.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_lint::{LateContext, LateLintPass};
66
use rustc_session::{declare_lint_pass, declare_tool_lint};
77
use rustc_span::source_map::Span;
88

9-
use crate::utils::{snippet_with_applicability, span_lint_and_sugg, SpanlessEq};
9+
use crate::utils::{eq_expr_value, snippet_with_applicability, span_lint_and_sugg};
1010

1111
declare_clippy_lint! {
1212
/// **What it does:** Checks for double comparisons that could be simplified to a single expression.
@@ -46,8 +46,7 @@ impl<'tcx> DoubleComparisons {
4646
},
4747
_ => return,
4848
};
49-
let mut spanless_eq = SpanlessEq::new(cx).ignore_fn();
50-
if !(spanless_eq.eq_expr(&llhs, &rlhs) && spanless_eq.eq_expr(&lrhs, &rrhs)) {
49+
if !(eq_expr_value(cx, &llhs, &rlhs) && eq_expr_value(cx, &lrhs, &rrhs)) {
5150
return;
5251
}
5352
macro_rules! lint_double_comparison {

clippy_lints/src/duration_subsec.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ impl<'tcx> LateLintPass<'tcx> for DurationSubsec {
5656
cx,
5757
DURATION_SUBSEC,
5858
expr.span,
59-
&format!("Calling `{}()` is more concise than this calculation", suggested_fn),
59+
&format!("calling `{}()` is more concise than this calculation", suggested_fn),
6060
"try",
6161
format!(
6262
"{}.{}()",

clippy_lints/src/enum_clike.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl<'tcx> LateLintPass<'tcx> for UnportableVariant {
7272
cx,
7373
ENUM_CLIKE_UNPORTABLE_VARIANT,
7474
var.span,
75-
"Clike enum variant discriminant is not portable to 32-bit targets",
75+
"C-like enum variant discriminant is not portable to 32-bit targets",
7676
);
7777
};
7878
}

clippy_lints/src/enum_variants.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,10 @@ fn check_variant(
183183
&& name.chars().nth(item_name_chars).map_or(false, |c| !c.is_lowercase())
184184
&& name.chars().nth(item_name_chars + 1).map_or(false, |c| !c.is_numeric())
185185
{
186-
span_lint(cx, lint, var.span, "Variant name starts with the enum's name");
186+
span_lint(cx, lint, var.span, "variant name starts with the enum's name");
187187
}
188188
if partial_rmatch(item_name, &name) == item_name_chars {
189-
span_lint(cx, lint, var.span, "Variant name ends with the enum's name");
189+
span_lint(cx, lint, var.span, "variant name ends with the enum's name");
190190
}
191191
}
192192
let first = &def.variants[0].ident.name.as_str();
@@ -227,7 +227,7 @@ fn check_variant(
227227
cx,
228228
lint,
229229
span,
230-
&format!("All variants have the same {}fix: `{}`", what, value),
230+
&format!("all variants have the same {}fix: `{}`", what, value),
231231
None,
232232
&format!(
233233
"remove the {}fixes and use full paths to \

clippy_lints/src/eq_op.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::utils::{
2-
implements_trait, in_macro, is_copy, multispan_sugg, snippet, span_lint, span_lint_and_then, SpanlessEq,
2+
eq_expr_value, implements_trait, in_macro, is_copy, multispan_sugg, snippet, span_lint, span_lint_and_then,
33
};
44
use rustc_errors::Applicability;
55
use rustc_hir::{BinOp, BinOpKind, BorrowKind, Expr, ExprKind};
@@ -69,7 +69,7 @@ impl<'tcx> LateLintPass<'tcx> for EqOp {
6969
if macro_with_not_op(&left.kind) || macro_with_not_op(&right.kind) {
7070
return;
7171
}
72-
if is_valid_operator(op) && SpanlessEq::new(cx).ignore_fn().eq_expr(left, right) {
72+
if is_valid_operator(op) && eq_expr_value(cx, left, right) {
7373
span_lint(
7474
cx,
7575
EQ_OP,

0 commit comments

Comments
 (0)