diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-02-15 17:35:29 +0100 |
|---|---|---|
| committer | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-02-15 20:57:12 +0100 |
| commit | 0e0c0286a2dfe62ca3093e68a77931bff8896b01 (patch) | |
| tree | 6e61ae4d51ca4882262e6b31c0f48f2fe95a5b28 | |
| parent | 91110fda27b2d227a5c5b20e3be01a47f7e39910 (diff) | |
| download | rust-0e0c0286a2dfe62ca3093e68a77931bff8896b01.tar.gz rust-0e0c0286a2dfe62ca3093e68a77931bff8896b01.zip | |
fuse extern & associated item parsing up to defaultness
19 files changed, 81 insertions, 115 deletions
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 5fcd72090ec..20d6182ddc1 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -13,7 +13,7 @@ use syntax::ast::{AssocItem, AssocItemKind, Item, ItemKind, UseTree, UseTreeKind use syntax::ast::{Async, Const, Defaultness, IsAuto, PathSegment, Unsafe}; use syntax::ast::{BindingMode, Block, FnDecl, FnSig, Mac, MacArgs, MacDelimiter, Param, SelfKind}; use syntax::ast::{EnumDef, Generics, StructField, TraitRef, Ty, TyKind, Variant, VariantData}; -use syntax::ast::{FnHeader, ForeignItem, ForeignItemKind, Mutability, Visibility, VisibilityKind}; +use syntax::ast::{FnHeader, ForeignItem, Mutability, Visibility, VisibilityKind}; use syntax::ptr::P; use syntax::token; use syntax::tokenstream::{DelimSpan, TokenStream, TokenTree}; @@ -333,29 +333,19 @@ impl<'a> Parser<'a> { self.token.is_keyword(kw::Async) && self.is_keyword_ahead(1, &[kw::Fn]) } - fn missing_assoc_item_kind_err( - &self, - item_type: &str, - prev_span: Span, - ) -> DiagnosticBuilder<'a> { - let expected_kinds = if item_type == "extern" { - "missing `fn`, `type`, or `static`" - } else { - "missing `fn`, `type`, or `const`" - }; - - // Given this code `path(`, it seems like this is not - // setting the visibility of a macro invocation, but rather - // a mistyped method declaration. - // Create a diagnostic pointing out that `fn` is missing. - // - // x | pub path(&self) { - // | ^ missing `fn`, `type`, or `const` - // pub path( - // ^^ `sp` below will point to this + /// Given this code `path(`, it seems like this is not + /// setting the visibility of a macro invocation, + /// but rather a mistyped method declaration. + /// Create a diagnostic pointing out that `fn` is missing. + /// + /// ``` + /// x | pub path(&self) { + /// | ^ missing `fn`, `type`, `const`, or `static` + /// ``` + fn missing_nested_item_kind_err(&self, prev_span: Span) -> DiagnosticBuilder<'a> { let sp = prev_span.between(self.token.span); - let mut err = self - .struct_span_err(sp, &format!("{} for {}-item declaration", expected_kinds, item_type)); + let expected_kinds = "missing `fn`, `type`, `const`, or `static`"; + let mut err = self.struct_span_err(sp, &format!("{} for item declaration", expected_kinds)); err.span_label(sp, expected_kinds); err } @@ -639,7 +629,7 @@ impl<'a> Parser<'a> { fn parse_assoc_item( &mut self, at_end: &mut bool, - req_name: fn(&token::Token) -> bool, + req_name: ReqName, ) -> PResult<'a, P<AssocItem>> { let attrs = self.parse_outer_attributes()?; let mut unclosed_delims = vec![]; @@ -660,39 +650,47 @@ impl<'a> Parser<'a> { &mut self, at_end: &mut bool, mut attrs: Vec<Attribute>, - req_name: fn(&token::Token) -> bool, + req_name: ReqName, ) -> PResult<'a, AssocItem> { let lo = self.token.span; let vis = self.parse_visibility(FollowedByType::No)?; let defaultness = self.parse_defaultness(); + let (ident, kind) = self.parse_assoc_item_kind(at_end, &mut attrs, req_name, &vis)?; + let span = lo.to(self.prev_span); + let id = DUMMY_NODE_ID; + Ok(AssocItem { id, span, ident, attrs, vis, defaultness, kind, tokens: None }) + } - let (ident, kind) = if self.eat_keyword(kw::Type) { - self.parse_assoc_ty()? + fn parse_assoc_item_kind( + &mut self, + at_end: &mut bool, + attrs: &mut Vec<Attribute>, + req_name: ReqName, + vis: &Visibility, + ) -> PResult<'a, (Ident, AssocItemKind)> { + if self.eat_keyword(kw::Type) { + self.parse_assoc_ty() } else if self.check_fn_front_matter() { - let (ident, sig, generics, body) = self.parse_fn(at_end, &mut attrs, req_name)?; - (ident, AssocItemKind::Fn(sig, generics, body)) + let (ident, sig, generics, body) = self.parse_fn(at_end, attrs, req_name)?; + Ok((ident, AssocItemKind::Fn(sig, generics, body))) } else if self.is_static_global() { self.bump(); // `static` let mutbl = self.parse_mutability(); let (ident, ty, expr) = self.parse_item_const_common(Some(mutbl))?; - (ident, AssocItemKind::Static(ty, mutbl, expr)) + Ok((ident, AssocItemKind::Static(ty, mutbl, expr))) } else if self.eat_keyword(kw::Const) { let (ident, ty, expr) = self.parse_item_const_common(None)?; - (ident, AssocItemKind::Const(ty, expr)) + Ok((ident, AssocItemKind::Const(ty, expr))) } else if self.isnt_macro_invocation() { - return Err(self.missing_assoc_item_kind_err("associated", self.prev_span)); + Err(self.missing_nested_item_kind_err(self.prev_span)) } else if self.token.is_path_start() { let mac = self.parse_item_macro(&vis)?; *at_end = true; - (Ident::invalid(), AssocItemKind::Macro(mac)) + Ok((Ident::invalid(), AssocItemKind::Macro(mac))) } else { - self.recover_attrs_no_item(&attrs)?; - self.unexpected()? - }; - - let span = lo.to(self.prev_span); - let id = DUMMY_NODE_ID; - Ok(AssocItem { id, span, ident, attrs, vis, defaultness, kind, tokens: None }) + self.recover_attrs_no_item(attrs)?; + self.unexpected() + } } /// Parses the following grammar: @@ -869,46 +867,10 @@ impl<'a> Parser<'a> { let mut attrs = self.parse_outer_attributes()?; let lo = self.token.span; let vis = self.parse_visibility(FollowedByType::No)?; - - let (ident, kind) = if self.eat_keyword(kw::Type) { - // FOREIGN TYPE ITEM - self.parse_item_foreign_type()? - } else if self.check_fn_front_matter() { - // FOREIGN FUNCTION ITEM - let (ident, sig, generics, body) = self.parse_fn(at_end, &mut attrs, |_| true)?; - (ident, ForeignItemKind::Fn(sig, generics, body)) - } else if self.is_static_global() { - // FOREIGN STATIC ITEM - self.bump(); // `static` - let mutbl = self.parse_mutability(); - let (ident, ty, expr) = self.parse_item_const_common(Some(mutbl))?; - (ident, ForeignItemKind::Static(ty, mutbl, expr)) - } else if self.eat_keyword(kw::Const) { - let (ident, ty, expr) = self.parse_item_const_common(None)?; - (ident, ForeignItemKind::Const(ty, expr)) - } else if self.isnt_macro_invocation() { - return Err(self.missing_assoc_item_kind_err("extern", self.prev_span)); - } else if self.token.is_path_start() { - let mac = self.parse_item_macro(&vis)?; - *at_end = true; - (Ident::invalid(), ForeignItemKind::Macro(mac)) - } else { - self.recover_attrs_no_item(&attrs)?; - self.unexpected()? - }; + let (ident, kind) = self.parse_assoc_item_kind(at_end, &mut attrs, |_| true, &vis)?; Ok(P(self.mk_item(lo, ident, kind, vis, attrs))) } - /// Parses a type from a foreign module. - fn parse_item_foreign_type(&mut self) -> PResult<'a, (Ident, ForeignItemKind)> { - let (ident, kind) = self.parse_assoc_ty()?; - let kind = match kind { - AssocItemKind::TyAlias(g, b, d) => ForeignItemKind::TyAlias(g, b, d), - _ => unreachable!(), - }; - Ok((ident, kind)) - } - fn is_static_global(&mut self) -> bool { if self.check_keyword(kw::Static) { // Check if this could be a closure. diff --git a/src/test/ui/did_you_mean/issue-40006.rs b/src/test/ui/did_you_mean/issue-40006.rs index 60633c6930c..2ed682cea95 100644 --- a/src/test/ui/did_you_mean/issue-40006.rs +++ b/src/test/ui/did_you_mean/issue-40006.rs @@ -18,10 +18,10 @@ trait A { //~ ERROR missing trait B { fn xxx() { ### } //~ ERROR expected } -trait C { //~ ERROR missing `fn`, `type`, or `const` for associated-item declaration +trait C { //~ ERROR missing `fn`, `type`, `const`, or `static` for item declaration L = M; } -trait D { //~ ERROR missing `fn`, `type`, or `const` for associated-item declaration +trait D { //~ ERROR missing `fn`, `type`, `const`, or `static` for item declaration Z = { 2 + 3 }; } trait E { diff --git a/src/test/ui/did_you_mean/issue-40006.stderr b/src/test/ui/did_you_mean/issue-40006.stderr index 072e61f6a3c..119e30a3e0f 100644 --- a/src/test/ui/did_you_mean/issue-40006.stderr +++ b/src/test/ui/did_you_mean/issue-40006.stderr @@ -1,26 +1,26 @@ -error: missing `fn`, `type`, or `const` for associated-item declaration +error: missing `fn`, `type`, `const`, or `static` for item declaration --> $DIR/issue-40006.rs:1:13 | LL | impl dyn A { | _____________^ LL | | Y - | |____^ missing `fn`, `type`, or `const` + | |____^ missing `fn`, `type`, `const`, or `static` -error: missing `fn`, `type`, or `const` for associated-item declaration +error: missing `fn`, `type`, `const`, or `static` for item declaration --> $DIR/issue-40006.rs:7:10 | LL | trait X { | __________^ LL | | X() {} - | |____^ missing `fn`, `type`, or `const` + | |____^ missing `fn`, `type`, `const`, or `static` -error: missing `fn`, `type`, or `const` for associated-item declaration +error: missing `fn`, `type`, `const`, or `static` for item declaration --> $DIR/issue-40006.rs:15:10 | LL | trait A { | __________^ LL | | X() {} - | |____^ missing `fn`, `type`, or `const` + | |____^ missing `fn`, `type`, `const`, or `static` error: expected `[`, found `#` --> $DIR/issue-40006.rs:19:17 @@ -28,21 +28,21 @@ error: expected `[`, found `#` LL | fn xxx() { ### } | ^ expected `[` -error: missing `fn`, `type`, or `const` for associated-item declaration +error: missing `fn`, `type`, `const`, or `static` for item declaration --> $DIR/issue-40006.rs:21:10 | LL | trait C { | __________^ LL | | L = M; - | |____^ missing `fn`, `type`, or `const` + | |____^ missing `fn`, `type`, `const`, or `static` -error: missing `fn`, `type`, or `const` for associated-item declaration +error: missing `fn`, `type`, `const`, or `static` for item declaration --> $DIR/issue-40006.rs:24:10 | LL | trait D { | __________^ LL | | Z = { 2 + 3 }; - | |____^ missing `fn`, `type`, or `const` + | |____^ missing `fn`, `type`, `const`, or `static` error: expected one of `!` or `::`, found `(` --> $DIR/issue-40006.rs:28:9 @@ -50,11 +50,11 @@ error: expected one of `!` or `::`, found `(` LL | ::Y (); | ^ expected one of `!` or `::` -error: missing `fn`, `type`, or `const` for associated-item declaration +error: missing `fn`, `type`, `const`, or `static` for item declaration --> $DIR/issue-40006.rs:32:8 | LL | pub hello_method(&self) { - | ^ missing `fn`, `type`, or `const` + | ^ missing `fn`, `type`, `const`, or `static` error[E0599]: no method named `hello_method` found for struct `S` in the current scope --> $DIR/issue-40006.rs:38:7 diff --git a/src/test/ui/macros/issue-54441.rs b/src/test/ui/macros/issue-54441.rs index a70163df1cb..5570f081b15 100644 --- a/src/test/ui/macros/issue-54441.rs +++ b/src/test/ui/macros/issue-54441.rs @@ -1,5 +1,5 @@ macro_rules! m { - //~^ ERROR missing `fn`, `type`, or `static` for extern-item declaration + //~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration () => { let }; diff --git a/src/test/ui/macros/issue-54441.stderr b/src/test/ui/macros/issue-54441.stderr index 761e7aec723..5857aacb431 100644 --- a/src/test/ui/macros/issue-54441.stderr +++ b/src/test/ui/macros/issue-54441.stderr @@ -1,11 +1,11 @@ -error: missing `fn`, `type`, or `static` for extern-item declaration +error: missing `fn`, `type`, `const`, or `static` for item declaration --> $DIR/issue-54441.rs:1:1 | LL | / macro_rules! m { LL | | LL | | () => { LL | | let - | |________^ missing `fn`, `type`, or `static` + | |________^ missing `fn`, `type`, `const`, or `static` error: aborting due to previous error diff --git a/src/test/ui/parser/default.rs b/src/test/ui/parser/default.rs index 65ecb1ebbe9..50952eef22f 100644 --- a/src/test/ui/parser/default.rs +++ b/src/test/ui/parser/default.rs @@ -20,7 +20,7 @@ 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 missing `fn`, `type`, or `const` for associated-item declaration + //~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration } fn main() {} diff --git a/src/test/ui/parser/default.stderr b/src/test/ui/parser/default.stderr index ede9e471518..07b051ece2b 100644 --- a/src/test/ui/parser/default.stderr +++ b/src/test/ui/parser/default.stderr @@ -1,8 +1,8 @@ -error: missing `fn`, `type`, or `const` for associated-item declaration +error: missing `fn`, `type`, `const`, or `static` for item declaration --> $DIR/default.rs:22:12 | LL | default pub fn foo<T: Default>() -> T { T::default() } - | ^ missing `fn`, `type`, or `const` + | ^ missing `fn`, `type`, `const`, or `static` error[E0449]: unnecessary visibility qualifier --> $DIR/default.rs:16:5 diff --git a/src/test/ui/parser/duplicate-visibility.rs b/src/test/ui/parser/duplicate-visibility.rs index 1d271fa64b0..f6e7f7e6abe 100644 --- a/src/test/ui/parser/duplicate-visibility.rs +++ b/src/test/ui/parser/duplicate-visibility.rs @@ -2,5 +2,5 @@ fn main() {} extern { pub pub fn foo(); - //~^ ERROR missing `fn`, `type`, or `static` for extern-item declaration + //~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration } diff --git a/src/test/ui/parser/duplicate-visibility.stderr b/src/test/ui/parser/duplicate-visibility.stderr index 36a3a1ed5a0..398ba65c9e1 100644 --- a/src/test/ui/parser/duplicate-visibility.stderr +++ b/src/test/ui/parser/duplicate-visibility.stderr @@ -1,8 +1,8 @@ -error: missing `fn`, `type`, or `static` for extern-item declaration +error: missing `fn`, `type`, `const`, or `static` for item declaration --> $DIR/duplicate-visibility.rs:4:8 | LL | pub pub fn foo(); - | ^ missing `fn`, `type`, or `static` + | ^ missing `fn`, `type`, `const`, or `static` error: aborting due to previous error diff --git a/src/test/ui/parser/extern-no-fn.rs b/src/test/ui/parser/extern-no-fn.rs index c37ddd69ce5..dc47f741073 100644 --- a/src/test/ui/parser/extern-no-fn.rs +++ b/src/test/ui/parser/extern-no-fn.rs @@ -1,4 +1,5 @@ -extern { //~ ERROR missing `fn`, `type`, or `static` for extern-item declaration +extern { +//~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration f(); } diff --git a/src/test/ui/parser/extern-no-fn.stderr b/src/test/ui/parser/extern-no-fn.stderr index d2d5e3c4687..8d55eefc8d0 100644 --- a/src/test/ui/parser/extern-no-fn.stderr +++ b/src/test/ui/parser/extern-no-fn.stderr @@ -1,10 +1,11 @@ -error: missing `fn`, `type`, or `static` for extern-item declaration +error: missing `fn`, `type`, `const`, or `static` for item declaration --> $DIR/extern-no-fn.rs:1:9 | LL | extern { | _________^ +LL | | LL | | f(); - | |____^ missing `fn`, `type`, or `static` + | |____^ missing `fn`, `type`, `const`, or `static` error: aborting due to previous error diff --git a/src/test/ui/parser/issue-19398.rs b/src/test/ui/parser/issue-19398.rs index 982a6be23ac..014c930ef82 100644 --- a/src/test/ui/parser/issue-19398.rs +++ b/src/test/ui/parser/issue-19398.rs @@ -1,5 +1,5 @@ trait T { - //~^ ERROR missing `fn`, `type`, or `const` for associated-item declaration + //~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration extern "Rust" unsafe fn foo(); } diff --git a/src/test/ui/parser/issue-19398.stderr b/src/test/ui/parser/issue-19398.stderr index 2bd6ac3a4b3..b38b39f9bd9 100644 --- a/src/test/ui/parser/issue-19398.stderr +++ b/src/test/ui/parser/issue-19398.stderr @@ -1,11 +1,11 @@ -error: missing `fn`, `type`, or `const` for associated-item declaration +error: missing `fn`, `type`, `const`, or `static` for item declaration --> $DIR/issue-19398.rs:1:10 | LL | trait T { | __________^ LL | | LL | | extern "Rust" unsafe fn foo(); - | |____^ missing `fn`, `type`, or `const` + | |____^ missing `fn`, `type`, `const`, or `static` error: aborting due to previous error diff --git a/src/test/ui/parser/issue-21153.rs b/src/test/ui/parser/issue-21153.rs index 46cd45f28b4..4fe05e6f041 100644 --- a/src/test/ui/parser/issue-21153.rs +++ b/src/test/ui/parser/issue-21153.rs @@ -1,4 +1,5 @@ -trait MyTrait<T>: Iterator { //~ ERROR missing `fn`, `type`, or `const` +trait MyTrait<T>: Iterator { + //~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration Item = T; } diff --git a/src/test/ui/parser/issue-21153.stderr b/src/test/ui/parser/issue-21153.stderr index 6e20a9ce3c4..e9824bd7290 100644 --- a/src/test/ui/parser/issue-21153.stderr +++ b/src/test/ui/parser/issue-21153.stderr @@ -1,10 +1,11 @@ -error: missing `fn`, `type`, or `const` for associated-item declaration +error: missing `fn`, `type`, `const`, or `static` for item declaration --> $DIR/issue-21153.rs:1:29 | LL | trait MyTrait<T>: Iterator { | _____________________________^ +LL | | LL | | Item = T; - | |____^ missing `fn`, `type`, or `const` + | |____^ missing `fn`, `type`, `const`, or `static` error: aborting due to previous error diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs index 592215030f5..748db8983b5 100644 --- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs +++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs @@ -3,7 +3,7 @@ fn main() {} impl T for () { //~ ERROR cannot find trait `T` in this scope fn foo(&self) {} -//~^ ERROR missing `fn`, `type`, or `const` +//~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration trait T { fn foo(&self); diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr index 1ec54525105..240be39eace 100644 --- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr +++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr @@ -7,7 +7,7 @@ LL | impl T for () { LL | | ^ -error: missing `fn`, `type`, or `const` for associated-item declaration +error: missing `fn`, `type`, `const`, or `static` for item declaration --> $DIR/missing-close-brace-in-impl-trait.rs:5:17 | LL | fn foo(&self) {} @@ -15,7 +15,7 @@ LL | fn foo(&self) {} LL | | LL | | LL | | trait T { - | |_ missing `fn`, `type`, or `const` + | |_ missing `fn`, `type`, `const`, or `static` error[E0405]: cannot find trait `T` in this scope --> $DIR/missing-close-brace-in-impl-trait.rs:3:6 diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs index 077e3347194..4e8cc6489bc 100644 --- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs +++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs @@ -3,7 +3,7 @@ trait T { fn foo(&self); pub(crate) struct Bar<T>(); -//~^ ERROR missing `fn`, `type`, or `const` +//~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration impl T for Bar<usize> { fn foo(&self) {} diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr index 1bb153c461d..54afad5755b 100644 --- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr +++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr @@ -7,11 +7,11 @@ LL | trait T { LL | fn main() {} | ^ -error: missing `fn`, `type`, or `const` for associated-item declaration +error: missing `fn`, `type`, `const`, or `static` for item declaration --> $DIR/missing-close-brace-in-trait.rs:5:11 | LL | pub(crate) struct Bar<T>(); - | ^ missing `fn`, `type`, or `const` + | ^ missing `fn`, `type`, `const`, or `static` error[E0601]: `main` function not found in crate `missing_close_brace_in_trait` --> $DIR/missing-close-brace-in-trait.rs:1:1 |
