about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Burka <aburka@seas.upenn.edu>2016-03-15 13:03:42 -0400
committerAlex Burka <aburka@seas.upenn.edu>2016-03-24 01:33:31 -0400
commit9799cacba3042420cc7b49d555289241cf0456e1 (patch)
tree7a08fce357b03fc4e9b5a53949dd52348c1aaddb
parentcd80c1bb5540fa2610a8f3d8a25560d1f0981400 (diff)
downloadrust-9799cacba3042420cc7b49d555289241cf0456e1.tar.gz
rust-9799cacba3042420cc7b49d555289241cf0456e1.zip
fatal error instead of ICE for impossible range during HIR lowering
End-less ranges (`a...`) don't parse but bad syntax extensions could
conceivably produce them. Unbounded ranges (`...`) do parse and are
caught here.

The other panics in HIR lowering are all for unexpanded macros, which
cannot be constructed by bad syntax extensions.
-rw-r--r--src/librustc/session/mod.rs4
-rw-r--r--src/librustc_front/lowering.rs9
-rw-r--r--src/libsyntax/ast.rs5
-rw-r--r--src/test/parse-fail/range_inclusive.rs5
4 files changed, 20 insertions, 3 deletions
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index b198eda1812..a02f8274527 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -336,6 +336,10 @@ impl NodeIdAssigner for Session {
     fn peek_node_id(&self) -> NodeId {
         self.next_node_id.get().checked_add(1).unwrap()
     }
+
+    fn diagnostic(&self) -> &errors::Handler {
+        self.diagnostic()
+    }
 }
 
 fn split_msg_into_multilines(msg: &str) -> Option<String> {
diff --git a/src/librustc_front/lowering.rs b/src/librustc_front/lowering.rs
index 8aac6356f9d..a0466de999a 100644
--- a/src/librustc_front/lowering.rs
+++ b/src/librustc_front/lowering.rs
@@ -68,6 +68,7 @@ use std::collections::HashMap;
 use std::iter;
 use syntax::ast::*;
 use syntax::attr::{ThinAttributes, ThinAttributesExt};
+use syntax::errors::Handler;
 use syntax::ext::mtwt;
 use syntax::ptr::P;
 use syntax::codemap::{respan, Spanned, Span};
@@ -140,6 +141,11 @@ impl<'a, 'hir> LoweringContext<'a> {
             result
         }
     }
+
+    // panics if this LoweringContext's NodeIdAssigner is not a Session
+    fn diagnostic(&self) -> &Handler {
+        self.id_assigner.diagnostic()
+    }
 }
 
 // Utility fn for setting and unsetting the cached id.
@@ -1289,7 +1295,8 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                             make_struct(lctx, e, &["RangeInclusive", "NonEmpty"],
                                                  &[("start", e1), ("end", e2)]),
 
-                        _ => panic!("impossible range in AST"),
+                        _ => panic!(lctx.diagnostic().span_fatal(e.span,
+                                                                 "inclusive range with no end"))
                     }
                 });
             }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index ac1a07d1cb5..e096aa99024 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -19,6 +19,7 @@ pub use self::PathParameters::*;
 use attr::ThinAttributes;
 use codemap::{Span, Spanned, DUMMY_SP, ExpnId};
 use abi::Abi;
+use errors;
 use ext::base;
 use ext::tt::macro_parser;
 use parse::token::InternedString;
@@ -344,6 +345,10 @@ pub const DUMMY_NODE_ID: NodeId = !0;
 pub trait NodeIdAssigner {
     fn next_node_id(&self) -> NodeId;
     fn peek_node_id(&self) -> NodeId;
+
+    fn diagnostic(&self) -> &errors::Handler {
+        panic!("this ID assigner cannot emit diagnostics")
+    }
 }
 
 /// The AST represents all type param bounds as types.
diff --git a/src/test/parse-fail/range_inclusive.rs b/src/test/parse-fail/range_inclusive.rs
index 5fd6f1834e0..be2a63a07bb 100644
--- a/src/test/parse-fail/range_inclusive.rs
+++ b/src/test/parse-fail/range_inclusive.rs
@@ -13,6 +13,7 @@
 #![feature(inclusive_range_syntax, inclusive_range)]
 
 pub fn main() {
-    for _ in 1... {}
-} //~ ERROR expected one of
+    for _ in 1... {} //~ERROR inclusive range with no end
+                     //~^HELP 28237
+}