mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-02 01:52:51 +00:00
Add pub as optional check_front_matter
async-pub check created a regression for default
This commit is contained in:
parent
c44a5feb05
commit
21c157442c
@ -204,6 +204,7 @@ impl<'a> Parser<'a> {
|
||||
def: &mut Defaultness,
|
||||
req_name: ReqName,
|
||||
) -> PResult<'a, Option<ItemInfo>> {
|
||||
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.
|
||||
|
@ -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)?;
|
||||
|
@ -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: Default>() -> 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() {}
|
||||
|
@ -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: Default>() -> 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: Default>() -> 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: Default>() -> 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: Default>() -> T;
|
||||
| -------------------------- `foo` from trait
|
||||
@ -37,7 +42,7 @@ LL | fn foo<T: Default>() -> 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`.
|
||||
|
@ -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 <s(f;Y(;]
|
||||
@ -12,7 +12,7 @@ error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `;`
|
||||
LL | impl W <s(f;Y(;]
|
||||
| ^ expected one of 7 possible tokens
|
||||
|
||||
error: expected one of `!`, `&&`, `&`, `(`, `)`, `*`, `+`, `,`, `->`, `...`, `::`, `<`, `>`, `?`, `[`, `_`, `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 <s(f;Y(;]
|
||||
|
Loading…
Reference in New Issue
Block a user