Unify associated item parsing.
An exception is `fn` params.
This commit is contained in:
parent
7672bff378
commit
63a9030e7b
4 changed files with 29 additions and 59 deletions
|
@ -6,8 +6,7 @@ use crate::maybe_whole;
|
|||
use rustc_errors::{PResult, Applicability, DiagnosticBuilder, StashKey};
|
||||
use rustc_error_codes::*;
|
||||
use syntax::ast::{self, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, AnonConst, Item};
|
||||
use syntax::ast::{ItemKind, ImplItem, TraitItem, TraitItemKind, UseTree, UseTreeKind};
|
||||
use syntax::ast::{AssocItemKind};
|
||||
use syntax::ast::{AssocItem, AssocItemKind, ItemKind, UseTree, UseTreeKind};
|
||||
use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness, Extern, StrLit};
|
||||
use syntax::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
|
||||
use syntax::ast::{Ty, TyKind, Generics, TraitRef, EnumDef, Variant, VariantData, StructField};
|
||||
|
@ -649,7 +648,7 @@ impl<'a> Parser<'a> {
|
|||
Ok((Ident::invalid(), item_kind, Some(attrs)))
|
||||
}
|
||||
|
||||
fn parse_impl_body(&mut self) -> PResult<'a, (Vec<ImplItem>, Vec<Attribute>)> {
|
||||
fn parse_impl_body(&mut self) -> PResult<'a, (Vec<AssocItem>, Vec<Attribute>)> {
|
||||
self.expect(&token::OpenDelim(token::Brace))?;
|
||||
let attrs = self.parse_inner_attributes()?;
|
||||
|
||||
|
@ -671,12 +670,12 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
/// Parses an impl item.
|
||||
pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, ImplItem> {
|
||||
pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, AssocItem> {
|
||||
maybe_whole!(self, NtImplItem, |x| x);
|
||||
let attrs = self.parse_outer_attributes()?;
|
||||
let mut unclosed_delims = vec![];
|
||||
let (mut item, tokens) = self.collect_tokens(|this| {
|
||||
let item = this.parse_impl_item_(at_end, attrs);
|
||||
let item = this.parse_assoc_item(at_end, attrs, |_| true);
|
||||
unclosed_delims.append(&mut this.unclosed_delims);
|
||||
item
|
||||
})?;
|
||||
|
@ -689,38 +688,6 @@ impl<'a> Parser<'a> {
|
|||
Ok(item)
|
||||
}
|
||||
|
||||
fn parse_impl_item_(
|
||||
&mut self,
|
||||
at_end: &mut bool,
|
||||
mut attrs: Vec<Attribute>,
|
||||
) -> PResult<'a, ImplItem> {
|
||||
let lo = self.token.span;
|
||||
let vis = self.parse_visibility(FollowedByType::No)?;
|
||||
let defaultness = self.parse_defaultness();
|
||||
let (name, kind, generics) = if self.eat_keyword(kw::Type) {
|
||||
self.parse_assoc_ty()?
|
||||
} else if self.is_const_item() {
|
||||
self.parse_assoc_const()?
|
||||
} else if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(&vis), at_end)? {
|
||||
// FIXME: code copied from `parse_macro_use_or_failure` -- use abstraction!
|
||||
(Ident::invalid(), ast::ImplItemKind::Macro(mac), Generics::default())
|
||||
} else {
|
||||
self.parse_assoc_fn(at_end, &mut attrs, |_| true)?
|
||||
};
|
||||
|
||||
Ok(ImplItem {
|
||||
id: DUMMY_NODE_ID,
|
||||
span: lo.to(self.prev_span),
|
||||
ident: name,
|
||||
attrs,
|
||||
vis,
|
||||
defaultness,
|
||||
generics,
|
||||
kind,
|
||||
tokens: None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Parses defaultness (i.e., `default` or nothing).
|
||||
fn parse_defaultness(&mut self) -> Defaultness {
|
||||
// `pub` is included for better error messages
|
||||
|
@ -843,12 +810,19 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
/// Parses the items in a trait declaration.
|
||||
pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, TraitItem> {
|
||||
pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, AssocItem> {
|
||||
maybe_whole!(self, NtTraitItem, |x| x);
|
||||
let attrs = self.parse_outer_attributes()?;
|
||||
let mut unclosed_delims = vec![];
|
||||
let (mut item, tokens) = self.collect_tokens(|this| {
|
||||
let item = this.parse_trait_item_(at_end, attrs);
|
||||
// This is somewhat dubious; We don't want to allow
|
||||
// param names to be left off if there is a definition...
|
||||
//
|
||||
// We don't allow param names to be left off in edition 2018.
|
||||
//
|
||||
// FIXME(Centril): bake closure into param parsing.
|
||||
// Also add semantic restrictions and add tests.
|
||||
let item = this.parse_assoc_item(at_end, attrs, |t| t.span.rust_2018());
|
||||
unclosed_delims.append(&mut this.unclosed_delims);
|
||||
item
|
||||
})?;
|
||||
|
@ -860,11 +834,12 @@ impl<'a> Parser<'a> {
|
|||
Ok(item)
|
||||
}
|
||||
|
||||
fn parse_trait_item_(
|
||||
fn parse_assoc_item(
|
||||
&mut self,
|
||||
at_end: &mut bool,
|
||||
mut attrs: Vec<Attribute>,
|
||||
) -> PResult<'a, TraitItem> {
|
||||
is_name_required: fn(&token::Token) -> bool,
|
||||
) -> PResult<'a, AssocItem> {
|
||||
let lo = self.token.span;
|
||||
let vis = self.parse_visibility(FollowedByType::No)?;
|
||||
let defaultness = self.parse_defaultness();
|
||||
|
@ -872,18 +847,13 @@ impl<'a> Parser<'a> {
|
|||
self.parse_assoc_ty()?
|
||||
} else if self.is_const_item() {
|
||||
self.parse_assoc_const()?
|
||||
} else if let Some(mac) = self.parse_assoc_macro_invoc("trait", None, &mut false)? {
|
||||
// trait item macro.
|
||||
(Ident::invalid(), TraitItemKind::Macro(mac), Generics::default())
|
||||
} else if let Some(mac) = self.parse_assoc_macro_invoc("associated", Some(&vis), at_end)? {
|
||||
(Ident::invalid(), AssocItemKind::Macro(mac), Generics::default())
|
||||
} else {
|
||||
// This is somewhat dubious; We don't want to allow
|
||||
// param names to be left off if there is a definition...
|
||||
//
|
||||
// We don't allow param names to be left off in edition 2018.
|
||||
self.parse_assoc_fn(at_end, &mut attrs, |t| t.span.rust_2018())?
|
||||
self.parse_assoc_fn(at_end, &mut attrs, is_name_required)?
|
||||
};
|
||||
|
||||
Ok(TraitItem {
|
||||
Ok(AssocItem {
|
||||
id: DUMMY_NODE_ID,
|
||||
span: lo.to(self.prev_span),
|
||||
ident: name,
|
||||
|
|
|
@ -18,10 +18,10 @@ trait A { //~ ERROR missing
|
|||
trait B {
|
||||
fn xxx() { ### } //~ ERROR expected
|
||||
}
|
||||
trait C { //~ ERROR missing `fn`, `type`, or `const` for trait-item declaration
|
||||
trait C { //~ ERROR missing `fn`, `type`, or `const` for associated-item declaration
|
||||
L = M;
|
||||
}
|
||||
trait D { //~ ERROR missing `fn`, `type`, or `const` for trait-item declaration
|
||||
trait D { //~ ERROR missing `fn`, `type`, or `const` for associated-item declaration
|
||||
Z = { 2 + 3 };
|
||||
}
|
||||
trait E {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: missing `fn`, `type`, or `const` for impl-item declaration
|
||||
error: missing `fn`, `type`, or `const` for associated-item declaration
|
||||
--> $DIR/issue-40006.rs:1:13
|
||||
|
|
||||
LL | impl dyn A {
|
||||
|
@ -6,7 +6,7 @@ LL | impl dyn A {
|
|||
LL | | Y
|
||||
| |____^ missing `fn`, `type`, or `const`
|
||||
|
||||
error: missing `fn`, `type`, or `const` for trait-item declaration
|
||||
error: missing `fn`, `type`, or `const` for associated-item declaration
|
||||
--> $DIR/issue-40006.rs:7:10
|
||||
|
|
||||
LL | trait X {
|
||||
|
@ -14,7 +14,7 @@ LL | trait X {
|
|||
LL | | X() {}
|
||||
| |____^ missing `fn`, `type`, or `const`
|
||||
|
||||
error: missing `fn`, `type`, or `const` for trait-item declaration
|
||||
error: missing `fn`, `type`, or `const` for associated-item declaration
|
||||
--> $DIR/issue-40006.rs:15:10
|
||||
|
|
||||
LL | trait A {
|
||||
|
@ -28,7 +28,7 @@ error: expected `[`, found `#`
|
|||
LL | fn xxx() { ### }
|
||||
| ^ expected `[`
|
||||
|
||||
error: missing `fn`, `type`, or `const` for trait-item declaration
|
||||
error: missing `fn`, `type`, or `const` for associated-item declaration
|
||||
--> $DIR/issue-40006.rs:21:10
|
||||
|
|
||||
LL | trait C {
|
||||
|
@ -36,7 +36,7 @@ LL | trait C {
|
|||
LL | | L = M;
|
||||
| |____^ missing `fn`, `type`, or `const`
|
||||
|
||||
error: missing `fn`, `type`, or `const` for trait-item declaration
|
||||
error: missing `fn`, `type`, or `const` for associated-item declaration
|
||||
--> $DIR/issue-40006.rs:24:10
|
||||
|
|
||||
LL | trait D {
|
||||
|
@ -50,7 +50,7 @@ error: expected one of `!` or `::`, found `(`
|
|||
LL | ::Y ();
|
||||
| ^ expected one of `!` or `::`
|
||||
|
||||
error: missing `fn`, `type`, or `const` for impl-item declaration
|
||||
error: missing `fn`, `type`, or `const` for associated-item declaration
|
||||
--> $DIR/issue-40006.rs:32:8
|
||||
|
|
||||
LL | pub hello_method(&self) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: missing `fn`, `type`, or `const` for trait-item declaration
|
||||
error: missing `fn`, `type`, or `const` for associated-item declaration
|
||||
--> $DIR/issue-21153.rs:1:29
|
||||
|
|
||||
LL | trait MyTrait<T>: Iterator {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue