about summary refs log tree commit diff
path: root/src/libsyntax/parse/parser.rs
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-08-11 18:34:42 +0200
committerMazdak Farrokhzad <twingoow@gmail.com>2019-08-11 18:34:42 +0200
commite81347c3685dfc818fca2d502819ee0d1b692621 (patch)
tree6535fd2cc6bc3626b10f90b87e70114dbe5500c2 /src/libsyntax/parse/parser.rs
parente742de2569f6222b26671171c1f32fcd02b80f67 (diff)
downloadrust-e81347c3685dfc818fca2d502819ee0d1b692621.tar.gz
rust-e81347c3685dfc818fca2d502819ee0d1b692621.zip
parser: split into {item,module}.rs
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
-rw-r--r--src/libsyntax/parse/parser.rs2238
1 files changed, 20 insertions, 2218 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index f7dced76b64..6537f59395f 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2,44 +2,34 @@
 
 mod expr;
 use expr::LhsExpr;
-
 mod pat;
-
-use crate::ast::{AngleBracketedArgs, ParenthesizedArgs, AttrStyle, BareFnTy};
-use crate::ast::{GenericBound, TraitBoundModifier};
-use crate::ast::Unsafety;
-use crate::ast::{Mod, AnonConst, Arg, Attribute, BindingMode, TraitItemKind};
-use crate::ast::{Block, BlockCheckMode};
-use crate::ast::{Constness, Crate};
-use crate::ast::Defaultness;
-use crate::ast::EnumDef;
-use crate::ast::{Expr, ExprKind};
-use crate::ast::{FnDecl, FnHeader};
-use crate::ast::{ForeignItem, ForeignItemKind, FunctionRetTy};
-use crate::ast::{GenericParam, GenericParamKind};
-use crate::ast::GenericArg;
-use crate::ast::{Ident, ImplItem, IsAsync, IsAuto, Item, ItemKind, Local, Lifetime};
-use crate::ast::{MacStmtStyle, Mac, Mac_, MacDelimiter};
+mod item;
+pub use item::AliasKind;
+mod module;
+pub use module::{ModulePath, ModulePathSuccess};
+
+use crate::ast::{self, AngleBracketedArgs, ParenthesizedArgs, AttrStyle, BareFnTy};
+use crate::ast::{AnonConst, Arg, Attribute, BindingMode};
+use crate::ast::{Block, BlockCheckMode, Expr, ExprKind, Stmt, StmtKind};
+use crate::ast::{FnDecl, FunctionRetTy};
+use crate::ast::{Ident, IsAsync, Local, Lifetime};
+use crate::ast::{MacStmtStyle, Mac_, MacDelimiter};
 use crate::ast::{MutTy, Mutability};
-use crate::ast::{PathSegment};
-use crate::ast::{PolyTraitRef, QSelf};
-use crate::ast::{Stmt, StmtKind};
-use crate::ast::{VariantData, StructField};
+use crate::ast::{PolyTraitRef, QSelf, PathSegment};
 use crate::ast::StrStyle;
 use crate::ast::SelfKind;
-use crate::ast::{TraitItem, TraitRef, TraitObjectSyntax};
+use crate::ast::{GenericBound, TraitBoundModifier, TraitObjectSyntax};
+use crate::ast::{GenericParam, GenericParamKind, GenericArg, WhereClause};
 use crate::ast::{Ty, TyKind, AssocTyConstraint, AssocTyConstraintKind, GenericBounds};
-use crate::ast::{Visibility, VisibilityKind, WhereClause, CrateSugar};
-use crate::ast::{UseTree, UseTreeKind};
-use crate::{ast, attr};
+use crate::ast::{Visibility, VisibilityKind, Unsafety, CrateSugar};
 use crate::ext::base::DummyResult;
 use crate::ext::hygiene::SyntaxContext;
-use crate::source_map::{self, SourceMap, Spanned, respan};
+use crate::source_map::{self, respan};
 use crate::parse::{SeqSep, classify, literal, token};
 use crate::parse::lexer::UnmatchedBrace;
 use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
 use crate::parse::token::{Token, TokenKind, DelimToken};
-use crate::parse::{new_sub_parser_from_file, ParseSess, Directory, DirectoryOwnership};
+use crate::parse::{ParseSess, Directory, DirectoryOwnership};
 use crate::print::pprust;
 use crate::ptr::P;
 use crate::parse::PResult;
@@ -48,25 +38,14 @@ use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
 use crate::symbol::{kw, sym, Symbol};
 use crate::parse::diagnostics::{Error, dummy_arg};
 
-use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError};
+use errors::{Applicability, DiagnosticId, FatalError};
 use rustc_target::spec::abi::{self, Abi};
 use syntax_pos::{Span, BytePos, DUMMY_SP, FileName};
 use log::debug;
 
 use std::borrow::Cow;
-use std::cmp;
-use std::mem;
-use std::path::{self, Path, PathBuf};
-use std::slice;
-
-#[derive(Debug)]
-/// Whether the type alias or associated type is a concrete type or an opaque type
-pub enum AliasKind {
-    /// Just a new name for the same type
-    Weak(P<Ty>),
-    /// Only trait impls of the type will be usable, not the actual type itself
-    OpaqueTy(GenericBounds),
-}
+use std::{cmp, mem, slice};
+use std::path::PathBuf;
 
 bitflags::bitflags! {
     struct Restrictions: u8 {
@@ -75,8 +54,6 @@ bitflags::bitflags! {
     }
 }
 
-type ItemInfo = (Ident, ItemKind, Option<Vec<Attribute>>);
-
 /// Specifies how to parse a path.
 #[derive(Copy, Clone, PartialEq)]
 pub enum PathStyle {
@@ -390,19 +367,6 @@ fn can_continue_type_after_non_fn_ident(t: &Token) -> bool {
     t == &token::BinOp(token::Shl)
 }
 
-/// Information about the path to a module.
-pub struct ModulePath {
-    name: String,
-    path_exists: bool,
-    pub result: Result<ModulePathSuccess, Error>,
-}
-
-pub struct ModulePathSuccess {
-    pub path: PathBuf,
-    pub directory_ownership: DirectoryOwnership,
-    warn: bool,
-}
-
 #[derive(Copy, Clone, Debug)]
 crate enum TokenExpectType {
     Expect,
@@ -1077,120 +1041,6 @@ 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> {
-        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);
-            unclosed_delims.append(&mut this.unclosed_delims);
-            item
-        })?;
-        self.unclosed_delims.append(&mut unclosed_delims);
-        // See `parse_item` for why this clause is here.
-        if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
-            item.tokens = Some(tokens);
-        }
-        Ok(item)
-    }
-
-    fn parse_trait_item_(&mut self,
-                         at_end: &mut bool,
-                         mut attrs: Vec<Attribute>) -> PResult<'a, TraitItem> {
-        let lo = self.token.span;
-        self.eat_bad_pub();
-        let (name, node, generics) = if self.eat_keyword(kw::Type) {
-            self.parse_trait_item_assoc_ty()?
-        } else if self.is_const_item() {
-            self.expect_keyword(kw::Const)?;
-            let ident = self.parse_ident()?;
-            self.expect(&token::Colon)?;
-            let ty = self.parse_ty()?;
-            let default = if self.eat(&token::Eq) {
-                let expr = self.parse_expr()?;
-                self.expect(&token::Semi)?;
-                Some(expr)
-            } else {
-                self.expect(&token::Semi)?;
-                None
-            };
-            (ident, TraitItemKind::Const(ty, default), ast::Generics::default())
-        } else if let Some(mac) = self.parse_assoc_macro_invoc("trait", None, &mut false)? {
-            // trait item macro.
-            (Ident::invalid(), ast::TraitItemKind::Macro(mac), ast::Generics::default())
-        } else {
-            let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
-
-            let ident = self.parse_ident()?;
-            let mut generics = self.parse_generics()?;
-
-            let decl = self.parse_fn_decl_with_self(|p: &mut Parser<'a>| {
-                // This is somewhat dubious; We don't want to allow
-                // argument names to be left off if there is a
-                // definition...
-
-                // We don't allow argument names to be left off in edition 2018.
-                let is_name_required = p.token.span.rust_2018();
-                p.parse_arg_general(true, false, |_| is_name_required)
-            })?;
-            generics.where_clause = self.parse_where_clause()?;
-
-            let sig = ast::MethodSig {
-                header: FnHeader {
-                    unsafety,
-                    constness,
-                    abi,
-                    asyncness,
-                },
-                decl,
-            };
-
-            let body = match self.token.kind {
-                token::Semi => {
-                    self.bump();
-                    *at_end = true;
-                    debug!("parse_trait_methods(): parsing required method");
-                    None
-                }
-                token::OpenDelim(token::Brace) => {
-                    debug!("parse_trait_methods(): parsing provided method");
-                    *at_end = true;
-                    let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
-                    attrs.extend(inner_attrs.iter().cloned());
-                    Some(body)
-                }
-                token::Interpolated(ref nt) => {
-                    match **nt {
-                        token::NtBlock(..) => {
-                            *at_end = true;
-                            let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
-                            attrs.extend(inner_attrs.iter().cloned());
-                            Some(body)
-                        }
-                        _ => {
-                            return self.expected_semi_or_open_brace();
-                        }
-                    }
-                }
-                _ => {
-                    return self.expected_semi_or_open_brace();
-                }
-            };
-            (ident, ast::TraitItemKind::Method(sig, body), generics)
-        };
-
-        Ok(TraitItem {
-            id: ast::DUMMY_NODE_ID,
-            ident: name,
-            attrs,
-            generics,
-            node,
-            span: lo.to(self.prev_span),
-            tokens: None,
-        })
-    }
-
     /// Parses an optional return type `[ -> TY ]` in a function declaration.
     fn parse_ret_ty(&mut self, allow_plus: bool) -> PResult<'a, FunctionRetTy> {
         if self.eat(&token::RArrow) {
@@ -1992,39 +1842,6 @@ impl<'a> Parser<'a> {
         }))
     }
 
-    /// Parses a structure field.
-    fn parse_name_and_ty(&mut self,
-                         lo: Span,
-                         vis: Visibility,
-                         attrs: Vec<Attribute>)
-                         -> PResult<'a, StructField> {
-        let name = self.parse_ident()?;
-        self.expect(&token::Colon)?;
-        let ty = self.parse_ty()?;
-        Ok(StructField {
-            span: lo.to(self.prev_span),
-            ident: Some(name),
-            vis,
-            id: ast::DUMMY_NODE_ID,
-            ty,
-            attrs,
-        })
-    }
-
-    /// Emits an expected-item-after-attributes error.
-    fn expected_item_err(&mut self, attrs: &[Attribute]) -> PResult<'a,  ()> {
-        let message = match attrs.last() {
-            Some(&Attribute { is_sugared_doc: true, .. }) => "expected item after doc comment",
-            _ => "expected item after attributes",
-        };
-
-        let mut err = self.diagnostic().struct_span_err(self.prev_span, message);
-        if attrs.last().unwrap().is_sugared_doc {
-            err.span_label(self.prev_span, "this doc comment doesn't document anything");
-        }
-        Err(err)
-    }
-
     /// Parse a statement. This stops just before trailing semicolons on everything but items.
     /// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed.
     pub fn parse_stmt(&mut self) -> PResult<'a, Option<Stmt>> {
