]> git.lizzy.rs Git - rust.git/blobdiff - src/libsyntax/parse/parser.rs
Auto merge of #28651 - dotdash:exhaustive_match, r=eddyb
[rust.git] / src / libsyntax / parse / parser.rs
index a7978babcb7e1c000d7b96a21a1e22bc2274c417..f47dfeb1d34679df56a14526ada66b747d4ea961 100644 (file)
@@ -22,7 +22,7 @@
 use ast::{UnDeref, BiDiv, EMPTY_CTXT, EnumDef, ExplicitSelf};
 use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain};
 use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox};
-use ast::{ExprBreak, ExprCall, ExprCast};
+use ast::{ExprBreak, ExprCall, ExprCast, ExprInPlace};
 use ast::{ExprField, ExprTupField, ExprClosure, ExprIf, ExprIfLet, ExprIndex};
 use ast::{ExprLit, ExprLoop, ExprMac, ExprRange};
 use ast::{ExprMethodCall, ExprParen, ExprPath};
@@ -37,7 +37,7 @@
 use ast::{LitBool, LitChar, LitByte, LitByteStr};
 use ast::{LitStr, LitInt, Local};
 use ast::{MacStmtWithBraces, MacStmtWithSemicolon, MacStmtWithoutBraces};
-use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, MatchSource};
+use ast::{MutImmutable, MutMutable, Mac_, MatchSource};
 use ast::{MutTy, BiMul, Mutability};
 use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, UnNot};
 use ast::{Pat, PatBox, PatEnum, PatIdent, PatLit, PatQPath, PatMac, PatRange};
@@ -54,7 +54,7 @@
 use ast::{TyMac};
 use ast::{TyFixedLengthVec, TyBareFn, TyTypeof, TyInfer};
 use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr};
-use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq};
+use ast::{TyRptr, TyTup, TyU32, TyVec};
 use ast::{TypeImplItem, TypeTraitItem};
 use ast::{UnnamedField, UnsafeBlock};
 use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
@@ -1381,7 +1381,7 @@ pub fn parse_ty_nopanic(&mut self) -> PResult<P<Ty>> {
                                                      seq_sep_none(),
                                                      |p| p.parse_token_tree()));
                 let hi = self.span.hi;
-                TyMac(spanned(lo, hi, MacInvocTT(path, tts, EMPTY_CTXT)))
+                TyMac(spanned(lo, hi, Mac_ { path: path, tts: tts, ctxt: EMPTY_CTXT }))
             } else {
                 // NAMED TYPE
                 TyPath(None, path)
@@ -2203,9 +2203,7 @@ pub fn parse_bottom_expr(&mut self) -> PResult<P<Expr>> {
 
                         return Ok(self.mk_mac_expr(lo,
                                                    hi,
-                                                   MacInvocTT(pth,
-                                                              tts,
-                                                              EMPTY_CTXT)));
+                                                   Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT }));
                     }
                     if self.check(&token::OpenDelim(token::Brace)) {
                         // This is a struct literal, unless we're prohibited
@@ -2619,76 +2617,19 @@ pub fn parse_prefix_expr(&mut self) -> PResult<P<Expr>> {
             hi = e.span.hi;
             ex = ExprAddrOf(m, e);
           }
-          token::Ident(_, _) => {
-            if !self.check_keyword(keywords::Box) && !self.check_keyword(keywords::In) {
-                return self.parse_dot_or_call_expr();
-            }
-
-            let lo = self.span.lo;
-            let keyword_hi = self.span.hi;
-
-            let is_in = self.token.is_keyword(keywords::In);
-            try!(self.bump());
-
-            if is_in {
+          token::Ident(..) if self.token.is_keyword(keywords::In) => {
+              try!(self.bump());
               let place = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL));
               let blk = try!(self.parse_block());
               hi = blk.span.hi;
               let blk_expr = self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk));
