Skip to content

Commit 63a9030

Browse files
committed
Unify associated item parsing.
An exception is `fn` params.
1 parent 7672bff commit 63a9030

File tree

4 files changed

+29
-59
lines changed

4 files changed

+29
-59
lines changed

src/librustc_parse/parser/item.rs

Lines changed: 20 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ use crate::maybe_whole;
66
use rustc_errors::{PResult, Applicability, DiagnosticBuilder, StashKey};
77
use rustc_error_codes::*;
88
use syntax::ast::{self, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, AnonConst, Item};
9-
use syntax::ast::{ItemKind, ImplItem, TraitItem, TraitItemKind, UseTree, UseTreeKind};
10-
use syntax::ast::{AssocItemKind};
9+
use syntax::ast::{AssocItem, AssocItemKind, ItemKind, UseTree, UseTreeKind};
1110
use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness, Extern, StrLit};
1211
use syntax::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
1312
use syntax::ast::{Ty, TyKind, Generics, TraitRef, EnumDef, Variant, VariantData, StructField};
@@ -649,7 +648,7 @@ impl<'a> Parser<'a> {
649648
Ok((Ident::invalid(), item_kind, Some(attrs)))
650649
}
651650

652-
fn parse_impl_body(&mut self) -> PResult<'a, (Vec<ImplItem>, Vec<Attribute>)> {
651+
fn parse_impl_body(&mut self) -> PResult<'a, (Vec<AssocItem>, Vec<Attribute>)> {
653652
self.expect(&token::OpenDelim(token::Brace))?;
654653
let attrs = self.parse_inner_attributes()?;
655654

@@ -671,12 +670,12 @@ impl<'a> Parser<'a> {
671670
}
672671

