Skip to content

Commit 0e0c028

Browse files
committed
fuse extern & associated item parsing up to defaultness
1 parent 91110fd commit 0e0c028

19 files changed

+81
-115
lines changed

src/librustc_parse/parser/item.rs

+39-77
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use syntax::ast::{AssocItem, AssocItemKind, Item, ItemKind, UseTree, UseTreeKind
1313
use syntax::ast::{Async, Const, Defaultness, IsAuto, PathSegment, Unsafe};
1414
use syntax::ast::{BindingMode, Block, FnDecl, FnSig, Mac, MacArgs, MacDelimiter, Param, SelfKind};
1515
use syntax::ast::{EnumDef, Generics, StructField, TraitRef, Ty, TyKind, Variant, VariantData};
16-
use syntax::ast::{FnHeader, ForeignItem, ForeignItemKind, Mutability, Visibility, VisibilityKind};
16+
use syntax::ast::{FnHeader, ForeignItem, Mutability, Visibility, VisibilityKind};
1717
use syntax::ptr::P;
1818
use syntax::token;
1919
use syntax::tokenstream::{DelimSpan, TokenStream, TokenTree};
@@ -333,29 +333,19 @@ impl<'a> Parser<'a> {
333333
self.token.is_keyword(kw::Async) && self.is_keyword_ahead(1, &[kw::Fn])
334334
}
335335

336-
fn missing_assoc_item_kind_err(
337-
&self,
338-
item_type: &str,
339-
prev_span: Span,
340-
) -> DiagnosticBuilder<'a> {
341-
let expected_kinds = if item_type == "extern" {
342-
"missing `fn`, `type`, or `static`"
343-
} else {
344-
"missing `fn`, `type`, or `const`"
345-
};
346-
347-
// Given this code `path(`, it seems like this is not
348-
// setting the visibility of a macro invocation, but rather
349-
// a mistyped method declaration.
350-
// Create a diagnostic pointing out that `fn` is missing.
351-
//
352-
// x | pub path(&self) {
353-
// | ^ missing `fn`, `type`, or `const`
354-
// pub path(
355-
// ^^ `sp` below will point to this
336+
/// Given this code `path(`, it seems like this is not
337+
/// setting the visibility of a macro invocation,
338+
/// but rather a mistyped method declaration.
339+
/// Create a diagnostic pointing out that `fn` is missing.
340+
///
341+
/// ```
342+
/// x | pub path(&self) {
343+
/// | ^ missing `fn`, `type`, `const`, or `static`
344+
/// ```
345+
fn missing_nested_item_kind_err(&self, prev_span: Span) -> DiagnosticBuilder<'a> {
356346
let sp = prev_span.between(self.token.span);
357-
let mut err = self
358-
.struct_span_err(sp, &format!("{} for {}-item declaration", expected_kinds, item_type));
347+
let expected_kinds = "missing `fn`, `type`, `const`, or `static`";
348+
let mut err = self.struct_span_err(sp, &format!("{} for item declaration", expected_kinds));
359349
err.span_label(sp, expected_kinds);
360350
err
361351
}
@@ -639,7 +629,7 @@ impl<'a> Parser<'a> {
639629
fn parse_assoc_item(
640630
&mut self,
641631
at_end: &mut bool,
642-
req_name: fn(&token::Token) -> bool,
632+
req_name: ReqName,
643633
) -> PResult<'a, P<AssocItem>> {
644634
let attrs = self.parse_outer_attributes()?;
645635
let mut unclosed_delims = vec![];
@@ -660,39 +650,47 @@ impl<'a> Parser<'a> {
660650
&mut self,
661651
at_end: &mut bool,
662652
mut attrs: Vec<Attribute>,
663-
req_name: fn(&token::Token) -> bool,
653+
req_name: ReqName,
664654
) -> PResult<'a, AssocItem> {
665655
let lo = self.token.span;
666656
let vis = self.parse_visibility(FollowedByType::No)?;
667657
let defaultness = self.parse_defaultness();
658+
let (ident, kind) = self.parse_assoc_item_kind(at_end, &mut attrs, req_name, &vis)?;
659+
let span = lo.to(self.prev_span);
660+
let id = DUMMY_NODE_ID;
661+
Ok(AssocItem { id, span, ident, attrs, vis, defaultness, kind, tokens: None })
662+
}
668663

