about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-03-09 05:25:48 -0800
committerbors <bors@rust-lang.org>2016-03-09 05:25:48 -0800
commitcbbd3d9b927e4dc73b071e7bce70e1a3fc119946 (patch)
treeb5c96ae5be805b96c7d02e0c42ae7a6081153598 /src
parent4b868411afee1208cfb18f7440df991b9f94265f (diff)
parent11e0ba43401b0fcf4d61a4e91ad8d7020da74994 (diff)
downloadrust-cbbd3d9b927e4dc73b071e7bce70e1a3fc119946.tar.gz
rust-cbbd3d9b927e4dc73b071e7bce70e1a3fc119946.zip
Auto merge of #31631 - jonas-schievink:agoraphobia, r=nrc
[breaking-batch] Move more uses of `panictry!` out of libsyntax
Diffstat (limited to 'src')
-rw-r--r--src/librustc_driver/driver.rs27
-rw-r--r--src/librustc_driver/lib.rs23
-rw-r--r--src/librustc_driver/pretty.rs2
-rw-r--r--src/librustc_driver/test.rs2
-rw-r--r--src/librustdoc/core.rs2
-rw-r--r--src/librustdoc/lib.rs2
-rw-r--r--src/librustdoc/test.rs2
-rw-r--r--src/libsyntax/ast.rs2
-rw-r--r--src/libsyntax/ext/expand.rs6
-rw-r--r--src/libsyntax/ext/quote.rs42
-rw-r--r--src/libsyntax/parse/mod.rs134
-rw-r--r--src/test/run-make/execution-engine/test.rs4
12 files changed, 129 insertions, 119 deletions
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 9c1be4c9f2f..43160ab3558 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -48,12 +48,10 @@ use std::fs;
 use std::io::{self, Write};
 use std::path::{Path, PathBuf};
 use syntax::ast::{self, NodeIdAssigner};
-use syntax::attr;
-use syntax::attr::AttrMetaMethods;
+use syntax::attr::{self, AttrMetaMethods};
 use syntax::diagnostics;
 use syntax::fold::Folder;
-use syntax::parse;
-use syntax::parse::token;
+use syntax::parse::{self, PResult, token};
 use syntax::util::node_count::NodeCounter;
 use syntax::visit;
 use syntax;
@@ -86,7 +84,13 @@ pub fn compile_input(sess: &Session,
     // possible to keep the peak memory usage low
     let (outputs, trans) = {
         let (outputs, expanded_crate, id) = {
-            let krate = phase_1_parse_input(sess, cfg, input);
+            let krate = match phase_1_parse_input(sess, cfg, input) {
+                Ok(krate) => krate,
+                Err(mut parse_error) => {
+                    parse_error.emit();
+                    return Err(1);
+                }
+            };
 
             controller_entry_point!(after_parse,
                                     sess,
@@ -415,17 +419,20 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
     }
 }
 
-pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input) -> ast::Crate {
+pub fn phase_1_parse_input<'a>(sess: &'a Session,
+                               cfg: ast::CrateConfig,
+                               input: &Input)
+                               -> PResult<'a, ast::Crate> {
     // These may be left in an incoherent state after a previous compile.
     // `clear_tables` and `get_ident_interner().clear()` can be used to free
     // memory, but they do not restore the initial state.
     syntax::ext::mtwt::reset_tables();
     token::reset_ident_interner();
 
-    let krate = time(sess.time_passes(), "parsing", || {
+    let krate = try!(time(sess.time_passes(), "parsing", || {
         match *input {
             Input::File(ref file) => {
-                parse::parse_crate_from_file(&(*file), cfg.clone(), &sess.parse_sess)
+                parse::parse_crate_from_file(file, cfg.clone(), &sess.parse_sess)
             }
             Input::Str(ref src) => {
                 parse::parse_crate_from_source_str(anon_src().to_string(),
@@ -434,7 +441,7 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input)
                                                    &sess.parse_sess)
             }
         }
-    });
+    }));
 
     if sess.opts.debugging_opts.ast_json_noexpand {
         println!("{}", json::as_json(&krate));
@@ -449,7 +456,7 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input)
         syntax::show_span::run(sess.diagnostic(), s, &krate);
     }
 
