Skip to content

Commit c616605

Browse files
committed
Point at enclosing fn/closure when it's not async
1 parent 91c36c4 commit c616605

File tree

5 files changed

+60
-41
lines changed

5 files changed

+60
-41
lines changed

src/librustc/hir/lowering.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ pub struct LoweringContext<'a> {
9999

100100
/// Used to get the current `fn`'s def span to point to when using `await`
101101
/// outside of an `async fn`.
102-
current_item_id: Option<hir::HirId>,
102+
current_item: Option<Span>,
103103

104104
catch_scopes: Vec<NodeId>,
105105
loop_scopes: Vec<NodeId>,
@@ -254,7 +254,7 @@ pub fn lower_crate(
254254
node_id_to_hir_id: IndexVec::new(),
255255
is_generator: false,
256256
is_async_body: false,
257-
current_item_id: None,
257+
current_item: None,
258258
is_in_trait_impl: false,
259259
lifetimes_to_define: Vec::new(),
260260
is_collecting_in_band_lifetimes: false,
@@ -3120,8 +3120,8 @@ impl<'a> LoweringContext<'a> {
31203120
}
31213121
ItemKind::Fn(ref decl, ref header, ref generics, ref body) => {
31223122
let fn_def_id = self.resolver.definitions().local_def_id(id);
3123-
let hir_id = self.lower_node_id(id);
31243123
self.with_new_scopes(|this| {
3124+
this.current_item = Some(ident.span);
31253125
let mut lower_fn = |decl: &FnDecl| {
31263126
// Note: we don't need to change the return type from `T` to
31273127
// `impl Future<Output = T>` here because lower_body
@@ -3159,7 +3159,6 @@ impl<'a> LoweringContext<'a> {
31593159
} else {
31603160
lower_fn(decl)
31613161
};
3162-
this.current_item_id = Some(hir_id);
31633162

31643163
hir::ItemKind::Fn(
31653164
fn_decl,
@@ -3661,6 +3660,7 @@ impl<'a> LoweringContext<'a> {
36613660
} else {
36623661
lower_method(sig)
36633662
};
3663+
self.current_item = Some(i.span);
36643664

36653665
(generics, hir::ImplItemKind::Method(sig, body_id))
36663666
}
@@ -4277,6 +4277,7 @@ impl<'a> LoweringContext<'a> {
42774277
let fn_decl = self.lower_fn_decl(decl, None, false, None);
42784278

42794279
self.with_new_scopes(|this| {
4280+
this.current_item = Some(fn_decl_span);
42804281
let mut is_generator = false;
42814282
let body_id = this.lower_body(Some(decl), |this| {
42824283
let e = this.lower_expr(body);
@@ -5565,11 +5566,8 @@ impl<'a> LoweringContext<'a> {
55655566
"`await` is only allowed inside `async` functions and blocks"
55665567
);
55675568
err.span_label(await_span, "only allowed inside `async` functions and blocks");
5568-
if let Some(item_id) = self.current_item_id {
5569-
err.span_label(
5570-
self.sess.source_map().def_span(self.items[&item_id].span),
5571-
"this function is not `async`",
5572-
);
5569+
if let Some(item_sp) = self.current_item {
5570+
err.span_label(item_sp, "this is not `async`");
55735571
}
55745572
err.emit();
55755573
return hir::ExprKind::Err;

src/test/ui/await-keyword/incorrect-syntax-suggestions.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,19 @@ fn foo16() -> Result<(), ()> {
8989
let _ = bar().await?; //~ ERROR `await` is only allowed inside `async` functions and blocks
9090
Ok(())
9191
}
92+
fn foo24() -> Result<(), ()> {
93+
fn foo() -> Result<(), ()> {
94+
let _ = bar().await?; //~ ERROR `await` is only allowed inside `async` functions and blocks
95+
Ok(())
96+
}
97+
foo()
98+
}
99+
fn foo25() -> Result<(), ()> {
100+
let foo = || {
101+
let _ = bar().await?; //~ ERROR `await` is only allowed inside `async` functions and blocks
102+
Ok(())
103+
};
104+
foo()
105+
}
92106

93107
fn main() {}

src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -91,75 +91,83 @@ LL | let _ = bar().await()?;
9191
error[E0728]: `await` is only allowed inside `async` functions and blocks
9292
--> $DIR/incorrect-syntax-suggestions.rs:55:13
9393
|
94-
LL | async fn foo8() -> Result<(), ()> {
95-
| --------------------------------- this function is not `async`
96-
...
94+
LL | fn foo9() -> Result<(), ()> {
95+
| ---- this is not `async`
9796
LL | let _ = await bar();
9897
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
9998

10099
error[E0728]: `await` is only allowed inside `async` functions and blocks
101100
--> $DIR/incorrect-syntax-suggestions.rs:60:13
102101
|
103-
LL | fn foo9() -> Result<(), ()> {
104-
| --------------------------- this function is not `async`
105-
...
102+
LL | fn foo10() -> Result<(), ()> {
103+
| ----- this is not `async`
106104
LL | let _ = await? bar();
107105
| ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
108106

109107
error[E0728]: `await` is only allowed inside `async` functions and blocks
110108
--> $DIR/incorrect-syntax-suggestions.rs:65:13
111109
|
112-
LL | fn foo10() -> Result<(), ()> {
113-
| ---------------------------- this function is not `async`
114-
...
110+
LL | fn foo11() -> Result<(), ()> {
111+
| ----- this is not `async`
115112
LL | let _ = await bar()?;
116113
| ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
117114

118115
error[E0728]: `await` is only allowed inside `async` functions and blocks
119116
--> $DIR/incorrect-syntax-suggestions.rs:70:14
120117
|
121-
LL | fn foo11() -> Result<(), ()> {
122-
| ---------------------------- this function is not `async`
123-
...
118+
LL | fn foo12() -> Result<(), ()> {
119+
| ----- this is not `async`
124120
LL | let _ = (await bar())?;
125121
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
126122

127123
error[E0728]: `await` is only allowed inside `async` functions and blocks
128124
--> $DIR/incorrect-syntax-suggestions.rs:75:13
129125
|
130-
LL | fn foo12() -> Result<(), ()> {
131-
| ---------------------------- this function is not `async`
132-
...
126+
LL | fn foo13() -> Result<(), ()> {
127+
| ----- this is not `async`
133128
LL | let _ = bar().await();
134129
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
135130

136131
error[E0728]: `await` is only allowed inside `async` functions and blocks
137132
--> $DIR/incorrect-syntax-suggestions.rs:80:13
138133
|
139-
LL | fn foo13() -> Result<(), ()> {
140-
| ---------------------------- this function is not `async`
141-
...
134+
LL | fn foo14() -> Result<(), ()> {
135+
| ----- this is not `async`
142136
LL | let _ = bar().await()?;
143137
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
144138

145139
error[E0728]: `await` is only allowed inside `async` functions and blocks
146140
--> $DIR/incorrect-syntax-suggestions.rs:85:13
147141
|
148-
LL | fn foo14() -> Result<(), ()> {
149-
| ---------------------------- this function is not `async`
150-
...
142+
LL | fn foo15() -> Result<(), ()> {
143+
| ----- this is not `async`
151144
LL | let _ = bar().await;
152145
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
153146

154147
error[E0728]: `await` is only allowed inside `async` functions and blocks
155148
--> $DIR/incorrect-syntax-suggestions.rs:89:13
156149
|
157-
LL | fn foo15() -> Result<(), ()> {
158-
| ---------------------------- this function is not `async`
159-
...
150+
LL | fn foo16() -> Result<(), ()> {
151+
| ----- this is not `async`
160152
LL | let _ = bar().await?;
161153
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
162154

155+
error[E0728]: `await` is only allowed inside `async` functions and blocks
156+
--> $DIR/incorrect-syntax-suggestions.rs:94:17
157+
|
158+
LL | fn foo() -> Result<(), ()> {
159+
| --- this is not `async`
160+
LL | let _ = bar().await?;
161+
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
162+
163+
error[E0728]: `await` is only allowed inside `async` functions and blocks
164+
--> $DIR/incorrect-syntax-suggestions.rs:101:17
165+
|
166+
LL | let foo = || {
167+
| -- this is not `async`
168+
LL | let _ = bar().await?;
169+
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
170+
163171
error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
164172
--> $DIR/incorrect-syntax-suggestions.rs:18:19
165173
|
@@ -169,6 +177,6 @@ LL | let _ = await bar()?;
169177
= help: the trait `std::ops::Try` is not implemented for `impl std::future::Future`
170178
= note: required by `std::ops::Try::into_result`
171179

172-
error: aborting due to 24 previous errors
180+
error: aborting due to 26 previous errors
173181

174182
For more information about this error, try `rustc --explain E0277`.

src/test/ui/issues/issue-51719.stderr

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
error[E0728]: `await` is only allowed inside `async` functions and blocks
22
--> $DIR/issue-51719.rs:10:19
33
|
4-
LL | async fn foo() {}
5-
| -------------- this function is not `async`
6-
...
74
LL | let _gen = || foo.await;
8-
| ^^^^^^^^^ only allowed inside `async` functions and blocks
5+
| -- ^^^^^^^^^ only allowed inside `async` functions and blocks
6+
| |
7+
| this is not `async`
98

109
error: aborting due to previous error
1110

src/test/ui/issues/issue-51751.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
error[E0728]: `await` is only allowed inside `async` functions and blocks
22
--> $DIR/issue-51751.rs:11:20
33
|
4-
LL | async fn inc(limit: i64) -> i64 {
5-
| ------------------------------- this function is not `async`
6-
...
4+
LL | fn main() {
5+
| ---- this is not `async`
6+
LL | let result = inc(10000);
77
LL | let finished = result.await;
88
| ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
99

0 commit comments

Comments
 (0)