Skip to content

Commit 2c56abb

Browse files
committed
Merge branch 'master' into use_last
2 parents 217ebe9 + 68114c4 commit 2c56abb

Some content is hidden

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

66 files changed

+1835
-1018
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,7 @@ All notable changes to this project will be documented in this file.
785785
[`double_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_comparisons
786786
[`double_neg`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_neg
787787
[`double_parens`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_parens
788+
[`drop_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#drop_bounds
788789
[`drop_copy`]: https://rust-lang.github.io/rust-clippy/master/index.html#drop_copy
789790
[`drop_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#drop_ref
790791
[`duplicate_underscore_argument`]: https://rust-lang.github.io/rust-clippy/master/index.html#duplicate_underscore_argument

README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ A collection of lints to catch common mistakes and improve your [Rust](https://g
1111

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

14-
* `clippy::all` (everything that has no false positives)
15-
* `clippy::pedantic` (everything)
16-
* `clippy::nursery` (new lints that aren't quite ready yet)
14+
* `clippy::all` (everything that is on by default: all the categories below except for `nursery`, `pedantic`, and `cargo`)
15+
* **`clippy::correctness`** (code that is just outright wrong or very very useless, causes hard errors by default)
1716
* `clippy::style` (code that should be written in a more idiomatic way)
1817
* `clippy::complexity` (code that does something simple but in a complex way)
1918
* `clippy::perf` (code that can be written in a faster way)
20-
* `clippy::cargo` (checks against the cargo manifest)
21-
* **`clippy::correctness`** (code that is just outright wrong or very very useless)
19+
* `clippy::pedantic` (lints which are rather strict, off by default)
20+
* `clippy::nursery` (new lints that aren't quite ready yet, off by default)
21+
* `clippy::cargo` (checks against the cargo manifest, off by default)
2222

2323
More to come, please [file an issue](https://github.com/rust-lang/rust-clippy/issues) if you have ideas!
2424

@@ -31,6 +31,8 @@ Only the following of those categories are enabled by default:
3131

3232
Other categories need to be enabled in order for their lints to be executed.
3333

34+
The [lint list](https://rust-lang.github.io/rust-clippy/master/index.html) also contains "restriction lints", which are for things which are usually not considered "bad", but may be useful to turn on in specific cases. These should be used very selectively, if at all.
35+
3436
Table of contents:
3537

3638
* [Usage instructions](#usage)

ci/base-tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ rustup override set nightly
5959
# avoid loop spam and allow cmds with exit status != 0
6060
set +ex
6161

62-
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
62+
for file in `find tests -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
6363
rustfmt ${file} --check
6464
if [ $? -ne 0 ]; then
6565
echo "${file} needs reformatting!"

clippy_dev/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ impl Lint {
4747
name: name.to_lowercase(),
4848
group: group.to_string(),
4949
desc: NL_ESCAPE_RE.replace(&desc.replace("\\\"", "\""), "").to_string(),
50-
deprecation: deprecation.map(|d| d.to_string()),
50+
deprecation: deprecation.map(std::string::ToString::to_string),
5151
module: module.to_string(),
5252
}
5353
}
@@ -178,7 +178,7 @@ fn lint_files() -> impl Iterator<Item = walkdir::DirEntry> {
178178
// Otherwise we would not collect all the lints, for example in `clippy_lints/src/methods/`.
179179
WalkDir::new("../clippy_lints/src")
180180
.into_iter()
181-
.filter_map(|f| f.ok())
181+
.filter_map(std::result::Result::ok)
182182
.filter(|f| f.path().extension() == Some(OsStr::new("rs")))
183183
}
184184

clippy_lints/src/assertions_on_constants.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::rustc::hir::{Expr, ExprKind};
33
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
44
use crate::rustc::{declare_tool_lint, lint_array};
55
use crate::syntax::ast::LitKind;
6-
use crate::utils::{is_direct_expn_of, span_help_and_lint};
6+
use crate::utils::{in_macro, is_direct_expn_of, span_help_and_lint};
77
use if_chain::if_chain;
88

99
/// **What it does:** Check to call assert!(true/false)
@@ -43,7 +43,9 @@ impl LintPass for AssertionsOnConstants {
4343
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssertionsOnConstants {
4444
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
4545
if_chain! {
46-
if is_direct_expn_of(e.span, "assert").is_some();
46+
if let Some(assert_span) = is_direct_expn_of(e.span, "assert");
47+
if !in_macro(assert_span)
48+
|| is_direct_expn_of(assert_span, "debug_assert").map_or(false, |span| !in_macro(span));
4749
if let ExprKind::Unary(_, ref lit) = e.node;
4850
then {
4951
if let ExprKind::Lit(ref inner) = lit.node {

clippy_lints/src/attrs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ fn check_clippy_lint_names(cx: &LateContext<'_, '_>, items: &[NestedMetaItem]) {
326326
lint.span,
327327
&format!("unknown clippy lint: clippy::{}", name),
328328
|db| {
329-
if name.as_str().chars().any(|c| c.is_uppercase()) {
329+
if name.as_str().chars().any(char::is_uppercase) {
330330
let name_lower = name.as_str().to_lowercase();
331331
match lint_store.check_lint_name(
332332
&name_lower,

clippy_lints/src/cargo_common_metadata.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ fn is_empty_str(value: &Option<String>) -> bool {
5353

5454
fn is_empty_vec(value: &[String]) -> bool {
5555
// This works because empty iterators return true
56-
value.iter().all(|v| v.is_empty())
56+
value.iter().all(std::string::String::is_empty)
5757
}
5858

5959
pub struct Pass;

clippy_lints/src/cyclomatic_complexity.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ impl CyclomaticComplexity {
7878
returns,
7979
..
8080
} = helper;
81-
let ret_ty = cx.tables.node_id_to_type(expr.hir_id);
81+
let ret_ty = cx.tables.node_type(expr.hir_id);
8282
let ret_adjust = if match_type(cx, ret_ty, &paths::RESULT) {
8383
returns
8484
} else {
@@ -94,7 +94,7 @@ impl CyclomaticComplexity {
9494
short_circuits,
9595
ret_adjust,
9696
span,
97-
body.id().node_id,
97+
body.id().hir_id,
9898
);
9999
} else {
100100
let mut rust_cc = cc + divergence - match_arms - short_circuits;
@@ -159,7 +159,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CCHelper<'a, 'tcx> {
159159
},
160160
ExprKind::Call(ref callee, _) => {
161161
walk_expr(self, e);
162-
let ty = self.cx.tables.node_id_to_type(callee.hir_id);
162+
let ty = self.cx.tables.node_type(callee.hir_id);
163163
match ty.sty {
164164
ty::FnDef(..) | ty::FnPtr(_) => {
165165
let sig = ty.fn_sig(self.cx.tcx);
@@ -197,7 +197,7 @@ fn report_cc_bug(
197197
shorts: u64,
198198
returns: u64,
199199
span: Span,
200-
_: NodeId,
200+
_: HirId,
201201
) {
202202
span_bug!(
203203
span,
@@ -220,9 +220,10 @@ fn report_cc_bug(
220220
shorts: u64,
221221
returns: u64,
222222
span: Span,
223-
id: NodeId,
223+
id: HirId,
224224
) {
225-
if !is_allowed(cx, CYCLOMATIC_COMPLEXITY, id) {
225+
let node_id = cx.tcx.hir().hir_to_node_id(id);
226+
if !is_allowed(cx, CYCLOMATIC_COMPLEXITY, node_id) {
226227
cx.sess().span_note_without_error(
227228
span,
228229
&format!(

clippy_lints/src/drop_bounds.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
use crate::utils::{match_def_path, paths, span_lint};
2+
use if_chain::if_chain;
3+
use rustc::hir::*;
4+
use rustc::lint::{LateLintPass, LintArray, LintPass};
5+
use rustc::{declare_tool_lint, lint_array};
6+
7+
/// **What it does:** Checks for generics with `std::ops::Drop` as bounds.
8+
///
9+
/// **Why is this bad?** `Drop` bounds do not really accomplish anything.
10+
/// A type may have compiler-generated drop glue without implementing the
11+
/// `Drop` trait itself. The `Drop` trait also only has one method,
12+
/// `Drop::drop`, and that function is by fiat not callable in user code.
13+
/// So there is really no use case for using `Drop` in trait bounds.
14+
///
15+
/// The most likely use case of a drop bound is to distinguish between types
16+
/// that have destructors and types that don't. Combined with specialization,
17+
/// a naive coder would write an implementation that assumed a type could be
18+
/// trivially dropped, then write a specialization for `T: Drop` that actually
19+
/// calls the destructor. Except that doing so is not correct; String, for
20+
/// example, doesn't actually implement Drop, but because String contains a
21+
/// Vec, assuming it can be trivially dropped will leak memory.
22+
///
23+
/// **Known problems:** None.
24+
///
25+
/// **Example:**
26+
/// ```rust
27+
/// fn foo<T: Drop>() {}
28+
/// ```
29+
declare_clippy_lint! {
30+
pub DROP_BOUNDS,
31+
correctness,
32+
"Bounds of the form `T: Drop` are useless"
33+
}
34+
35+
const DROP_BOUNDS_SUMMARY: &str = "Bounds of the form `T: Drop` are useless. \
36+
Use `std::mem::needs_drop` to detect if a type has drop glue.";
37+
38+
pub struct Pass;
39+
40+
impl LintPass for Pass {
41+
fn get_lints(&self) -> LintArray {
42+
lint_array!(DROP_BOUNDS)
43+
}
44+
45+
fn name(&self) -> &'static str {
46+
"DropBounds"
47+
}
48+
}
49+
50+
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
51+
fn check_generic_param(&mut self, cx: &rustc::lint::LateContext<'a, 'tcx>, p: &'tcx GenericParam) {
52+
for bound in &p.bounds {
53+
lint_bound(cx, bound);
54+
}
55+
}
56+
fn check_where_predicate(&mut self, cx: &rustc::lint::LateContext<'a, 'tcx>, p: &'tcx WherePredicate) {
57+
if let WherePredicate::BoundPredicate(WhereBoundPredicate { bounds, .. }) = p {
58+
for bound in bounds {
59+
lint_bound(cx, bound);
60+
}
61+
}
62+
}
63+
}
64+
65+
fn lint_bound<'a, 'tcx>(cx: &rustc::lint::LateContext<'a, 'tcx>, bound: &'tcx GenericBound) {
66+
if_chain! {
67+
if let GenericBound::Trait(t, _) = bound;
68+
if let Some(def_id) = t.trait_ref.path.def.opt_def_id();
69+
if match_def_path(cx.tcx, def_id, &paths::DROP_TRAIT);
70+
then {
71+
span_lint(
72+
cx,
73+
DROP_BOUNDS,
74+
t.span,
75+
DROP_BOUNDS_SUMMARY
76+
);
77+
}
78+
}
79+
}

0 commit comments

Comments
 (0)