Skip to content

Commit 3e35631

Browse files
committed
Auto merge of #120089 - matthiaskrgr:rollup-xyfqrb5, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #119172 (Detect `NulInCStr` error earlier.) - #119833 (Make tcx optional from StableMIR run macro and extend it to accept closures) - #119967 (Add `PatKind::Err` to AST/HIR) - #119978 (Move async closure parameters into the resultant closure's future eagerly) - #120021 (don't store const var origins for known vars) - #120038 (Don't create a separate "basename" when naming and opening a MIR dump file) - #120057 (Don't ICE when deducing future output if other errors already occurred) - #120073 (Remove spastorino from users_on_vacation) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 90b6648 + 04ad168 commit 3e35631

File tree

9 files changed

+92
-46
lines changed

9 files changed

+92
-46
lines changed

clippy_lints/src/async_yields_async.rs

Lines changed: 60 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -45,50 +45,72 @@ declare_lint_pass!(AsyncYieldsAsync => [ASYNC_YIELDS_ASYNC]);
4545

4646
impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync {
4747
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
48-
// For functions, with explicitly defined types, don't warn.
49-
// XXXkhuey maybe we should?
50-
if let ExprKind::Closure(Closure {
51-
kind:
52-
ClosureKind::Coroutine(CoroutineKind::Desugared(
53-
CoroutineDesugaring::Async,
54-
CoroutineSource::Block | CoroutineSource::Closure,
55-
)),
48+
let ExprKind::Closure(Closure {
49+
kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, kind)),
5650
body: body_id,
5751
..
5852
}) = expr.kind
59-
{
60-
if let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() {
61-
let typeck_results = cx.tcx.typeck_body(*body_id);
62-
let body = cx.tcx.hir().body(*body_id);
63-
let expr_ty = typeck_results.expr_ty(body.value);
53+
else {
54+
return;
55+
};
6456

65-
if implements_trait(cx, expr_ty, future_trait_def_id, &[]) {
66-
let return_expr_span = match &body.value.kind {
67-
// XXXkhuey there has to be a better way.
68-
ExprKind::Block(block, _) => block.expr.map(|e| e.span),
69-
ExprKind::Path(QPath::Resolved(_, path)) => Some(path.span),
70-
_ => None,
71-
};
72-
if let Some(return_expr_span) = return_expr_span {
73-
span_lint_hir_and_then(
74-
cx,
75-
ASYNC_YIELDS_ASYNC,
76-
body.value.hir_id,
57+
let body_expr = match kind {
58+
CoroutineSource::Fn => {
59+
// For functions, with explicitly defined types, don't warn.
60+
// XXXkhuey maybe we should?
61+
return;
62+
},
63+
CoroutineSource::Block => cx.tcx.hir().body(*body_id).value,
64+
CoroutineSource::Closure => {
65+
// Like `async fn`, async closures are wrapped in an additional block
66+
// to move all of the closure's arguments into the future.
67+
68+
let async_closure_body = cx.tcx.hir().body(*body_id).value;
69+
let ExprKind::Block(block, _) = async_closure_body.kind else {
70+
return;
71+
};
72+
let Some(block_expr) = block.expr else {
73+
return;
74+
};
75+
let ExprKind::DropTemps(body_expr) = block_expr.kind else {
76+
return;
77+
};
78+
body_expr
79+
},
80+
};
81+
82+
let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() else {
83+
return;
84+
};
85+
86+
let typeck_results = cx.tcx.typeck_body(*body_id);
87+
let expr_ty = typeck_results.expr_ty(body_expr);
88+
89+
if implements_trait(cx, expr_ty, future_trait_def_id, &[]) {
90+
let return_expr_span = match &body_expr.kind {
91+
// XXXkhuey there has to be a better way.
92+
ExprKind::Block(block, _) => block.expr.map(|e| e.span),
93+
ExprKind::Path(QPath::Resolved(_, path)) => Some(path.span),
94+
_ => None,
95+
};
96+
if let Some(return_expr_span) = return_expr_span {
97+
span_lint_hir_and_then(
98+
cx,
99+
ASYNC_YIELDS_ASYNC,
100+
body_expr.hir_id,
101+
return_expr_span,
102+
"an async construct yields a type which is itself awaitable",
103+
|db| {
104+
db.span_label(body_expr.span, "outer async construct");
105+
db.span_label(return_expr_span, "awaitable value not awaited");
106+
db.span_suggestion(
77107
return_expr_span,
78-
"an async construct yields a type which is itself awaitable",
79-
|db| {
80-
db.span_label(body.value.span, "outer async construct");
81-
db.span_label(return_expr_span, "awaitable value not awaited");
82-
db.span_suggestion(
83-
return_expr_span,
84-
"consider awaiting this value",
85-
format!("{}.await", snippet(cx, return_expr_span, "..")),
86-
Applicability::MaybeIncorrect,
87-
);
88-
},
108+
"consider awaiting this value",
109+
format!("{}.await", snippet(cx, return_expr_span, "..")),
110+
Applicability::MaybeIncorrect,
89111
);
90-
}
91-
}
112+
},
113+
);
92114
}
93115
}
94116
}

clippy_lints/src/equatable_if_let.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ fn unary_pattern(pat: &Pat<'_>) -> bool {
5151
| PatKind::Binding(..)
5252
| PatKind::Wild
5353
| PatKind::Never
54-
| PatKind::Or(_) => false,
54+
| PatKind::Or(_)
55+
| PatKind::Err(_) => false,
5556
PatKind::Struct(_, a, etc) => !etc && a.iter().all(|x| unary_pattern(x.pat)),
5657
PatKind::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => etc.as_opt_usize().is_none() && array_rec(a),
5758
PatKind::Ref(x, _) | PatKind::Box(x) => unary_pattern(x),

clippy_lints/src/matches/match_same_arms.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_hir::{Arm, Expr, ExprKind, HirId, HirIdMap, HirIdMapEntry, HirIdSet, P
1111
use rustc_lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
1212
use rustc_lint::LateContext;
1313
use rustc_middle::ty;
14-
use rustc_span::Symbol;
14+
use rustc_span::{ErrorGuaranteed, Symbol};
1515

1616
use super::MATCH_SAME_ARMS;
1717

@@ -167,6 +167,8 @@ enum NormalizedPat<'a> {
167167
/// contains everything afterwards. Note that either side, or both sides, may contain zero
168168
/// patterns.
169169
Slice(&'a [Self], Option<&'a [Self]>),
170+
/// A placeholder for a pattern that wasn't well formed in some way.
171+
Err(ErrorGuaranteed),
170172
}
171173

172174
#[derive(Clone, Copy)]
@@ -329,6 +331,7 @@ impl<'a> NormalizedPat<'a> {
329331
arena.alloc_from_iter(front.iter().map(|pat| Self::from_pat(cx, arena, pat))),
330332
wild_pat.map(|_| &*arena.alloc_from_iter(back.iter().map(|pat| Self::from_pat(cx, arena, pat)))),
331333
),
334+
PatKind::Err(guar) => Self::Err(guar),
332335
}
333336
}
334337

clippy_lints/src/redundant_closure_call.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ use clippy_utils::sugg::Sugg;
55
use rustc_errors::Applicability;
66
use rustc_hir as hir;
77
use rustc_hir::intravisit::{Visitor as HirVisitor, Visitor};
8-
use rustc_hir::{intravisit as hir_visit, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Node};
8+
use rustc_hir::{
9+
intravisit as hir_visit, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, ExprKind, Node,
10+
};
911
use rustc_lint::{LateContext, LateLintPass};
1012
use rustc_middle::hir::nested_filter;
1113
use rustc_middle::lint::in_external_macro;
@@ -166,10 +168,22 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
166168
if coroutine_kind.is_async()
167169
&& let hir::ExprKind::Closure(closure) = body.kind
168170
{
169-
let async_closure_body = cx.tcx.hir().body(closure.body);
171+
// Like `async fn`, async closures are wrapped in an additional block
172+
// to move all of the closure's arguments into the future.
173+
174+
let async_closure_body = cx.tcx.hir().body(closure.body).value;
175+
let ExprKind::Block(block, _) = async_closure_body.kind else {
176+
return;
177+
};
178+
let Some(block_expr) = block.expr else {
179+
return;
180+
};
181+
let ExprKind::DropTemps(body_expr) = block_expr.kind else {
182+
return;
183+
};
170184

171185
// `async x` is a syntax error, so it becomes `async { x }`
172-
if !matches!(async_closure_body.value.kind, hir::ExprKind::Block(_, _)) {
186+
if !matches!(body_expr.kind, hir::ExprKind::Block(_, _)) {
173187
hint = hint.blockify();
174188
}
175189

clippy_lints/src/unnested_or_patterns.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: us
226226
// Therefore they are not some form of constructor `C`,
227227
// with which a pattern `C(p_0)` may be formed,
228228
// which we would want to join with other `C(p_j)`s.
229-
Ident(.., None) | Lit(_) | Wild | Never | Path(..) | Range(..) | Rest | MacCall(_)
229+
Ident(.., None) | Lit(_) | Wild | Err(_) | Never | Path(..) | Range(..) | Rest | MacCall(_)
230230
// Skip immutable refs, as grouping them saves few characters,
231231
// and almost always requires adding parens (increasing noisiness).
232232
// In the case of only two patterns, replacement adds net characters.

clippy_lints/src/utils/author.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
710710
self.slice(start, |pat| self.pat(pat));
711711
self.slice(end, |pat| self.pat(pat));
712712
},
713+
PatKind::Err(_) => kind!("Err"),
713714
}
714715
}
715716

clippy_utils/src/hir_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
10071007
}
10081008
e.hash(&mut self.s);
10091009
},
1010-
PatKind::Never | PatKind::Wild => {},
1010+
PatKind::Never | PatKind::Wild | PatKind::Err(_) => {},
10111011
}
10121012
}
10131013

clippy_utils/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1733,6 +1733,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
17331733
},
17341734
}
17351735
},
1736+
PatKind::Err(_) => true,
17361737
}
17371738
}
17381739

tests/ui/author/blocks.stdout

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@ if let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_
4848
&& expr2 = &cx.tcx.hir().body(body_id1).value
4949
&& let ExprKind::Block(block, None) = expr2.kind
5050
&& block.stmts.is_empty()
51-
&& block.expr.is_none()
51+
&& let Some(trailing_expr) = block.expr
52+
&& let ExprKind::DropTemps(expr3) = trailing_expr.kind
53+
&& let ExprKind::Block(block1, None) = expr3.kind
54+
&& block1.stmts.is_empty()
55+
&& block1.expr.is_none()
5256
{
5357
// report your lint here
5458
}

0 commit comments

Comments
 (0)