mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-29 02:03:53 +00:00
Rollup merge of #117282 - clubby789:recover-wrong-function-header, r=TaKO8Ki
Recover from incorrectly ordered/duplicated function keywords Fixes #115714
This commit is contained in:
commit
c828371179
@ -2401,22 +2401,39 @@ impl<'a> Parser<'a> {
|
|||||||
Misplaced(Span),
|
Misplaced(Span),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We may be able to recover
|
||||||
|
let mut recover_constness = constness;
|
||||||
|
let mut recover_asyncness = asyncness;
|
||||||
|
let mut recover_unsafety = unsafety;
|
||||||
// This will allow the machine fix to directly place the keyword in the correct place or to indicate
|
// This will allow the machine fix to directly place the keyword in the correct place or to indicate
|
||||||
// that the keyword is already present and the second instance should be removed.
|
// that the keyword is already present and the second instance should be removed.
|
||||||
let wrong_kw = if self.check_keyword(kw::Const) {
|
let wrong_kw = if self.check_keyword(kw::Const) {
|
||||||
match constness {
|
match constness {
|
||||||
Const::Yes(sp) => Some(WrongKw::Duplicated(sp)),
|
Const::Yes(sp) => Some(WrongKw::Duplicated(sp)),
|
||||||
Const::No => Some(WrongKw::Misplaced(async_start_sp)),
|
Const::No => {
|
||||||
|
recover_constness = Const::Yes(self.token.span);
|
||||||
|
Some(WrongKw::Misplaced(async_start_sp))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if self.check_keyword(kw::Async) {
|
} else if self.check_keyword(kw::Async) {
|
||||||
match asyncness {
|
match asyncness {
|
||||||
Async::Yes { span, .. } => Some(WrongKw::Duplicated(span)),
|
Async::Yes { span, .. } => Some(WrongKw::Duplicated(span)),
|
||||||
Async::No => Some(WrongKw::Misplaced(unsafe_start_sp)),
|
Async::No => {
|
||||||
|
recover_asyncness = Async::Yes {
|
||||||
|
span: self.token.span,
|
||||||
|
closure_id: DUMMY_NODE_ID,
|
||||||
|
return_impl_trait_id: DUMMY_NODE_ID,
|
||||||
|
};
|
||||||
|
Some(WrongKw::Misplaced(unsafe_start_sp))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if self.check_keyword(kw::Unsafe) {
|
} else if self.check_keyword(kw::Unsafe) {
|
||||||
match unsafety {
|
match unsafety {
|
||||||
Unsafe::Yes(sp) => Some(WrongKw::Duplicated(sp)),
|
Unsafe::Yes(sp) => Some(WrongKw::Duplicated(sp)),
|
||||||
Unsafe::No => Some(WrongKw::Misplaced(ext_start_sp)),
|
Unsafe::No => {
|
||||||
|
recover_unsafety = Unsafe::Yes(self.token.span);
|
||||||
|
Some(WrongKw::Misplaced(ext_start_sp))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -2486,6 +2503,23 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if wrong_kw.is_some()
|
||||||
|
&& self.may_recover()
|
||||||
|
&& self.look_ahead(1, |tok| tok.is_keyword_case(kw::Fn, case))
|
||||||
|
{
|
||||||
|
// Advance past the misplaced keyword and `fn`
|
||||||
|
self.bump();
|
||||||
|
self.bump();
|
||||||
|
err.emit();
|
||||||
|
return Ok(FnHeader {
|
||||||
|
constness: recover_constness,
|
||||||
|
unsafety: recover_unsafety,
|
||||||
|
asyncness: recover_asyncness,
|
||||||
|
ext,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,3 +3,4 @@
|
|||||||
|
|
||||||
pub async const fn x() {}
|
pub async const fn x() {}
|
||||||
//~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `const`
|
//~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `const`
|
||||||
|
//~| ERROR functions cannot be both `const` and `async`
|
||||||
|
@ -9,5 +9,14 @@ LL | pub async const fn x() {}
|
|||||||
|
|
|
|
||||||
= note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
|
= note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: functions cannot be both `const` and `async`
|
||||||
|
--> $DIR/no-async-const.rs:4:5
|
||||||
|
|
|
||||||
|
LL | pub async const fn x() {}
|
||||||
|
| ----^^^^^-^^^^^----------
|
||||||
|
| | |
|
||||||
|
| | `const` because of this
|
||||||
|
| `async` because of this
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -9,3 +9,5 @@ impl S {
|
|||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(FALSE)]
|
||||||
unsafe async fn f() {} //~ ERROR expected one of `extern` or `fn`, found keyword `async`
|
unsafe async fn f() {} //~ ERROR expected one of `extern` or `fn`, found keyword `async`
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
@ -1,16 +1,11 @@
|
|||||||
error: expected one of `extern` or `fn`, found keyword `async`
|
error: expected one of `extern` or `fn`, found keyword `async`
|
||||||
--> $DIR/no-unsafe-async.rs:7:12
|
--> $DIR/no-unsafe-async.rs:7:12
|
||||||
|
|
|
|
||||||
LL | impl S {
|
|
||||||
| - while parsing this item list starting here
|
|
||||||
LL | #[cfg(FALSE)]
|
|
||||||
LL | unsafe async fn g() {}
|
LL | unsafe async fn g() {}
|
||||||
| -------^^^^^
|
| -------^^^^^
|
||||||
| | |
|
| | |
|
||||||
| | expected one of `extern` or `fn`
|
| | expected one of `extern` or `fn`
|
||||||
| help: `async` must come before `unsafe`: `async unsafe`
|
| help: `async` must come before `unsafe`: `async unsafe`
|
||||||
LL | }
|
|
||||||
| - the item list ends here
|
|
||||||
|
|
|
|
||||||
= note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
|
= note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
|
||||||
|
|
||||||
|
@ -7,3 +7,8 @@ const async const fn test() {}
|
|||||||
//~| NOTE expected one of `extern`, `fn`, or `unsafe`
|
//~| NOTE expected one of `extern`, `fn`, or `unsafe`
|
||||||
//~| HELP `const` already used earlier, remove this one
|
//~| HELP `const` already used earlier, remove this one
|
||||||
//~| NOTE `const` first seen here
|
//~| NOTE `const` first seen here
|
||||||
|
//~| ERROR functions cannot be both `const` and `async`
|
||||||
|
//~| NOTE `const` because of this
|
||||||
|
//~| NOTE `async` because of this
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
@ -13,5 +13,14 @@ note: `const` first seen here
|
|||||||
LL | const async const fn test() {}
|
LL | const async const fn test() {}
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: functions cannot be both `const` and `async`
|
||||||
|
--> $DIR/const-async-const.rs:5:1
|
||||||
|
|
|
||||||
|
LL | const async const fn test() {}
|
||||||
|
| ^^^^^-^^^^^-------------------
|
||||||
|
| | |
|
||||||
|
| | `async` because of this
|
||||||
|
| `const` because of this
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
22
tests/ui/parser/issues/issue-87217-keyword-order/recovery.rs
Normal file
22
tests/ui/parser/issues/issue-87217-keyword-order/recovery.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// test for #115714
|
||||||
|
|
||||||
|
struct Misplaced;
|
||||||
|
|
||||||
|
impl Misplaced {
|
||||||
|
unsafe const fn from_u32(val: u32) {}
|
||||||
|
//~^ ERROR expected one of `extern` or `fn`
|
||||||
|
fn oof(self){}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Duplicated;
|
||||||
|
|
||||||
|
impl Duplicated {
|
||||||
|
unsafe unsafe fn from_u32(val: u32) {}
|
||||||
|
//~^ ERROR expected one of `extern` or `fn`
|
||||||
|
fn oof(self){}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
Misplaced.oof();
|
||||||
|
Duplicated.oof();
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
error: expected one of `extern` or `fn`, found keyword `const`
|
||||||
|
--> $DIR/recovery.rs:6:12
|
||||||
|
|
|
||||||
|
LL | unsafe const fn from_u32(val: u32) {}
|
||||||
|
| -------^^^^^
|
||||||
|
| | |
|
||||||
|
| | expected one of `extern` or `fn`
|
||||||
|
| help: `const` must come before `unsafe`: `const unsafe`
|
||||||
|
|
|
||||||
|
= note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
|
||||||
|
|
||||||
|
error: expected one of `extern` or `fn`, found keyword `unsafe`
|
||||||
|
--> $DIR/recovery.rs:14:12
|
||||||
|
|
|
||||||
|
LL | unsafe unsafe fn from_u32(val: u32) {}
|
||||||
|
| ^^^^^^
|
||||||
|
| |
|
||||||
|
| expected one of `extern` or `fn`
|
||||||
|
| help: `unsafe` already used earlier, remove this one
|
||||||
|
|
|
||||||
|
note: `unsafe` first seen here
|
||||||
|
--> $DIR/recovery.rs:14:5
|
||||||
|
|
|
||||||
|
LL | unsafe unsafe fn from_u32(val: u32) {}
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
@ -12,3 +12,8 @@ async unsafe const fn test() {}
|
|||||||
//~| HELP `const` must come before `async unsafe`
|
//~| HELP `const` must come before `async unsafe`
|
||||||
//~| SUGGESTION const async unsafe
|
//~| SUGGESTION const async unsafe
|
||||||
//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
|
//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
|
||||||
|
//~| ERROR functions cannot be both `const` and `async`
|
||||||
|
//~| NOTE `const` because of this
|
||||||
|
//~| NOTE `async` because of this
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
@ -9,5 +9,14 @@ LL | async unsafe const fn test() {}
|
|||||||
|
|
|
|
||||||
= note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
|
= note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: functions cannot be both `const` and `async`
|
||||||
|
--> $DIR/several-kw-jump.rs:9:1
|
||||||
|
|
|
||||||
|
LL | async unsafe const fn test() {}
|
||||||
|
| ^^^^^--------^^^^^-------------
|
||||||
|
| | |
|
||||||
|
| | `const` because of this
|
||||||
|
| `async` because of this
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -12,3 +12,5 @@ unsafe async fn test() {}
|
|||||||
//~| HELP `async` must come before `unsafe`
|
//~| HELP `async` must come before `unsafe`
|
||||||
//~| SUGGESTION async unsafe
|
//~| SUGGESTION async unsafe
|
||||||
//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
|
//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
@ -12,3 +12,5 @@ unsafe const fn test() {}
|
|||||||
//~| HELP `const` must come before `unsafe`
|
//~| HELP `const` must come before `unsafe`
|
||||||
//~| SUGGESTION const unsafe
|
//~| SUGGESTION const unsafe
|
||||||
//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
|
//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
@ -12,3 +12,5 @@ extern unsafe fn test() {}
|
|||||||
//~| HELP `unsafe` must come before `extern`
|
//~| HELP `unsafe` must come before `extern`
|
||||||
//~| SUGGESTION unsafe extern
|
//~| SUGGESTION unsafe extern
|
||||||
//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
|
//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
Loading…
Reference in New Issue
Block a user