about summary refs log tree commit diff
path: root/src/libsyntax/ext/tt/macro_parser.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-04-06 22:08:01 +0000
committerbors <bors@rust-lang.org>2015-04-06 22:08:01 +0000
commitb49a5ef003fedcbb0d78aebda62ba30dfdd17a20 (patch)
treed99b438e04f810e098c79b634ed6d730d2dbcb4a /src/libsyntax/ext/tt/macro_parser.rs
parentaab8669ddad0432ef7279cc7f7b0b20d32785314 (diff)
parente3427c3c341fcd15cbac783bf8dad7276422c97a (diff)
downloadrust-b49a5ef003fedcbb0d78aebda62ba30dfdd17a20.tar.gz
rust-b49a5ef003fedcbb0d78aebda62ba30dfdd17a20.zip
Auto merge of #23857 - phildawes:libsyntax_nopanic, r=nikomatsakis
Hello! 

I've been working towards a libsyntax without panics. See:
http://internals.rust-lang.org/t/changing-libsyntax-to-use-result-instead-of-panic/1670

This patch changes the internals of parser.rs to use Result<> rather than panicing. It keeps the following old-style panicing functions as a facade:
parse_expr, parse_item, parse_pat, parse_arm, parse_ty, parse_stmt

I left these functions because I wasn't sure what to do about the quote_* macros or how many syntax-extensions would break if these and quoting macros returned Result.

The gyst of the rest of the patch is:

 - Functions in parse/parser.rs return PResult<> rather than panicing
 - Other functions in libsyntax call panic! explicitly if they rely on panicing behaviour.
 - I added a macro 'panictry!()' to act as scaffolding for callers while converting panicing functions. (This does the same as 'unwrap()' but is easier to grep for and turn into try!()).

Am I on the right track?  I'd quite like to get something merged soon as keeping this rebased in the face of libsyntax changes is a lot of work. Please let me know what changes you'd like to see to make this happen.

Thanks!, Phil
Diffstat (limited to 'src/libsyntax/ext/tt/macro_parser.rs')
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs30
1 files changed, 15 insertions, 15 deletions
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index b7d40a46f3e..4e0b74401a2 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -226,10 +226,10 @@ pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc<NamedMatch>])
                     }
                     Occupied(..) => {
                         let string = token::get_ident(bind_name);
-                        p_s.span_diagnostic
+                        panic!(p_s.span_diagnostic
                            .span_fatal(sp,
                                        &format!("duplicated bind name: {}",
-                                               &string))
+                                               &string)))
                     }
                 }
             }
@@ -260,10 +260,10 @@ pub fn parse_or_else(sess: &ParseSess,
     match parse(sess, cfg, rdr, &ms[..]) {
         Success(m) => m,
         Failure(sp, str) => {
-            sess.span_diagnostic.span_fatal(sp, &str[..])
+            panic!(sess.span_diagnostic.span_fatal(sp, &str[..]))
         }
         Error(sp, str) => {
-            sess.span_diagnostic.span_fatal(sp, &str[..])
+            panic!(sess.span_diagnostic.span_fatal(sp, &str[..]))
         }
     }
 }
@@ -512,46 +512,46 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
     match name {
         "tt" => {
             p.quote_depth += 1; //but in theory, non-quoted tts might be useful
-            let res = token::NtTT(P(p.parse_token_tree()));
+            let res = token::NtTT(P(panictry!(p.parse_token_tree())));
             p.quote_depth -= 1;
             return res;
         }
         _ => {}
     }
     // check at the beginning and the parser checks after each bump
-    p.check_unknown_macro_variable();
+    panictry!(p.check_unknown_macro_variable());
     match name {
       "item" => match p.parse_item() {
         Some(i) => token::NtItem(i),
-        None => p.fatal("expected an item keyword")
+        None => panic!(p.fatal("expected an item keyword"))
       },
-      "block" => token::NtBlock(p.parse_block()),
+      "block" => token::NtBlock(panictry!(p.parse_block())),
       "stmt" => match p.parse_stmt() {
         Some(s) => token::NtStmt(s),
-        None => p.fatal("expected a statement")
+        None => panic!(p.fatal("expected a statement"))
       },
       "pat" => token::NtPat(p.parse_pat()),
       "expr" => token::NtExpr(p.parse_expr()),
       "ty" => token::NtTy(p.parse_ty()),
       // this could be handled like a token, since it is one
       "ident" => match p.token {
-        token::Ident(sn,b) => { p.bump(); token::NtIdent(box sn,b) }
+        token::Ident(sn,b) => { panictry!(p.bump()); token::NtIdent(box sn,b) }
         _ => {
             let token_str = pprust::token_to_string(&p.token);
-            p.fatal(&format!("expected ident, found {}",
-                             &token_str[..]))
+            panic!(p.fatal(&format!("expected ident, found {}",
+                             &token_str[..])))
         }
       },
       "path" => {
-        token::NtPath(box p.parse_path(LifetimeAndTypesWithoutColons))
+        token::NtPath(box panictry!(p.parse_path(LifetimeAndTypesWithoutColons)))
       }
       "meta" => token::NtMeta(p.parse_meta_item()),
       _ => {
-          p.span_fatal_help(sp,
+          panic!(p.span_fatal_help(sp,
                             &format!("invalid fragment specifier `{}`", name),
                             "valid fragment specifiers are `ident`, `block`, \
                              `stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt` \
-                             and `item`")
+                             and `item`"))
       }
     }
 }