@@ -2044,11 +1861,6 @@ impl<'a> Parser<'a> {
             self.is_keyword_ahead(1, &[kw::Fn])
     }
 
-    fn is_union_item(&self) -> bool {
-        self.token.is_keyword(kw::Union) &&
-        self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident())
-    }
-
     fn is_crate_vis(&self) -> bool {
         self.token.is_keyword(kw::Crate) && self.look_ahead(1, |t| t != &token::ModSep)
     }
@@ -2063,58 +1875,6 @@ impl<'a> Parser<'a> {
          self.is_keyword_ahead(2, &[kw::Trait]))
     }
 
-    fn eat_macro_def(&mut self, attrs: &[Attribute], vis: &Visibility, lo: Span)
-                     -> PResult<'a, Option<P<Item>>> {
-        let token_lo = self.token.span;
-        let (ident, def) = if self.eat_keyword(kw::Macro) {
-            let ident = self.parse_ident()?;
-            let tokens = if self.check(&token::OpenDelim(token::Brace)) {
-                match self.parse_token_tree() {
-                    TokenTree::Delimited(_, _, tts) => tts,
-                    _ => unreachable!(),
-                }
-            } else if self.check(&token::OpenDelim(token::Paren)) {
-                let args = self.parse_token_tree();
-                let body = if self.check(&token::OpenDelim(token::Brace)) {
-                    self.parse_token_tree()
-                } else {
-                    self.unexpected()?;
-                    unreachable!()
-                };
-                TokenStream::new(vec![
-                    args.into(),
-                    TokenTree::token(token::FatArrow, token_lo.to(self.prev_span)).into(),
-                    body.into(),
-                ])
-            } else {
-                self.unexpected()?;
-                unreachable!()
-            };
-
-            (ident, ast::MacroDef { tokens: tokens.into(), legacy: false })
-        } else if self.check_keyword(sym::macro_rules) &&
-                  self.look_ahead(1, |t| *t == token::Not) &&
-                  self.look_ahead(2, |t| t.is_ident()) {
-            let prev_span = self.prev_span;
-            self.complain_if_pub_macro(&vis.node, prev_span);
-            self.bump();
-            self.bump();
-
-            let ident = self.parse_ident()?;
-            let (delim, tokens) = self.expect_delimited_token_tree()?;
-            if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
-                self.report_invalid_macro_expansion_item();
-            }
-
-            (ident, ast::MacroDef { tokens, legacy: true })
-        } else {
-            return Ok(None);
-        };
-
-        let span = lo.to(self.prev_span);
-        Ok(Some(self.mk_item(span, ident, ItemKind::MacroDef(def), vis.clone(), attrs.to_vec())))
-    }
-
     fn parse_stmt_without_recovery(
         &mut self,
         macro_legacy_warnings: bool,
@@ -2613,32 +2373,6 @@ impl<'a> Parser<'a> {
         })
     }
 
-    /// Parses the following grammar:
-    ///
-    ///     TraitItemAssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty]
-    fn parse_trait_item_assoc_ty(&mut self)
-        -> PResult<'a, (Ident, TraitItemKind, ast::Generics)> {
-        let ident = self.parse_ident()?;
-        let mut generics = self.parse_generics()?;
-
-        // Parse optional colon and param bounds.
-        let bounds = if self.eat(&token::Colon) {
-            self.parse_generic_bounds(None)?
-        } else {
-            Vec::new()
-        };
-        generics.where_clause = self.parse_where_clause()?;
-
-        let default = if self.eat(&token::Eq) {
-            Some(self.parse_ty()?)
-        } else {
-            None
-        };
-        self.expect(&token::Semi)?;
-
-        Ok((ident, TraitItemKind::Type(bounds, default), generics))
-    }
-
     fn parse_const_param(&mut self, preceding_attrs: Vec<Attribute>) -> PResult<'a, GenericParam> {
         self.expect_keyword(kw::Const)?;
         let ident = self.parse_ident()?;
@@ -3134,18 +2868,6 @@ impl<'a> Parser<'a> {
         Ok((args, c_variadic))
     }
 
-    /// Parses the argument list and result type of a function declaration.
-    fn parse_fn_decl(&mut self, allow_c_variadic: bool) -> PResult<'a, P<FnDecl>> {
-        let (args, c_variadic) = self.parse_fn_args(true, allow_c_variadic)?;
-        let ret_ty = self.parse_ret_ty(true)?;
-
-        Ok(P(FnDecl {
-            inputs: args,
-            output: ret_ty,
-            c_variadic,
-        }))
-    }
-
     /// Returns the parsed optional self argument and whether a self shortcut was used.
     ///
     /// See `parse_self_arg_with_attrs` to collect attributes.
@@ -3340,301 +3062,6 @@ impl<'a> Parser<'a> {
         }))
     }
 
-    /// Parses the name and optional generic types of a function header.
-    fn parse_fn_header(&mut self) -> PResult<'a, (Ident, ast::Generics)> {
-        let id = self.parse_ident()?;
-        let generics = self.parse_generics()?;
-        Ok((id, generics))
-    }
-
-    fn mk_item(&self, span: Span, ident: Ident, node: ItemKind, vis: Visibility,
-               attrs: Vec<Attribute>) -> P<Item> {
-        P(Item {
-            ident,
-            attrs,
-            id: ast::DUMMY_NODE_ID,
-            node,
-            vis,
-            span,
-            tokens: None,
-        })
-    }
-
-    /// Parses an item-position function declaration.
-    fn parse_item_fn(&mut self,
-                     unsafety: Unsafety,
-                     asyncness: Spanned<IsAsync>,
-                     constness: Spanned<Constness>,
-                     abi: Abi)
-                     -> PResult<'a, ItemInfo> {
-        let (ident, mut generics) = self.parse_fn_header()?;
-        let allow_c_variadic = abi == Abi::C && unsafety == Unsafety::Unsafe;
-        let decl = self.parse_fn_decl(allow_c_variadic)?;
-        generics.where_clause = self.parse_where_clause()?;
-        let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
-        let header = FnHeader { unsafety, asyncness, constness, abi };
-        Ok((ident, ItemKind::Fn(decl, header, generics, body), Some(inner_attrs)))
-    }
-
-    /// Returns `true` if we are looking at `const ID`
-    /// (returns `false` for things like `const fn`, etc.).
-    fn is_const_item(&self) -> bool {
-        self.token.is_keyword(kw::Const) &&
-            !self.is_keyword_ahead(1, &[kw::Fn, kw::Unsafe])
-    }
-
-    /// Parses all the "front matter" for a `fn` declaration, up to
-    /// and including the `fn` keyword:
-    ///
-    /// - `const fn`
-    /// - `unsafe fn`
-    /// - `const unsafe fn`
-    /// - `extern fn`
-    /// - etc.
-    fn parse_fn_front_matter(&mut self)
-        -> PResult<'a, (
-            Spanned<Constness>,
-            Unsafety,
-            Spanned<IsAsync>,
-            Abi
-        )>
-    {
-        let is_const_fn = self.eat_keyword(kw::Const);
-        let const_span = self.prev_span;
-        let asyncness = self.parse_asyncness();
-        if let IsAsync::Async { .. } = asyncness {
-            self.ban_async_in_2015(self.prev_span);
-        }
-        let asyncness = respan(self.prev_span, asyncness);
-        let unsafety = self.parse_unsafety();
-        let (constness, unsafety, abi) = if is_const_fn {
-            (respan(const_span, Constness::Const), unsafety, Abi::Rust)
-        } else {
-            let abi = if self.eat_keyword(kw::Extern) {
-                self.parse_opt_abi()?.unwrap_or(Abi::C)
-            } else {
-                Abi::Rust
-            };
-            (respan(self.prev_span, Constness::NotConst), unsafety, abi)
-        };
-        if !self.eat_keyword(kw::Fn) {
-            // It is possible for `expect_one_of` to recover given the contents of
-            // `self.expected_tokens`, therefore, do not use `self.unexpected()` which doesn't
-            // account for this.
-            if !self.expect_one_of(&[], &[])? { unreachable!() }
-        }
-        Ok((constness, unsafety, asyncness, abi))
-    }
-
-    /// Parses an impl item.
-    pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, ImplItem> {
-        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);
-            unclosed_delims.append(&mut this.unclosed_delims);
-            item
-        })?;
-        self.unclosed_delims.append(&mut unclosed_delims);
-
-        // See `parse_item` for why this clause is here.
-        if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
-            item.tokens = Some(tokens);
-        }
-        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(false)?;
-        let defaultness = self.parse_defaultness();
-        let (name, node, generics) = if let Some(type_) = self.eat_type() {
-            let (name, alias, generics) = type_?;
-            let kind = match alias {
-                AliasKind::Weak(typ) => ast::ImplItemKind::TyAlias(typ),
-                AliasKind::OpaqueTy(bounds) => ast::ImplItemKind::OpaqueTy(bounds),
-            };
-            (name, kind, generics)
-        } else if self.is_const_item() {
-            // This parses the grammar:
-            //     ImplItemConst = "const" Ident ":" Ty "=" Expr ";"
-            self.expect_keyword(kw::Const)?;
-            let name = self.parse_ident()?;
-            self.expect(&token::Colon)?;
-            let typ = self.parse_ty()?;
-            self.expect(&token::Eq)?;
-            let expr = self.parse_expr()?;
-            self.expect(&token::Semi)?;
-            (name, ast::ImplItemKind::Const(typ, expr), ast::Generics::default())
-        } else {
-            let (name, inner_attrs, generics, node) = self.parse_impl_method(&vis, at_end)?;
-            attrs.extend(inner_attrs);
-            (name, node, generics)
-        };
-
-        Ok(ImplItem {
-            id: ast::DUMMY_NODE_ID,
-            span: lo.to(self.prev_span),
-            ident: name,
-            vis,
-            defaultness,
-            attrs,
-            generics,
-            node,
-            tokens: None,
-        })
-    }
-
-    fn complain_if_pub_macro(&self, vis: &VisibilityKind, sp: Span) {
-        match *vis {
-            VisibilityKind::Inherited => {}
-            _ => {
-                let mut err = if self.token.is_keyword(sym::macro_rules) {
-                    let mut err = self.diagnostic()
-                        .struct_span_err(sp, "can't qualify macro_rules invocation with `pub`");
-                    err.span_suggestion(
-                        sp,
-                        "try exporting the macro",
-                        "#[macro_export]".to_owned(),
-                        Applicability::MaybeIncorrect // speculative
-                    );
-                    err
-                } else {
-                    let mut err = self.diagnostic()
-                        .struct_span_err(sp, "can't qualify macro invocation with `pub`");
-                    err.help("try adjusting the macro to put `pub` inside the invocation");
-                    err
-                };
-                err.emit();
-            }
-        }
-    }
-
-    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
-        let sp = prev_span.between(self.prev_span);
-        let mut err = self.diagnostic().struct_span_err(
-            sp,
-            &format!("{} for {}-item declaration",
-                     expected_kinds, item_type));
-        err.span_label(sp, expected_kinds);
-        err
-    }
-
-    /// Parse a method or a macro invocation in a trait impl.
-    fn parse_impl_method(&mut self, vis: &Visibility, at_end: &mut bool)
-                         -> PResult<'a, (Ident, Vec<Attribute>, ast::Generics,
-                             ast::ImplItemKind)> {
-        // code copied from parse_macro_use_or_failure... abstraction!
-        if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(vis), at_end)? {
-            // method macro
-            Ok((Ident::invalid(), vec![], ast::Generics::default(),
-                ast::ImplItemKind::Macro(mac)))
-        } else {
-            let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
-            let ident = self.parse_ident()?;
-            let mut generics = self.parse_generics()?;
-            let decl = self.parse_fn_decl_with_self(|p| {
-                p.parse_arg_general(true, false, |_| true)
-            })?;
-            generics.where_clause = self.parse_where_clause()?;
-            *at_end = true;
-            let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
-            let header = ast::FnHeader { abi, unsafety, constness, asyncness };
-            Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(
-                ast::MethodSig { header, decl },
-                body
-            )))
-        }
-    }
-
-    /// Parses `trait Foo { ... }` or `trait Foo = Bar;`.
-    fn parse_item_trait(&mut self, is_auto: IsAuto, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
-        let ident = self.parse_ident()?;
-        let mut tps = self.parse_generics()?;
-
-        // Parse optional colon and supertrait bounds.
-        let bounds = if self.eat(&token::Colon) {
-            self.parse_generic_bounds(Some(self.prev_span))?
-        } else {
-            Vec::new()
-        };
-
-        if self.eat(&token::Eq) {
-            // it's a trait alias
-            let bounds = self.parse_generic_bounds(None)?;
-            tps.where_clause = self.parse_where_clause()?;
-            self.expect(&token::Semi)?;
-            if is_auto == IsAuto::Yes {
-                let msg = "trait aliases cannot be `auto`";
-                self.struct_span_err(self.prev_span, msg)
-                    .span_label(self.prev_span, msg)
-                    .emit();
-            }
-            if unsafety != Unsafety::Normal {
-                let msg = "trait aliases cannot be `unsafe`";
-                self.struct_span_err(self.prev_span, msg)
-                    .span_label(self.prev_span, msg)
-                    .emit();
-            }
-            Ok((ident, ItemKind::TraitAlias(tps, bounds), None))
-        } else {
-            // it's a normal trait
-            tps.where_clause = self.parse_where_clause()?;
-            self.expect(&token::OpenDelim(token::Brace))?;
-            let mut trait_items = vec![];
-            while !self.eat(&token::CloseDelim(token::Brace)) {
-                if let token::DocComment(_) = self.token.kind {
-                    if self.look_ahead(1,
-                    |tok| tok == &token::CloseDelim(token::Brace)) {
-                        self.diagnostic().struct_span_err_with_code(
-                            self.token.span,
-                            "found a documentation comment that doesn't document anything",
-                            DiagnosticId::Error("E0584".into()),
-                        )
-                        .help(
-                            "doc comments must come before what they document, maybe a \
-                            comment was intended with `//`?",
-                        )
-                        .emit();
-                        self.bump();
-                        continue;
-                    }
-                }
-                let mut at_end = false;
-                match self.parse_trait_item(&mut at_end) {
-                    Ok(item) => trait_items.push(item),
-                    Err(mut e) => {
-                        e.emit();
-                        if !at_end {
-                            self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
-                        }
-                    }
-                }
-            }
-            Ok((ident, ItemKind::Trait(is_auto, unsafety, tps, bounds, trait_items), None))
-        }
-    }
-
     fn choose_generics_over_qpath(&self) -> bool {
         // There's an ambiguity between generic parameters and qualified paths in impls.
         // If we see `<` it may start both, so we have to inspect some following tokens.
@@ -3660,118 +3087,6 @@ impl<'a> Parser<'a> {
             self.is_keyword_ahead(1, &[kw::Const]))
     }
 
