From 9321efd8f7138e99c69d134fda24b7bf9dc0c95b Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Mon, 7 Sep 2020 22:27:00 +0800 Subject: [PATCH 1/3] Detect pub fn attr wrong order like `async pub` Redirects `const? async? unsafe? pub` to `pub const? async? unsafe?`. Fix #76437 --- compiler/rustc_parse/src/parser/item.rs | 27 ++++++++++++++-- src/test/ui/parser/default.rs | 4 +-- src/test/ui/parser/default.stderr | 31 ++++++++----------- src/test/ui/parser/duplicate-visibility.rs | 5 +-- .../ui/parser/duplicate-visibility.stderr | 25 ++++++--------- src/test/ui/parser/issue-63116.stderr | 4 +-- src/test/ui/parser/issue-76437-async.rs | 6 ++++ src/test/ui/parser/issue-76437-async.stderr | 11 +++++++ .../parser/issue-76437-const-async-unsafe.rs | 6 ++++ .../issue-76437-const-async-unsafe.stderr | 11 +++++++ src/test/ui/parser/issue-76437-const-async.rs | 6 ++++ .../ui/parser/issue-76437-const-async.stderr | 11 +++++++ src/test/ui/parser/issue-76437-const.rs | 6 ++++ src/test/ui/parser/issue-76437-const.stderr | 11 +++++++ .../ui/parser/issue-76437-pub-crate-unsafe.rs | 6 ++++ .../issue-76437-pub-crate-unsafe.stderr | 11 +++++++ src/test/ui/parser/issue-76437-unsafe.rs | 6 ++++ src/test/ui/parser/issue-76437-unsafe.stderr | 11 +++++++ 18 files changed, 156 insertions(+), 42 deletions(-) create mode 100644 src/test/ui/parser/issue-76437-async.rs create mode 100644 src/test/ui/parser/issue-76437-async.stderr create mode 100644 src/test/ui/parser/issue-76437-const-async-unsafe.rs create mode 100644 src/test/ui/parser/issue-76437-const-async-unsafe.stderr create mode 100644 src/test/ui/parser/issue-76437-const-async.rs create mode 100644 src/test/ui/parser/issue-76437-const-async.stderr create mode 100644 src/test/ui/parser/issue-76437-const.rs create mode 100644 src/test/ui/parser/issue-76437-const.stderr create mode 100644 src/test/ui/parser/issue-76437-pub-crate-unsafe.rs create mode 100644 src/test/ui/parser/issue-76437-pub-crate-unsafe.stderr create mode 100644 src/test/ui/parser/issue-76437-unsafe.rs create mode 100644 src/test/ui/parser/issue-76437-unsafe.stderr diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index a28595e6fae67..2dc4edf9a1441 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1639,7 +1639,8 @@ impl<'a> Parser<'a> { pub(super) fn check_fn_front_matter(&mut self) -> bool { // We use an over-approximation here. // `const const`, `fn const` won't parse, but we're not stepping over other syntax either. - const QUALS: [Symbol; 4] = [kw::Const, kw::Async, kw::Unsafe, kw::Extern]; + // `pub` is added in case users got confused with the ordering like `async pub fn`. + const QUALS: [Symbol; 5] = [kw::Pub, kw::Const, kw::Async, kw::Unsafe, kw::Extern]; self.check_keyword(kw::Fn) // Definitely an `fn`. // `$qual fn` or `$qual $qual`: || QUALS.iter().any(|&kw| self.check_keyword(kw)) @@ -1668,6 +1669,7 @@ impl<'a> Parser<'a> { /// FnFrontMatter = FnQual "fn" ; /// ``` pub(super) fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> { + let sp_start = self.token.span; let constness = self.parse_constness(); let asyncness = self.parse_asyncness(); let unsafety = self.parse_unsafety(); @@ -1681,8 +1683,27 @@ impl<'a> Parser<'a> { // It is possible for `expect_one_of` to recover given the contents of // `self.expected_tokens`, therefore, do not use `self.unexpected()` which doesn't // account for this. - if !self.expect_one_of(&[], &[])? { - unreachable!() + match self.expect_one_of(&[], &[]) { + Ok(true) => {} + Ok(false) => unreachable!(), + Err(mut err) => { + // Recover incorrect visibility order such as `async pub`. + if self.check_keyword(kw::Pub) { + let sp = sp_start.to(self.prev_token.span); + if let Ok(snippet) = self.span_to_snippet(sp) { + let vis = self.parse_visibility(FollowedByType::No)?; + let vs = pprust::vis_to_string(&vis); + let vs = vs.trim_end(); + err.span_suggestion( + sp_start.to(self.prev_token.span), + &format!("visibility `{}` must come before `{}`", vs, snippet), + format!("{} {}", vs, snippet), + Applicability::MachineApplicable, + ); + } + } + return Err(err); + } } } diff --git a/src/test/ui/parser/default.rs b/src/test/ui/parser/default.rs index 52338c1f13aad..1e31a026d9482 100644 --- a/src/test/ui/parser/default.rs +++ b/src/test/ui/parser/default.rs @@ -1,3 +1,4 @@ +// ignore-tidy-linelength // Test successful and unsuccessful parsing of the `default` contextual keyword #![feature(specialization)] @@ -21,8 +22,7 @@ impl Foo for u16 { impl Foo for u32 { //~ ERROR not all trait items implemented, missing: `foo` default pub fn foo() -> T { T::default() } - //~^ ERROR `default` is not followed by an item - //~| ERROR non-item in item list + //~^ ERROR expected one of `async`, `const`, `extern`, `fn`, `pub`, `unsafe`, or `use`, found keyword `pub` } fn main() {} diff --git a/src/test/ui/parser/default.stderr b/src/test/ui/parser/default.stderr index 5b763ae72f5ee..489613b1e0965 100644 --- a/src/test/ui/parser/default.stderr +++ b/src/test/ui/parser/default.stderr @@ -1,30 +1,25 @@ -error: `default` is not followed by an item - --> $DIR/default.rs:23:5 - | -LL | default pub fn foo() -> T { T::default() } - | ^^^^^^^ the `default` qualifier - | - = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default` - -error: non-item in item list - --> $DIR/default.rs:23:13 +error: expected one of `async`, `const`, `extern`, `fn`, `pub`, `unsafe`, or `use`, found keyword `pub` + --> $DIR/default.rs:24:13 | LL | impl Foo for u32 { - | - item list starts here + | - while parsing this item list starting here LL | default pub fn foo() -> T { T::default() } - | ^^^ non-item starts here -... + | ^^^ + | | + | expected one of 7 possible tokens + | help: visibility `pub` must come before `default pub`: `pub default pub` +LL | LL | } - | - item list ends here + | - the item list ends here error[E0449]: unnecessary visibility qualifier - --> $DIR/default.rs:17:5 + --> $DIR/default.rs:18:5 | LL | pub default fn foo() -> T { | ^^^ `pub` not permitted here because it's implied warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default.rs:3:12 + --> $DIR/default.rs:4:12 | LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ @@ -34,7 +29,7 @@ LL | #![feature(specialization)] = help: consider using `min_specialization` instead, which is more stable and complete error[E0046]: not all trait items implemented, missing: `foo` - --> $DIR/default.rs:22:1 + --> $DIR/default.rs:23:1 | LL | fn foo() -> T; | -------------------------- `foo` from trait @@ -42,7 +37,7 @@ LL | fn foo() -> T; LL | impl Foo for u32 { | ^^^^^^^^^^^^^^^^ missing `foo` in implementation -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted Some errors have detailed explanations: E0046, E0449. For more information about an error, try `rustc --explain E0046`. diff --git a/src/test/ui/parser/duplicate-visibility.rs b/src/test/ui/parser/duplicate-visibility.rs index 547329cfb1b84..97f19b3da4526 100644 --- a/src/test/ui/parser/duplicate-visibility.rs +++ b/src/test/ui/parser/duplicate-visibility.rs @@ -1,7 +1,8 @@ +// ignore-tidy-linelength + fn main() {} extern "C" { pub pub fn foo(); - //~^ ERROR visibility `pub` is not followed by an item - //~| ERROR non-item in item list + //~^ ERROR expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `unsafe`, or `use`, found keyword `pub` } diff --git a/src/test/ui/parser/duplicate-visibility.stderr b/src/test/ui/parser/duplicate-visibility.stderr index 8d8122292ae9a..6ac27078ea387 100644 --- a/src/test/ui/parser/duplicate-visibility.stderr +++ b/src/test/ui/parser/duplicate-visibility.stderr @@ -1,21 +1,16 @@ -error: visibility `pub` is not followed by an item - --> $DIR/duplicate-visibility.rs:4:5 - | -LL | pub pub fn foo(); - | ^^^ the visibility - | - = help: you likely meant to define an item, e.g., `pub fn foo() {}` - -error: non-item in item list - --> $DIR/duplicate-visibility.rs:4:9 +error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `unsafe`, or `use`, found keyword `pub` + --> $DIR/duplicate-visibility.rs:6:9 | LL | extern "C" { - | - item list starts here + | - while parsing this item list starting here LL | pub pub fn foo(); - | ^^^ non-item starts here -... + | ^^^ + | | + | expected one of 9 possible tokens + | help: visibility `pub` must come before `pub pub`: `pub pub pub` +LL | LL | } - | - item list ends here + | - the item list ends here -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/src/test/ui/parser/issue-63116.stderr b/src/test/ui/parser/issue-63116.stderr index e249a93df92a2..8d46f9c0fc49b 100644 --- a/src/test/ui/parser/issue-63116.stderr +++ b/src/test/ui/parser/issue-63116.stderr @@ -1,4 +1,4 @@ -error: this file contains an unclosed delimiter +=rror: this file contains an unclosed delimiter --> $DIR/issue-63116.rs:3:18 | LL | impl W `, `...`, `::`, `:`, `<`, `=`, `>`, `?`, `[`, `_`, `async`, `const`, `dyn`, `extern`, `fn`, `for`, `impl`, `unsafe`, lifetime, or path, found `;` +error: expected one of `!`, `&&`, `&`, `(`, `)`, `*`, `+`, `,`, `->`, `...`, `::`, `<`, `>`, `?`, `[`, `_`, `async`, `const`, `dyn`, `extern`, `fn`, `for`, `impl`, `pub`, `unsafe`, lifetime, or path, found `;` --> $DIR/issue-63116.rs:3:15 | LL | impl W $DIR/issue-76437-async.rs:4:11 + | +LL | async pub fn t() {} + | ------^^^ + | | | + | | expected one of `extern`, `fn`, or `unsafe` + | help: visibility `pub` must come before `async`: `pub async` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issue-76437-const-async-unsafe.rs b/src/test/ui/parser/issue-76437-const-async-unsafe.rs new file mode 100644 index 0000000000000..f9c0c6dbed8e7 --- /dev/null +++ b/src/test/ui/parser/issue-76437-const-async-unsafe.rs @@ -0,0 +1,6 @@ +// edition:2018 + +mod t { + const async unsafe pub fn t() {} + //~^ ERROR expected one of `extern` or `fn`, found keyword `pub` +} diff --git a/src/test/ui/parser/issue-76437-const-async-unsafe.stderr b/src/test/ui/parser/issue-76437-const-async-unsafe.stderr new file mode 100644 index 0000000000000..2e91beda1165d --- /dev/null +++ b/src/test/ui/parser/issue-76437-const-async-unsafe.stderr @@ -0,0 +1,11 @@ +error: expected one of `extern` or `fn`, found keyword `pub` + --> $DIR/issue-76437-const-async-unsafe.rs:4:24 + | +LL | const async unsafe pub fn t() {} + | -------------------^^^ + | | | + | | expected one of `extern` or `fn` + | help: visibility `pub` must come before `const async unsafe`: `pub const async unsafe` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issue-76437-const-async.rs b/src/test/ui/parser/issue-76437-const-async.rs new file mode 100644 index 0000000000000..79bf801ece3cc --- /dev/null +++ b/src/test/ui/parser/issue-76437-const-async.rs @@ -0,0 +1,6 @@ +// edition:2018 + +mod t { + const async pub fn t() {} + //~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `pub` +} diff --git a/src/test/ui/parser/issue-76437-const-async.stderr b/src/test/ui/parser/issue-76437-const-async.stderr new file mode 100644 index 0000000000000..21b96c14d7de0 --- /dev/null +++ b/src/test/ui/parser/issue-76437-const-async.stderr @@ -0,0 +1,11 @@ +error: expected one of `extern`, `fn`, or `unsafe`, found keyword `pub` + --> $DIR/issue-76437-const-async.rs:4:17 + | +LL | const async pub fn t() {} + | ------------^^^ + | | | + | | expected one of `extern`, `fn`, or `unsafe` + | help: visibility `pub` must come before `const async`: `pub const async` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issue-76437-const.rs b/src/test/ui/parser/issue-76437-const.rs new file mode 100644 index 0000000000000..5dd151d8b7683 --- /dev/null +++ b/src/test/ui/parser/issue-76437-const.rs @@ -0,0 +1,6 @@ +// edition:2018 + +mod t { + const pub fn t() {} + //~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub` +} diff --git a/src/test/ui/parser/issue-76437-const.stderr b/src/test/ui/parser/issue-76437-const.stderr new file mode 100644 index 0000000000000..cf80d9a9037c9 --- /dev/null +++ b/src/test/ui/parser/issue-76437-const.stderr @@ -0,0 +1,11 @@ +error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub` + --> $DIR/issue-76437-const.rs:4:11 + | +LL | const pub fn t() {} + | ------^^^ + | | | + | | expected one of `async`, `extern`, `fn`, or `unsafe` + | help: visibility `pub` must come before `const`: `pub const` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issue-76437-pub-crate-unsafe.rs b/src/test/ui/parser/issue-76437-pub-crate-unsafe.rs new file mode 100644 index 0000000000000..e9269ef8e0fc7 --- /dev/null +++ b/src/test/ui/parser/issue-76437-pub-crate-unsafe.rs @@ -0,0 +1,6 @@ +// edition:2018 + +mod t { + unsafe pub(crate) fn t() {} + //~^ ERROR expected one of `extern` or `fn`, found keyword `pub` +} diff --git a/src/test/ui/parser/issue-76437-pub-crate-unsafe.stderr b/src/test/ui/parser/issue-76437-pub-crate-unsafe.stderr new file mode 100644 index 0000000000000..fa8f13721c894 --- /dev/null +++ b/src/test/ui/parser/issue-76437-pub-crate-unsafe.stderr @@ -0,0 +1,11 @@ +error: expected one of `extern` or `fn`, found keyword `pub` + --> $DIR/issue-76437-pub-crate-unsafe.rs:4:12 + | +LL | unsafe pub(crate) fn t() {} + | -------^^^------- + | | | + | | expected one of `extern` or `fn` + | help: visibility `pub(crate)` must come before `unsafe`: `pub(crate) unsafe` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issue-76437-unsafe.rs b/src/test/ui/parser/issue-76437-unsafe.rs new file mode 100644 index 0000000000000..95538aaea696f --- /dev/null +++ b/src/test/ui/parser/issue-76437-unsafe.rs @@ -0,0 +1,6 @@ +// edition:2018 + +mod t { + unsafe pub fn t() {} + //~^ ERROR expected one of `extern` or `fn`, found keyword `pub` +} diff --git a/src/test/ui/parser/issue-76437-unsafe.stderr b/src/test/ui/parser/issue-76437-unsafe.stderr new file mode 100644 index 0000000000000..c63292ef85395 --- /dev/null +++ b/src/test/ui/parser/issue-76437-unsafe.stderr @@ -0,0 +1,11 @@ +error: expected one of `extern` or `fn`, found keyword `pub` + --> $DIR/issue-76437-unsafe.rs:4:12 + | +LL | unsafe pub fn t() {} + | -------^^^ + | | | + | | expected one of `extern` or `fn` + | help: visibility `pub` must come before `unsafe`: `pub unsafe` + +error: aborting due to previous error + From c44a5feb0526edf44782c2c3e9012b3e408be725 Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Fri, 18 Sep 2020 00:56:04 +0800 Subject: [PATCH 2/3] Add help assertion for async pub test --- src/test/ui/parser/issue-76437-async.rs | 1 + src/test/ui/parser/issue-76437-const-async-unsafe.rs | 1 + src/test/ui/parser/issue-76437-const-async.rs | 1 + src/test/ui/parser/issue-76437-const.rs | 1 + src/test/ui/parser/issue-76437-pub-crate-unsafe.rs | 1 + src/test/ui/parser/issue-76437-unsafe.rs | 1 + 6 files changed, 6 insertions(+) diff --git a/src/test/ui/parser/issue-76437-async.rs b/src/test/ui/parser/issue-76437-async.rs index 6a6e96f2c881f..84ee3dd21123c 100644 --- a/src/test/ui/parser/issue-76437-async.rs +++ b/src/test/ui/parser/issue-76437-async.rs @@ -3,4 +3,5 @@ mod t { async pub fn t() {} //~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `pub` + //~| HELP visibility `pub` must come before `async` } diff --git a/src/test/ui/parser/issue-76437-const-async-unsafe.rs b/src/test/ui/parser/issue-76437-const-async-unsafe.rs index f9c0c6dbed8e7..f1e06e4ad89e7 100644 --- a/src/test/ui/parser/issue-76437-const-async-unsafe.rs +++ b/src/test/ui/parser/issue-76437-const-async-unsafe.rs @@ -3,4 +3,5 @@ mod t { const async unsafe pub fn t() {} //~^ ERROR expected one of `extern` or `fn`, found keyword `pub` + //~| HELP visibility `pub` must come before `const async unsafe` } diff --git a/src/test/ui/parser/issue-76437-const-async.rs b/src/test/ui/parser/issue-76437-const-async.rs index 79bf801ece3cc..3c789fdcd0228 100644 --- a/src/test/ui/parser/issue-76437-const-async.rs +++ b/src/test/ui/parser/issue-76437-const-async.rs @@ -3,4 +3,5 @@ mod t { const async pub fn t() {} //~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `pub` + //~| HELP visibility `pub` must come before `const async` } diff --git a/src/test/ui/parser/issue-76437-const.rs b/src/test/ui/parser/issue-76437-const.rs index 5dd151d8b7683..d3815a52346ee 100644 --- a/src/test/ui/parser/issue-76437-const.rs +++ b/src/test/ui/parser/issue-76437-const.rs @@ -3,4 +3,5 @@ mod t { const pub fn t() {} //~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub` + //~| HELP visibility `pub` must come before `const` } diff --git a/src/test/ui/parser/issue-76437-pub-crate-unsafe.rs b/src/test/ui/parser/issue-76437-pub-crate-unsafe.rs index e9269ef8e0fc7..daa1d120795fd 100644 --- a/src/test/ui/parser/issue-76437-pub-crate-unsafe.rs +++ b/src/test/ui/parser/issue-76437-pub-crate-unsafe.rs @@ -3,4 +3,5 @@ mod t { unsafe pub(crate) fn t() {} //~^ ERROR expected one of `extern` or `fn`, found keyword `pub` + //~| HELP visibility `pub(crate)` must come before `unsafe` } diff --git a/src/test/ui/parser/issue-76437-unsafe.rs b/src/test/ui/parser/issue-76437-unsafe.rs index 95538aaea696f..785a79a79a2e0 100644 --- a/src/test/ui/parser/issue-76437-unsafe.rs +++ b/src/test/ui/parser/issue-76437-unsafe.rs @@ -3,4 +3,5 @@ mod t { unsafe pub fn t() {} //~^ ERROR expected one of `extern` or `fn`, found keyword `pub` + //~| HELP visibility `pub` must come before `unsafe` } From 21c157442c1e97745b91b8c3286ceabbc9f7be3f Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Tue, 8 Dec 2020 00:32:13 +0800 Subject: [PATCH 3/3] Add pub as optional check_front_matter async-pub check created a regression for default --- compiler/rustc_parse/src/parser/item.rs | 21 ++++++++++++----- compiler/rustc_parse/src/parser/ty.rs | 4 ++-- src/test/ui/parser/default.rs | 4 ++-- src/test/ui/parser/default.stderr | 31 ++++++++++++++----------- src/test/ui/parser/issue-63116.stderr | 4 ++-- 5 files changed, 39 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 2dc4edf9a1441..65c104bf80b7a 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -204,6 +204,7 @@ impl<'a> Parser<'a> { def: &mut Defaultness, req_name: ReqName, ) -> PResult<'a, Option> { + let def_final = def == &Defaultness::Final; let mut def = || mem::replace(def, Defaultness::Final); let info = if self.eat_keyword(kw::Use) { @@ -226,7 +227,7 @@ impl<'a> Parser<'a> { } (Ident::invalid(), ItemKind::Use(tree)) - } else if self.check_fn_front_matter() { + } else if self.check_fn_front_matter(def_final) { // FUNCTION ITEM let (ident, sig, generics, body) = self.parse_fn(attrs, req_name, lo)?; (ident, ItemKind::Fn(box FnKind(def(), sig, generics, body))) @@ -1636,19 +1637,27 @@ impl<'a> Parser<'a> { } /// Is the current token the start of an `FnHeader` / not a valid parse? - pub(super) fn check_fn_front_matter(&mut self) -> bool { + /// + /// `check_pub` adds additional `pub` to the checks in case users place it + /// wrongly, can be used to ensure `pub` never comes after `default`. + pub(super) fn check_fn_front_matter(&mut self, check_pub: bool) -> bool { // We use an over-approximation here. // `const const`, `fn const` won't parse, but we're not stepping over other syntax either. - // `pub` is added in case users got confused with the ordering like `async pub fn`. - const QUALS: [Symbol; 5] = [kw::Pub, kw::Const, kw::Async, kw::Unsafe, kw::Extern]; + // `pub` is added in case users got confused with the ordering like `async pub fn`, + // only if it wasn't preceeded by `default` as `default pub` is invalid. + let quals: &[Symbol] = if check_pub { + &[kw::Pub, kw::Const, kw::Async, kw::Unsafe, kw::Extern] + } else { + &[kw::Const, kw::Async, kw::Unsafe, kw::Extern] + }; self.check_keyword(kw::Fn) // Definitely an `fn`. // `$qual fn` or `$qual $qual`: - || QUALS.iter().any(|&kw| self.check_keyword(kw)) + || quals.iter().any(|&kw| self.check_keyword(kw)) && self.look_ahead(1, |t| { // `$qual fn`, e.g. `const fn` or `async fn`. t.is_keyword(kw::Fn) // Two qualifiers `$qual $qual` is enough, e.g. `async unsafe`. - || t.is_non_raw_ident_where(|i| QUALS.contains(&i.name) + || t.is_non_raw_ident_where(|i| quals.contains(&i.name) // Rule out 2015 `const async: T = val`. && i.is_reserved() // Rule out unsafe extern block. diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 8f03bfd4c3ab7..0f7b8ebd376b9 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -209,7 +209,7 @@ impl<'a> Parser<'a> { } else if self.eat_keyword(kw::Underscore) { // A type to be inferred `_` TyKind::Infer - } else if self.check_fn_front_matter() { + } else if self.check_fn_front_matter(false) { // Function pointer type self.parse_ty_bare_fn(lo, Vec::new(), recover_return_sign)? } else if self.check_keyword(kw::For) { @@ -217,7 +217,7 @@ impl<'a> Parser<'a> { // `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T` // `for<'lt> Trait1<'lt> + Trait2 + 'a` let lifetime_defs = self.parse_late_bound_lifetime_defs()?; - if self.check_fn_front_matter() { + if self.check_fn_front_matter(false) { self.parse_ty_bare_fn(lo, lifetime_defs, recover_return_sign)? } else { let path = self.parse_path(PathStyle::Type)?; diff --git a/src/test/ui/parser/default.rs b/src/test/ui/parser/default.rs index 1e31a026d9482..52338c1f13aad 100644 --- a/src/test/ui/parser/default.rs +++ b/src/test/ui/parser/default.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // Test successful and unsuccessful parsing of the `default` contextual keyword #![feature(specialization)] @@ -22,7 +21,8 @@ impl Foo for u16 { impl Foo for u32 { //~ ERROR not all trait items implemented, missing: `foo` default pub fn foo() -> T { T::default() } - //~^ ERROR expected one of `async`, `const`, `extern`, `fn`, `pub`, `unsafe`, or `use`, found keyword `pub` + //~^ ERROR `default` is not followed by an item + //~| ERROR non-item in item list } fn main() {} diff --git a/src/test/ui/parser/default.stderr b/src/test/ui/parser/default.stderr index 489613b1e0965..5b763ae72f5ee 100644 --- a/src/test/ui/parser/default.stderr +++ b/src/test/ui/parser/default.stderr @@ -1,25 +1,30 @@ -error: expected one of `async`, `const`, `extern`, `fn`, `pub`, `unsafe`, or `use`, found keyword `pub` - --> $DIR/default.rs:24:13 +error: `default` is not followed by an item + --> $DIR/default.rs:23:5 + | +LL | default pub fn foo() -> T { T::default() } + | ^^^^^^^ the `default` qualifier + | + = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default` + +error: non-item in item list + --> $DIR/default.rs:23:13 | LL | impl Foo for u32 { - | - while parsing this item list starting here + | - item list starts here LL | default pub fn foo() -> T { T::default() } - | ^^^ - | | - | expected one of 7 possible tokens - | help: visibility `pub` must come before `default pub`: `pub default pub` -LL | + | ^^^ non-item starts here +... LL | } - | - the item list ends here + | - item list ends here error[E0449]: unnecessary visibility qualifier - --> $DIR/default.rs:18:5 + --> $DIR/default.rs:17:5 | LL | pub default fn foo() -> T { | ^^^ `pub` not permitted here because it's implied warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default.rs:4:12 + --> $DIR/default.rs:3:12 | LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ @@ -29,7 +34,7 @@ LL | #![feature(specialization)] = help: consider using `min_specialization` instead, which is more stable and complete error[E0046]: not all trait items implemented, missing: `foo` - --> $DIR/default.rs:23:1 + --> $DIR/default.rs:22:1 | LL | fn foo() -> T; | -------------------------- `foo` from trait @@ -37,7 +42,7 @@ LL | fn foo() -> T; LL | impl Foo for u32 { | ^^^^^^^^^^^^^^^^ missing `foo` in implementation -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 4 previous errors; 1 warning emitted Some errors have detailed explanations: E0046, E0449. For more information about an error, try `rustc --explain E0046`. diff --git a/src/test/ui/parser/issue-63116.stderr b/src/test/ui/parser/issue-63116.stderr index 8d46f9c0fc49b..e249a93df92a2 100644 --- a/src/test/ui/parser/issue-63116.stderr +++ b/src/test/ui/parser/issue-63116.stderr @@ -1,4 +1,4 @@ -=rror: this file contains an unclosed delimiter +error: this file contains an unclosed delimiter --> $DIR/issue-63116.rs:3:18 | LL | impl W `, `...`, `::`, `<`, `>`, `?`, `[`, `_`, `async`, `const`, `dyn`, `extern`, `fn`, `for`, `impl`, `pub`, `unsafe`, lifetime, or path, found `;` +error: expected one of `!`, `&&`, `&`, `(`, `)`, `*`, `+`, `,`, `->`, `...`, `::`, `:`, `<`, `=`, `>`, `?`, `[`, `_`, `async`, `const`, `dyn`, `extern`, `fn`, `for`, `impl`, `unsafe`, lifetime, or path, found `;` --> $DIR/issue-63116.rs:3:15 | LL | impl W