Skip to content

Commit d5a8be4

Browse files
authored
Rollup merge of rust-lang#105464 - nbdd0121:hir, r=compiler-errors
Support #[track_caller] on async closures Follow up on rust-lang#105180 r? `@compiler-errors` cc `@cjgillot`
2 parents 9448ab6 + 3c0983c commit d5a8be4

File tree

10 files changed

+124
-49
lines changed

10 files changed

+124
-49
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+48-37
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,44 @@ impl<'hir> LoweringContext<'_, 'hir> {
3131

3232
pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
3333
ensure_sufficient_stack(|| {
34+
match &e.kind {
35+
// Paranthesis expression does not have a HirId and is handled specially.
36+
ExprKind::Paren(ex) => {
37+
let mut ex = self.lower_expr_mut(ex);
38+
// Include parens in span, but only if it is a super-span.
39+
if e.span.contains(ex.span) {
40+
ex.span = self.lower_span(e.span);
41+
}
42+
// Merge attributes into the inner expression.
43+
if !e.attrs.is_empty() {
44+
let old_attrs =
45+
self.attrs.get(&ex.hir_id.local_id).map(|la| *la).unwrap_or(&[]);
46+
self.attrs.insert(
47+
ex.hir_id.local_id,
48+
&*self.arena.alloc_from_iter(
49+
e.attrs
50+
.iter()
51+
.map(|a| self.lower_attr(a))
52+
.chain(old_attrs.iter().cloned()),
53+
),
54+
);
55+
}
56+
return ex;
57+
}
58+
// Desugar `ExprForLoop`
59+
// from: `[opt_ident]: for <pat> in <head> <body>`
60+
//
61+
// This also needs special handling because the HirId of the returned `hir::Expr` will not
62+
// correspond to the `e.id`, so `lower_expr_for` handles attribute lowering itself.
63+
ExprKind::ForLoop(pat, head, body, opt_label) => {
64+
return self.lower_expr_for(e, pat, head, body, *opt_label);
65+
}
66+
_ => (),
67+
}
68+
69+
let hir_id = self.lower_node_id(e.id);
70+
self.lower_attrs(hir_id, &e.attrs);
71+
3472
let kind = match &e.kind {
3573
ExprKind::Box(inner) => hir::ExprKind::Box(self.lower_expr(inner)),
3674
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
@@ -48,7 +86,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
4886
if e.attrs.get(0).map_or(false, |a| a.has_name(sym::rustc_box)) {
4987
if let [inner] = &args[..] && e.attrs.len() == 1 {
5088
let kind = hir::ExprKind::Box(self.lower_expr(&inner));
51-
let hir_id = self.lower_node_id(e.id);
5289
return hir::Expr { hir_id, kind, span: self.lower_span(e.span) };
5390
} else {
5491
self.tcx.sess.emit_err(RustcBoxAttributeError { span: e.span });
@@ -147,7 +184,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
147184
),
148185
ExprKind::Async(capture_clause, closure_node_id, block) => self.make_async_expr(
149186
*capture_clause,
150-
None,
187+
hir_id,
151188
*closure_node_id,
152189
None,
153190
e.span,
@@ -184,6 +221,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
184221
binder,
185222
*capture_clause,
186223
e.id,
224+
hir_id,
187225
*closure_id,
188226
fn_decl,
189227
body,
@@ -279,39 +317,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
279317
ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
280318
ExprKind::Err => hir::ExprKind::Err,
281319
ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr),
282-
ExprKind::Paren(ex) => {
283-
let mut ex = self.lower_expr_mut(ex);
284-
// Include parens in span, but only if it is a super-span.
285-
if e.span.contains(ex.span) {
286-
ex.span = self.lower_span(e.span);
287-
}
288-
// Merge attributes into the inner expression.
289-
if !e.attrs.is_empty() {
290-
let old_attrs =
291-
self.attrs.get(&ex.hir_id.local_id).map(|la| *la).unwrap_or(&[]);
292-
self.attrs.insert(
293-
ex.hir_id.local_id,
294-
&*self.arena.alloc_from_iter(
295-
e.attrs
296-
.iter()
297-
.map(|a| self.lower_attr(a))
298-
.chain(old_attrs.iter().cloned()),
299-
),
300-
);
301-
}
302-
return ex;
303-
}
304320

305-
// Desugar `ExprForLoop`
306-
// from: `[opt_ident]: for <pat> in <head> <body>`
307-
ExprKind::ForLoop(pat, head, body, opt_label) => {
308-
return self.lower_expr_for(e, pat, head, body, *opt_label);
309-
}
321+
ExprKind::Paren(_) | ExprKind::ForLoop(..) => unreachable!("already handled"),
322+
310323
ExprKind::MacCall(_) => panic!("{:?} shouldn't exist here", e.span),
311324
};
312325

313-
let hir_id = self.lower_node_id(e.id);
314-
self.lower_attrs(hir_id, &e.attrs);
315326
hir::Expr { hir_id, kind, span: self.lower_span(e.span) }
316327
})
317328
}
@@ -576,7 +587,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
576587
pub(super) fn make_async_expr(
577588
&mut self,
578589
capture_clause: CaptureBy,
579-
outer_hir_id: Option<hir::HirId>,
590+
outer_hir_id: hir::HirId,
580591
closure_node_id: NodeId,
581592
ret_ty: Option<hir::FnRetTy<'hir>>,
582593
span: Span,
@@ -669,8 +680,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
669680
hir::ExprKind::Closure(c)
670681
};
671682

