Skip to content

Commit da86067

Browse files
committed
Merge remote-tracking branch 'upstream/master' into sync-from-rust
2 parents fdc48fb + 48248af commit da86067

23 files changed

+629
-62
lines changed

CHANGELOG.md

Lines changed: 106 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,113 @@ document.
66

77
## Unreleased / In Rust Nightly
88

9-
[c2c07fa...master](https://github.com/rust-lang/rust-clippy/compare/c2c07fa...master)
9+
[09bd400...master](https://github.com/rust-lang/rust-clippy/compare/09bd400...master)
10+
11+
## Rust 1.47
12+
13+
Current beta, release 2020-10-08
14+
15+
[c2c07fa...09bd400](https://github.com/rust-lang/rust-clippy/compare/c2c07fa...09bd400)
16+
17+
### New lints
18+
19+
* [`derive_ord_xor_partial_ord`] [#5848](https://github.com/rust-lang/rust-clippy/pull/5848)
20+
* [`trait_duplication_in_bounds`] [#5852](https://github.com/rust-lang/rust-clippy/pull/5852)
21+
* [`map_identity`] [#5694](https://github.com/rust-lang/rust-clippy/pull/5694)
22+
* [`unit_return_expecting_ord`] [#5737](https://github.com/rust-lang/rust-clippy/pull/5737)
23+
* [`pattern_type_mismatch`] [#4841](https://github.com/rust-lang/rust-clippy/pull/4841)
24+
* [`repeat_once`] [#5773](https://github.com/rust-lang/rust-clippy/pull/5773)
25+
* [`same_item_push`] [#5825](https://github.com/rust-lang/rust-clippy/pull/5825)
26+
* [`needless_arbitrary_self_type`] [#5869](https://github.com/rust-lang/rust-clippy/pull/5869)
27+
* [`match_like_matches_macro`] [#5769](https://github.com/rust-lang/rust-clippy/pull/5769)
28+
* [`stable_sort_primitive`] [#5809](https://github.com/rust-lang/rust-clippy/pull/5809)
29+
* [`blanket_clippy_restriction_lints`] [#5750](https://github.com/rust-lang/rust-clippy/pull/5750)
30+
* [`option_if_let_else`] [#5301](https://github.com/rust-lang/rust-clippy/pull/5301)
31+
32+
### Moves and Deprecations
33+
34+
* Deprecate [`regex_macro`] lint
35+
[#5760](https://github.com/rust-lang/rust-clippy/pull/5760)
36+
* Move [`range_minus_one`] to `pedantic`
37+
[#5752](https://github.com/rust-lang/rust-clippy/pull/5752)
38+
39+
### Enhancements
40+
41+
* Improve [`needless_collect`] by catching `collect` calls followed by `iter` or `into_iter` calls
42+
[#5837](https://github.com/rust-lang/rust-clippy/pull/5837)
43+
* [`panic`], [`todo`], [`unimplemented`] and [`unreachable`] now detect calls with formatting
44+
[#5811](https://github.com/rust-lang/rust-clippy/pull/5811)
45+
* Detect more cases of [`suboptimal_flops`] and [`imprecise_flops`]
46+
[#5443](https://github.com/rust-lang/rust-clippy/pull/5443)
47+
* Handle asymmetrical implementations of `PartialEq` in [`cmp_owned`]
48+
[#5701](https://github.com/rust-lang/rust-clippy/pull/5701)
49+
* Make it possible to allow [`unsafe_derive_deserialize`]
50+
[#5870](https://github.com/rust-lang/rust-clippy/pull/5870)
51+
* Catch `ord.min(a).max(b)` where a < b in [`min_max`]
52+
[#5871](https://github.com/rust-lang/rust-clippy/pull/5871)
53+
* Make [`clone_on_copy`] suggestion machine applicable
54+
[#5745](https://github.com/rust-lang/rust-clippy/pull/5745)
55+
* Enable [`len_zero`] on ranges now that `is_empty` is stable on them
56+
[#5961](https://github.com/rust-lang/rust-clippy/pull/5961)
57+
58+
### False Positive Fixes
59+
60+
* Avoid triggering [`or_fun_call`] with const fns that take no arguments
61+
[#5889](https://github.com/rust-lang/rust-clippy/pull/5889)
62+
* Fix [`redundant_closure_call`] false positive for closures that have multiple calls
63+
[#5800](https://github.com/rust-lang/rust-clippy/pull/5800)
64+
* Don't lint cases involving `ManuallyDrop` in [`redundant_clone`]
65+
[#5824](https://github.com/rust-lang/rust-clippy/pull/5824)
66+
* Treat a single expression the same as a single statement in the 2nd arm of a match in [`single_match_else`]
67+
[#5771](https://github.com/rust-lang/rust-clippy/pull/5771)
68+
* Don't trigger [`unnested_or_patterns`] if the feature `or_patterns` is not enabled
69+
[#5758](https://github.com/rust-lang/rust-clippy/pull/5758)
70+
* Avoid linting if key borrows in [`unnecessary_sort_by`]
71+
[#5756](https://github.com/rust-lang/rust-clippy/pull/5756)
72+
* Consider `Try` impl for `Poll` when generating suggestions in [`try_err`]
73+
[#5857](https://github.com/rust-lang/rust-clippy/pull/5857)
74+
* Take input lifetimes into account in `manual_async_fn`
75+
[#5859](https://github.com/rust-lang/rust-clippy/pull/5859)
76+
* Fix multiple false positives in [`type_repetition_in_bounds`] and add a configuration option
77+
[#5761](https://github.com/rust-lang/rust-clippy/pull/5761)
78+
* Limit the [`suspicious_arithmetic_impl`] lint to one binary operation
79+
[#5820](https://github.com/rust-lang/rust-clippy/pull/5820)
80+
81+
### Suggestion Fixes/Improvements
82+
83+
* Improve readability of [`shadow_unrelated`] suggestion by truncating the RHS snippet
84+
[#5788](https://github.com/rust-lang/rust-clippy/pull/5788)
85+
* Suggest `filter_map` instead of `flat_map` when mapping to `Option` in [`map_flatten`]
86+
[#5846](https://github.com/rust-lang/rust-clippy/pull/5846)
87+
* Ensure suggestion is shown correctly for long method call chains in [`iter_nth_zero`]
88+
[#5793](https://github.com/rust-lang/rust-clippy/pull/5793)
89+
* Drop borrow operator in suggestions of [`redundant_pattern_matching`]
90+
[#5815](https://github.com/rust-lang/rust-clippy/pull/5815)
91+
* Add suggestion for [`iter_skip_next`]
92+
[#5843](https://github.com/rust-lang/rust-clippy/pull/5843)
93+
* Improve [`collapsible_if`] fix suggestion
94+
[#5732](https://github.com/rust-lang/rust-clippy/pull/5732)
95+
96+
### ICE Fixes
97+
98+
* Fix ICE caused by [`needless_collect`]
99+
[#5877](https://github.com/rust-lang/rust-clippy/pull/5877)
100+
* Fix ICE caused by [`unnested_or_patterns`]
101+
[#5784](https://github.com/rust-lang/rust-clippy/pull/5784)
102+
103+
### Documentation Improvements
104+
105+
* Fix grammar of [`await_holding_lock`] documentation
106+
[#5748](https://github.com/rust-lang/rust-clippy/pull/5748)
107+
108+
### Others
109+
110+
* Make lints adhere to the rustc dev guide
111+
[#5888](https://github.com/rust-lang/rust-clippy/pull/5888)
10112

11113
## Rust 1.46
12114

13-
Current beta, release 2020-08-27
115+
Current stable, released 2020-08-27
14116

15117
[7ea7cd1...c2c07fa](https://github.com/rust-lang/rust-clippy/compare/7ea7cd1...c2c07fa)
16118

@@ -72,7 +174,7 @@ Current beta, release 2020-08-27
72174

73175
## Rust 1.45
74176

75-
Current stable, released 2020-07-16
177+
Released 2020-07-16
76178

77179
[891e1a8...7ea7cd1](https://github.com/rust-lang/rust-clippy/compare/891e1a8...7ea7cd1)
78180

@@ -1410,6 +1512,7 @@ Released 2018-09-13
14101512
[`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants
14111513
[`assign_op_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_op_pattern
14121514
[`assign_ops`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_ops
1515+
[`async_yields_async`]: https://rust-lang.github.io/rust-clippy/master/index.html#async_yields_async
14131516
[`await_holding_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_lock
14141517
[`bad_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#bad_bit_mask
14151518
[`bind_instead_of_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#bind_instead_of_map
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
use crate::utils::{implements_trait, snippet, span_lint_and_then};
2+
use rustc_errors::Applicability;
3+
use rustc_hir::{AsyncGeneratorKind, Body, BodyId, ExprKind, GeneratorKind, QPath};
4+
use rustc_lint::{LateContext, LateLintPass};
5+
use rustc_session::{declare_lint_pass, declare_tool_lint};
6+
7+
declare_clippy_lint! {
8+
/// **What it does:** Checks for async blocks that yield values of types
9+
/// that can themselves be awaited.
10+
///
11+
/// **Why is this bad?** An await is likely missing.
12+
///
13+
/// **Known problems:** None.
14+
///
15+
/// **Example:**
16+
///
17+
/// ```rust
18+
/// async fn foo() {}
19+
///
20+
/// fn bar() {
21+
/// let x = async {
22+
/// foo()
23+
/// };
24+
/// }
25+
/// ```
26+
/// Use instead:
27+
/// ```rust
28+
/// async fn foo() {}
29+
///
30+
/// fn bar() {
31+
/// let x = async {
32+
/// foo().await
33+
/// };
34+
/// }
35+
/// ```
36+
pub ASYNC_YIELDS_ASYNC,
37+
correctness,
38+
"async blocks that return a type that can be awaited"
39+
}
40+
41+
declare_lint_pass!(AsyncYieldsAsync => [ASYNC_YIELDS_ASYNC]);
42+
43+
impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync {
44+
fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) {
45+
use AsyncGeneratorKind::{Block, Closure};
46+
// For functions, with explicitly defined types, don't warn.
47+
// XXXkhuey maybe we should?
48+
if let Some(GeneratorKind::Async(Block | Closure)) = body.generator_kind {
49+
if let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() {
50+
let body_id = BodyId {
51+
hir_id: body.value.hir_id,
52+
};
53+
let def_id = cx.tcx.hir().body_owner_def_id(body_id);
54+
let typeck_results = cx.tcx.typeck(def_id);
55+
let expr_ty = typeck_results.expr_ty(&body.value);
56+
57+
if implements_trait(cx, expr_ty, future_trait_def_id, &[]) {
58+
let return_expr_span = match &body.value.kind {
59+
// XXXkhuey there has to be a better way.
60+
ExprKind::Block(block, _) => block.expr.map(|e| e.span),
61+
ExprKind::Path(QPath::Resolved(_, path)) => Some(path.span),
62+
_ => None,
63+
};
64+
if let Some(return_expr_span) = return_expr_span {
65+
span_lint_and_then(
66+
cx,
67+
ASYNC_YIELDS_ASYNC,
68+
return_expr_span,
69+
"an async construct yields a type which is itself awaitable",
70+
|db| {
71+
db.span_label(body.value.span, "outer async construct");
72+
db.span_label(return_expr_span, "awaitable value not awaited");
73+
db.span_suggestion(
74+
return_expr_span,
75+
"consider awaiting this value",
76+
format!("{}.await", snippet(cx, return_expr_span, "..")),
77+
Applicability::MaybeIncorrect,
78+
);
79+
},
80+
);
81+
}
82+
}
83+
}
84+
}
85+
}
86+
}

clippy_lints/src/default_trait_access.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ impl<'tcx> LateLintPass<'tcx> for DefaultTraitAccess {
5555
// TODO: Work out a way to put "whatever the imported way of referencing
5656
// this type in this file" rather than a fully-qualified type.
5757
let expr_ty = cx.typeck_results().expr_ty(expr);
58-
if let ty::Adt(..) = expr_ty.kind {
59-
let replacement = format!("{}::default()", expr_ty);
58+
if let ty::Adt(def, ..) = expr_ty.kind {
59+
let replacement = format!("{}::default()", cx.tcx.def_path_str(def.did));
6060
span_lint_and_sugg(
6161
cx,
6262
DEFAULT_TRAIT_ACCESS,

clippy_lints/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ mod arithmetic;
154154
mod as_conversions;
155155
mod assertions_on_constants;
156156
mod assign_ops;
157+
mod async_yields_async;
157158
mod atomic_ordering;
158159
mod attrs;
159160
mod await_holding_lock;
@@ -483,6 +484,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
483484
&assertions_on_constants::ASSERTIONS_ON_CONSTANTS,
484485
&assign_ops::ASSIGN_OP_PATTERN,
485486
&assign_ops::MISREFACTORED_ASSIGN_OP,
487+
&async_yields_async::ASYNC_YIELDS_ASYNC,
486488
&atomic_ordering::INVALID_ATOMIC_ORDERING,
487489
&attrs::BLANKET_CLIPPY_RESTRICTION_LINTS,
488490
&attrs::DEPRECATED_CFG_ATTR,
@@ -1099,6 +1101,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
10991101
store.register_late_pass(|| box unwrap_in_result::UnwrapInResult);
11001102
store.register_late_pass(|| box self_assignment::SelfAssignment);
11011103
store.register_late_pass(|| box float_equality_without_abs::FloatEqualityWithoutAbs);
1104+
store.register_late_pass(|| box async_yields_async::AsyncYieldsAsync);
11021105

11031106
store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
11041107
LintId::of(&arithmetic::FLOAT_ARITHMETIC),
@@ -1232,6 +1235,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
12321235
LintId::of(&assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
12331236
LintId::of(&assign_ops::ASSIGN_OP_PATTERN),
12341237
LintId::of(&assign_ops::MISREFACTORED_ASSIGN_OP),
1238+
LintId::of(&async_yields_async::ASYNC_YIELDS_ASYNC),
12351239
LintId::of(&atomic_ordering::INVALID_ATOMIC_ORDERING),
12361240
LintId::of(&attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
12371241
LintId::of(&attrs::DEPRECATED_CFG_ATTR),
@@ -1675,6 +1679,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
16751679

16761680
store.register_group(true, "clippy::correctness", Some("clippy_correctness"), vec![
16771681
LintId::of(&approx_const::APPROX_CONSTANT),
1682+
LintId::of(&async_yields_async::ASYNC_YIELDS_ASYNC),
16781683
LintId::of(&atomic_ordering::INVALID_ATOMIC_ORDERING),
16791684
LintId::of(&attrs::DEPRECATED_SEMVER),
16801685
LintId::of(&attrs::MISMATCHED_TARGET_OS),

clippy_lints/src/methods/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,20 +1324,20 @@ declare_clippy_lint! {
13241324
}
13251325

13261326
declare_clippy_lint! {
1327-
/// **What it does:** Warns when using push_str with a single-character string literal,
1328-
/// and push with a char would work fine.
1327+
/// **What it does:** Warns when using `push_str` with a single-character string literal,
1328+
/// and `push` with a `char` would work fine.
13291329
///
1330-
/// **Why is this bad?** It's less clear that we are pushing a single character
1330+
/// **Why is this bad?** It's less clear that we are pushing a single character.
13311331
///
13321332
/// **Known problems:** None
13331333
///
13341334
/// **Example:**
1335-
/// ```
1335+
/// ```rust
13361336
/// let mut string = String::new();
13371337
/// string.push_str("R");
13381338
/// ```
13391339
/// Could be written as
1340-
/// ```
1340+
/// ```rust
13411341
/// let mut string = String::new();
13421342
/// string.push('R');
13431343
/// ```

clippy_lints/src/transmute.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,9 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
331331
if let Some(def_id) = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id();
332332
if match_def_path(cx, def_id, &paths::TRANSMUTE);
333333
then {
334-
// Avoid suggesting from/to bits in const contexts.
334+
// Avoid suggesting from/to bits and dereferencing raw pointers in const contexts.
335335
// See https://github.com/rust-lang/rust/issues/73736 for progress on making them `const fn`.
336+
// And see https://github.com/rust-lang/rust/issues/51911 for dereferencing raw pointers.
336337
let const_context = in_constant(cx, e.hir_id);
337338

338339
let from_ty = cx.typeck_results().expr_ty(&args[0]);
@@ -486,7 +487,8 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
486487
Applicability::Unspecified,
487488
);
488489
} else {
489-
if cx.tcx.erase_regions(&from_ty) != cx.tcx.erase_regions(&to_ty) {
490+
if (cx.tcx.erase_regions(&from_ty) != cx.tcx.erase_regions(&to_ty))
491+
&& !const_context {
490492
span_lint_and_then(
491493
cx,
492494
TRANSMUTE_PTR_TO_PTR,

clippy_lints/src/utils/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -899,7 +899,7 @@ pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_>, expr: &Expr<'_
899899
return match res {
900900
def::Res::Def(DefKind::Variant | DefKind::Ctor(..), ..) => true,
901901
// FIXME: check the constness of the arguments, see https://github.com/rust-lang/rust-clippy/pull/5682#issuecomment-638681210
902-
def::Res::Def(DefKind::Fn, def_id) if has_no_arguments(cx, def_id) => {
902+
def::Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) if has_no_arguments(cx, def_id) => {
903903
const_eval::is_const_fn(cx.tcx, def_id)
904904
},
905905
def::Res::Def(_, def_id) => cx.tcx.is_promotable_const_fn(def_id),

clippy_lints/src/utils/sugg.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,11 @@ impl<'a> Sugg<'a> {
132132
pub fn ast(cx: &EarlyContext<'_>, expr: &ast::Expr, default: &'a str) -> Self {
133133
use rustc_ast::ast::RangeLimits;
134134

135-
let snippet = snippet(cx, expr.span, default);
135+
let snippet = if expr.span.from_expansion() {
136+
snippet_with_macro_callsite(cx, expr.span, default)
137+
} else {
138+
snippet(cx, expr.span, default)
139+
};
136140

137141
match expr.kind {
138142
ast::ExprKind::AddrOf(..)

src/lintlist/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
5252
deprecation: None,
5353
module: "assign_ops",
5454
},
55+
Lint {
56+
name: "async_yields_async",
57+
group: "correctness",
58+
desc: "async blocks that return a type that can be awaited",
59+
deprecation: None,
60+
module: "async_yields_async",
61+
},
5562
Lint {
5663
name: "await_holding_lock",
5764
group: "pedantic",

0 commit comments

Comments
 (0)