-              ex = ExprBox(Some(place), blk_expr);
-              return Ok(self.mk_expr(lo, hi, ex));
-            }
-
-            // FIXME (#22181) Remove `box (PLACE) EXPR` support
-            // entirely after next release (enabling `(box (EXPR))`),
-            // since it will be replaced by `in PLACE { EXPR }`, ...
-            //
-            // ... but for now: check for a place: `box(PLACE) EXPR`.
-
-            if try!(self.eat(&token::OpenDelim(token::Paren))) {
-                let box_span = mk_sp(lo, self.last_span.hi);
-                self.span_warn(box_span,
-                    "deprecated syntax; use the `in` keyword now \
-                           (e.g. change `box (<expr>) <expr>` to \
-                                        `in <expr> { <expr> }`)");
-
-                // Continue supporting `box () EXPR` (temporarily)
-                if !try!(self.eat(&token::CloseDelim(token::Paren))) {
-                    let place = try!(self.parse_expr_nopanic());
-                    try!(self.expect(&token::CloseDelim(token::Paren)));
-                    // Give a suggestion to use `box()` when a parenthesised expression is used
-                    if !self.token.can_begin_expr() {
-                        let span = self.span;
-                        let this_token_to_string = self.this_token_to_string();
-                        self.span_err(span,
-                                      &format!("expected expression, found `{}`",
-                                              this_token_to_string));
-
-                        // Spanning just keyword avoids constructing
-                        // printout of arg expression (which starts
-                        // with parenthesis, as established above).
-
-                        let box_span = mk_sp(lo, keyword_hi);
-                        self.span_suggestion(box_span,
-                                             "try using `box ()` instead:",
-                                             format!("box ()"));
-                        self.abort_if_errors();
-                    }
-                    let subexpression = try!(self.parse_prefix_expr());
-                    hi = subexpression.span.hi;
-                    ex = ExprBox(Some(place), subexpression);
-                    return Ok(self.mk_expr(lo, hi, ex));
-                }
-            }
-
-            // Otherwise, we use the unique pointer default.
-            let subexpression = try!(self.parse_prefix_expr());
-            hi = subexpression.span.hi;
-
-            // FIXME (pnkfelix): After working out kinks with box
-            // desugaring, should be `ExprBox(None, subexpression)`
-            // instead.
-            ex = self.mk_unary(UnUniq, subexpression);
+              ex = ExprInPlace(place, blk_expr);
+          }
+          token::Ident(..) if self.token.is_keyword(keywords::Box) => {
+              try!(self.bump());
+              let subexpression = try!(self.parse_prefix_expr());
+              hi = subexpression.span.hi;
+              ex = ExprBox(subexpression);
           }
           _ => return self.parse_dot_or_call_expr()
         }
@@ -3289,7 +3230,7 @@ pub fn parse_pat_nopanic(&mut self) -> PResult<P<Pat>> {
                         let delim = try!(self.expect_open_delim());
                         let tts = try!(self.parse_seq_to_end(&token::CloseDelim(delim),
                                 seq_sep_none(), |p| p.parse_token_tree()));
-                        let mac = MacInvocTT(path, tts, EMPTY_CTXT);
+                        let mac = Mac_ { path: path, tts: tts, ctxt: EMPTY_CTXT };
                         pat = PatMac(codemap::Spanned {node: mac, span: self.span});
                     } else {
                         // Parse ident @ pat
@@ -3557,7 +3498,7 @@ fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
                 spanned(lo, hi,
                         StmtMac(P(spanned(lo,
                                           hi,
-                                          MacInvocTT(pth, tts, EMPTY_CTXT))),
+                                          Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT })),
                                   style))
             } else {
                 // if it has a special ident, it's definitely an item
@@ -3576,7 +3517,8 @@ fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
                     P(spanned(lo, hi, DeclItem(
                         self.mk_item(
                             lo, hi, id /*id is good here*/,
-                            ItemMac(spanned(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT))),
+                            ItemMac(spanned(lo, hi,
+                                            Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT })),
                             Inherited, Vec::new(/*no attrs*/))))),
                     ast::DUMMY_NODE_ID))
             }
@@ -4524,7 +4466,7 @@ fn parse_impl_method(&mut self, vis: Visibility)
             let tts = try!(self.parse_seq_to_end(&token::CloseDelim(delim),
                                             seq_sep_none(),
                                             |p| p.parse_token_tree()));
-            let m_ = ast::MacInvocTT(pth, tts, EMPTY_CTXT);
+            let m_ = Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT };
             let m: ast::Mac = codemap::Spanned { node: m_,
                                                 span: mk_sp(self.span.lo,
                                                             self.span.hi) };
