about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSimonas Kazlauskas <git@kazlauskas.me>2015-12-22 18:43:05 +0200
committerSimonas Kazlauskas <git@kazlauskas.me>2016-01-06 13:57:52 +0200
commitf9814242dc0066441db9391af9b56dea8fa4376f (patch)
treef9a6bf77cb127b25a054b997ac6e075f44654856
parentd1c644c1e94403f0cd42c7afc2ac06c0554422b7 (diff)
downloadrust-f9814242dc0066441db9391af9b56dea8fa4376f.tar.gz
rust-f9814242dc0066441db9391af9b56dea8fa4376f.zip
panic/panic_bounds_check to destructure tys
Not any more beautiful.
-rw-r--r--src/librustc_mir/build/expr/as_lvalue.rs2
-rw-r--r--src/librustc_mir/build/scope.rs88
2 files changed, 51 insertions, 39 deletions
diff --git a/src/librustc_mir/build/expr/as_lvalue.rs b/src/librustc_mir/build/expr/as_lvalue.rs
index 6baf3ad2fe1..4e03ed489eb 100644
--- a/src/librustc_mir/build/expr/as_lvalue.rs
+++ b/src/librustc_mir/build/expr/as_lvalue.rs
@@ -71,7 +71,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
                                        cond: Operand::Consume(lt),
                                        targets: (success, failure),
                                    });