672-
let track_caller = outer_hir_id
673-
.and_then(|id| self.attrs.get(&id.local_id))
683+
let track_caller = self
684+
.attrs
685+
.get(&outer_hir_id.local_id)
674686
.map_or(false, |attrs| attrs.into_iter().any(|attr| attr.has_name(sym::track_caller)));
675687

676688
let hir_id = self.lower_node_id(closure_node_id);
@@ -985,6 +997,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
985997
binder: &ClosureBinder,
986998
capture_clause: CaptureBy,
987999
closure_id: NodeId,
1000+
closure_hir_id: hir::HirId,
9881001
inner_closure_id: NodeId,
9891002
decl: &FnDecl,
9901003
body: &Expr,
@@ -1018,9 +1031,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10181031

10191032
let async_body = this.make_async_expr(
10201033
capture_clause,
1021-
// FIXME(nbdd0121): This should also use a proper HIR id so `#[track_caller]`
1022-
// can be applied on async closures as well.
1023-
None,
1034+
closure_hir_id,
10241035
inner_closure_id,
10251036
async_ret_ty,
10261037
body.span,

compiler/rustc_ast_lowering/src/item.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1139,7 +1139,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
11391139

11401140
let async_expr = this.make_async_expr(
11411141
CaptureBy::Value,
1142-
Some(fn_id),
1142+
fn_id,
11431143
closure_id,
11441144
None,
11451145
body.span,

src/test/incremental/hashes/loop_expressions.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,9 @@ pub fn change_continue_label() {
187187
}
188188

189189
#[cfg(not(any(cfail1,cfail4)))]
190-
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, typeck")]
190+
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
191191
#[rustc_clean(cfg="cfail3")]
192-
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, typeck, optimized_mir")]
192+
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
193193
#[rustc_clean(cfg="cfail6")]
194194
pub fn change_continue_label() {
195195
let mut _x = 0;

src/test/incremental/hashes/while_let_loops.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,9 @@ pub fn change_break_label() {
158158
}
159159

160160
#[cfg(not(any(cfail1,cfail4)))]
161-
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
161+
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
162162
#[rustc_clean(cfg="cfail3")]
163-
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck")]
163+
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
164164
#[rustc_clean(cfg="cfail6")]
165165
pub fn change_break_label() {
166166
let mut _x = 0;
@@ -210,9 +210,9 @@ pub fn change_continue_label() {
210210
}
211211

212212
#[cfg(not(any(cfail1,cfail4)))]
213-
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
213+
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
214214
#[rustc_clean(cfg="cfail3")]
215-
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck")]
215+
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
216216
#[rustc_clean(cfg="cfail6")]
217217
pub fn change_continue_label() {
218218
let mut _x = 0;

src/test/incremental/hashes/while_loops.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,9 @@ pub fn change_break_label() {
158158
}
159159

160160
#[cfg(not(any(cfail1,cfail4)))]
161-
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
161+
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
162162
#[rustc_clean(cfg="cfail3")]
163-
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
163+
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
164164
#[rustc_clean(cfg="cfail6")]
165165
pub fn change_break_label() {
166166
let mut _x = 0;
@@ -212,9 +212,9 @@ pub fn change_continue_label() {
212212
}
213213

214214
#[cfg(not(any(cfail1,cfail4)))]
215-
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
215+
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
216216
#[rustc_clean(cfg="cfail3")]
217-
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
217+
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
218218
#[rustc_clean(cfg="cfail6")]
219219
pub fn change_continue_label() {
220220
let mut _x = 0;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// edition:2021
2+
3+
#![feature(closure_track_caller, stmt_expr_attributes)]
4+
5+
fn main() {
6+
let _ = #[track_caller] async {
7+
//~^ ERROR attribute should be applied to a function definition [E0739]
8+
};
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0739]: attribute should be applied to a function definition
2+
--> $DIR/async-block.rs:6:13
3+
|
4+
LL | let _ = #[track_caller] async {
5+
| _____________^^^^^^^^^^^^^^^_-
6+
LL | |
7+
LL | | };
8+
| |_____- not a function definition
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0739`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// edition:2021
2+
3+
#![feature(async_closure, stmt_expr_attributes)]
4+
5+
fn main() {
6+
let _ = #[track_caller] async || {
7+
//~^ ERROR `#[track_caller]` on closures is currently unstable [E0658]
8+
//~| ERROR `#[track_caller]` on closures is currently unstable [E0658]
9+
};
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
error[E0658]: `#[track_caller]` on closures is currently unstable
2+
--> $DIR/async-closure-gate.rs:6:13
3+
|
4+
LL | let _ = #[track_caller] async || {
5+
| ^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
8+
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
9+
10+
error[E0658]: `#[track_caller]` on closures is currently unstable
11+
--> $DIR/async-closure-gate.rs:6:38
12+
|
13+
LL | let _ = #[track_caller] async || {
14+
| ______________________________________^
15+
LL | |
16+
LL | |
17+
LL | | };
18+
| |_____^
19+
|
20+
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
21+
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
22+
23+
error: aborting due to 2 previous errors
24+
25+
For more information about this error, try `rustc --explain E0658`.

src/test/ui/async-await/track-caller/panic-track-caller.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// run-pass
22
// edition:2021
33
// needs-unwind
4-
#![feature(closure_track_caller)]
4+
#![feature(closure_track_caller, async_closure, stmt_expr_attributes)]
55

66
use std::future::Future;
77
use std::panic;
@@ -67,6 +67,13 @@ async fn foo_assoc() {
6767
Foo::bar_assoc().await
6868
}
6969

70+
async fn foo_closure() {
71+
let c = #[track_caller] async || {
72+
panic!();
73+
};
74+
c().await
75+
}
76+
7077
fn panicked_at(f: impl FnOnce() + panic::UnwindSafe) -> u32 {
7178
let loc = Arc::new(Mutex::new(None));
7279

@@ -87,4 +94,5 @@ fn main() {
8794
assert_eq!(panicked_at(|| block_on(foo())), 41);
8895
assert_eq!(panicked_at(|| block_on(foo_track_caller())), 54);
8996
assert_eq!(panicked_at(|| block_on(foo_assoc())), 67);
97+
assert_eq!(panicked_at(|| block_on(foo_closure())), 74);
9098
}

0 commit comments

Comments
 (0)