669-
let (ident, kind) = if self.eat_keyword(kw::Type) {
670-
self.parse_assoc_ty()?
664+
fn parse_assoc_item_kind(
665+
&mut self,
666+
at_end: &mut bool,
667+
attrs: &mut Vec<Attribute>,
668+
req_name: ReqName,
669+
vis: &Visibility,
670+
) -> PResult<'a, (Ident, AssocItemKind)> {
671+
if self.eat_keyword(kw::Type) {
672+
self.parse_assoc_ty()
671673
} else if self.check_fn_front_matter() {
672-
let (ident, sig, generics, body) = self.parse_fn(at_end, &mut attrs, req_name)?;
673-
(ident, AssocItemKind::Fn(sig, generics, body))
674+
let (ident, sig, generics, body) = self.parse_fn(at_end, attrs, req_name)?;
675+
Ok((ident, AssocItemKind::Fn(sig, generics, body)))
674676
} else if self.is_static_global() {
675677
self.bump(); // `static`
676678
let mutbl = self.parse_mutability();
677679
let (ident, ty, expr) = self.parse_item_const_common(Some(mutbl))?;
678-
(ident, AssocItemKind::Static(ty, mutbl, expr))
680+
Ok((ident, AssocItemKind::Static(ty, mutbl, expr)))
679681
} else if self.eat_keyword(kw::Const) {
680682
let (ident, ty, expr) = self.parse_item_const_common(None)?;
681-
(ident, AssocItemKind::Const(ty, expr))
683+
Ok((ident, AssocItemKind::Const(ty, expr)))
682684
} else if self.isnt_macro_invocation() {
683-
return Err(self.missing_assoc_item_kind_err("associated", self.prev_span));
685+
Err(self.missing_nested_item_kind_err(self.prev_span))
684686
} else if self.token.is_path_start() {
685687
let mac = self.parse_item_macro(&vis)?;
686688
*at_end = true;
687-
(Ident::invalid(), AssocItemKind::Macro(mac))
689+
Ok((Ident::invalid(), AssocItemKind::Macro(mac)))
688690
} else {
689-
self.recover_attrs_no_item(&attrs)?;
690-
self.unexpected()?
691-
};
692-
693-
let span = lo.to(self.prev_span);
694-
let id = DUMMY_NODE_ID;
695-
Ok(AssocItem { id, span, ident, attrs, vis, defaultness, kind, tokens: None })
691+
self.recover_attrs_no_item(attrs)?;
692+
self.unexpected()
693+
}
696694
}
697695

698696
/// Parses the following grammar:
@@ -869,46 +867,10 @@ impl<'a> Parser<'a> {
869867
let mut attrs = self.parse_outer_attributes()?;
870868
let lo = self.token.span;
871869
let vis = self.parse_visibility(FollowedByType::No)?;
872-
873-
let (ident, kind) = if self.eat_keyword(kw::Type) {
874-
// FOREIGN TYPE ITEM
875-
self.parse_item_foreign_type()?
876-
} else if self.check_fn_front_matter() {
877-
// FOREIGN FUNCTION ITEM
878-
let (ident, sig, generics, body) = self.parse_fn(at_end, &mut attrs, |_| true)?;
879-
(ident, ForeignItemKind::Fn(sig, generics, body))
880-
} else if self.is_static_global() {
881-
// FOREIGN STATIC ITEM
882-
self.bump(); // `static`
883-
let mutbl = self.parse_mutability();
884-
let (ident, ty, expr) = self.parse_item_const_common(Some(mutbl))?;
885-
(ident, ForeignItemKind::Static(ty, mutbl, expr))
886-
} else if self.eat_keyword(kw::Const) {
887-
let (ident, ty, expr) = self.parse_item_const_common(None)?;
888-
(ident, ForeignItemKind::Const(ty, expr))
889-
} else if self.isnt_macro_invocation() {
890-
return Err(self.missing_assoc_item_kind_err("extern", self.prev_span));
891-
} else if self.token.is_path_start() {
892-
let mac = self.parse_item_macro(&vis)?;
893-
*at_end = true;
894-
(Ident::invalid(), ForeignItemKind::Macro(mac))
895-
} else {
896-
self.recover_attrs_no_item(&attrs)?;
897-
self.unexpected()?
898-
};
870+
let (ident, kind) = self.parse_assoc_item_kind(at_end, &mut attrs, |_| true, &vis)?;
899871
Ok(P(self.mk_item(lo, ident, kind, vis, attrs)))
900872
}
901873

