diff options
| author | clubby789 <jamie@hill-daniel.co.uk> | 2023-10-27 13:22:10 +0000 |
|---|---|---|
| committer | clubby789 <jamie@hill-daniel.co.uk> | 2023-10-27 18:29:43 +0000 |
| commit | be0b42fabe4b4abe10e7b6eb5e57ea12b6fa07c9 (patch) | |
| tree | 6588b04a225c58862a0f91233a901a2704279862 /compiler/rustc_parse/src/parser/item.rs | |
| parent | 54e57e66ffb8ef4f97916d46f40ddcb464fc8be3 (diff) | |
| download | rust-be0b42fabe4b4abe10e7b6eb5e57ea12b6fa07c9.tar.gz rust-be0b42fabe4b4abe10e7b6eb5e57ea12b6fa07c9.zip | |
Recover from incorrectly ordered/duplicated function keywords
Diffstat (limited to 'compiler/rustc_parse/src/parser/item.rs')
| -rw-r--r-- | compiler/rustc_parse/src/parser/item.rs | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 982f601c0d5..884ae7be2ef 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2382,22 +2382,39 @@ impl<'a> Parser<'a> { 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 // that the keyword is already present and the second instance should be removed. let wrong_kw = if self.check_keyword(kw::Const) { match constness { 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) { match asyncness { 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) { match unsafety { 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 { None @@ -2467,6 +2484,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); } } |