-    krate
+    Ok(krate)
 }
 
 fn count_nodes(krate: &ast::Crate) -> usize {
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index da565856a9f..d1c287b1e39 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -89,7 +89,7 @@ use std::thread;
 use rustc::session::{early_error, early_warn};
 
 use syntax::ast;
-use syntax::parse;
+use syntax::parse::{self, PResult};
 use syntax::errors;
 use syntax::errors::emitter::Emitter;
 use syntax::diagnostics;
@@ -531,7 +531,19 @@ impl RustcDefaultCalls {
             return Compilation::Continue;
         }
 
-        let attrs = input.map(|input| parse_crate_attrs(sess, input));
+        let attrs = match input {
+            None => None,
+            Some(input) => {
+                let result = parse_crate_attrs(sess, input);
+                match result {
+                    Ok(attrs) => Some(attrs),
+                    Err(mut parse_error) => {
+                        parse_error.emit();
+                        return Compilation::Stop;
+                    }
+                }
+            }
+        };
         for req in &sess.opts.prints {
             match *req {
                 PrintRequest::TargetList => {
@@ -977,8 +989,8 @@ pub fn handle_options(mut args: Vec<String>) -> Option<getopts::Matches> {
     Some(matches)
 }
 
-fn parse_crate_attrs(sess: &Session, input: &Input) -> Vec<ast::Attribute> {
-    let result = match *input {
+fn parse_crate_attrs<'a>(sess: &'a Session, input: &Input) -> PResult<'a, Vec<ast::Attribute>> {
+    match *input {
         Input::File(ref ifile) => {
             parse::parse_crate_attrs_from_file(ifile, Vec::new(), &sess.parse_sess)
         }
@@ -988,8 +1000,7 @@ fn parse_crate_attrs(sess: &Session, input: &Input) -> Vec<ast::Attribute> {
                                                      Vec::new(),
                                                      &sess.parse_sess)
         }
-    };
-    result.into_iter().collect()
+    }
 }
 
 /// Run a procedure which will detect panics in the compiler and print nicer
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index eb4668e6abb..9f9824eae35 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -686,7 +686,7 @@ pub fn pretty_print_input(sess: Session,
                           ppm: PpMode,
                           opt_uii: Option<UserIdentifiedItem>,
                           ofile: Option<PathBuf>) {
-    let krate = driver::phase_1_parse_input(&sess, cfg, input);
+    let krate = panictry!(driver::phase_1_parse_input(&sess, cfg, input));
 
     let krate = if let PpmSource(PpmEveryBodyLoops) = ppm {
         let mut fold = ReplaceBodyWithLoop::new();
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index abeaffe80ab..5c3c5beafad 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -114,7 +114,7 @@ fn test_env<F>(source_string: &str,
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
     let krate_config = Vec::new();
     let input = config::Input::Str(source_string.to_string());
-    let krate = driver::phase_1_parse_input(&sess, krate_config, &input);
+    let krate = driver::phase_1_parse_input(&sess, krate_config, &input).unwrap();
     let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate, "test", None)
                     .expect("phase 2 aborted");
 
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 345b84e0cac..5a6fe060eb8 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -133,7 +133,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
     let mut cfg = config::build_configuration(&sess);
     target_features::add_configuration(&mut cfg, &sess);
 
-    let krate = driver::phase_1_parse_input(&sess, cfg, &input);
+    let krate = panictry!(driver::phase_1_parse_input(&sess, cfg, &input));
 
     let name = link::find_crate_name(Some(&sess), &krate.attrs,
                                      &input);
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 6ff23943a98..21df784b098 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -43,7 +43,7 @@ extern crate rustc_back;
 extern crate rustc_front;
 extern crate rustc_metadata;
 extern crate serialize;
-extern crate syntax;
+#[macro_use] extern crate syntax;
 extern crate test as testing;
 extern crate rustc_unicode;
 #[macro_use] extern crate log;
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index e97357f9889..6294b676651 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -91,7 +91,7 @@ pub fn run(input: &str,
 
     let mut cfg = config::build_configuration(&sess);
     cfg.extend(config::parse_cfgspecs(cfgs.clone()));
-    let krate = driver::phase_1_parse_input(&sess, cfg, &input);
+    let krate = panictry!(driver::phase_1_parse_input(&sess, cfg, &input));
     let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate,
                                                      "rustdoc-test", None)
         .expect("phase_2_configure_and_expand aborted in rustdoc!");
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 342ba60e553..a8bea2da833 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -458,7 +458,7 @@ pub struct WhereEqPredicate {
 
 /// The set of MetaItems that define the compilation environment of the crate,
 /// used to drive conditional compilation
-pub type CrateConfig = Vec<P<MetaItem>> ;
+pub type CrateConfig = Vec<P<MetaItem>>;
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct Crate {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index e8098cfff45..f5794f7219b 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1519,7 +1519,7 @@ mod tests {
         let crate_ast = parse::parse_crate_from_source_str(
             "<test>".to_string(),
             src,
-            Vec::new(), &sess);
+            Vec::new(), &sess).unwrap();
         // should fail:
         let mut gated_cfgs = vec![];
         let ecx = ExtCtxt::new(&sess, vec![], test_ecfg(), &mut gated_cfgs);
@@ -1535,7 +1535,7 @@ mod tests {
         let crate_ast = parse::parse_crate_from_source_str(
             "<test>".to_string(),
             src,
-            Vec::new(), &sess);
+            Vec::new(), &sess).unwrap();
         let mut gated_cfgs = vec![];
         let ecx = ExtCtxt::new(&sess, vec![], test_ecfg(), &mut gated_cfgs);
         expand_crate(ecx, vec![], vec![], crate_ast);
@@ -1549,7 +1549,7 @@ mod tests {
         let crate_ast = parse::parse_crate_from_source_str(
             "<test>".to_string(),
             src,
-            Vec::new(), &sess);
+            Vec::new(), &sess).unwrap();
         let mut gated_cfgs = vec![];
         let ecx = ExtCtxt::new(&sess, vec![], test_ecfg(), &mut gated_cfgs);
         expand_crate(ecx, vec![], vec![], crate_ast);
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index d0eaa89e4ae..38da478b5ed 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -18,12 +18,12 @@ use parse::token::*;
 use parse::token;
 use ptr::P;
 
-///  Quasiquoting works via token trees.
+/// Quasiquoting works via token trees.
 ///
-///  This is registered as a set of expression syntax extension called quote!
-///  that lifts its argument token-tree to an AST representing the
-///  construction of the same token tree, with token::SubstNt interpreted
-///  as antiquotes (splices).
+/// This is registered as a set of expression syntax extension called quote!
+/// that lifts its argument token-tree to an AST representing the
+/// construction of the same token tree, with token::SubstNt interpreted
+/// as antiquotes (splices).
 
 pub mod rt {
     use ast;
@@ -319,34 +319,36 @@ pub mod rt {
     }
 
     impl<'a> ExtParseUtils for ExtCtxt<'a> {
-
         fn parse_item(&self, s: String) -> P<ast::Item> {
-            parse::parse_item_from_source_str(
+            panictry!(parse::parse_item_from_source_str(
                 "<quote expansion>".to_string(),
                 s,
                 self.cfg(),
-                self.parse_sess()).expect("parse error")
+                self.parse_sess())).expect("parse error")
         }
 
         fn parse_stmt(&self, s: String) -> ast::Stmt {
-            parse::parse_stmt_from_source_str("<quote expansion>".to_string(),
-                                              s,
-                                              self.cfg(),
-                                              self.parse_sess()).expect("parse error")
+            panictry!(parse::parse_stmt_from_source_str(
+                "<quote expansion>".to_string(),
+                s,
+                self.cfg(),
+                self.parse_sess())).expect("parse error")
         }
 
         fn parse_expr(&self, s: String) -> P<ast::Expr> {
-            parse::parse_expr_from_source_str("<quote expansion>".to_string(),
-                                              s,
-                                              self.cfg(),
-                                              self.parse_sess())
+            panictry!(parse::parse_expr_from_source_str(
+                "<quote expansion>".to_string(),
+                s,
+                self.cfg(),
+                self.parse_sess()))
         }
 
         fn parse_tts(&self, s: String) -> Vec<TokenTree> {
-            parse::parse_tts_from_source_str("<quote expansion>".to_string(),
-                                             s,
-                                             self.cfg(),
-                                             self.parse_sess())
+            panictry!(parse::parse_tts_from_source_str(
+                "<quote expansion>".to_string(),
+                s,
+                self.cfg(),
+                self.parse_sess()))
         }
     }
 }
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 1ec2479058c..ea5d6739e6d 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -71,95 +71,97 @@ impl ParseSess {
 // uses a HOF to parse anything, and <source> includes file and
 // source_str.
 
-pub fn parse_crate_from_file(
-    input: &Path,
-    cfg: ast::CrateConfig,
-    sess: &ParseSess
-) -> ast::Crate {
+pub fn parse_crate_from_file<'a>(input: &Path,
+                                 cfg: ast::CrateConfig,
+                                 sess: &'a ParseSess)
+                                 -> PResult<'a, ast::Crate> {
     let mut parser = new_parser_from_file(sess, cfg, input);
-    abort_if_errors(parser.parse_crate_mod(), &parser)
+    parser.parse_crate_mod()
 }
 
-pub fn parse_crate_attrs_from_file(
-    input: &Path,
-    cfg: ast::CrateConfig,
-    sess: &ParseSess
-) -> Vec<ast::Attribute> {
+pub fn parse_crate_attrs_from_file<'a>(input: &Path,
+                                       cfg: ast::CrateConfig,
+                                       sess: &'a ParseSess)
+                                       -> PResult<'a, Vec<ast::Attribute>> {
     let mut parser = new_parser_from_file(sess, cfg, input);
-    abort_if_errors(parser.parse_inner_attributes(), &parser)
+    parser.parse_inner_attributes()
 }
 
-pub fn parse_crate_from_source_str(name: String,
-                                   source: String,
-                                   cfg: ast::CrateConfig,
-                                   sess: &ParseSess)
-                                   -> ast::Crate {
+pub fn parse_crate_from_source_str<'a>(name: String,
+                                       source: String,
+                                       cfg: ast::CrateConfig,
+                                       sess: &'a ParseSess)
+                                       -> PResult<'a, ast::Crate> {
     let mut p = new_parser_from_source_str(sess,
                                            cfg,
                                            name,
                                            source);
-    panictry!(p.parse_crate_mod())
+    p.parse_crate_mod()
 }
 
-pub fn parse_crate_attrs_from_source_str(name: String,
-                                         source: String,
-                                         cfg: ast::CrateConfig,
-                                         sess: &ParseSess)
-                                         -> Vec<ast::Attribute> {
+pub fn parse_crate_attrs_from_source_str<'a>(name: String,
+                                             source: String,
+                                             cfg: ast::CrateConfig,
+                                             sess: &'a ParseSess)
+                                             -> PResult<'a, Vec<ast::Attribute>> {
     let mut p = new_parser_from_source_str(sess,
                                            cfg,
                                            name,
                                            source);
-    panictry!(p.parse_inner_attributes())
+    p.parse_inner_attributes()
 }
 
-pub fn parse_expr_from_source_str(name: String,
-                                  source: String,
-                                  cfg: ast::CrateConfig,
-                                  sess: &ParseSess)
-                                  -> P<ast::Expr> {
+pub fn parse_expr_from_source_str<'a>(name: String,
+                                      source: String,
+                                      cfg: ast::CrateConfig,
+                                      sess: &'a ParseSess)
+                                      -> PResult<'a, P<ast::Expr>> {
     let mut p = new_parser_from_source_str(sess, cfg, name, source);
-    panictry!(p.parse_expr())
+    p.parse_expr()
 }
 
-pub fn parse_item_from_source_str(name: String,
-                                  source: String,
-                                  cfg: ast::CrateConfig,
-                                  sess: &ParseSess)
-                                  -> Option<P<ast::Item>> {
+/// Parses an item.
+///
+/// Returns `Ok(Some(item))` when successful, `Ok(None)` when no item was found, and`Err`
+/// when a syntax error occurred.
+pub fn parse_item_from_source_str<'a>(name: String,
+                                      source: String,
+                                      cfg: ast::CrateConfig,
+                                      sess: &'a ParseSess)
+                                      -> PResult<'a, Option<P<ast::Item>>> {
     let mut p = new_parser_from_source_str(sess, cfg, name, source);
-    panictry!(p.parse_item())
+    p.parse_item()
 }
 
-pub fn parse_meta_from_source_str(name: String,
-                                  source: String,
-                                  cfg: ast::CrateConfig,
-                                  sess: &ParseSess)
-                                  -> P<ast::MetaItem> {
+pub fn parse_meta_from_source_str<'a>(name: String,
+                                      source: String,
+                                      cfg: ast::CrateConfig,
+                                      sess: &'a ParseSess)
+                                      -> PResult<'a, P<ast::MetaItem>> {
     let mut p = new_parser_from_source_str(sess, cfg, name, source);
-    panictry!(p.parse_meta_item())
+    p.parse_meta_item()
 }
 
-pub fn parse_stmt_from_source_str(name: String,
-                                  source: String,
-                                  cfg: ast::CrateConfig,
-                                  sess: &ParseSess)
-                                  -> Option<ast::Stmt> {
+pub fn parse_stmt_from_source_str<'a>(name: String,
+                                      source: String,
+                                      cfg: ast::CrateConfig,
+                                      sess: &'a ParseSess)
+                                      -> PResult<'a, Option<ast::Stmt>> {
     let mut p = new_parser_from_source_str(
         sess,
         cfg,
         name,
         source
     );
-    panictry!(p.parse_stmt())
+    p.parse_stmt()
 }
 
 // Warning: This parses with quote_depth > 0, which is not the default.
-pub fn parse_tts_from_source_str(name: String,
-                                 source: String,
-                                 cfg: ast::CrateConfig,
-                                 sess: &ParseSess)
-                                 -> Vec<ast::TokenTree> {
+pub fn parse_tts_from_source_str<'a>(name: String,
+                                     source: String,
+                                     cfg: ast::CrateConfig,
+                                     sess: &'a ParseSess)
+                                     -> PResult<'a, Vec<ast::TokenTree>> {
     let mut p = new_parser_from_source_str(
         sess,
         cfg,
@@ -168,7 +170,7 @@ pub fn parse_tts_from_source_str(name: String,
     );
     p.quote_depth += 1;
     // right now this is re-creating the token trees from ... token trees.
-    panictry!(p.parse_all_token_trees())
+    p.parse_all_token_trees()
 }
 
 // Create a new parser from a source string
@@ -265,20 +267,6 @@ pub fn tts_to_parser<'a>(sess: &'a ParseSess,
     p
 }
 
-
-fn abort_if_errors<'a, T>(result: PResult<'a, T>, p: &Parser) -> T {
-    match result {
-        Ok(c) => {
-            c
-        }
-        Err(mut e) => {
-            e.emit();
-            p.abort_if_errors();
-            unreachable!();
-        }
-    }
-}
-
 /// Parse a string representing a character literal into its final form.
 /// Rather than just accepting/rejecting a given literal, unescapes it as
 /// well. Can take any slice prefixed by a character escape. Returns the
@@ -1078,19 +1066,21 @@ mod tests {
 
         let name = "<source>".to_string();
         let source = "/// doc comment\r\nfn foo() {}".to_string();
-        let item = parse_item_from_source_str(name.clone(), source, Vec::new(), &sess).unwrap();
+        let item = parse_item_from_source_str(name.clone(), source, Vec::new(), &sess)
+            .unwrap().unwrap();
         let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
         assert_eq!(&doc[..], "/// doc comment");
 
         let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string();
-        let item = parse_item_from_source_str(name.clone(), source, Vec::new(), &sess).unwrap();
+        let item = parse_item_from_source_str(name.clone(), source, Vec::new(), &sess)
+            .unwrap().unwrap();
         let docs = item.attrs.iter().filter(|a| &*a.name() == "doc")
                     .map(|a| a.value_str().unwrap().to_string()).collect::<Vec<_>>();
         let b: &[_] = &["/// doc comment".to_string(), "/// line 2".to_string()];
         assert_eq!(&docs[..], b);
 
         let source = "/** doc comment\r\n *  with CRLF */\r\nfn foo() {}".to_string();
-        let item = parse_item_from_source_str(name, source, Vec::new(), &sess).unwrap();
+        let item = parse_item_from_source_str(name, source, Vec::new(), &sess).unwrap().unwrap();
         let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
         assert_eq!(&doc[..], "/** doc comment\n *  with CRLF */");
     }
@@ -1099,7 +1089,7 @@ mod tests {
     fn ttdelim_span() {
         let sess = ParseSess::new();
         let expr = parse::parse_expr_from_source_str("foo".to_string(),
-            "foo!( fn main() { body } )".to_string(), vec![], &sess);
+            "foo!( fn main() { body } )".to_string(), vec![], &sess).unwrap();
 
         let tts = match expr.node {
             ast::ExprKind::Mac(ref mac) => mac.node.tts.clone(),
diff --git a/src/test/run-make/execution-engine/test.rs b/src/test/run-make/execution-engine/test.rs
index 13cbdfe24d6..29063c5a607 100644
--- a/src/test/run-make/execution-engine/test.rs
+++ b/src/test/run-make/execution-engine/test.rs
@@ -18,7 +18,7 @@ extern crate rustc_front;
 extern crate rustc_lint;
 extern crate rustc_metadata;
 extern crate rustc_resolve;
-extern crate syntax;
+#[macro_use] extern crate syntax;
 
 use std::ffi::{CStr, CString};
 use std::mem::transmute;
@@ -230,7 +230,7 @@ fn compile_program(input: &str, sysroot: PathBuf)
 
         let id = "input".to_string();
 
-        let krate = driver::phase_1_parse_input(&sess, cfg, &input);
+        let krate = panictry!(driver::phase_1_parse_input(&sess, cfg, &input));
 
         let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate, &id, None)
             .expect("phase_2 returned `None`");