902-
/// Parses a type from a foreign module.
903-
fn parse_item_foreign_type(&mut self) -> PResult<'a, (Ident, ForeignItemKind)> {
904-
let (ident, kind) = self.parse_assoc_ty()?;
905-
let kind = match kind {
906-
AssocItemKind::TyAlias(g, b, d) => ForeignItemKind::TyAlias(g, b, d),
907-
_ => unreachable!(),
908-
};
909-
Ok((ident, kind))
910-
}
911-
912874
fn is_static_global(&mut self) -> bool {
913875
if self.check_keyword(kw::Static) {
914876
// Check if this could be a closure.

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

+2-2
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 associated-item declaration
21+
trait C { //~ ERROR missing `fn`, `type`, `const`, or `static` for item declaration
2222
L = M;
2323
}
24-
trait D { //~ ERROR missing `fn`, `type`, or `const` for associated-item declaration
24+
trait D { //~ ERROR missing `fn`, `type`, `const`, or `static` for item declaration
2525
Z = { 2 + 3 };
2626
}
2727
trait E {

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

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,60 @@
1-
error: missing `fn`, `type`, or `const` for associated-item declaration
1+
error: missing `fn`, `type`, `const`, or `static` for item declaration
22
--> $DIR/issue-40006.rs:1:13
33
|
44
LL | impl dyn A {
55
| _____________^
66
LL | | Y
7-
| |____^ missing `fn`, `type`, or `const`
7+
| |____^ missing `fn`, `type`, `const`, or `static`
88

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

17-
error: missing `fn`, `type`, or `const` for associated-item declaration
17+
error: missing `fn`, `type`, `const`, or `static` for item declaration
1818
--> $DIR/issue-40006.rs:15:10
1919
|
2020
LL | trait A {
2121
| __________^
2222
LL | | X() {}
23-
| |____^ missing `fn`, `type`, or `const`
23+
| |____^ missing `fn`, `type`, `const`, or `static`
2424

2525
error: expected `[`, found `#`
2626
--> $DIR/issue-40006.rs:19:17
2727
|
2828
LL | fn xxx() { ### }
2929
| ^ expected `[`
3030

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

39-
error: missing `fn`, `type`, or `const` for associated-item declaration
39+
error: missing `fn`, `type`, `const`, or `static` for item declaration
4040
--> $DIR/issue-40006.rs:24:10
4141
|
4242
LL | trait D {
4343
| __________^
4444
LL | | Z = { 2 + 3 };
45-
| |____^ missing `fn`, `type`, or `const`
45+
| |____^ missing `fn`, `type`, `const`, or `static`
4646

4747
error: expected one of `!` or `::`, found `(`
4848
--> $DIR/issue-40006.rs:28:9
4949
|
5050
LL | ::Y ();
5151
| ^ expected one of `!` or `::`
5252

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

5959
error[E0599]: no method named `hello_method` found for struct `S` in the current scope
6060
--> $DIR/issue-40006.rs:38:7

src/test/ui/macros/issue-54441.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
macro_rules! m {
2-
//~^ ERROR missing `fn`, `type`, or `static` for extern-item declaration
2+
//~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration
33
() => {
44
let
55
};

src/test/ui/macros/issue-54441.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
error: missing `fn`, `type`, or `static` for extern-item declaration
1+
error: missing `fn`, `type`, `const`, or `static` for item declaration
22
--> $DIR/issue-54441.rs:1:1
33
|
44
LL | / macro_rules! m {
55
LL | |
66
LL | | () => {
77
LL | | let
8-
| |________^ missing `fn`, `type`, or `static`
8+
| |________^ missing `fn`, `type`, `const`, or `static`
99

1010
error: aborting due to previous error
1111

src/test/ui/parser/default.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ impl Foo for u16 {
2020

2121
impl Foo for u32 { //~ ERROR not all trait items implemented, missing: `foo`
2222
default pub fn foo<T: Default>() -> T { T::default() }
23-
//~^ ERROR missing `fn`, `type`, or `const` for associated-item declaration
23+
//~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration
2424
}
2525

2626
fn main() {}

src/test/ui/parser/default.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: missing `fn`, `type`, or `const` for associated-item declaration
1+
error: missing `fn`, `type`, `const`, or `static` for item declaration
22
--> $DIR/default.rs:22:12
33
|
44
LL | default pub fn foo<T: Default>() -> T { T::default() }
5-
| ^ missing `fn`, `type`, or `const`
5+
| ^ missing `fn`, `type`, `const`, or `static`
66

77
error[E0449]: unnecessary visibility qualifier
88
--> $DIR/default.rs:16:5

src/test/ui/parser/duplicate-visibility.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ fn main() {}
22

33
extern {
44
pub pub fn foo();
5-
//~^ ERROR missing `fn`, `type`, or `static` for extern-item declaration
5+
//~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration
66
}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: missing `fn`, `type`, or `static` for extern-item declaration
1+
error: missing `fn`, `type`, `const`, or `static` for item declaration
22
--> $DIR/duplicate-visibility.rs:4:8
33
|
44
LL | pub pub fn foo();
5-
| ^ missing `fn`, `type`, or `static`
5+
| ^ missing `fn`, `type`, `const`, or `static`
66

77
error: aborting due to previous error
88

src/test/ui/parser/extern-no-fn.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
extern { //~ ERROR missing `fn`, `type`, or `static` for extern-item declaration
1+
extern {
2+
//~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration
23
f();
34
}
45

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
error: missing `fn`, `type`, or `static` for extern-item declaration
1+
error: missing `fn`, `type`, `const`, or `static` for item declaration
22
--> $DIR/extern-no-fn.rs:1:9
33
|
44
LL | extern {
55
| _________^
6+
LL | |
67
LL | | f();
7-
| |____^ missing `fn`, `type`, or `static`
8+
| |____^ missing `fn`, `type`, `const`, or `static`
89

910
error: aborting due to previous error
1011

src/test/ui/parser/issue-19398.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
trait T {
2-
//~^ ERROR missing `fn`, `type`, or `const` for associated-item declaration
2+
//~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration
33
extern "Rust" unsafe fn foo();
44
}
55

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
error: missing `fn`, `type`, or `const` for associated-item declaration
1+
error: missing `fn`, `type`, `const`, or `static` for item declaration
22
--> $DIR/issue-19398.rs:1:10
33
|
44
LL | trait T {
55
| __________^
66
LL | |
77
LL | | extern "Rust" unsafe fn foo();
8-
| |____^ missing `fn`, `type`, or `const`
8+
| |____^ missing `fn`, `type`, `const`, or `static`
99

1010
error: aborting due to previous error
1111

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
trait MyTrait<T>: Iterator { //~ ERROR missing `fn`, `type`, or `const`
1+
trait MyTrait<T>: Iterator {
2+
//~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration
23
Item = T;
34
}
45

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
error: missing `fn`, `type`, or `const` for associated-item declaration
1+
error: missing `fn`, `type`, `const`, or `static` for item declaration
22
--> $DIR/issue-21153.rs:1:29
33
|
44
LL | trait MyTrait<T>: Iterator {
55
| _____________________________^
6+
LL | |
67
LL | | Item = T;
7-
| |____^ missing `fn`, `type`, or `const`
8+
| |____^ missing `fn`, `type`, `const`, or `static`
89

910
error: aborting due to previous error
1011

src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ fn main() {}
33
impl T for () { //~ ERROR cannot find trait `T` in this scope
44

55
fn foo(&self) {}
6-
//~^ ERROR missing `fn`, `type`, or `const`
6+
//~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration
77

88
trait T {
99
fn foo(&self);

0 commit comments

Comments
 (0)