-    fn parse_impl_body(&mut self) -> PResult<'a, (Vec<ImplItem>, Vec<Attribute>)> {
-        self.expect(&token::OpenDelim(token::Brace))?;
-        let attrs = self.parse_inner_attributes()?;
-
-        let mut impl_items = Vec::new();
-        while !self.eat(&token::CloseDelim(token::Brace)) {
-            let mut at_end = false;
-            match self.parse_impl_item(&mut at_end) {
-                Ok(impl_item) => impl_items.push(impl_item),
-                Err(mut err) => {
-                    err.emit();
-                    if !at_end {
-                        self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
-                    }
-                }
-            }
-        }
-        Ok((impl_items, attrs))
-    }
-
-    /// Parses an implementation item, `impl` keyword is already parsed.
-    ///
-    ///    impl<'a, T> TYPE { /* impl items */ }
-    ///    impl<'a, T> TRAIT for TYPE { /* impl items */ }
-    ///    impl<'a, T> !TRAIT for TYPE { /* impl items */ }
-    ///
-    /// We actually parse slightly more relaxed grammar for better error reporting and recovery.
-    ///     `impl` GENERICS `!`? TYPE `for`? (TYPE | `..`) (`where` PREDICATES)? `{` BODY `}`
-    ///     `impl` GENERICS `!`? TYPE (`where` PREDICATES)? `{` BODY `}`
-    fn parse_item_impl(&mut self, unsafety: Unsafety, defaultness: Defaultness)
-                       -> PResult<'a, ItemInfo> {
-        // First, parse generic parameters if necessary.
-        let mut generics = if self.choose_generics_over_qpath() {
-            self.parse_generics()?
-        } else {
-            ast::Generics::default()
-        };
-
-        // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type.
-        let polarity = if self.check(&token::Not) && self.look_ahead(1, |t| t.can_begin_type()) {
-            self.bump(); // `!`
-            ast::ImplPolarity::Negative
-        } else {
-            ast::ImplPolarity::Positive
-        };
-
-        // Parse both types and traits as a type, then reinterpret if necessary.
-        let err_path = |span| ast::Path::from_ident(Ident::new(kw::Invalid, span));
-        let ty_first = if self.token.is_keyword(kw::For) &&
-                          self.look_ahead(1, |t| t != &token::Lt) {
-            let span = self.prev_span.between(self.token.span);
-            self.struct_span_err(span, "missing trait in a trait impl").emit();
-            P(Ty { node: TyKind::Path(None, err_path(span)), span, id: ast::DUMMY_NODE_ID })
-        } else {
-            self.parse_ty()?
-        };
-
-        // If `for` is missing we try to recover.
-        let has_for = self.eat_keyword(kw::For);
-        let missing_for_span = self.prev_span.between(self.token.span);
-
-        let ty_second = if self.token == token::DotDot {
-            // We need to report this error after `cfg` expansion for compatibility reasons
-            self.bump(); // `..`, do not add it to expected tokens
-            Some(DummyResult::raw_ty(self.prev_span, true))
-        } else if has_for || self.token.can_begin_type() {
-            Some(self.parse_ty()?)
-        } else {
-            None
-        };
-
-        generics.where_clause = self.parse_where_clause()?;
-
-        let (impl_items, attrs) = self.parse_impl_body()?;
-
-        let item_kind = match ty_second {
-            Some(ty_second) => {
-                // impl Trait for Type
-                if !has_for {
-                    self.struct_span_err(missing_for_span, "missing `for` in a trait impl")
-                        .span_suggestion_short(
-                            missing_for_span,
-                            "add `for` here",
-                            " for ".to_string(),
-                            Applicability::MachineApplicable,
-                        ).emit();
-                }
-
-                let ty_first = ty_first.into_inner();
-                let path = match ty_first.node {
-                    // This notably includes paths passed through `ty` macro fragments (#46438).
-                    TyKind::Path(None, path) => path,
-                    _ => {
-                        self.span_err(ty_first.span, "expected a trait, found type");
-                        err_path(ty_first.span)
-                    }
-                };
-                let trait_ref = TraitRef { path, ref_id: ty_first.id };
-
-                ItemKind::Impl(unsafety, polarity, defaultness,
-                               generics, Some(trait_ref), ty_second, impl_items)
-            }
-            None => {
-                // impl Type
-                ItemKind::Impl(unsafety, polarity, defaultness,
-                               generics, None, ty_first, impl_items)
-            }
-        };
-
-        Ok((Ident::invalid(), item_kind, Some(attrs)))
-    }
-
     fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<GenericParam>> {
         if self.eat_keyword(kw::For) {
             self.expect_lt()?;
@@ -3785,206 +3100,6 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Parses `struct Foo { ... }`.
-    fn parse_item_struct(&mut self) -> PResult<'a, ItemInfo> {
-        let class_name = self.parse_ident()?;
-
-        let mut generics = self.parse_generics()?;
-
-        // There is a special case worth noting here, as reported in issue #17904.
-        // If we are parsing a tuple struct it is the case that the where clause
-        // should follow the field list. Like so:
-        //
-        // struct Foo<T>(T) where T: Copy;
-        //
-        // If we are parsing a normal record-style struct it is the case
-        // that the where clause comes before the body, and after the generics.
-        // So if we look ahead and see a brace or a where-clause we begin
-        // parsing a record style struct.
-        //
-        // Otherwise if we look ahead and see a paren we parse a tuple-style
-        // struct.
-
-        let vdata = if self.token.is_keyword(kw::Where) {
-            generics.where_clause = self.parse_where_clause()?;
-            if self.eat(&token::Semi) {
-                // If we see a: `struct Foo<T> where T: Copy;` style decl.
-                VariantData::Unit(ast::DUMMY_NODE_ID)
-            } else {
-                // If we see: `struct Foo<T> where T: Copy { ... }`
-                let (fields, recovered) = self.parse_record_struct_body()?;
-                VariantData::Struct(fields, recovered)
-            }
-        // No `where` so: `struct Foo<T>;`
-        } else if self.eat(&token::Semi) {
-            VariantData::Unit(ast::DUMMY_NODE_ID)
-        // Record-style struct definition
-        } else if self.token == token::OpenDelim(token::Brace) {
-            let (fields, recovered) = self.parse_record_struct_body()?;
-            VariantData::Struct(fields, recovered)
-        // Tuple-style struct definition with optional where-clause.
-        } else if self.token == token::OpenDelim(token::Paren) {
-            let body = VariantData::Tuple(self.parse_tuple_struct_body()?, ast::DUMMY_NODE_ID);
-            generics.where_clause = self.parse_where_clause()?;
-            self.expect(&token::Semi)?;
-            body
-        } else {
-            let token_str = self.this_token_descr();
-            let mut err = self.fatal(&format!(
-                "expected `where`, `{{`, `(`, or `;` after struct name, found {}",
-                token_str
-            ));
-            err.span_label(self.token.span, "expected `where`, `{`, `(`, or `;` after struct name");
-            return Err(err);
-        };
-
-        Ok((class_name, ItemKind::Struct(vdata, generics), None))
-    }
-
-    /// Parses `union Foo { ... }`.
-    fn parse_item_union(&mut self) -> PResult<'a, ItemInfo> {
-        let class_name = self.parse_ident()?;
-
-        let mut generics = self.parse_generics()?;
-
-        let vdata = if self.token.is_keyword(kw::Where) {
-            generics.where_clause = self.parse_where_clause()?;
-            let (fields, recovered) = self.parse_record_struct_body()?;
-            VariantData::Struct(fields, recovered)
-        } else if self.token == token::OpenDelim(token::Brace) {
-            let (fields, recovered) = self.parse_record_struct_body()?;
-            VariantData::Struct(fields, recovered)
-        } else {
-            let token_str = self.this_token_descr();
-            let mut err = self.fatal(&format!(
-                "expected `where` or `{{` after union name, found {}", token_str));
-            err.span_label(self.token.span, "expected `where` or `{` after union name");
-            return Err(err);
-        };
-
-        Ok((class_name, ItemKind::Union(vdata, generics), None))
-    }
-
-    fn parse_record_struct_body(
-        &mut self,
-    ) -> PResult<'a, (Vec<StructField>, /* recovered */ bool)> {
-        let mut fields = Vec::new();
-        let mut recovered = false;
-        if self.eat(&token::OpenDelim(token::Brace)) {
-            while self.token != token::CloseDelim(token::Brace) {
-                let field = self.parse_struct_decl_field().map_err(|e| {
-                    self.recover_stmt();
-                    recovered = true;
-                    e
-                });
-                match field {
-                    Ok(field) => fields.push(field),
-                    Err(mut err) => {
-                        err.emit();
-                    }
-                }
-            }
-            self.eat(&token::CloseDelim(token::Brace));
-        } else {
-            let token_str = self.this_token_descr();
-            let mut err = self.fatal(&format!(
-                    "expected `where`, or `{{` after struct name, found {}", token_str));
-            err.span_label(self.token.span, "expected `where`, or `{` after struct name");
-            return Err(err);
-        }
-
-        Ok((fields, recovered))
-    }
-
-    fn parse_tuple_struct_body(&mut self) -> PResult<'a, Vec<StructField>> {
-        // This is the case where we find `struct Foo<T>(T) where T: Copy;`
-        // Unit like structs are handled in parse_item_struct function
-        self.parse_paren_comma_seq(|p| {
-            let attrs = p.parse_outer_attributes()?;
-            let lo = p.token.span;
-            let vis = p.parse_visibility(true)?;
-            let ty = p.parse_ty()?;
-            Ok(StructField {
-                span: lo.to(ty.span),
-                vis,
-                ident: None,
-                id: ast::DUMMY_NODE_ID,
-                ty,
-                attrs,
-            })
-        }).map(|(r, _)| r)
-    }
-
-    /// Parses a structure field declaration.
-    fn parse_single_struct_field(&mut self,
-                                     lo: Span,
-                                     vis: Visibility,
-                                     attrs: Vec<Attribute> )
-                                     -> PResult<'a, StructField> {
-        let mut seen_comma: bool = false;
-        let a_var = self.parse_name_and_ty(lo, vis, attrs)?;
-        if self.token == token::Comma {
-            seen_comma = true;
-        }
-        match self.token.kind {
-            token::Comma => {
-                self.bump();
-            }
-            token::CloseDelim(token::Brace) => {}
-            token::DocComment(_) => {
-                let previous_span = self.prev_span;
-                let mut err = self.span_fatal_err(self.token.span, Error::UselessDocComment);
-                self.bump(); // consume the doc comment
-                let comma_after_doc_seen = self.eat(&token::Comma);
-                // `seen_comma` is always false, because we are inside doc block
-                // condition is here to make code more readable
-                if seen_comma == false && comma_after_doc_seen == true {
-                    seen_comma = true;
-                }
-                if comma_after_doc_seen || self.token == token::CloseDelim(token::Brace) {
-                    err.emit();
-                } else {
-                    if seen_comma == false {
-                        let sp = self.sess.source_map().next_point(previous_span);
-                        err.span_suggestion(
-                            sp,
-                            "missing comma here",
-                            ",".into(),
-                            Applicability::MachineApplicable
-                        );
-                    }
-                    return Err(err);
-                }
-            }
-            _ => {
-                let sp = self.sess.source_map().next_point(self.prev_span);
-                let mut err = self.struct_span_err(sp, &format!("expected `,`, or `}}`, found {}",
-                                                                self.this_token_descr()));
-                if self.token.is_ident() {
-                    // This is likely another field; emit the diagnostic and keep going
-                    err.span_suggestion(
-                        sp,
-                        "try adding a comma",
-                        ",".into(),
-                        Applicability::MachineApplicable,
-                    );
-                    err.emit();
-                } else {
-                    return Err(err)
-                }
-            }
-        }
-        Ok(a_var)
-    }
-
-    /// Parses an element of a struct declaration.
-    fn parse_struct_decl_field(&mut self) -> PResult<'a, StructField> {
-        let attrs = self.parse_outer_attributes()?;
-        let lo = self.token.span;
-        let vis = self.parse_visibility(false)?;
-        self.parse_single_struct_field(lo, vis, attrs)
-    }
-
     /// Parses `pub`, `pub(crate)` and `pub(in path)` plus shortcuts `crate` for `pub(crate)`,
     /// `pub(self)` for `pub(in self)` and `pub(super)` for `pub(in super)`.
     /// If the following element can't be a tuple (i.e., it's a function definition), then
