]> git.lizzy.rs Git - rust.git/commitdiff
syntax: merge ast::ViewItem into ast::Item.
authorEduard Burtescu <edy.burt@gmail.com>
Tue, 23 Dec 2014 13:07:30 +0000 (15:07 +0200)
committerEduard Burtescu <edy.burt@gmail.com>
Wed, 21 Jan 2015 14:27:25 +0000 (16:27 +0200)
src/libsyntax/ast.rs
src/libsyntax/parse/parser.rs

index fcf80410da240abc47f15246aa708ed4f5c546f8..9d0675388131f1ba7972c51a00aff199d1442a77 100644 (file)
@@ -53,7 +53,6 @@
 pub use self::UnOp::*;
 pub use self::UnsafeSource::*;
 pub use self::VariantKind::*;
-pub use self::ViewItem_::*;
 pub use self::ViewPath_::*;
 pub use self::Visibility::*;
 pub use self::PathParameters::*;
@@ -511,7 +510,6 @@ fn eq(&self, other: &MetaItem_) -> bool {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
 pub struct Block {
-    pub view_items: Vec<ViewItem>,
     pub stmts: Vec<P<Stmt>>,
     pub expr: Option<P<Expr>>,
     pub id: NodeId,
@@ -1452,14 +1450,12 @@ pub struct Mod {
     /// For `mod foo;`, the inner span ranges from the first token
     /// to the last token in the external file.
     pub inner: Span,
-    pub view_items: Vec<ViewItem>,
     pub items: Vec<P<Item>>,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
 pub struct ForeignMod {
     pub abi: Abi,
-    pub view_items: Vec<ViewItem>,
     pub items: Vec<P<ForeignItem>>,
 }
 
@@ -1518,44 +1514,13 @@ pub enum ViewPath_ {
     /// or just
     ///
     /// `foo::bar::baz` (with `as baz` implicitly on the right)
-    ViewPathSimple(Ident, Path, NodeId),
+    ViewPathSimple(Ident, Path),
 
     /// `foo::bar::*`
-    ViewPathGlob(Path, NodeId),
+    ViewPathGlob(Path),
 
     /// `foo::bar::{a,b,c}`
-    ViewPathList(Path, Vec<PathListItem> , NodeId)
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
-pub struct ViewItem {
-    pub node: ViewItem_,
-    pub attrs: Vec<Attribute>,
-    pub vis: Visibility,
-    pub span: Span,
-}
-
-impl ViewItem {
-    pub fn id(&self) -> NodeId {
-        match self.node {
-            ViewItemExternCrate(_, _, id) => id,
-            ViewItemUse(ref vp) => match vp.node {
-                ViewPathSimple(_, _, id) => id,
-                ViewPathGlob(_, id) => id,
-                ViewPathList(_, _, id) => id,
-            }
-        }
-    }
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
-pub enum ViewItem_ {
-    /// Ident: name used to refer to this crate in the code
-    /// optional (InternedString,StrStyle): if present, this is a location
-    /// (containing arbitrary characters) from which to fetch the crate sources
-    /// For example, extern crate whatever = "github.com/rust-lang/rust"
-    ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId),
-    ViewItemUse(P<ViewPath>),
+    ViewPathList(Path, Vec<PathListItem>)
 }
 
 /// Meta-data associated with an item
@@ -1677,6 +1642,12 @@ pub struct Item {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
 pub enum Item_ {
+    // Optional location (containing arbitrary characters) from which
+    // to fetch the crate sources.
+    // For example, extern crate whatever = "github.com/rust-lang/rust".
+    ItemExternCrate(Option<(InternedString, StrStyle)>),
+    ItemUse(P<ViewPath>),
+
     ItemStatic(P<Ty>, Mutability, P<Expr>),
     ItemConst(P<Ty>, P<Expr>),
     ItemFn(P<FnDecl>, Unsafety, Abi, Generics, P<Block>),
@@ -1703,6 +1674,8 @@ pub enum Item_ {
 impl Item_ {
     pub fn descriptive_variant(&self) -> &str {
         match *self {
+            ItemExternCrate(..) => "extern crate",
+            ItemUse(..) => "use",
             ItemStatic(..) => "static item",
             ItemConst(..) => "constant item",
             ItemFn(..) => "function",
index 83a7504bc49848939cccbc71106f0875591c7bea..a474e4c2bad93737acd04e77d077a26bd127a25f 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 pub use self::PathParsingMode::*;
-use self::ItemOrViewItem::*;
 
 use abi;
 use ast::{AssociatedType, BareFnTy};
@@ -35,6 +34,7 @@
 use ast::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic};
 use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst};
 use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy};
+use ast::{ItemExternCrate, ItemUse};
 use ast::{LifetimeDef, Lit, Lit_};
 use ast::{LitBool, LitChar, LitByte, LitBinary};
 use ast::{LitStr, LitInt, Local, LocalLet};
@@ -59,7 +59,6 @@
 use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq};
 use ast::{TypeImplItem, TypeTraitItem, Typedef, UnboxedClosureKind};
 use ast::{UnnamedField, UnsafeBlock};
-use ast::{ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse};
 use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
 use ast::{Visibility, WhereClause};
 use ast;
@@ -122,14 +121,9 @@ pub enum BoundParsingMode {
     Modified,
 }
 
-enum ItemOrViewItem {
-    /// Indicates a failure to parse any kind of item. The attributes are
-    /// returned.
-    IoviNone(Vec<Attribute>),
-    IoviItem(P<Item>),
-    IoviForeignItem(P<ForeignItem>),
-    IoviViewItem(ViewItem)
-}
+/// The `Err` case indicates a failure to parse any kind of item.
+/// The attributes are returned.
+type MaybeItem = Result<P<Item>, Vec<Attribute>>;
 
 
 /// Possibly accept an `token::Interpolated` expression (a pre-parsed expression
@@ -231,19 +225,6 @@ macro_rules! maybe_whole {
             }
         }
     );
-    (iovi $p:expr, $constructor:ident) => (
-        {
-            let found = match ($p).token {
-                token::Interpolated(token::$constructor(_)) => {
-                    Some(($p).bump_and_get())
-                }
-                _ => None
-            };
-            if let Some(token::Interpolated(token::$constructor(x))) = found {
-                return IoviItem(x.clone());
-            }
-        }
-    );
     (pair_empty $p:expr, $constructor:ident) => (
         {
             let found = match ($p).token {
@@ -269,14 +250,6 @@ fn maybe_append(mut lhs: Vec<Attribute>, rhs: Option<Vec<Attribute>>)
     lhs
 }
 
-
-struct ParsedItemsAndViewItems {
-    attrs_remaining: Vec<Attribute>,
-    view_items: Vec<ViewItem>,
-    items: Vec<P<Item>> ,
-    foreign_items: Vec<P<ForeignItem>>
-}
-
 /* ident is handled by common.rs */
 
 pub struct Parser<'a> {
@@ -3032,8 +3005,7 @@ pub fn parse_lambda_expr(&mut self, capture_clause: CaptureClause)
         let body = self.parse_expr();
         let fakeblock = P(ast::Block {
             id: ast::DUMMY_NODE_ID,
-            view_items: Vec::new(),
-            stmts: Vec::new(),
+            stmts: vec![],
             span: body.span,
             expr: Some(body),
             rules: DefaultBlock,
@@ -3731,20 +3703,13 @@ fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
         } else {
             let found_attrs = !item_attrs.is_empty();
             let item_err = Parser::expected_item_err(&item_attrs[]);
-            match self.parse_item_or_view_item(item_attrs, false) {
-                IoviItem(i) => {
+            match self.parse_item_(item_attrs, false) {
+                Ok(i) => {
                     let hi = i.span.hi;
                     let decl = P(spanned(lo, hi, DeclItem(i)));
                     P(spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID)))
                 }
-                IoviViewItem(vi) => {
-                    self.span_fatal(vi.span,
-                                    "view items must be declared at the top of the block");
-                }
-                IoviForeignItem(_) => {
-                    self.fatal("foreign items are not allowed here");
-                }
-                IoviNone(_) => {
+                Err(_) => {
                     if found_attrs {
                         let last_span = self.last_span;
                         self.span_err(last_span, item_err);
@@ -3794,36 +3759,17 @@ fn parse_inner_attrs_and_block(&mut self)
         (inner, self.parse_block_tail_(lo, DefaultBlock, next))
     }
 
-    /// Precondition: already parsed the '{' or '#{'
-    /// I guess that also means "already parsed the 'impure'" if
-    /// necessary, and this should take a qualifier.
-    /// Some blocks start with "#{"...
+    /// Precondition: already parsed the '{'.
     fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> P<Block> {
         self.parse_block_tail_(lo, s, Vec::new())
     }
 
     /// Parse the rest of a block expression or function body
     fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
-                         first_item_attrs: Vec<Attribute> ) -> P<Block> {
-        let mut stmts = Vec::new();
+                         first_item_attrs: Vec<Attribute>) -> P<Block> {
+        let mut stmts = vec![];
         let mut expr = None;
-
-        // wouldn't it be more uniform to parse view items only, here?
-        let ParsedItemsAndViewItems {
-            attrs_remaining,
-            view_items,
-            items,
-            ..
-        } = self.parse_items_and_view_items(first_item_attrs,
-                                            false, false);
-
-        for item in items.into_iter() {
-            let span = item.span;
-            let decl = P(spanned(span.lo, span.hi, DeclItem(item)));
-            stmts.push(P(spanned(span.lo, span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID))));
-        }
-
-        let mut attributes_box = attrs_remaining;
+        let mut attributes_box = first_item_attrs;
 
         while self.token != token::CloseDelim(token::Brace) {
             // parsing items even when they're not allowed lets us give
@@ -3932,7 +3878,6 @@ fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
         let hi = self.span.hi;
         self.bump();
         P(ast::Block {
-            view_items: view_items,
             stmts: stmts,
             expr: expr,
             id: ast::DUMMY_NODE_ID,
@@ -5031,39 +4976,34 @@ fn parse_mod_items(&mut self,
                        first_item_attrs: Vec<Attribute>,
                        inner_lo: BytePos)
                        -> Mod {
-        // parse all of the items up to closing or an attribute.
-        // view items are legal here.
-        let ParsedItemsAndViewItems {
-            attrs_remaining,
-            view_items,
-            items: starting_items,
-            ..
-        } = self.parse_items_and_view_items(first_item_attrs, true, true);
-        let mut items: Vec<P<Item>> = starting_items;
-        let attrs_remaining_len = attrs_remaining.len();
+        // Parse all of the items up to closing or an attribute.
+
+        let mut attrs = first_item_attrs;
+        attrs.push_all(&self.parse_outer_attributes()[]);
+        let mut items = vec![];
+
+        loop {
+            match self.parse_item_(attrs, true) {
+                Err(returned_attrs) => {
+                    attrs = returned_attrs;
+                    break
+                }
+                Ok(item) => {
+                    attrs = self.parse_outer_attributes();
+                    items.push(item)
+                }
+            }
+        }
 
         // don't think this other loop is even necessary....
 
-        let mut first = true;
         while self.token != term {
-            let mut attrs = self.parse_outer_attributes();
-            if first {
-                let mut tmp = attrs_remaining.clone();
-                tmp.push_all(&attrs[]);
-                attrs = tmp;
-                first = false;
-            }
-            debug!("parse_mod_items: parse_item_or_view_item(attrs={:?})",
-                   attrs);
-            match self.parse_item_or_view_item(attrs,
-                                               true /* macros allowed */) {
-              IoviItem(item) => items.push(item),
-              IoviViewItem(view_item) => {
-                self.span_fatal(view_item.span,
-                                "view items must be declared at the top of \
-                                 the module");
-              }
-              _ => {
+            let mut attrs = mem::replace(&mut attrs, vec![]);
+            attrs.push_all(&self.parse_outer_attributes()[]);
+            debug!("parse_mod_items: parse_item_(attrs={:?})", attrs);
+            match self.parse_item_(attrs, true /* macros allowed */) {
+              Ok(item) => items.push(item),
+              Err(_) => {
                   let token_str = self.this_token_to_string();
                   self.fatal(&format!("expected item, found `{}`",
                                      token_str)[])
@@ -5071,16 +5011,15 @@ fn parse_mod_items(&mut self,
             }
         }
 
-        if first && attrs_remaining_len > 0u {
+        if !attrs.is_empty() {
             // We parsed attributes for the first item but didn't find it
             let last_span = self.last_span;
             self.span_err(last_span,
-                          Parser::expected_item_err(&attrs_remaining[]));
+                          Parser::expected_item_err(&attrs[]));
         }
 
         ast::Mod {
             inner: mk_sp(inner_lo, self.span.lo),
-            view_items: view_items,
             items: items
         }
     }
@@ -5298,23 +5237,12 @@ fn parse_item_foreign_static(&mut self, vis: ast::Visibility,
     /// parse_foreign_items.
     fn parse_foreign_mod_items(&mut self,
                                abi: abi::Abi,
-                               first_item_attrs: Vec<Attribute> )
+                               first_item_attrs: Vec<Attribute>)
                                -> ForeignMod {
-        let ParsedItemsAndViewItems {
-            attrs_remaining,
-            view_items,
-            items: _,
-            foreign_items,
-        } = self.parse_foreign_items(first_item_attrs, true);
-        if !attrs_remaining.is_empty() {
-            let last_span = self.last_span;
-            self.span_err(last_span,
-                          Parser::expected_item_err(&attrs_remaining[]));
-        }
+        let foreign_items = self.parse_foreign_items(first_item_attrs);
         assert!(self.token == token::CloseDelim(token::Brace));
         ast::ForeignMod {
             abi: abi,
-            view_items: view_items,
             items: foreign_items
         }
     }
@@ -5329,8 +5257,8 @@ fn parse_foreign_mod_items(&mut self,
     fn parse_item_extern_crate(&mut self,
                                 lo: BytePos,
                                 visibility: Visibility,
-                                attrs: Vec<Attribute> )
-                                -> ItemOrViewItem {
+                                attrs: Vec<Attribute>)
+                                -> P<Item> {
 
         let span = self.span;
         let (maybe_path, ident) = match self.token {
@@ -5374,12 +5302,13 @@ fn parse_item_extern_crate(&mut self,
             }
         };
 
-        IoviViewItem(ast::ViewItem {
-                node: ViewItemExternCrate(ident, maybe_path, ast::DUMMY_NODE_ID),
-                attrs: attrs,
-                vis: visibility,
-                span: mk_sp(lo, self.last_span.hi)
-            })
+        let last_span = self.last_span;
+        self.mk_item(lo,
+                     last_span.hi,
+                     ident,
+                     ItemExternCrate(maybe_path),
+                     visibility,
+                     attrs)
     }
 
     /// Parse `extern` for foreign ABIs
@@ -5396,8 +5325,8 @@ fn parse_item_foreign_mod(&mut self,
                               lo: BytePos,
                               opt_abi: Option<abi::Abi>,
                               visibility: Visibility,
-                              attrs: Vec<Attribute> )
-                              -> ItemOrViewItem {
+                              attrs: Vec<Attribute>)
+                              -> P<Item> {
 
         self.expect(&token::OpenDelim(token::Brace));
 
@@ -5408,13 +5337,12 @@ fn parse_item_foreign_mod(&mut self,
         self.expect(&token::CloseDelim(token::Brace));
 
         let last_span = self.last_span;
-        let item = self.mk_item(lo,
-                                last_span.hi,
-                                special_idents::invalid,
-                                ItemForeignMod(m),
-                                visibility,
-                                maybe_append(attrs, Some(inner)));
-        return IoviItem(item);
+        self.mk_item(lo,
+                     last_span.hi,
+                     special_idents::invalid,
+                     ItemForeignMod(m),
+                     visibility,
+                     maybe_append(attrs, Some(inner)))
     }
 
     /// Parse type Foo = Bar;
@@ -5556,14 +5484,12 @@ fn parse_opt_abi(&mut self) -> Option<abi::Abi> {
         }
     }
 
-    /// Parse one of the items or view items allowed by the
-    /// flags; on failure, return IoviNone.
+    /// Parse one of the items allowed by the flags; on failure,
+    /// return `Err(remaining_attrs)`.
     /// NB: this function no longer parses the items inside an
     /// extern crate.
-    fn parse_item_or_view_item(&mut self,
-                               attrs: Vec<Attribute> ,
-                               macros_allowed: bool)
-                               -> ItemOrViewItem {
+    fn parse_item_(&mut self, attrs: Vec<Attribute>,
+                   macros_allowed: bool) -> MaybeItem {
         let nt_item = match self.token {
             token::Interpolated(token::NtItem(ref item)) => {
                 Some((**item).clone())
@@ -5576,7 +5502,7 @@ fn parse_item_or_view_item(&mut self,
                 let mut attrs = attrs;
                 mem::swap(&mut item.attrs, &mut attrs);
                 item.attrs.extend(attrs.into_iter());
-                return IoviItem(P(item));
+                return Ok(P(item));
             }
             None => {}
         }
@@ -5585,22 +5511,24 @@ fn parse_item_or_view_item(&mut self,
 
         let visibility = self.parse_visibility();
 
-        // must be a view item:
         if self.eat_keyword(keywords::Use) {
-            // USE ITEM (IoviViewItem)
-            let view_item = self.parse_use();
+            // USE ITEM
+            let item_ = ItemUse(self.parse_view_path());
             self.expect(&token::Semi);
-            return IoviViewItem(ast::ViewItem {
-                node: view_item,
-                attrs: attrs,
-                vis: visibility,
-                span: mk_sp(lo, self.last_span.hi)
-            });
+
+            let last_span = self.last_span;
+            let item = self.mk_item(lo,
+                                    last_span.hi,
+                                    token::special_idents::invalid,
+                                    item_,
+                                    visibility,
+                                    attrs);
+            return Ok(item);
         }
-        // either a view item or an item:
+
         if self.eat_keyword(keywords::Extern) {
             if self.eat_keyword(keywords::Crate) {
-                return self.parse_item_extern_crate(lo, visibility, attrs);
+                return Ok(self.parse_item_extern_crate(lo, visibility, attrs));
             }
 
             let opt_abi = self.parse_opt_abi();
@@ -5617,9 +5545,9 @@ fn parse_item_or_view_item(&mut self,
                                         item_,
                                         visibility,
                                         maybe_append(attrs, extra_attrs));
-                return IoviItem(item);
+                return Ok(item);
             } else if self.check(&token::OpenDelim(token::Brace)) {
-                return self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs);
+                return Ok(self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs));
             }
 
             let span = self.span;
@@ -5634,7 +5562,6 @@ fn parse_item_or_view_item(&mut self,
             self.span_err(span, "`virtual` structs have been removed from the language");
         }
 
-        // the rest are all guaranteed to be items:
         if self.token.is_keyword(keywords::Static) {
             // STATIC ITEM
             self.bump();
@@ -5647,7 +5574,7 @@ fn parse_item_or_view_item(&mut self,
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.token.is_keyword(keywords::Const) {
             // CONST ITEM
@@ -5665,7 +5592,7 @@ fn parse_item_or_view_item(&mut self,
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.token.is_keyword(keywords::Unsafe) &&
             self.look_ahead(1u, |t| t.is_keyword(keywords::Trait))
@@ -5682,7 +5609,7 @@ fn parse_item_or_view_item(&mut self,
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.token.is_keyword(keywords::Unsafe) &&
             self.look_ahead(1u, |t| t.is_keyword(keywords::Impl))
@@ -5698,7 +5625,7 @@ fn parse_item_or_view_item(&mut self,
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.token.is_keyword(keywords::Fn) {
             // FUNCTION ITEM
@@ -5712,7 +5639,7 @@ fn parse_item_or_view_item(&mut self,
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.token.is_keyword(keywords::Unsafe)
             && self.look_ahead(1u, |t| *t != token::OpenDelim(token::Brace)) {
@@ -5733,7 +5660,7 @@ fn parse_item_or_view_item(&mut self,
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.eat_keyword(keywords::Mod) {
             // MODULE ITEM
@@ -5746,7 +5673,7 @@ fn parse_item_or_view_item(&mut self,
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.eat_keyword(keywords::Type) {
             // TYPE ITEM
@@ -5758,7 +5685,7 @@ fn parse_item_or_view_item(&mut self,
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.eat_keyword(keywords::Enum) {
             // ENUM ITEM
@@ -5770,7 +5697,7 @@ fn parse_item_or_view_item(&mut self,
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.eat_keyword(keywords::Trait) {
             // TRAIT ITEM
@@ -5783,7 +5710,7 @@ fn parse_item_or_view_item(&mut self,
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.eat_keyword(keywords::Impl) {
             // IMPL ITEM
@@ -5795,7 +5722,7 @@ fn parse_item_or_view_item(&mut self,
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.eat_keyword(keywords::Struct) {
             // STRUCT ITEM
@@ -5807,32 +5734,30 @@ fn parse_item_or_view_item(&mut self,
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
     }
 
-    /// Parse a foreign item; on failure, return IoviNone.
-    fn parse_foreign_item(&mut self,
-                          attrs: Vec<Attribute> ,
-                          macros_allowed: bool)
-                          -> ItemOrViewItem {
-        maybe_whole!(iovi self, NtItem);
+    /// Parse a foreign item; on failure, return `Err(remaining_attrs)`.
+    fn parse_foreign_item(&mut self, attrs: Vec<Attribute>)
+                          -> Result<P<ForeignItem>, Vec<Attribute>> {
         let lo = self.span.lo;
 
         let visibility = self.parse_visibility();
 
         if self.token.is_keyword(keywords::Static) {
             // FOREIGN STATIC ITEM
-            let item = self.parse_item_foreign_static(visibility, attrs);
-            return IoviForeignItem(item);
+            return Ok(self.parse_item_foreign_static(visibility, attrs));
         }
         if self.token.is_keyword(keywords::Fn) || self.token.is_keyword(keywords::Unsafe) {
             // FOREIGN FUNCTION ITEM
-            let item = self.parse_item_foreign_fn(visibility, attrs);
-            return IoviForeignItem(item);
+            return Ok(self.parse_item_foreign_fn(visibility, attrs));
         }
-        self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
+
+        // FIXME #5668: this will occur for a macro invocation:
+        let item = try!(self.parse_macro_use_or_failure(attrs, true, lo, visibility));
+        self.span_fatal(item.span, "macros cannot expand to foreign items");
     }
 
     /// This is the fall-through for parsing items.
@@ -5842,7 +5767,7 @@ fn parse_macro_use_or_failure(
         macros_allowed: bool,
         lo: BytePos,
         visibility: Visibility
-    ) -> ItemOrViewItem {
+    ) -> MaybeItem {
         if macros_allowed && !self.token.is_any_keyword()
                 && self.look_ahead(1, |t| *t == token::Not)
                 && (self.look_ahead(2, |t| t.is_plain_ident())
@@ -5891,7 +5816,7 @@ fn parse_macro_use_or_failure(
                                     item_,
                                     visibility,
                                     attrs);
-            return IoviItem(item);
+            return Ok(item);
         }
 
         // FAILURE TO PARSE ITEM
@@ -5902,7 +5827,7 @@ fn parse_macro_use_or_failure(
                 self.span_fatal(last_span, "unmatched visibility `pub`");
             }
         }
-        return IoviNone(attrs);
+        Err(attrs)
     }
 
     pub fn parse_item_with_outer_attributes(&mut self) -> Option<P<Item>> {
@@ -5911,30 +5836,9 @@ pub fn parse_item_with_outer_attributes(&mut self) -> Option<P<Item>> {
     }
 
     pub fn parse_item(&mut self, attrs: Vec<Attribute>) -> Option<P<Item>> {
-        match self.parse_item_or_view_item(attrs, true) {
-            IoviNone(_) => None,
-            IoviViewItem(_) =>
-                self.fatal("view items are not allowed here"),
-            IoviForeignItem(_) =>
-                self.fatal("foreign items are not allowed here"),
-            IoviItem(item) => Some(item)
-        }
+        self.parse_item_(attrs, true).ok()
     }
 
-    /// Parse a ViewItem, e.g. `use foo::bar` or `extern crate foo`
-    pub fn parse_view_item(&mut self, attrs: Vec<Attribute>) -> ViewItem {
-        match self.parse_item_or_view_item(attrs, false) {
-            IoviViewItem(vi) => vi,
-            _ => self.fatal("expected `use` or `extern crate`"),
-        }
-    }
-
-    /// Parse, e.g., "use a::b::{z,y}"
-    fn parse_use(&mut self) -> ViewItem_ {
-        return ViewItemUse(self.parse_view_path());
-    }
-
-
     /// Matches view_path : MOD? non_global_path as IDENT
     /// | MOD? non_global_path MOD_SEP LBRACE RBRACE
     /// | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE
@@ -5959,8 +5863,7 @@ fn parse_view_path(&mut self) -> P<ViewPath> {
                 global: false,
                 segments: Vec::new()
             };
-            return P(spanned(lo, self.span.hi,
-                             ViewPathList(path, idents, ast::DUMMY_NODE_ID)));
+            return P(spanned(lo, self.span.hi, ViewPathList(path, idents)));
         }
 
         let first_ident = self.parse_ident();
@@ -5994,8 +5897,7 @@ fn parse_view_path(&mut self) -> P<ViewPath> {
                             }
                         }).collect()
                     };
-                    return P(spanned(lo, self.span.hi,
-                                     ViewPathList(path, idents, ast::DUMMY_NODE_ID)));
+                    return P(spanned(lo, self.span.hi, ViewPathList(path, idents)));
                   }
 
                   // foo::bar::*
@@ -6011,8 +5913,7 @@ fn parse_view_path(&mut self) -> P<ViewPath> {
                             }
                         }).collect()
                     };
-                    return P(spanned(lo, self.span.hi,
-                                     ViewPathGlob(path, ast::DUMMY_NODE_ID)));
+                    return P(spanned(lo, self.span.hi, ViewPathGlob(path)));
                   }
 
                   _ => break
@@ -6033,136 +5934,39 @@ fn parse_view_path(&mut self) -> P<ViewPath> {
         if self.eat_keyword(keywords::As) {
             rename_to = self.parse_ident()
         }
-        P(spanned(lo,
-                  self.last_span.hi,
-                  ViewPathSimple(rename_to, path, ast::DUMMY_NODE_ID)))
-    }
-
-    /// Parses a sequence of items. Stops when it finds program
-    /// text that can't be parsed as an item
-    /// - mod_items uses extern_mod_allowed = true
-    /// - block_tail_ uses extern_mod_allowed = false
-    fn parse_items_and_view_items(&mut self,
-                                  first_item_attrs: Vec<Attribute> ,
-                                  mut extern_mod_allowed: bool,
-                                  macros_allowed: bool)
-                                  -> ParsedItemsAndViewItems {
-        let mut attrs = first_item_attrs;
-        attrs.push_all(&self.parse_outer_attributes()[]);
-        // First, parse view items.
-        let mut view_items : Vec<ast::ViewItem> = Vec::new();
-        let mut items = Vec::new();
-
-        // I think this code would probably read better as a single
-        // loop with a mutable three-state-variable (for extern crates,
-        // view items, and regular items) ... except that because
-        // of macros, I'd like to delay that entire check until later.
-        loop {
-            match self.parse_item_or_view_item(attrs, macros_allowed) {
-                IoviNone(attrs) => {
-                    return ParsedItemsAndViewItems {
-                        attrs_remaining: attrs,
-                        view_items: view_items,
-                        items: items,
-                        foreign_items: Vec::new()
-                    }
-                }
-                IoviViewItem(view_item) => {
-                    match view_item.node {
-                        ViewItemUse(..) => {
-                            // `extern crate` must precede `use`.
-                            extern_mod_allowed = false;
-                        }
-                        ViewItemExternCrate(..) if !extern_mod_allowed => {
-                            self.span_err(view_item.span,
-                                          "\"extern crate\" declarations are \
-                                           not allowed here");
-                        }
-                        ViewItemExternCrate(..) => {}
-                    }
-                    view_items.push(view_item);
-                }
-                IoviItem(item) => {
-                    items.push(item);
-                    attrs = self.parse_outer_attributes();
-                    break;
-                }
-                IoviForeignItem(_) => {
-                    panic!();
-                }
-            }
-            attrs = self.parse_outer_attributes();
-        }
-
-        // Next, parse items.
-        loop {
-            match self.parse_item_or_view_item(attrs, macros_allowed) {
-                IoviNone(returned_attrs) => {
-                    attrs = returned_attrs;
-                    break
-                }
-                IoviViewItem(view_item) => {
-                    attrs = self.parse_outer_attributes();
-                    self.span_err(view_item.span,
-                                  "`use` and `extern crate` declarations must precede items");
-                }
-                IoviItem(item) => {
-                    attrs = self.parse_outer_attributes();
-                    items.push(item)
-                }
-                IoviForeignItem(_) => {
-                    panic!();
-                }
-            }
-        }
-
-        ParsedItemsAndViewItems {
-            attrs_remaining: attrs,
-            view_items: view_items,
-            items: items,
-            foreign_items: Vec::new()
-        }
+        P(spanned(lo, self.last_span.hi, ViewPathSimple(rename_to, path)))
     }
 
     /// Parses a sequence of foreign items. Stops when it finds program
     /// text that can't be parsed as an item
-    fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute> ,
-                           macros_allowed: bool)
-        -> ParsedItemsAndViewItems {
+    fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute>)
+                           -> Vec<P<ForeignItem>> {
         let mut attrs = first_item_attrs;
         attrs.push_all(&self.parse_outer_attributes()[]);
         let mut foreign_items = Vec::new();
         loop {
-            match self.parse_foreign_item(attrs, macros_allowed) {
-                IoviNone(returned_attrs) => {
+            match self.parse_foreign_item(attrs) {
+                Ok(foreign_item) => {
+                    foreign_items.push(foreign_item);
+                }
+                Err(returned_attrs) => {
                     if self.check(&token::CloseDelim(token::Brace)) {
                         attrs = returned_attrs;
                         break
                     }
                     self.unexpected();
-                },
-                IoviViewItem(view_item) => {
-                    // I think this can't occur:
-                    self.span_err(view_item.span,
-                                  "`use` and `extern crate` declarations must precede items");
-                }
-                IoviItem(item) => {
-                    // FIXME #5668: this will occur for a macro invocation:
-                    self.span_fatal(item.span, "macros cannot expand to foreign items");
-                }
-                IoviForeignItem(foreign_item) => {
-                    foreign_items.push(foreign_item);
                 }
             }
             attrs = self.parse_outer_attributes();
         }
 
-        ParsedItemsAndViewItems {
-            attrs_remaining: attrs,
-            view_items: Vec::new(),
-            items: Vec::new(),
-            foreign_items: foreign_items
+        if !attrs.is_empty() {
+            let last_span = self.last_span;
+            self.span_err(last_span,
+                          Parser::expected_item_err(&attrs[]));
         }
+
+        foreign_items
     }
 
     /// Parses a source module as a crate. This is the main