about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/obsolete.rs12
-rw-r--r--src/libsyntax/parse/parser.rs160
-rw-r--r--src/libsyntax/parse/token.rs53
3 files changed, 108 insertions, 117 deletions
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index 6f6f8d7d563..24227dea531 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -30,7 +30,6 @@ pub enum ObsoleteSyntax {
     ObsoleteSwap,
     ObsoleteUnsafeBlock,
     ObsoleteBareFnType,
-    ObsoleteNamedExternModule,
     ObsoleteMultipleLocalDecl,
     ObsoleteUnsafeExternFn,
     ObsoleteTraitFuncVisibility,
@@ -42,7 +41,6 @@ pub enum ObsoleteSyntax {
     ObsoleteBoxedClosure,
     ObsoleteClosureType,
     ObsoleteMultipleImport,
-    ObsoleteExternModAttributesInParens,
     ObsoleteManagedPattern,
     ObsoleteManagedString,
     ObsoleteManagedVec,
@@ -86,11 +84,6 @@ impl ParserObsoleteMethods for Parser {
                 "bare function type",
                 "use `|A| -> B` or `extern fn(A) -> B` instead"
             ),
-            ObsoleteNamedExternModule => (
-                "named external module",
-                "instead of `extern mod foo { ... }`, write `mod foo { \
-                 extern { ... } }`"
-            ),
             ObsoleteMultipleLocalDecl => (
                 "declaration of multiple locals at once",
                 "instead of e.g. `let a = 1, b = 2`, write \
@@ -141,11 +134,6 @@ impl ParserObsoleteMethods for Parser {
                 "multiple imports",
                 "only one import is allowed per `use` statement"
             ),
-            ObsoleteExternModAttributesInParens => (
-                "`extern mod` with linkage attribute list",
-                "use `extern mod foo = \"bar\";` instead of \
-                `extern mod foo (name = \"bar\")`"
-            ),
             ObsoleteManagedPattern => (
                 "managed pointer pattern",
                 "use a nested `match` expression instead of a managed box \
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 4bef7dc5bb5..15608a0f28e 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -866,7 +866,10 @@ impl Parser {
 
         */
 
-        let opt_abis = self.parse_opt_abis();
+        let opt_abis = if self.eat_keyword(keywords::Extern) {
+            self.parse_opt_abis()
+        } else { None };
+
         let abis = opt_abis.unwrap_or(AbiSet::Rust());
         let purity = self.parse_unsafety();
         self.expect_keyword(keywords::Fn);
@@ -4308,91 +4311,78 @@ impl Parser {
         }
     }
 
-    // parse extern foo; or extern mod foo { ... } or extern { ... }
-    fn parse_item_foreign_mod(&mut self,
-                              lo: BytePos,
-                              opt_abis: Option<AbiSet>,
-                              visibility: Visibility,
-                              attrs: ~[Attribute],
-                              items_allowed: bool)
-                              -> ItemOrViewItem {
-        let mut must_be_named_mod = false;
-        if self.is_keyword(keywords::Mod) {
-            must_be_named_mod = true;
-            self.expect_keyword(keywords::Mod);
-        } else if self.token != token::LBRACE {
-            let token_str = self.this_token_to_str();
-            self.span_fatal(self.span,
-                            format!("expected `\\{` or `mod` but found `{}`",
-                                    token_str))
-        }
+    /// Parse extern crate links
+    ///
+    /// # Example
+    ///
+    /// extern crate extra;
+    /// extern crate foo = "bar";
+    fn parse_item_extern_crate(&mut self,
+                                lo: BytePos,
+                                visibility: Visibility,
+                                attrs: ~[Attribute])
+                                -> ItemOrViewItem {
 
-        let (named, maybe_path, ident) = match self.token {
+        let (maybe_path, ident) = match self.token {
             token::IDENT(..) => {
                 let the_ident = self.parse_ident();
+                self.expect_one_of(&[], &[token::EQ, token::SEMI]);
                 let path = if self.token == token::EQ {
                     self.bump();
                     Some(self.parse_str())
-                }
-                else { None };
-                (true, path, the_ident)
+                } else {None};
+
+                self.expect(&token::SEMI);
+                (path, the_ident)
             }
             _ => {
-                if must_be_named_mod {
-                    let token_str = self.this_token_to_str();
-                    self.span_fatal(self.span,
-                                    format!("expected foreign module name but \
-                                             found `{}`",
-                                            token_str))
-                }
-
-                (false, None,
-                 special_idents::clownshoes_foreign_mod)
+                let token_str = self.this_token_to_str();
+                self.span_fatal(self.span,
+                                format!("expected extern crate name but found `{}`",
+                                        token_str));
             }
         };
 
-        // extern mod foo { ... } or extern { ... }
-        if items_allowed && self.eat(&token::LBRACE) {
-            // `extern mod foo { ... }` is obsolete.
-            if named {
-                self.obsolete(self.last_span, ObsoleteNamedExternModule);
-            }
-
-            let abis = opt_abis.unwrap_or(AbiSet::C());
+        IoviViewItem(ast::ViewItem {
+                node: ViewItemExternMod(ident, maybe_path, ast::DUMMY_NODE_ID),
+                attrs: attrs,
+                vis: visibility,
+                span: mk_sp(lo, self.last_span.hi)
+            })
+    }
 
-            let (inner, next) = self.parse_inner_attrs_and_next();
-            let m = self.parse_foreign_mod_items(abis, next);
-            self.expect(&token::RBRACE);
+    /// Parse `extern` for foreign ABIs
+    /// modules.
+    ///
+    /// `extern` is expected to have been
+    /// consumed before calling this method
+    ///
+    /// # Examples:
+    ///
+    /// extern "C" {}
+    /// extern {}
+    fn parse_item_foreign_mod(&mut self,
+                              lo: BytePos,
+                              opt_abis: Option<AbiSet>,
+                              visibility: Visibility,
+                              attrs: ~[Attribute])
+                              -> ItemOrViewItem {
 
-            let item = self.mk_item(lo,
-                                    self.last_span.hi,
-                                    ident,
-                                    ItemForeignMod(m),
-                                    visibility,
-                                    maybe_append(attrs, Some(inner)));
-            return IoviItem(item);
-        }
+        self.expect(&token::LBRACE);
 
-        if opt_abis.is_some() {
-            self.span_err(self.span, "an ABI may not be specified here");
-        }
+        let abis = opt_abis.unwrap_or(AbiSet::C());
 
+        let (inner, next) = self.parse_inner_attrs_and_next();
+        let m = self.parse_foreign_mod_items(abis, next);
+        self.expect(&token::RBRACE);
 
-        if self.token == token::LPAREN {
-            // `extern mod foo (name = "bar"[,vers = "version"]) is obsolete,
-            // `extern mod foo = "bar#[version]";` should be used.
-            // Parse obsolete options to avoid wired parser errors
-            self.parse_optional_meta();
-            self.obsolete(self.span, ObsoleteExternModAttributesInParens);
-        }
-        // extern mod foo;
-        self.expect(&token::SEMI);
-        IoviViewItem(ast::ViewItem {
-            node: ViewItemExternMod(ident, maybe_path, ast::DUMMY_NODE_ID),
-            attrs: attrs,
-            vis: visibility,
-            span: mk_sp(lo, self.last_span.hi)
-        })
+        let item = self.mk_item(lo,
+                                self.last_span.hi,
+                                special_idents::clownshoes_foreign_mod,
+                                ItemForeignMod(m),
+                                visibility,
+                                maybe_append(attrs, Some(inner)));
+        return IoviItem(item);
     }
 
     // parse type Foo = Bar;
@@ -4504,10 +4494,6 @@ impl Parser {
     // Parses a string as an ABI spec on an extern type or module. Consumes
     // the `extern` keyword, if one is found.
     fn parse_opt_abis(&mut self) -> Option<AbiSet> {
-        if !self.eat_keyword(keywords::Extern) {
-            return None
-        }
-
         match self.token {
             token::LIT_STR(s)
             | token::LIT_STR_RAW(s, _) => {
@@ -4585,7 +4571,20 @@ impl Parser {
             });
         }
         // either a view item or an item:
-        if self.is_keyword(keywords::Extern) {
+        if self.eat_keyword(keywords::Extern) {
+            let next_is_mod = self.eat_keyword(keywords::Mod);
+
+            if next_is_mod || self.eat_keyword(keywords::Crate) {
+                // NOTE(flaper87): Uncomment this when this changes gets into stage0
+                //
+                // if next_is_mod {
+                //    self.span_err(self.span,
+                //                   format!("`extern mod` is obsolete, use `extern crate` instead \
+                //                           to refer to external crates."))
+                // }
+                return self.parse_item_extern_crate(lo, visibility, attrs);
+            }
+
             let opt_abis = self.parse_opt_abis();
 
             if self.eat_keyword(keywords::Fn) {
@@ -4600,12 +4599,15 @@ impl Parser {
                                         visibility,
                                         maybe_append(attrs, extra_attrs));
                 return IoviItem(item);
-            } else  {
-                // EXTERN MODULE ITEM (IoviViewItem)
-                return self.parse_item_foreign_mod(lo, opt_abis, visibility, attrs,
-                                                   true);
+            } else if self.token == token::LBRACE {
+                return self.parse_item_foreign_mod(lo, opt_abis, visibility, attrs);
             }
+
+            let token_str = self.this_token_to_str();
+            self.span_fatal(self.span,
+                            format!("expected `\\{` or `fn` but found `{}`", token_str));
         }
+
         // the rest are all guaranteed to be items:
         if self.is_keyword(keywords::Static) {
             // STATIC ITEM
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 1e9eab1573b..423ddb82808 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -462,37 +462,38 @@ declare_special_idents_and_keywords! {
         (28,                         Loop,       "loop");
         (29,                         Match,      "match");
         (30,                         Mod,        "mod");
-        (31,                         Mut,        "mut");
-        (32,                         Once,       "once");
-        (33,                         Priv,       "priv");
-        (34,                         Pub,        "pub");
-        (35,                         Ref,        "ref");
-        (36,                         Return,     "return");
+        (31,                         Crate,      "crate");
+        (32,                         Mut,        "mut");
+        (33,                         Once,       "once");
+        (34,                         Priv,       "priv");
+        (35,                         Pub,        "pub");
+        (36,                         Ref,        "ref");
+        (37,                         Return,     "return");
         // Static and Self are also special idents (prefill de-dupes)
         (super::STATIC_KEYWORD_NAME, Static,     "static");
         (super::SELF_KEYWORD_NAME,   Self,       "self");
-        (37,                         Struct,     "struct");
-        (38,                         Super,      "super");
-        (39,                         True,       "true");
-        (40,                         Trait,      "trait");
-        (41,                         Type,       "type");
-        (42,                         Unsafe,     "unsafe");
-        (43,                         Use,        "use");
-        (44,                         While,      "while");
-        (45,                         Continue,   "continue");
-        (46,                         Proc,       "proc");
-        (47,                         Box,        "box");
+        (38,                         Struct,     "struct");
+        (39,                         Super,      "super");
+        (40,                         True,       "true");
+        (41,                         Trait,      "trait");
+        (42,                         Type,       "type");
+        (43,                         Unsafe,     "unsafe");
+        (44,                         Use,        "use");
+        (45,                         While,      "while");
+        (46,                         Continue,   "continue");
+        (47,                         Proc,       "proc");
+        (48,                         Box,        "box");
 
         'reserved:
-        (48,                         Alignof,    "alignof");
-        (49,                         Be,         "be");
-        (50,                         Offsetof,   "offsetof");
-        (51,                         Pure,       "pure");
-        (52,                         Sizeof,     "sizeof");
-        (53,                         Typeof,     "typeof");
-        (54,                         Unsized,    "unsized");
-        (55,                         Yield,      "yield");
-        (56,                         Do,         "do");
+        (49,                         Alignof,    "alignof");
+        (50,                         Be,         "be");
+        (51,                         Offsetof,   "offsetof");
+        (52,                         Pure,       "pure");
+        (53,                         Sizeof,     "sizeof");
+        (54,                         Typeof,     "typeof");
+        (55,                         Unsized,    "unsized");
+        (56,                         Yield,      "yield");
+        (57,                         Do,         "do");
     }
 }