@@ -4074,606 +3189,6 @@ impl<'a> Parser<'a> {
         Ok(respan(lo, VisibilityKind::Public))
     }
 
-    /// Parses defaultness (i.e., `default` or nothing).
-    fn parse_defaultness(&mut self) -> Defaultness {
-        // `pub` is included for better error messages
-        if self.check_keyword(kw::Default) &&
-            self.is_keyword_ahead(1, &[
-                kw::Impl,
-                kw::Const,
-                kw::Fn,
-                kw::Unsafe,
-                kw::Extern,
-                kw::Type,
-                kw::Pub,
-            ])
-        {
-            self.bump(); // `default`
-            Defaultness::Default
-        } else {
-            Defaultness::Final
-        }
-    }
-
-    /// Given a termination token, parses all of the items in a module.
-    fn parse_mod_items(&mut self, term: &TokenKind, inner_lo: Span) -> PResult<'a, Mod> {
-        let mut items = vec![];
-        while let Some(item) = self.parse_item()? {
-            items.push(item);
-            self.maybe_consume_incorrect_semicolon(&items);
-        }
-
-        if !self.eat(term) {
-            let token_str = self.this_token_descr();
-            if !self.maybe_consume_incorrect_semicolon(&items) {
-                let mut err = self.fatal(&format!("expected item, found {}", token_str));
-                err.span_label(self.token.span, "expected item");
-                return Err(err);
-            }
-        }
-
-        let hi = if self.token.span.is_dummy() {
-            inner_lo
-        } else {
-            self.prev_span
-        };
-
-        Ok(ast::Mod {
-            inner: inner_lo.to(hi),
-            items,
-            inline: true
-        })
-    }
-
-    fn parse_item_const(&mut self, m: Option<Mutability>) -> PResult<'a, ItemInfo> {
-        let id = if m.is_none() { self.parse_ident_or_underscore() } else { self.parse_ident() }?;
-        self.expect(&token::Colon)?;
-        let ty = self.parse_ty()?;
-        self.expect(&token::Eq)?;
-        let e = self.parse_expr()?;
-        self.expect(&token::Semi)?;
-        let item = match m {
-            Some(m) => ItemKind::Static(ty, m, e),
-            None => ItemKind::Const(ty, e),
-        };
-        Ok((id, item, None))
-    }
-
-    /// Parse a `mod <foo> { ... }` or `mod <foo>;` item
-    fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo> {
-        let (in_cfg, outer_attrs) = {
-            let mut strip_unconfigured = crate::config::StripUnconfigured {
-                sess: self.sess,
-                features: None, // don't perform gated feature checking
-            };
-            let mut outer_attrs = outer_attrs.to_owned();
-            strip_unconfigured.process_cfg_attrs(&mut outer_attrs);
-            (!self.cfg_mods || strip_unconfigured.in_cfg(&outer_attrs), outer_attrs)
-        };
-
-        let id_span = self.token.span;
-        let id = self.parse_ident()?;
-        if self.eat(&token::Semi) {
-            if in_cfg && self.recurse_into_file_modules {
-                // This mod is in an external file. Let's go get it!
-                let ModulePathSuccess { path, directory_ownership, warn } =
-                    self.submod_path(id, &outer_attrs, id_span)?;
-                let (module, mut attrs) =
-                    self.eval_src_mod(path, directory_ownership, id.to_string(), id_span)?;
-                // Record that we fetched the mod from an external file
-                if warn {
-                    let attr = attr::mk_attr_outer(
-                        attr::mk_word_item(Ident::with_empty_ctxt(sym::warn_directory_ownership)));
-                    attr::mark_known(&attr);
-                    attrs.push(attr);
-                }
-                Ok((id, ItemKind::Mod(module), Some(attrs)))
-            } else {
-                let placeholder = ast::Mod {
-                    inner: DUMMY_SP,
-                    items: Vec::new(),
-                    inline: false
-                };
-                Ok((id, ItemKind::Mod(placeholder), None))
-            }
-        } else {
-            let old_directory = self.directory.clone();
-            self.push_directory(id, &outer_attrs);
-
-            self.expect(&token::OpenDelim(token::Brace))?;
-            let mod_inner_lo = self.token.span;
-            let attrs = self.parse_inner_attributes()?;
-            let module = self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo)?;
-
-            self.directory = old_directory;
-            Ok((id, ItemKind::Mod(module), Some(attrs)))
-        }
-    }
-
-    fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) {
-        if let Some(path) = attr::first_attr_value_str_by_name(attrs, sym::path) {
-            self.directory.path.to_mut().push(&path.as_str());
-            self.directory.ownership = DirectoryOwnership::Owned { relative: None };
-        } else {
-            // We have to push on the current module name in the case of relative
-            // paths in order to ensure that any additional module paths from inline
-            // `mod x { ... }` come after the relative extension.
-            //
-            // For example, a `mod z { ... }` inside `x/y.rs` should set the current
-            // directory path to `/x/y/z`, not `/x/z` with a relative offset of `y`.
-            if let DirectoryOwnership::Owned { relative } = &mut self.directory.ownership {
-                if let Some(ident) = relative.take() { // remove the relative offset
-                    self.directory.path.to_mut().push(ident.as_str());
-                }
-            }
-            self.directory.path.to_mut().push(&id.as_str());
-        }
-    }
-
-    pub fn submod_path_from_attr(attrs: &[Attribute], dir_path: &Path) -> Option<PathBuf> {
-        if let Some(s) = attr::first_attr_value_str_by_name(attrs, sym::path) {
-            let s = s.as_str();
-
-            // On windows, the base path might have the form
-            // `\\?\foo\bar` in which case it does not tolerate
-            // mixed `/` and `\` separators, so canonicalize
-            // `/` to `\`.
-            #[cfg(windows)]
-            let s = s.replace("/", "\\");
-            Some(dir_path.join(s))
-        } else {
-            None
-        }
-    }
-
-    /// Returns a path to a module.
-    pub fn default_submod_path(
-        id: ast::Ident,
-        relative: Option<ast::Ident>,
-        dir_path: &Path,
-        source_map: &SourceMap) -> ModulePath
-    {
-        // If we're in a foo.rs file instead of a mod.rs file,
-        // we need to look for submodules in
-        // `./foo/<id>.rs` and `./foo/<id>/mod.rs` rather than
-        // `./<id>.rs` and `./<id>/mod.rs`.
-        let relative_prefix_string;
-        let relative_prefix = if let Some(ident) = relative {
-            relative_prefix_string = format!("{}{}", ident.as_str(), path::MAIN_SEPARATOR);
-            &relative_prefix_string
-        } else {
-            ""
-        };
-
-        let mod_name = id.to_string();
-        let default_path_str = format!("{}{}.rs", relative_prefix, mod_name);
-        let secondary_path_str = format!("{}{}{}mod.rs",
-                                         relative_prefix, mod_name, path::MAIN_SEPARATOR);
-        let default_path = dir_path.join(&default_path_str);
-        let secondary_path = dir_path.join(&secondary_path_str);
-        let default_exists = source_map.file_exists(&default_path);
-        let secondary_exists = source_map.file_exists(&secondary_path);
-
-        let result = match (default_exists, secondary_exists) {
-            (true, false) => Ok(ModulePathSuccess {
-                path: default_path,
-                directory_ownership: DirectoryOwnership::Owned {
-                    relative: Some(id),
-                },
-                warn: false,
-            }),
-            (false, true) => Ok(ModulePathSuccess {
-                path: secondary_path,
-                directory_ownership: DirectoryOwnership::Owned {
-                    relative: None,
-                },
-                warn: false,
-            }),
-            (false, false) => Err(Error::FileNotFoundForModule {
-                mod_name: mod_name.clone(),
-                default_path: default_path_str,
-                secondary_path: secondary_path_str,
-                dir_path: dir_path.display().to_string(),
-            }),
-            (true, true) => Err(Error::DuplicatePaths {
-                mod_name: mod_name.clone(),
-                default_path: default_path_str,
-                secondary_path: secondary_path_str,
-            }),
-        };
-
-        ModulePath {
-            name: mod_name,
-            path_exists: default_exists || secondary_exists,
-            result,
-        }
-    }
-
-    fn submod_path(&mut self,
-                   id: ast::Ident,
-                   outer_attrs: &[Attribute],
-                   id_sp: Span)
-                   -> PResult<'a, ModulePathSuccess> {
-        if let Some(path) = Parser::submod_path_from_attr(outer_attrs, &self.directory.path) {
-            return Ok(ModulePathSuccess {
-                directory_ownership: match path.file_name().and_then(|s| s.to_str()) {
-                    // All `#[path]` files are treated as though they are a `mod.rs` file.
-                    // This means that `mod foo;` declarations inside `#[path]`-included
-                    // files are siblings,
-                    //
-                    // Note that this will produce weirdness when a file named `foo.rs` is
-                    // `#[path]` included and contains a `mod foo;` declaration.
-                    // If you encounter this, it's your own darn fault :P
-                    Some(_) => DirectoryOwnership::Owned { relative: None },
-                    _ => DirectoryOwnership::UnownedViaMod(true),
-                },
-                path,
-                warn: false,
-            });
-        }
-
-        let relative = match self.directory.ownership {
-            DirectoryOwnership::Owned { relative } => relative,
-            DirectoryOwnership::UnownedViaBlock |
-            DirectoryOwnership::UnownedViaMod(_) => None,
-        };
-        let paths = Parser::default_submod_path(
-                        id, relative, &self.directory.path, self.sess.source_map());
-
-        match self.directory.ownership {
-            DirectoryOwnership::Owned { .. } => {
-                paths.result.map_err(|err| self.span_fatal_err(id_sp, err))
-            },
-            DirectoryOwnership::UnownedViaBlock => {
-                let msg =
-                    "Cannot declare a non-inline module inside a block \
-                    unless it has a path attribute";
-                let mut err = self.diagnostic().struct_span_err(id_sp, msg);
-                if paths.path_exists {
-                    let msg = format!("Maybe `use` the module `{}` instead of redeclaring it",
-                                      paths.name);
-                    err.span_note(id_sp, &msg);
-                }
-                Err(err)
-            }
-            DirectoryOwnership::UnownedViaMod(warn) => {
-                if warn {
-                    if let Ok(result) = paths.result {
-                        return Ok(ModulePathSuccess { warn: true, ..result });
-                    }
-                }
-                let mut err = self.diagnostic().struct_span_err(id_sp,
-                    "cannot declare a new module at this location");
-                if !id_sp.is_dummy() {
-                    let src_path = self.sess.source_map().span_to_filename(id_sp);
-                    if let FileName::Real(src_path) = src_path {
-                        if let Some(stem) = src_path.file_stem() {
-                            let mut dest_path = src_path.clone();
-                            dest_path.set_file_name(stem);
-                            dest_path.push("mod.rs");
-                            err.span_note(id_sp,
-                                    &format!("maybe move this module `{}` to its own \
-                                                directory via `{}`", src_path.display(),
-                                            dest_path.display()));
-                        }
-                    }
-                }
-                if paths.path_exists {
-                    err.span_note(id_sp,
-                                  &format!("... or maybe `use` the module `{}` instead \
-                                            of possibly redeclaring it",
-                                           paths.name));
-                }
-                Err(err)
-            }
-        }
-    }
-
-    /// Reads a module from a source file.
-    fn eval_src_mod(
-        &mut self,
-        path: PathBuf,
-        directory_ownership: DirectoryOwnership,
-        name: String,
-        id_sp: Span,
-    ) -> PResult<'a, (ast::Mod, Vec<Attribute>)> {
-        let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut();
-        if let Some(i) = included_mod_stack.iter().position(|p| *p == path) {
-            let mut err = String::from("circular modules: ");
-            let len = included_mod_stack.len();
-            for p in &included_mod_stack[i.. len] {
-                err.push_str(&p.to_string_lossy());
-                err.push_str(" -> ");
-            }
-            err.push_str(&path.to_string_lossy());
-            return Err(self.span_fatal(id_sp, &err[..]));
-        }
-        included_mod_stack.push(path.clone());
-        drop(included_mod_stack);
-
-        let mut p0 =
-            new_sub_parser_from_file(self.sess, &path, directory_ownership, Some(name), id_sp);
-        p0.cfg_mods = self.cfg_mods;
-        let mod_inner_lo = p0.token.span;
-        let mod_attrs = p0.parse_inner_attributes()?;
-        let mut m0 = p0.parse_mod_items(&token::Eof, mod_inner_lo)?;
-        m0.inline = false;
-        self.sess.included_mod_stack.borrow_mut().pop();
-        Ok((m0, mod_attrs))
-    }
-
-    /// Parses a function declaration from a foreign module.
-    fn parse_item_foreign_fn(
-        &mut self,
-        vis: ast::Visibility,
-        lo: Span,
-        attrs: Vec<Attribute>,
-        extern_sp: Span,
-    ) -> PResult<'a, ForeignItem> {
-        self.expect_keyword(kw::Fn)?;
-
-        let (ident, mut generics) = self.parse_fn_header()?;
-        let decl = self.parse_fn_decl(true)?;
-        generics.where_clause = self.parse_where_clause()?;
-        let hi = self.token.span;
-        self.parse_semi_or_incorrect_foreign_fn_body(&ident, extern_sp)?;
-        Ok(ast::ForeignItem {
-            ident,
-            attrs,
-            node: ForeignItemKind::Fn(decl, generics),
-            id: ast::DUMMY_NODE_ID,
-            span: lo.to(hi),
-            vis,
-        })
-    }
-
-    /// Parses a static item from a foreign module.
-    /// Assumes that the `static` keyword is already parsed.
-    fn parse_item_foreign_static(&mut self, vis: ast::Visibility, lo: Span, attrs: Vec<Attribute>)
-                                 -> PResult<'a, ForeignItem> {
-        let mutbl = self.parse_mutability();
-        let ident = self.parse_ident()?;
-        self.expect(&token::Colon)?;
-        let ty = self.parse_ty()?;
-        let hi = self.token.span;
-        self.expect(&token::Semi)?;
-        Ok(ForeignItem {
-            ident,
-            attrs,
-            node: ForeignItemKind::Static(ty, mutbl),
-            id: ast::DUMMY_NODE_ID,
-            span: lo.to(hi),
-            vis,
-        })
-    }
-
-    /// Parses a type from a foreign module.
-    fn parse_item_foreign_type(&mut self, vis: ast::Visibility, lo: Span, attrs: Vec<Attribute>)
-                             -> PResult<'a, ForeignItem> {
-        self.expect_keyword(kw::Type)?;
-
-        let ident = self.parse_ident()?;
-        let hi = self.token.span;
-        self.expect(&token::Semi)?;
-        Ok(ast::ForeignItem {
-            ident,
-            attrs,
-            node: ForeignItemKind::Ty,
-            id: ast::DUMMY_NODE_ID,
-            span: lo.to(hi),
-            vis
-        })
-    }
-
-    fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, ast::Ident> {
-        let error_msg = "crate name using dashes are not valid in `extern crate` statements";
-        let suggestion_msg = "if the original crate name uses dashes you need to use underscores \
-                              in the code";
-        let mut ident = if self.token.is_keyword(kw::SelfLower) {
-            self.parse_path_segment_ident()
-        } else {
-            self.parse_ident()
-        }?;
-        let mut idents = vec![];
-        let mut replacement = vec![];
-        let mut fixed_crate_name = false;
-        // Accept `extern crate name-like-this` for better diagnostics
-        let dash = token::BinOp(token::BinOpToken::Minus);
-        if self.token == dash {  // Do not include `-` as part of the expected tokens list
-            while self.eat(&dash) {
-                fixed_crate_name = true;
-                replacement.push((self.prev_span, "_".to_string()));
-                idents.push(self.parse_ident()?);
-            }
-        }
-        if fixed_crate_name {
-            let fixed_name_sp = ident.span.to(idents.last().unwrap().span);
-            let mut fixed_name = format!("{}", ident.name);
-            for part in idents {
-                fixed_name.push_str(&format!("_{}", part.name));
-            }
-            ident = Ident::from_str(&fixed_name).with_span_pos(fixed_name_sp);
-
-            self.struct_span_err(fixed_name_sp, error_msg)
-                .span_label(fixed_name_sp, "dash-separated idents are not valid")
-                .multipart_suggestion(suggestion_msg, replacement, Applicability::MachineApplicable)
-                .emit();
-        }
-        Ok(ident)
-    }
-
-    /// Parses `extern crate` links.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// extern crate foo;
-    /// extern crate bar as foo;
-    /// ```
-    fn parse_item_extern_crate(&mut self,
-                               lo: Span,
-                               visibility: Visibility,
-                               attrs: Vec<Attribute>)
-                               -> PResult<'a, P<Item>> {
-        // Accept `extern crate name-like-this` for better diagnostics
-        let orig_name = self.parse_crate_name_with_dashes()?;
-        let (item_name, orig_name) = if let Some(rename) = self.parse_rename()? {
-            (rename, Some(orig_name.name))
-        } else {
-            (orig_name, None)
-        };
-        self.expect(&token::Semi)?;
-
-        let span = lo.to(self.prev_span);
-        Ok(self.mk_item(span, item_name, ItemKind::ExternCrate(orig_name), visibility, attrs))
-    }
-
-    /// Parses `extern` for foreign ABIs modules.
-    ///
-    /// `extern` is expected to have been
-    /// consumed before calling this method.
-    ///
-    /// # Examples
-    ///
-    /// ```ignore (only-for-syntax-highlight)
-    /// extern "C" {}
-    /// extern {}
-    /// ```
-    fn parse_item_foreign_mod(
-        &mut self,
-        lo: Span,
-        opt_abi: Option<Abi>,
-        visibility: Visibility,
-        mut attrs: Vec<Attribute>,
-        extern_sp: Span,
-    ) -> PResult<'a, P<Item>> {
-        self.expect(&token::OpenDelim(token::Brace))?;
-
-        let abi = opt_abi.unwrap_or(Abi::C);
-
-        attrs.extend(self.parse_inner_attributes()?);
-
-        let mut foreign_items = vec![];
-        while !self.eat(&token::CloseDelim(token::Brace)) {
-            foreign_items.push(self.parse_foreign_item(extern_sp)?);
-        }
-
-        let prev_span = self.prev_span;
-        let m = ast::ForeignMod {
-            abi,
-            items: foreign_items
-        };
-        let invalid = Ident::invalid();
-        Ok(self.mk_item(lo.to(prev_span), invalid, ItemKind::ForeignMod(m), visibility, attrs))
-    }
-
-    /// Parses `type Foo = Bar;` or returns `None`
-    /// without modifying the parser state.
-    fn eat_type(&mut self) -> Option<PResult<'a, (Ident, AliasKind, ast::Generics)>> {
-        // This parses the grammar:
-        //     Ident ["<"...">"] ["where" ...] ("=" | ":") Ty ";"
-        if self.eat_keyword(kw::Type) {
-            Some(self.parse_type_alias())
-        } else {
-            None
-        }
-    }
-
-    /// Parses a type alias or opaque type.
-    fn parse_type_alias(&mut self) -> PResult<'a, (Ident, AliasKind, ast::Generics)> {
-        let ident = self.parse_ident()?;
-        let mut tps = self.parse_generics()?;
-        tps.where_clause = self.parse_where_clause()?;
-        self.expect(&token::Eq)?;
-        let alias = if self.check_keyword(kw::Impl) {
-            self.bump();
-            let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
-            AliasKind::OpaqueTy(bounds)
-        } else {
-            let ty = self.parse_ty()?;
-            AliasKind::Weak(ty)
-        };
-        self.expect(&token::Semi)?;
-        Ok((ident, alias, tps))
-    }
-
-    /// Parses the part of an enum declaration following the `{`.
-    fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<'a, EnumDef> {
-        let mut variants = Vec::new();
-        while self.token != token::CloseDelim(token::Brace) {
-            let variant_attrs = self.parse_outer_attributes()?;
-            let vlo = self.token.span;
-
-            self.eat_bad_pub();
-            let ident = self.parse_ident()?;
-
-            let struct_def = if self.check(&token::OpenDelim(token::Brace)) {
-                // Parse a struct variant.
-                let (fields, recovered) = self.parse_record_struct_body()?;
-                VariantData::Struct(fields, recovered)
-            } else if self.check(&token::OpenDelim(token::Paren)) {
-                VariantData::Tuple(
-                    self.parse_tuple_struct_body()?,
-                    ast::DUMMY_NODE_ID,
-                )
-            } else {
-                VariantData::Unit(ast::DUMMY_NODE_ID)
-            };
-
-            let disr_expr = if self.eat(&token::Eq) {
-                Some(AnonConst {
-                    id: ast::DUMMY_NODE_ID,
-                    value: self.parse_expr()?,
-                })
-            } else {
-                None
-            };
-
-            let vr = ast::Variant_ {
-                ident,
-                id: ast::DUMMY_NODE_ID,
-                attrs: variant_attrs,
-                data: struct_def,
-                disr_expr,
-            };
-            variants.push(respan(vlo.to(self.prev_span), vr));
-
-            if !self.eat(&token::Comma) {
-                if self.token.is_ident() && !self.token.is_reserved_ident() {
-                    let sp = self.sess.source_map().next_point(self.prev_span);
-                    self.struct_span_err(sp, "missing comma")
-                        .span_suggestion_short(
-                            sp,
-                            "missing comma",
-                            ",".to_owned(),
-                            Applicability::MaybeIncorrect,
-                        )
-                        .emit();
-                } else {
-                    break;
-                }
-            }
-        }
-        self.expect(&token::CloseDelim(token::Brace))?;
-
-        Ok(ast::EnumDef { variants })
-    }
-
-    /// Parses an enum declaration.
-    fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
-        let id = self.parse_ident()?;
-        let mut generics = self.parse_generics()?;
-        generics.where_clause = self.parse_where_clause()?;
-        self.expect(&token::OpenDelim(token::Brace))?;
-
-        let enum_definition = self.parse_enum_def(&generics).map_err(|e| {
-            self.recover_stmt();
-            self.eat(&token::CloseDelim(token::Brace));
-            e
-        })?;
-        Ok((id, ItemKind::Enum(enum_definition, generics), None))
-    }
-
     /// Parses a string as an ABI spec on an extern type or module. Consumes
     /// the `extern` keyword, if one is found.
     fn parse_opt_abi(&mut self) -> PResult<'a, Option<Abi>> {
