]> git.lizzy.rs Git - rust.git/commitdiff
Generate DivergingCall terminator
authorSimonas Kazlauskas <git@kazlauskas.me>
Tue, 15 Dec 2015 10:20:49 +0000 (12:20 +0200)
committerSimonas Kazlauskas <git@kazlauskas.me>
Wed, 6 Jan 2016 11:57:47 +0000 (13:57 +0200)
This simplifies CFG greatly for some cases :)

src/librustc_mir/build/expr/into.rs
src/librustc_mir/hair/cx/expr.rs
src/librustc_mir/hair/mod.rs

index 4a262196d367049fb264ade77e5e8ea695b60402..a173018b74fea1a4f1f4081f11fb4e8203ec7cb6 100644 (file)
@@ -15,6 +15,7 @@
 use build::scope::LoopScope;
 use hair::*;
 use rustc::middle::region::CodeExtent;
+use rustc::middle::ty;
 use rustc::mir::repr::*;
 use syntax::codemap::Span;
 
@@ -210,22 +211,30 @@ pub fn into_expr(&mut self,
                 this.exit_scope(expr_span, extent, block, END_BLOCK);
                 this.cfg.start_new_block().unit()
             }
-            ExprKind::Call { fun, args } => {
+            ExprKind::Call { ty, fun, args } => {
+                let diverges = match ty.sty {
+                    ty::TyBareFn(_, ref f) => f.sig.0.output.diverges(),
+                    _ => false
+                };
                 let fun = unpack!(block = this.as_operand(block, fun));
                 let args: Vec<_> =
                     args.into_iter()
                         .map(|arg| unpack!(block = this.as_operand(block, arg)))
                         .collect();
+
                 let success = this.cfg.start_new_block();
-                let panic = this.diverge_cleanup();
-                let targets = CallTargets::WithCleanup((success, panic));
-                this.cfg.terminate(block,
-                                   Terminator::Call {
-                                       func: fun,
-                                       args: args,
-                                       destination: destination.clone(),
-                                       targets: targets
-                                   });
+                let cleanup = this.diverge_cleanup();
+                let term = if diverges {
+                    Terminator::DivergingCall { func: fun, args: args, cleanup: Some(cleanup) }
+                } else {
+                    Terminator::Call {
+                        func: fun,
+                        args: args,
+                        destination: destination.clone(),
+                        targets: CallTargets::WithCleanup((success, cleanup))
+                    }
+                };
+                this.cfg.terminate(block, term);
                 success.unit()
             }
 
index aa6257345fe445a31a147ce12cc2619315306826..012bd9691be5f6b28e863818ef8265370214cec6 100644 (file)
@@ -41,6 +41,7 @@ fn make_mirror<'a>(self, cx: &mut Cx<'a, 'tcx>) -> Expr<'tcx> {
                                .map(|e| e.to_ref())
                                .collect();
                 ExprKind::Call {
+                    ty: expr.ty,
                     fun: expr.to_ref(),
                     args: args,
                 }
@@ -58,11 +59,17 @@ fn make_mirror<'a>(self, cx: &mut Cx<'a, 'tcx>) -> Expr<'tcx> {
                     argrefs.extend(args.iter().map(|a| a.to_ref()));
 
                     ExprKind::Call {
+                        ty: method.ty,
                         fun: method.to_ref(),
                         args: argrefs,
                     }
                 } else {
-                    ExprKind::Call { fun: fun.to_ref(), args: args.to_ref() }
+                    ExprKind::Call {
+                        ty: &cx.tcx.node_id_to_type(fun.id),
+                        fun: fun.to_ref(),
+                        args: args.to_ref(),
+                    }
+
                 }
             }
 
@@ -802,6 +809,7 @@ fn overloaded_operator<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>,
     // now create the call itself
     let fun = method_callee(cx, expr, method_call);
     ExprKind::Call {
+        ty: fun.ty,
         fun: fun.to_ref(),
         args: argrefs,
     }
index 6363ddf1e1477b987cec22959da84df1bd8e5655..fb81cc7e6d97a4394d65702fbf809466616046d0 100644 (file)
@@ -19,7 +19,7 @@
 use rustc::middle::def_id::DefId;
 use rustc::middle::region::CodeExtent;
 use rustc::middle::subst::Substs;
-use rustc::middle::ty::{AdtDef, ClosureSubsts, Region, Ty};
+use rustc::middle::ty::{self, AdtDef, ClosureSubsts, Region, Ty};
 use rustc_front::hir;
 use syntax::ast;
 use syntax::codemap::Span;
@@ -124,6 +124,7 @@ pub enum ExprKind<'tcx> {
         value: ExprRef<'tcx>,
     },
     Call {
+        ty: ty::Ty<'tcx>,
         fun: ExprRef<'tcx>,
         args: Vec<ExprRef<'tcx>>,
     },