@@ -4716,7 +4658,7 @@ fn parse_item_struct(&mut self) -> PResult<ItemInfo> {
             (fields, None)
         // Tuple-style struct definition with optional where-clause.
         } else if self.token == token::OpenDelim(token::Paren) {
-            let fields = try!(self.parse_tuple_struct_body(&class_name, &mut generics));
+            let fields = try!(self.parse_tuple_struct_body(class_name, &mut generics));
             (fields, Some(ast::DUMMY_NODE_ID))
         } else {
             let token_str = self.this_token_to_string();
@@ -4751,7 +4693,7 @@ pub fn parse_record_struct_body(&mut self) -> PResult<Vec<StructField>> {
     }
 
     pub fn parse_tuple_struct_body(&mut self,
-                                   class_name: &ast::Ident,
+                                   class_name: ast::Ident,
                                    generics: &mut ast::Generics)
                                    -> PResult<Vec<StructField>> {
         // This is the case where we find `struct Foo<T>(T) where T: Copy;`
@@ -4843,7 +4785,7 @@ fn parse_mod_items(&mut self, term: &token::Token, inner_lo: BytePos) -> PResult
         let hi = if self.span == codemap::DUMMY_SP {
             inner_lo
         } else {
-            self.span.lo
+            self.last_span.hi
         };
 
         Ok(ast::Mod {
@@ -5037,9 +4979,8 @@ fn eval_src_mod_from_path(&mut self,
     }
 
     /// Parse a function declaration from a foreign module
-    fn parse_item_foreign_fn(&mut self, vis: ast::Visibility,
+    fn parse_item_foreign_fn(&mut self, vis: ast::Visibility, lo: BytePos,
                              attrs: Vec<Attribute>) -> PResult<P<ForeignItem>> {
-        let lo = self.span.lo;
         try!(self.expect_keyword(keywords::Fn));
 
         let (ident, mut generics) = try!(self.parse_fn_header());
@@ -5058,10 +4999,8 @@ fn parse_item_foreign_fn(&mut self, vis: ast::Visibility,
     }
 
     /// Parse a static item from a foreign module
-    fn parse_item_foreign_static(&mut self, vis: ast::Visibility,
+    fn parse_item_foreign_static(&mut self, vis: ast::Visibility, lo: BytePos,
                                  attrs: Vec<Attribute>) -> PResult<P<ForeignItem>> {
-        let lo = self.span.lo;
-
         try!(self.expect_keyword(keywords::Static));
         let mutbl = try!(self.eat_keyword(keywords::Mut));
 
@@ -5101,12 +5040,19 @@ fn parse_item_extern_crate(&mut self,
         try!(self.expect(&token::Semi));
 
         let last_span = self.last_span;
+
+        if visibility == ast::Public {
+            self.span_warn(mk_sp(lo, last_span.hi),
+                           "`pub extern crate` does not work as expected and should not be used. \
+                            Likely to become an error. Prefer `extern crate` and `pub use`.");
+        }
+
         Ok(self.mk_item(lo,
-                     last_span.hi,
-                     ident,
-                     ItemExternCrate(maybe_path),
-                     visibility,
-                     attrs))
+                        last_span.hi,
+                        ident,
+                        ItemExternCrate(maybe_path),
+                        visibility,
+                        attrs))
     }
 
     /// Parse `extern` for foreign ABIs
@@ -5185,13 +5131,10 @@ fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<EnumDef> {
             let variant_attrs = self.parse_outer_attributes();
             let vlo = self.span.lo;
 
-            let vis = try!(self.parse_visibility());
-
-            let ident;
             let kind;
             let mut args = Vec::new();
             let mut disr_expr = None;
-            ident = try!(self.parse_ident());
+            let ident = try!(self.parse_ident());
             if try!(self.eat(&token::OpenDelim(token::Brace)) ){
                 // Parse a struct variant.
                 all_nullary = false;
@@ -5233,7 +5176,6 @@ fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<EnumDef> {
                 kind: kind,
                 id: ast::DUMMY_NODE_ID,
                 disr_expr: disr_expr,
-                vis: vis,
             };
             variants.push(P(spanned(vlo, self.last_span.hi, vr)));
 
@@ -5554,11 +5496,11 @@ fn parse_foreign_item(&mut self) -> PResult<Option<P<ForeignItem>>> {
 
         if self.check_keyword(keywords::Static) {
             // FOREIGN STATIC ITEM
-            return Ok(Some(try!(self.parse_item_foreign_static(visibility, attrs))));
+            return Ok(Some(try!(self.parse_item_foreign_static(visibility, lo, attrs))));
         }
         if self.check_keyword(keywords::Fn) || self.check_keyword(keywords::Unsafe) {
             // FOREIGN FUNCTION ITEM
-            return Ok(Some(try!(self.parse_item_foreign_fn(visibility, attrs))));
+            return Ok(Some(try!(self.parse_item_foreign_fn(visibility, lo, attrs))));
         }
 
         // FIXME #5668: this will occur for a macro invocation:
@@ -5606,7 +5548,7 @@ fn parse_macro_use_or_failure(
                                             seq_sep_none(),
                                             |p| p.parse_token_tree()));
             // single-variant-enum... :
-            let m = ast::MacInvocTT(pth, tts, EMPTY_CTXT);
+            let m = Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT };
             let m: ast::Mac = codemap::Spanned { node: m,
                                              span: mk_sp(self.span.lo,
                                                          self.span.hi) };
@@ -5781,10 +5723,10 @@ pub fn parse_optional_str(&mut self)
                                                  Option<ast::Name>)>> {
         let ret = match self.token {
             token::Literal(token::Str_(s), suf) => {
-                (self.id_to_interned_str(s.ident()), ast::CookedStr, suf)
+                (self.id_to_interned_str(ast::Ident::with_empty_ctxt(s)), ast::CookedStr, suf)
             }
             token::Literal(token::StrRaw(s, n), suf) => {
-                (self.id_to_interned_str(s.ident()), ast::RawStr(n), suf)
+                (self.id_to_interned_str(ast::Ident::with_empty_ctxt(s)), ast::RawStr(n), suf)
             }
             _ => return Ok(None)
         };