-                this.panic_bound_check(failure, idx.clone(), Operand::Consume(len), expr_span);
+                this.panic_bounds_check(failure, idx.clone(), Operand::Consume(len), expr_span);
                 success.and(slice.index(idx))
             }
             ExprKind::SelfRef => {
diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs
index 8167ffcff1e..e912e933bd8 100644
--- a/src/librustc_mir/build/scope.rs
+++ b/src/librustc_mir/build/scope.rs
@@ -90,7 +90,7 @@ use build::{BlockAnd, BlockAndExtension, Builder};
 use rustc::middle::region::CodeExtent;
 use rustc::middle::lang_items;
 use rustc::middle::subst::Substs;
-use rustc::middle::ty::{Ty, Region};
+use rustc::middle::ty::{self, Ty};
 use rustc::mir::repr::*;
 use syntax::codemap::{Span, DUMMY_SP};
 use syntax::parse::token::intern_and_get_ident;
@@ -297,27 +297,34 @@ impl<'a,'tcx> Builder<'a,'tcx> {
         self.scopes.first().map(|scope| scope.extent).unwrap()
     }
 
-    pub fn panic_bound_check(&mut self,
+    pub fn panic_bounds_check(&mut self,
                              block: BasicBlock,
                              index: Operand<'tcx>,
                              len: Operand<'tcx>,
                              span: Span) {
+        // fn(&(filename: &'static str, line: u32), index: usize, length: usize) -> !
         let func = self.lang_function(lang_items::PanicBoundsCheckFnLangItem);
-        let str_ty = self.hir.tcx().mk_static_str();
-        let tup_ty = self.hir.tcx().mk_tup(vec![str_ty, self.hir.tcx().types.u32]);
-        // FIXME: ReStatic might be wrong here?
-        let ref_region = self.hir.tcx().mk_region(Region::ReStatic);
-        let ref_ty = self.hir.tcx().mk_imm_ref(ref_region, tup_ty.clone());
-        let (file_arg, line_arg) = self.span_to_fileline_args(span);
+        let args = func.ty.fn_args();
+        let ref_ty = args.skip_binder()[0];
+        let (region, tup_ty) = if let ty::TyRef(region, tyandmut) = ref_ty.sty {
+            (region, tyandmut.ty)
+        } else {
+            self.hir.span_bug(span, &format!("unexpected panic_bound_check type: {:?}", func.ty));
+        };
         let (tuple, tuple_ref) = (self.temp(tup_ty), self.temp(ref_ty));
-        self.cfg.push_assign(block, DUMMY_SP, &tuple, // tuple = (message_arg, file_arg, line_arg);
-                             Rvalue::Aggregate(AggregateKind::Tuple, vec![file_arg, line_arg]));
-        // FIXME: ReStatic might be wrong here?
+        let (file, line) = self.span_to_fileline_args(span);
+        let elems = vec![Operand::Constant(file), Operand::Constant(line)];
+        // FIXME: We should have this as a constant, rather than a stack variable (to not pollute
+        // icache with cold branch code), however to achieve that we either have to rely on rvalue
+        // promotion or have some way, in MIR, to create constants.
+        self.cfg.push_assign(block, DUMMY_SP, &tuple, // tuple = (file_arg, line_arg);
+                             Rvalue::Aggregate(AggregateKind::Tuple, elems));
+        // FIXME: is this region really correct here?
         self.cfg.push_assign(block, DUMMY_SP, &tuple_ref, // tuple_ref = &tuple;
-                             Rvalue::Ref(*ref_region, BorrowKind::Unique, tuple));
+                             Rvalue::Ref(*region, BorrowKind::Unique, tuple));
         let cleanup = self.diverge_cleanup();
         self.cfg.terminate(block, Terminator::Call {
-            func: func,
+            func: Operand::Constant(func),
             args: vec![Operand::Consume(tuple_ref), index, len],
             kind: match cleanup {
                 None => CallKind::Diverging,
@@ -328,31 +335,36 @@ impl<'a,'tcx> Builder<'a,'tcx> {
 
     /// Create diverge cleanup and branch to it from `block`.
     pub fn panic(&mut self, block: BasicBlock, msg: &'static str, span: Span) {
+        // fn(&(msg: &'static str filename: &'static str, line: u32)) -> !
         let func = self.lang_function(lang_items::PanicFnLangItem);
-
-        let str_ty = self.hir.tcx().mk_static_str();
-        let tup_ty = self.hir.tcx().mk_tup(vec![str_ty, str_ty, self.hir.tcx().types.u32]);
-        // FIXME: ReStatic might be wrong here?
-        let ref_region = self.hir.tcx().mk_region(Region::ReStatic);
-        let ref_ty = self.hir.tcx().mk_imm_ref(ref_region, tup_ty.clone());
-        let message_arg = Operand::Constant(Constant {
+        let args = func.ty.fn_args();
+        let ref_ty = args.skip_binder()[0];
+        let (region, tup_ty) = if let ty::TyRef(region, tyandmut) = ref_ty.sty {
+            (region, tyandmut.ty)
+        } else {
+            self.hir.span_bug(span, &format!("unexpected panic type: {:?}", func.ty));
+        };
+        let (tuple, tuple_ref) = (self.temp(tup_ty), self.temp(ref_ty));
+        let (file, line) = self.span_to_fileline_args(span);
+        let message = Constant {
             span: DUMMY_SP,
-            ty: str_ty,
+            ty: self.hir.tcx().mk_static_str(),
             literal: self.hir.str_literal(intern_and_get_ident(msg))
-        });
-        let (file_arg, line_arg) = self.span_to_fileline_args(span);
-        let tuple = self.temp(tup_ty);
-        let tuple_ref = self.temp(ref_ty);
+        };
+        let elems = vec![Operand::Constant(message),
+                         Operand::Constant(file),
+                         Operand::Constant(line)];
+        // FIXME: We should have this as a constant, rather than a stack variable (to not pollute
+        // icache with cold branch code), however to achieve that we either have to rely on rvalue
+        // promotion or have some way, in MIR, to create constants.
         self.cfg.push_assign(block, DUMMY_SP, &tuple, // tuple = (message_arg, file_arg, line_arg);
-                             Rvalue::Aggregate(AggregateKind::Tuple,
-                                               vec![message_arg, file_arg, line_arg])
-        );
-        // FIXME: ReStatic might be wrong here?
+                             Rvalue::Aggregate(AggregateKind::Tuple, elems));
+        // FIXME: is this region really correct here?
         self.cfg.push_assign(block, DUMMY_SP, &tuple_ref, // tuple_ref = &tuple;
-                             Rvalue::Ref(*ref_region, BorrowKind::Unique, tuple));
+                             Rvalue::Ref(*region, BorrowKind::Unique, tuple));
         let cleanup = self.diverge_cleanup();
         self.cfg.terminate(block, Terminator::Call {
-            func: func,
+            func: Operand::Constant(func),
             args: vec![Operand::Consume(tuple_ref)],
             kind: match cleanup {
                 None => CallKind::Diverging,
@@ -361,14 +373,14 @@ impl<'a,'tcx> Builder<'a,'tcx> {
         });
     }
 
-    fn lang_function(&mut self, lang_item: lang_items::LangItem) -> Operand<'tcx> {
+    fn lang_function(&mut self, lang_item: lang_items::LangItem) -> Constant<'tcx> {
         let funcdid = match self.hir.tcx().lang_items.require(lang_item) {
             Ok(d) => d,
             Err(m) => {
                 self.hir.tcx().sess.fatal(&*m)
             }
         };
-        Operand::Constant(Constant {
+        Constant {
             span: DUMMY_SP,
             ty: self.hir.tcx().lookup_item_type(funcdid).ty,
             literal: Literal::Item {
@@ -376,19 +388,19 @@ impl<'a,'tcx> Builder<'a,'tcx> {
                 kind: ItemKind::Function,
                 substs: self.hir.tcx().mk_substs(Substs::empty())
             }
-        })
+        }
     }
 
-    fn span_to_fileline_args(&mut self, span: Span) -> (Operand<'tcx>, Operand<'tcx>) {
+    fn span_to_fileline_args(&mut self, span: Span) -> (Constant<'tcx>, Constant<'tcx>) {
         let span_lines = self.hir.tcx().sess.codemap().lookup_char_pos(span.lo);
-        (Operand::Constant(Constant {
+        (Constant {
             span: DUMMY_SP,
             ty: self.hir.tcx().mk_static_str(),
             literal: self.hir.str_literal(intern_and_get_ident(&span_lines.file.name))
-        }), Operand::Constant(Constant {
+        }, Constant {
             span: DUMMY_SP,
             ty: self.hir.tcx().types.u32,
             literal: self.hir.usize_literal(span_lines.line)
-        }))
+        })
     }
 }