about summary refs log tree commit diff
path: root/src/librustc_mir/transform
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2017-08-01 18:26:28 -0700
committerRalf Jung <post@ralfj.de>2017-08-01 18:26:28 -0700
commit321a72c1c1329415c6b94cc18b42b05c1ce8b59d (patch)
treeae55380e500dd76f3f474354b08f7723e1ff9fc4 /src/librustc_mir/transform
parenta8129d128c314975d4d34a47e9cb7127de0d0dbc (diff)
downloadrust-321a72c1c1329415c6b94cc18b42b05c1ce8b59d.tar.gz
rust-321a72c1c1329415c6b94cc18b42b05c1ce8b59d.zip
closure unsafety check: stop moving up when we hit an item
Diffstat (limited to 'src/librustc_mir/transform')
-rw-r--r--src/librustc_mir/transform/add_validation.rs30
1 files changed, 15 insertions, 15 deletions
diff --git a/src/librustc_mir/transform/add_validation.rs b/src/librustc_mir/transform/add_validation.rs
index 2afaa070118..bbd2829c303 100644
--- a/src/librustc_mir/transform/add_validation.rs
+++ b/src/librustc_mir/transform/add_validation.rs
@@ -128,29 +128,29 @@ fn fn_contains_unsafe<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource) ->
         let mut cur = fn_like.id();
         loop {
             // Go further upwards.
-            let parent = tcx.hir.get_parent_node(cur);
-            if cur == parent {
-                bug!("Closures muts be inside a non-closure fn_like");
-            }
-            cur = parent;
-            // Check if this is an unsafe block
-            match tcx.hir.find(cur) {
-                Some(Node::NodeExpr(&hir::Expr { node: hir::ExprBlock(ref block), ..})) => {
-                    if block_is_unsafe(&*block) {
-                        // Found an unsafe block, we can bail out here.
+            cur = tcx.hir.get_parent_node(cur);
+            let node = tcx.hir.get(cur);
+            // Check if this is an unsafe function
+            if let Some(fn_like) = FnLikeNode::from_node(node) {
+                if !fn_is_closure(fn_like) {
+                    if fn_like.unsafety() == hir::Unsafety::Unsafe {
                         return true;
                     }
                 }
-                _ => {},
             }
-            // Check if this is a non-closure fn_like, at which point we have to stop moving up
-            if let Some(fn_like) = FnLikeNode::from_node(tcx.hir.get(cur)) {
-                if !fn_is_closure(fn_like) {
-                    if fn_like.unsafety() == hir::Unsafety::Unsafe {
+            // Check if this is an unsafe block, or an item
+            match node {
+                Node::NodeExpr(&hir::Expr { node: hir::ExprBlock(ref block), ..}) => {
+                    if block_is_unsafe(&*block) {
+                        // Found an unsafe block, we can bail out here.
                         return true;
                     }
+                }
+                Node::NodeItem(..) => {
+                    // No walking up beyond items.  This makes sure the loop always terminates.
                     break;
                 }
+                _ => {},
             }
         }
     }