Skip to content

Commit 54db272

Browse files
Better error message in ed 2015
1 parent cd2fd34 commit 54db272

File tree

6 files changed

+75
-23
lines changed

6 files changed

+75
-23
lines changed

compiler/rustc_parse/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ parse_associated_static_item_not_allowed = associated `static` items are not all
2222
2323
parse_async_block_in_2015 = `async` blocks are only allowed in Rust 2018 or later
2424
25+
parse_async_bound_modifier_in_2015 = `async` trait bounds are only allowed in Rust 2018 or later
26+
2527
parse_async_fn_in_2015 = `async fn` is not permitted in Rust 2015
2628
.label = to use `async fn`, switch to Rust 2018 or later
2729

compiler/rustc_parse/src/errors.rs

+9
Original file line numberDiff line numberDiff line change
@@ -1588,6 +1588,15 @@ pub(crate) struct AsyncMoveBlockIn2015 {
15881588
pub span: Span,
15891589
}
15901590

1591+
#[derive(Diagnostic)]
1592+
#[diag(parse_async_bound_modifier_in_2015)]
1593+
pub(crate) struct AsyncBoundModifierIn2015 {
1594+
#[primary_span]
1595+
pub span: Span,
1596+
#[subdiagnostic]
1597+
pub help: HelpUseLatestEdition,
1598+
}
1599+
15911600
#[derive(Diagnostic)]
15921601
#[diag(parse_self_argument_pointer)]
15931602
pub(crate) struct SelfArgumentPointer {

compiler/rustc_parse/src/parser/ty.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use super::{Parser, PathStyle, TokenType};
33
use crate::errors::{
44
self, DynAfterMut, ExpectedFnPathFoundFnKeyword, ExpectedMutOrConstInRawPointerType,
55
FnPointerCannotBeAsync, FnPointerCannotBeConst, FnPtrWithGenerics, FnPtrWithGenericsSugg,
6-
InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime, NestedCVariadicType,
7-
ReturnTypesUseThinArrow,
6+
HelpUseLatestEdition, InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime,
7+
NestedCVariadicType, ReturnTypesUseThinArrow,
88
};
99
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
1010

@@ -882,6 +882,17 @@ impl<'a> Parser<'a> {
882882
let asyncness = if self.token.span.at_least_rust_2018() && self.eat_keyword(kw::Async) {
883883
self.sess.gated_spans.gate(sym::async_closure, self.prev_token.span);
884884
BoundAsyncness::Async(self.prev_token.span)
885+
} else if self.may_recover()
886+
&& self.token.span.is_rust_2015()
887+
&& self.is_kw_followed_by_ident(kw::Async)
888+
{
889+
self.bump(); // eat `async`
890+
self.dcx().emit_err(errors::AsyncBoundModifierIn2015 {
891+
span: self.prev_token.span,
892+
help: HelpUseLatestEdition::new(),
893+
});
894+
self.sess.gated_spans.gate(sym::async_closure, self.prev_token.span);
895+
BoundAsyncness::Async(self.prev_token.span)
885896
} else {
886897
BoundAsyncness::Normal
887898
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// check-pass
2+
// Make sure that we don't eagerly recover `async ::Bound` in edition 2015.
3+
4+
mod async {
5+
pub trait Foo {}
6+
}
7+
8+
fn test(x: impl async ::Foo) {}
9+
10+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
// FIXME(async_closures): This error message could be made better.
2-
3-
fn foo(x: impl async Fn()) -> impl async Fn() {}
4-
//~^ ERROR expected
5-
//~| ERROR expected
6-
//~| ERROR expected
1+
fn foo(x: impl async Fn()) -> impl async Fn() { x }
2+
//~^ ERROR `async` trait bounds are only allowed in Rust 2018 or later
3+
//~| ERROR `async` trait bounds are only allowed in Rust 2018 or later
4+
//~| ERROR async closures are unstable
5+
//~| ERROR async closures are unstable
76

87
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,43 @@
1-
error: expected one of `:` or `|`, found `)`
2-
--> $DIR/edition-2015.rs:3:26
1+
error: `async` trait bounds are only allowed in Rust 2018 or later
2+
--> $DIR/edition-2015.rs:1:16
33
|
4-
LL | fn foo(x: impl async Fn()) -> impl async Fn() {}
5-
| ^ expected one of `:` or `|`
4+
LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
5+
| ^^^^^
6+
|
7+
= help: pass `--edition 2021` to `rustc`
8+
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
9+
10+
error: `async` trait bounds are only allowed in Rust 2018 or later
11+
--> $DIR/edition-2015.rs:1:36
12+
|
13+
LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
14+
| ^^^^^
15+
|
16+
= help: pass `--edition 2021` to `rustc`
17+
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
618

7-
error: expected one of `(`, `)`, `+`, `,`, `::`, or `<`, found `Fn`
8-
--> $DIR/edition-2015.rs:3:22
19+
error[E0658]: async closures are unstable
20+
--> $DIR/edition-2015.rs:1:16
21+
|
22+
LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
23+
| ^^^^^
924
|
10-
LL | fn foo(x: impl async Fn()) -> impl async Fn() {}
11-
| -^^ expected one of `(`, `)`, `+`, `,`, `::`, or `<`
12-
| |
13-
| help: missing `,`
25+
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
26+
= help: add `#![feature(async_closure)]` to the crate attributes to enable
27+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
28+
= help: to use an async block, remove the `||`: `async {`
1429

15-
error: expected one of `(`, `+`, `::`, `<`, `where`, or `{`, found `Fn`
16-
--> $DIR/edition-2015.rs:3:42
30+
error[E0658]: async closures are unstable
31+
--> $DIR/edition-2015.rs:1:36
32+
|
33+
LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
34+
| ^^^^^
1735
|
18-
LL | fn foo(x: impl async Fn()) -> impl async Fn() {}
19-
| ^^ expected one of `(`, `+`, `::`, `<`, `where`, or `{`
36+
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
37+
= help: add `#![feature(async_closure)]` to the crate attributes to enable
38+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
39+
= help: to use an async block, remove the `||`: `async {`
2040

21-
error: aborting due to 3 previous errors
41+
error: aborting due to 4 previous errors
2242

43+
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)