673672
/// Parses an impl item.
674-
pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, ImplItem> {
673+
pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, AssocItem> {
675674
maybe_whole!(self, NtImplItem, |x| x);
676675
let attrs = self.parse_outer_attributes()?;
677676
let mut unclosed_delims = vec![];
678677
let (mut item, tokens) = self.collect_tokens(|this| {
679-
let item = this.parse_impl_item_(at_end, attrs);
678+
let item = this.parse_assoc_item(at_end, attrs, |_| true);
680679
unclosed_delims.append(&mut this.unclosed_delims);
681680
item
682681
})?;
@@ -689,38 +688,6 @@ impl<'a> Parser<'a> {
689688
Ok(item)
690689
}
691690

692-
fn parse_impl_item_(
693-
&mut self,
694-
at_end: &mut bool,
695-
mut attrs: Vec<Attribute>,
696-
) -> PResult<'a, ImplItem> {
697-
let lo = self.token.span;
698-
let vis = self.parse_visibility(FollowedByType::No)?;
699-
let defaultness = self.parse_defaultness();
700-
let (name, kind, generics) = if self.eat_keyword(kw::Type) {
701-
self.parse_assoc_ty()?
702-
} else if self.is_const_item() {
703-
self.parse_assoc_const()?
704-
} else if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(&vis), at_end)? {
705-
// FIXME: code copied from `parse_macro_use_or_failure` -- use abstraction!
706-
(Ident::invalid(), ast::ImplItemKind::Macro(mac), Generics::default())
707-
} else {
708-
self.parse_assoc_fn(at_end, &mut attrs, |_| true)?
709-
};
710-
711-
Ok(ImplItem {
712-
id: DUMMY_NODE_ID,
713-
span: lo.to(self.prev_span),
714-
ident: name,
715-
attrs,
716-
vis,
717-
defaultness,
718-
generics,
719-
kind,
720-
tokens: None,
721-
})
722-
}
723-
724691
/// Parses defaultness (i.e., `default` or nothing).
725692
fn parse_defaultness(&mut self) -> Defaultness {
726693
// `pub` is included for better error messages
@@ -843,12 +810,19 @@ impl<'a> Parser<'a> {
843810
}
844811

845812
/// Parses the items in a trait declaration.
846-
pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, TraitItem> {
813+
pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, AssocItem> {
847814
maybe_whole!(self, NtTraitItem, |x| x);
848815
let attrs = self.parse_outer_attributes()?;
849816
let mut unclosed_delims = vec![];
850817
let (mut item, tokens) = self.collect_tokens(|this| {
851-
let item = this.parse_trait_item_(at_end, attrs);
818+
// This is somewhat dubious; We don't want to allow
819+
// param names to be left off if there is a definition...
820+
//
821+
// We don't allow param names to be left off in edition 2018.
822+
//
823+
// FIXME(Centril): bake closure into param parsing.
824+
// Also add semantic restrictions and add tests.
825+
let item = this.parse_assoc_item(at_end, attrs, |t| t.span.rust_2018());
852826
unclosed_delims.append(&mut this.unclosed_delims);
853827
item
854828
})?;
@@ -860,30 +834,26 @@ impl<'a> Parser<'a> {
860834
Ok(item)
861835
}
862836

863-
fn parse_trait_item_(
837+
fn parse_assoc_item(
864838
&mut self,
865839
at_end: &mut bool,
866840
mut attrs: Vec<Attribute>,
867-
) -> PResult<'a, TraitItem> {
841+
is_name_required: fn(&token::Token) -> bool,
842+
) -> PResult<'a, AssocItem> {
868843
let lo = self.token.span;
869844
let vis = self.parse_visibility(FollowedByType::No)?;
870845
let defaultness = self.parse_defaultness();
871846
let (name, kind, generics) = if self.eat_keyword(kw::Type) {
872847
self.parse_assoc_ty()?
873848
} else if self.is_const_item() {
874849
self.parse_assoc_const()?
875-
} else if let Some(mac) = self.parse_assoc_macro_invoc("trait", None, &mut false)? {
876-
// trait item macro.
877-
(Ident::invalid(), TraitItemKind::Macro(mac), Generics::default())
850+
} else if let Some(mac) = self.parse_assoc_macro_invoc("associated", Some(&vis), at_end)? {
851+
(Ident::invalid(), AssocItemKind::Macro(mac), Generics::default())
878852
} else {
879-
// This is somewhat dubious; We don't want to allow
880-
// param names to be left off if there is a definition...
881-
//
882-
// We don't allow param names to be left off in edition 2018.
883-
self.parse_assoc_fn(at_end, &mut attrs, |t| t.span.rust_2018())?
853+
self.parse_assoc_fn(at_end, &mut attrs, is_name_required)?
884854
};
885855

886-
Ok(TraitItem {
856+
Ok(AssocItem {
887857
id: DUMMY_NODE_ID,
888858
span: lo.to(self.prev_span),
889859
ident: name,

src/test/ui/did_you_mean/issue-40006.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ trait A { //~ ERROR missing
1818
trait B {
1919
fn xxx() { ### } //~ ERROR expected
2020
}
21-
trait C { //~ ERROR missing `fn`, `type`, or `const` for trait-item declaration
21+
trait C { //~ ERROR missing `fn`, `type`, or `const` for associated-item declaration
2222
L = M;
2323
}
24-
trait D { //~ ERROR missing `fn`, `type`, or `const` for trait-item declaration
24+
trait D { //~ ERROR missing `fn`, `type`, or `const` for associated-item declaration
2525
Z = { 2 + 3 };
2626
}
2727
trait E {

src/test/ui/did_you_mean/issue-40006.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
error: missing `fn`, `type`, or `const` for impl-item declaration
1+
error: missing `fn`, `type`, or `const` for associated-item declaration
22
--> $DIR/issue-40006.rs:1:13
33
|
44
LL | impl dyn A {
55
| _____________^
66
LL | | Y
77
| |____^ missing `fn`, `type`, or `const`
88

9-
error: missing `fn`, `type`, or `const` for trait-item declaration
9+
error: missing `fn`, `type`, or `const` for associated-item declaration
1010
--> $DIR/issue-40006.rs:7:10
1111
|
1212
LL | trait X {
1313
| __________^
1414
LL | | X() {}
1515
| |____^ missing `fn`, `type`, or `const`
1616

17-
error: missing `fn`, `type`, or `const` for trait-item declaration
17+
error: missing `fn`, `type`, or `const` for associated-item declaration
1818
--> $DIR/issue-40006.rs:15:10
1919
|
2020
LL | trait A {
@@ -28,15 +28,15 @@ error: expected `[`, found `#`
2828
LL | fn xxx() { ### }
2929
| ^ expected `[`
3030

31-
error: missing `fn`, `type`, or `const` for trait-item declaration
31+
error: missing `fn`, `type`, or `const` for associated-item declaration
3232
--> $DIR/issue-40006.rs:21:10
3333
|
3434
LL | trait C {
3535
| __________^
3636
LL | | L = M;
3737
| |____^ missing `fn`, `type`, or `const`
3838

39-
error: missing `fn`, `type`, or `const` for trait-item declaration
39+
error: missing `fn`, `type`, or `const` for associated-item declaration
4040
--> $DIR/issue-40006.rs:24:10
4141
|
4242
LL | trait D {
@@ -50,7 +50,7 @@ error: expected one of `!` or `::`, found `(`
5050
LL | ::Y ();
5151
| ^ expected one of `!` or `::`
5252

53-
error: missing `fn`, `type`, or `const` for impl-item declaration
53+
error: missing `fn`, `type`, or `const` for associated-item declaration
5454
--> $DIR/issue-40006.rs:32:8
5555
|
5656
LL | pub hello_method(&self) {

src/test/ui/parser/issue-21153.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: missing `fn`, `type`, or `const` for trait-item declaration
1+
error: missing `fn`, `type`, or `const` for associated-item declaration
22
--> $DIR/issue-21153.rs:1:29
33
|
44
LL | trait MyTrait<T>: Iterator {

0 commit comments

Comments
 (0)