@@ -4706,489 +3221,6 @@ impl<'a> Parser<'a> {
         }
     }
 
-    fn is_static_global(&mut self) -> bool {
-        if self.check_keyword(kw::Static) {
-            // Check if this could be a closure
-            !self.look_ahead(1, |token| {
-                if token.is_keyword(kw::Move) {
-                    return true;
-                }
-                match token.kind {
-                    token::BinOp(token::Or) | token::OrOr => true,
-                    _ => false,
-                }
-            })
-        } else {
-            false
-        }
-    }
-
-    fn parse_item_(
-        &mut self,
-        attrs: Vec<Attribute>,
-        macros_allowed: bool,
-        attributes_allowed: bool,
-    ) -> PResult<'a, Option<P<Item>>> {
-        let mut unclosed_delims = vec![];
-        let (ret, tokens) = self.collect_tokens(|this| {
-            let item = this.parse_item_implementation(attrs, macros_allowed, attributes_allowed);
-            unclosed_delims.append(&mut this.unclosed_delims);
-            item
-        })?;
-        self.unclosed_delims.append(&mut unclosed_delims);
-
-        // Once we've parsed an item and recorded the tokens we got while
-        // parsing we may want to store `tokens` into the item we're about to
-        // return. Note, though, that we specifically didn't capture tokens
-        // related to outer attributes. The `tokens` field here may later be
-        // used with procedural macros to convert this item back into a token
-        // stream, but during expansion we may be removing attributes as we go
-        // along.
-        //
-        // If we've got inner attributes then the `tokens` we've got above holds
-        // these inner attributes. If an inner attribute is expanded we won't
-        // actually remove it from the token stream, so we'll just keep yielding
-        // it (bad!). To work around this case for now we just avoid recording
-        // `tokens` if we detect any inner attributes. This should help keep
-        // expansion correct, but we should fix this bug one day!
-        Ok(ret.map(|item| {
-            item.map(|mut i| {
-                if !i.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
-                    i.tokens = Some(tokens);
-                }
-                i
-            })
-        }))
-    }
-
-    /// Parses one of the items allowed by the flags.
-    fn parse_item_implementation(
-        &mut self,
-        attrs: Vec<Attribute>,
-        macros_allowed: bool,
-        attributes_allowed: bool,
-    ) -> PResult<'a, Option<P<Item>>> {
-        maybe_whole!(self, NtItem, |item| {
-            let mut item = item.into_inner();
-            let mut attrs = attrs;
-            mem::swap(&mut item.attrs, &mut attrs);
-            item.attrs.extend(attrs);
-            Some(P(item))
-        });
-
-        let lo = self.token.span;
-
-        let visibility = self.parse_visibility(false)?;
-
-        if self.eat_keyword(kw::Use) {
-            // USE ITEM
-            let item_ = ItemKind::Use(P(self.parse_use_tree()?));
-            self.expect(&token::Semi)?;
-
-            let span = lo.to(self.prev_span);
-            let item =
-                self.mk_item(span, Ident::invalid(), item_, visibility, attrs);
-            return Ok(Some(item));
-        }
-
-        if self.eat_keyword(kw::Extern) {
-            let extern_sp = self.prev_span;
-            if self.eat_keyword(kw::Crate) {
-                return Ok(Some(self.parse_item_extern_crate(lo, visibility, attrs)?));
-            }
-
-            let opt_abi = self.parse_opt_abi()?;
-
-            if self.eat_keyword(kw::Fn) {
-                // EXTERN FUNCTION ITEM
-                let fn_span = self.prev_span;
-                let abi = opt_abi.unwrap_or(Abi::C);
-                let (ident, item_, extra_attrs) =
-                    self.parse_item_fn(Unsafety::Normal,
-                                       respan(fn_span, IsAsync::NotAsync),
-                                       respan(fn_span, Constness::NotConst),
-                                       abi)?;
-                let prev_span = self.prev_span;
-                let item = self.mk_item(lo.to(prev_span),
-                                        ident,
-                                        item_,
-                                        visibility,
-                                        maybe_append(attrs, extra_attrs));
-                return Ok(Some(item));
-            } else if self.check(&token::OpenDelim(token::Brace)) {
-                return Ok(Some(
-                    self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs, extern_sp)?,
-                ));
-            }
-
-            self.unexpected()?;
-        }
-
-        if self.is_static_global() {
-            self.bump();
-            // STATIC ITEM
-            let m = if self.eat_keyword(kw::Mut) {
-                Mutability::Mutable
-            } else {
-                Mutability::Immutable
-            };
-            let (ident, item_, extra_attrs) = self.parse_item_const(Some(m))?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
-        }
-        if self.eat_keyword(kw::Const) {
-            let const_span = self.prev_span;
-            if self.check_keyword(kw::Fn)
-                || (self.check_keyword(kw::Unsafe)
-                    && self.is_keyword_ahead(1, &[kw::Fn])) {
-                // CONST FUNCTION ITEM
-                let unsafety = self.parse_unsafety();
-                self.bump();
-                let (ident, item_, extra_attrs) =
-                    self.parse_item_fn(unsafety,
-                                       respan(const_span, IsAsync::NotAsync),
-                                       respan(const_span, Constness::Const),
-                                       Abi::Rust)?;
-                let prev_span = self.prev_span;
-                let item = self.mk_item(lo.to(prev_span),
-                                        ident,
-                                        item_,
-                                        visibility,
-                                        maybe_append(attrs, extra_attrs));
-                return Ok(Some(item));
-            }
-
-            // CONST ITEM
-            if self.eat_keyword(kw::Mut) {
-                let prev_span = self.prev_span;
-                self.struct_span_err(prev_span, "const globals cannot be mutable")
-                    .span_label(prev_span, "cannot be mutable")
-                    .span_suggestion(
-                        const_span,
-                        "you might want to declare a static instead",
-                        "static".to_owned(),
-                        Applicability::MaybeIncorrect,
-                    )
-                    .emit();
-            }
-            let (ident, item_, extra_attrs) = self.parse_item_const(None)?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
-        }
-
-        // Parse `async unsafe? fn`.
-        if self.check_keyword(kw::Async) {
-            let async_span = self.token.span;
-            if self.is_keyword_ahead(1, &[kw::Fn])
-                || self.is_keyword_ahead(2, &[kw::Fn])
-            {
-                // ASYNC FUNCTION ITEM
-                self.bump(); // `async`
-                let unsafety = self.parse_unsafety(); // `unsafe`?
-                self.expect_keyword(kw::Fn)?; // `fn`
-                let fn_span = self.prev_span;
-                let (ident, item_, extra_attrs) =
-                    self.parse_item_fn(unsafety,
-                                    respan(async_span, IsAsync::Async {
-                                        closure_id: ast::DUMMY_NODE_ID,
-                                        return_impl_trait_id: ast::DUMMY_NODE_ID,
-                                    }),
-                                    respan(fn_span, Constness::NotConst),
-                                    Abi::Rust)?;
-                let prev_span = self.prev_span;
-                let item = self.mk_item(lo.to(prev_span),
-                                        ident,
-                                        item_,
-                                        visibility,
-                                        maybe_append(attrs, extra_attrs));
-                self.ban_async_in_2015(async_span);
-                return Ok(Some(item));
-            }
-        }
-        if self.check_keyword(kw::Unsafe) &&
-            self.is_keyword_ahead(1, &[kw::Trait, kw::Auto])
-        {
-            // UNSAFE TRAIT ITEM
-            self.bump(); // `unsafe`
-            let is_auto = if self.eat_keyword(kw::Trait) {
-                IsAuto::No
-            } else {
-                self.expect_keyword(kw::Auto)?;
-                self.expect_keyword(kw::Trait)?;
-                IsAuto::Yes
-            };
-            let (ident, item_, extra_attrs) =
-                self.parse_item_trait(is_auto, Unsafety::Unsafe)?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
-        }
-        if self.check_keyword(kw::Impl) ||
-           self.check_keyword(kw::Unsafe) &&
-                self.is_keyword_ahead(1, &[kw::Impl]) ||
-           self.check_keyword(kw::Default) &&
-                self.is_keyword_ahead(1, &[kw::Impl, kw::Unsafe]) {
-            // IMPL ITEM
-            let defaultness = self.parse_defaultness();
-            let unsafety = self.parse_unsafety();
-            self.expect_keyword(kw::Impl)?;
-            let (ident, item, extra_attrs) = self.parse_item_impl(unsafety, defaultness)?;
-            let span = lo.to(self.prev_span);
-            return Ok(Some(self.mk_item(span, ident, item, visibility,
-                                        maybe_append(attrs, extra_attrs))));
-        }
-        if self.check_keyword(kw::Fn) {
-            // FUNCTION ITEM
-            self.bump();
-            let fn_span = self.prev_span;
-            let (ident, item_, extra_attrs) =
-                self.parse_item_fn(Unsafety::Normal,
-                                   respan(fn_span, IsAsync::NotAsync),
-                                   respan(fn_span, Constness::NotConst),
-                                   Abi::Rust)?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
-        }
-        if self.check_keyword(kw::Unsafe)
-            && self.look_ahead(1, |t| *t != token::OpenDelim(token::Brace)) {
-            // UNSAFE FUNCTION ITEM
-            self.bump(); // `unsafe`
-            // `{` is also expected after `unsafe`, in case of error, include it in the diagnostic
-            self.check(&token::OpenDelim(token::Brace));
-            let abi = if self.eat_keyword(kw::Extern) {
-                self.parse_opt_abi()?.unwrap_or(Abi::C)
-            } else {
-                Abi::Rust
-            };
-            self.expect_keyword(kw::Fn)?;
-            let fn_span = self.prev_span;
-            let (ident, item_, extra_attrs) =
-                self.parse_item_fn(Unsafety::Unsafe,
-                                   respan(fn_span, IsAsync::NotAsync),
-                                   respan(fn_span, Constness::NotConst),
-                                   abi)?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
-        }
-        if self.eat_keyword(kw::Mod) {
-            // MODULE ITEM
-            let (ident, item_, extra_attrs) =
-                self.parse_item_mod(&attrs[..])?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
-        }
-        if let Some(type_) = self.eat_type() {
-            let (ident, alias, generics) = type_?;
-            // TYPE ITEM
-            let item_ = match alias {
-                AliasKind::Weak(ty) => ItemKind::TyAlias(ty, generics),
-                AliasKind::OpaqueTy(bounds) => ItemKind::OpaqueTy(bounds, generics),
-            };
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    attrs);
-            return Ok(Some(item));
-        }
-        if self.eat_keyword(kw::Enum) {
-            // ENUM ITEM
-            let (ident, item_, extra_attrs) = self.parse_item_enum()?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
-        }
-        if self.check_keyword(kw::Trait)
-            || (self.check_keyword(kw::Auto)
-                && self.is_keyword_ahead(1, &[kw::Trait]))
-        {
-            let is_auto = if self.eat_keyword(kw::Trait) {
-                IsAuto::No
-            } else {
-                self.expect_keyword(kw::Auto)?;
-                self.expect_keyword(kw::Trait)?;
-                IsAuto::Yes
-            };
-            // TRAIT ITEM
-            let (ident, item_, extra_attrs) =
-                self.parse_item_trait(is_auto, Unsafety::Normal)?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
-        }
-        if self.eat_keyword(kw::Struct) {
-            // STRUCT ITEM
-            let (ident, item_, extra_attrs) = self.parse_item_struct()?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
-        }
-        if self.is_union_item() {
-            // UNION ITEM
-            self.bump();
-            let (ident, item_, extra_attrs) = self.parse_item_union()?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
-        }
-        if let Some(macro_def) = self.eat_macro_def(&attrs, &visibility, lo)? {
-            return Ok(Some(macro_def));
-        }
-
-        // Verify whether we have encountered a struct or method definition where the user forgot to
-        // add the `struct` or `fn` keyword after writing `pub`: `pub S {}`
-        if visibility.node.is_pub() &&
-            self.check_ident() &&
-            self.look_ahead(1, |t| *t != token::Not)
-        {
-            // Space between `pub` keyword and the identifier
-            //
-            //     pub   S {}
-            //        ^^^ `sp` points here
-            let sp = self.prev_span.between(self.token.span);
-            let full_sp = self.prev_span.to(self.token.span);
-            let ident_sp = self.token.span;
-            if self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) {
-                // possible public struct definition where `struct` was forgotten
-                let ident = self.parse_ident().unwrap();
-                let msg = format!("add `struct` here to parse `{}` as a public struct",
-                                  ident);
-                let mut err = self.diagnostic()
-                    .struct_span_err(sp, "missing `struct` for struct definition");
-                err.span_suggestion_short(
-                    sp, &msg, " struct ".into(), Applicability::MaybeIncorrect // speculative
-                );
-                return Err(err);
-            } else if self.look_ahead(1, |t| *t == token::OpenDelim(token::Paren)) {
-                let ident = self.parse_ident().unwrap();
-                self.bump();  // `(`
-                let kw_name = if let Ok(Some(_)) = self.parse_self_arg_with_attrs()
-                    .map_err(|mut e| e.cancel())
-                {
-                    "method"
-                } else {
-                    "function"
-                };
-                self.consume_block(token::Paren);
-                let (kw, kw_name, ambiguous) = if self.check(&token::RArrow) {
-                    self.eat_to_tokens(&[&token::OpenDelim(token::Brace)]);
-                    self.bump();  // `{`
-                    ("fn", kw_name, false)
-                } else if self.check(&token::OpenDelim(token::Brace)) {
-                    self.bump();  // `{`
-                    ("fn", kw_name, false)
-                } else if self.check(&token::Colon) {
-                    let kw = "struct";
-                    (kw, kw, false)
-                } else {
-                    ("fn` or `struct", "function or struct", true)
-                };
-
-                let msg = format!("missing `{}` for {} definition", kw, kw_name);
-                let mut err = self.diagnostic().struct_span_err(sp, &msg);
-                if !ambiguous {
-                    self.consume_block(token::Brace);
-                    let suggestion = format!("add `{}` here to parse `{}` as a public {}",
-                                             kw,
-                                             ident,
-                                             kw_name);
-                    err.span_suggestion_short(
-                        sp, &suggestion, format!(" {} ", kw), Applicability::MachineApplicable
-                    );
-                } else {
-                    if let Ok(snippet) = self.span_to_snippet(ident_sp) {
-                        err.span_suggestion(
-                            full_sp,
-                            "if you meant to call a macro, try",
-                            format!("{}!", snippet),
-                            // this is the `ambiguous` conditional branch
-                            Applicability::MaybeIncorrect
-                        );
-                    } else {
-                        err.help("if you meant to call a macro, remove the `pub` \
-                                  and add a trailing `!` after the identifier");
-                    }
-                }
-                return Err(err);
-            } else if self.look_ahead(1, |t| *t == token::Lt) {
-                let ident = self.parse_ident().unwrap();
-                self.eat_to_tokens(&[&token::Gt]);
-                self.bump();  // `>`
-                let (kw, kw_name, ambiguous) = if self.eat(&token::OpenDelim(token::Paren)) {
-                    if let Ok(Some(_)) = self.parse_self_arg_with_attrs()
-                        .map_err(|mut e| e.cancel())
-                    {
-                        ("fn", "method", false)
-                    } else {
-                        ("fn", "function", false)
-                    }
-                } else if self.check(&token::OpenDelim(token::Brace)) {
-                    ("struct", "struct", false)
-                } else {
-                    ("fn` or `struct", "function or struct", true)
-                };
-                let msg = format!("missing `{}` for {} definition", kw, kw_name);
-                let mut err = self.diagnostic().struct_span_err(sp, &msg);
-                if !ambiguous {
-                    err.span_suggestion_short(
-                        sp,
-                        &format!("add `{}` here to parse `{}` as a public {}", kw, ident, kw_name),
-                        format!(" {} ", kw),
-                        Applicability::MachineApplicable,
-                    );
-                }
-                return Err(err);
-            }
-        }
-        self.parse_macro_use_or_failure(attrs, macros_allowed, attributes_allowed, lo, visibility)
-    }
-
     /// We are parsing `async fn`. If we are on Rust 2015, emit an error.
     fn ban_async_in_2015(&self, async_span: Span) {
         if async_span.rust_2015() {
@@ -5202,155 +3234,6 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Parses a foreign item.
-    crate fn parse_foreign_item(&mut self, extern_sp: Span) -> PResult<'a, ForeignItem> {
-        maybe_whole!(self, NtForeignItem, |ni| ni);
-
-        let attrs = self.parse_outer_attributes()?;
-        let lo = self.token.span;
-        let visibility = self.parse_visibility(false)?;
-
-        // FOREIGN STATIC ITEM
-        // Treat `const` as `static` for error recovery, but don't add it to expected tokens.
-        if self.check_keyword(kw::Static) || self.token.is_keyword(kw::Const) {
-            if self.token.is_keyword(kw::Const) {
-                self.diagnostic()
-                    .struct_span_err(self.token.span, "extern items cannot be `const`")
-                    .span_suggestion(
-                        self.token.span,
-                        "try using a static value",
-                        "static".to_owned(),
-                        Applicability::MachineApplicable
-                    ).emit();
-            }
-            self.bump(); // `static` or `const`
-            return Ok(self.parse_item_foreign_static(visibility, lo, attrs)?);
-        }
-        // FOREIGN FUNCTION ITEM
-        if self.check_keyword(kw::Fn) {
-            return Ok(self.parse_item_foreign_fn(visibility, lo, attrs, extern_sp)?);
-        }
-        // FOREIGN TYPE ITEM
-        if self.check_keyword(kw::Type) {
-            return Ok(self.parse_item_foreign_type(visibility, lo, attrs)?);
-        }
-
-        match self.parse_assoc_macro_invoc("extern", Some(&visibility), &mut false)? {
-            Some(mac) => {
-                Ok(
-                    ForeignItem {
-                        ident: Ident::invalid(),
-                        span: lo.to(self.prev_span),
-                        id: ast::DUMMY_NODE_ID,
-                        attrs,
-                        vis: visibility,
-                        node: ForeignItemKind::Macro(mac),
-                    }
-                )
-            }
-            None => {
-                if !attrs.is_empty()  {
-                    self.expected_item_err(&attrs)?;
-                }
-
-                self.unexpected()
-            }
-        }
-    }
-
-    /// This is the fall-through for parsing items.
-    fn parse_macro_use_or_failure(
-        &mut self,
-        attrs: Vec<Attribute> ,
-        macros_allowed: bool,
-        attributes_allowed: bool,
-        lo: Span,
-        visibility: Visibility
-    ) -> PResult<'a, Option<P<Item>>> {
-        if macros_allowed && self.token.is_path_start() &&
-                !(self.is_async_fn() && self.token.span.rust_2015()) {
-            // MACRO INVOCATION ITEM
-
-            let prev_span = self.prev_span;
-            self.complain_if_pub_macro(&visibility.node, prev_span);
-
-            let mac_lo = self.token.span;
-
-            // item macro.
-            let path = self.parse_path(PathStyle::Mod)?;
-            self.expect(&token::Not)?;
-            let (delim, tts) = self.expect_delimited_token_tree()?;
-            if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
-                self.report_invalid_macro_expansion_item();
-            }
-
-            let hi = self.prev_span;
-            let mac = respan(mac_lo.to(hi), Mac_ {
-                path,
-                tts,
-                delim,
-                prior_type_ascription: self.last_type_ascription,
-            });
-            let item =
-                self.mk_item(lo.to(hi), Ident::invalid(), ItemKind::Mac(mac), visibility, attrs);
-            return Ok(Some(item));
-        }
-
-        // FAILURE TO PARSE ITEM
-        match visibility.node {
-            VisibilityKind::Inherited => {}
-            _ => {
-                return Err(self.span_fatal(self.prev_span, "unmatched visibility `pub`"));
-            }
-        }
-
-        if !attributes_allowed && !attrs.is_empty() {
-            self.expected_item_err(&attrs)?;
-        }
-        Ok(None)
-    }
-
-    /// Parses a macro invocation inside a `trait`, `impl` or `extern` block.
-    fn parse_assoc_macro_invoc(&mut self, item_kind: &str, vis: Option<&Visibility>,
-                               at_end: &mut bool) -> PResult<'a, Option<Mac>>
-    {
-        if self.token.is_path_start() &&
-                !(self.is_async_fn() && self.token.span.rust_2015()) {
-            let prev_span = self.prev_span;
-            let lo = self.token.span;
-            let path = self.parse_path(PathStyle::Mod)?;
-
-            if path.segments.len() == 1 {
-                if !self.eat(&token::Not) {
-                    return Err(self.missing_assoc_item_kind_err(item_kind, prev_span));
-                }
-            } else {
-                self.expect(&token::Not)?;
-            }
-
-            if let Some(vis) = vis {
-                self.complain_if_pub_macro(&vis.node, prev_span);
-            }
-
-            *at_end = true;
-
-            // eat a matched-delimiter token tree:
-            let (delim, tts) = self.expect_delimited_token_tree()?;
-            if delim != MacDelimiter::Brace {
-                self.expect(&token::Semi)?;
-            }
-
-            Ok(Some(respan(lo.to(self.prev_span), Mac_ {
-                path,
-                tts,
-                delim,
-                prior_type_ascription: self.last_type_ascription,
-            })))
-        } else {
-            Ok(None)
-        }
-    }
-
     fn collect_tokens<F, R>(&mut self, f: F) -> PResult<'a, (R, TokenStream)>
         where F: FnOnce(&mut Self) -> PResult<'a, R>
     {
@@ -5420,11 +3303,6 @@ impl<'a> Parser<'a> {
         Ok((ret?, TokenStream::new(collected_tokens)))
     }
 
-    pub fn parse_item(&mut self) -> PResult<'a, Option<P<Item>>> {
-        let attrs = self.parse_outer_attributes()?;
-        self.parse_item_(attrs, true, false)
-    }
-
     /// `::{` or `::*`
     fn is_import_coupler(&mut self) -> bool {
         self.check(&token::ModSep) &&
@@ -5432,82 +3310,6 @@ impl<'a> Parser<'a> {
                                    *t == token::BinOp(token::Star))
     }
 
-    /// Parses a `UseTree`.
-    ///
-    /// ```
-    /// USE_TREE = [`::`] `*` |
-    ///            [`::`] `{` USE_TREE_LIST `}` |
-    ///            PATH `::` `*` |
-    ///            PATH `::` `{` USE_TREE_LIST `}` |
-    ///            PATH [`as` IDENT]
-    /// ```
-    fn parse_use_tree(&mut self) -> PResult<'a, UseTree> {
-        let lo = self.token.span;
-
-        let mut prefix = ast::Path { segments: Vec::new(), span: lo.shrink_to_lo() };
-        let kind = if self.check(&token::OpenDelim(token::Brace)) ||
-                      self.check(&token::BinOp(token::Star)) ||
-                      self.is_import_coupler() {
-            // `use *;` or `use ::*;` or `use {...};` or `use ::{...};`
-            let mod_sep_ctxt = self.token.span.ctxt();
-            if self.eat(&token::ModSep) {
-                prefix.segments.push(
-                    PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt))
-                );
-            }
-
-            if self.eat(&token::BinOp(token::Star)) {
-                UseTreeKind::Glob
-            } else {
-                UseTreeKind::Nested(self.parse_use_tree_list()?)
-            }
-        } else {
-            // `use path::*;` or `use path::{...};` or `use path;` or `use path as bar;`
-            prefix = self.parse_path(PathStyle::Mod)?;
-
-            if self.eat(&token::ModSep) {
-                if self.eat(&token::BinOp(token::Star)) {
-                    UseTreeKind::Glob
-                } else {
-                    UseTreeKind::Nested(self.parse_use_tree_list()?)
-                }
-            } else {
-                UseTreeKind::Simple(self.parse_rename()?, ast::DUMMY_NODE_ID, ast::DUMMY_NODE_ID)
-            }
-        };
-
-        Ok(UseTree { prefix, kind, span: lo.to(self.prev_span) })
-    }
-
-    /// Parses a `UseTreeKind::Nested(list)`.
-    ///
-    /// ```
-    /// USE_TREE_LIST = Ø | (USE_TREE `,`)* USE_TREE [`,`]
-    /// ```
-    fn parse_use_tree_list(&mut self) -> PResult<'a, Vec<(UseTree, ast::NodeId)>> {
-        self.parse_delim_comma_seq(token::Brace, |p| Ok((p.parse_use_tree()?, ast::DUMMY_NODE_ID)))
-            .map(|(r, _)| r)
-    }
-
-    fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
-        if self.eat_keyword(kw::As) {
-            self.parse_ident_or_underscore().map(Some)
-        } else {
-            Ok(None)
-        }
-    }
-
-    /// Parses a source module as a crate. This is the main entry point for the parser.
-    pub fn parse_crate_mod(&mut self) -> PResult<'a, Crate> {
-        let lo = self.token.span;
-        let krate = Ok(ast::Crate {
-            attrs: self.parse_inner_attributes()?,
-            module: self.parse_mod_items(&token::Eof, lo)?,
-            span: lo.to(self.token.span),
-        });
-        krate
-    }
-
     pub fn parse_optional_str(&mut self) -> Option<(Symbol, ast::StrStyle, Option<ast::Name>)> {
         let ret = match self.token.kind {
             token::Literal(token::Lit { kind: token::Str, symbol, suffix }) =>