about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2017-05-02 06:07:54 -0400
committerNiko Matsakis <niko@alum.mit.edu>2017-05-02 16:21:57 -0400
commitc7023d1c2fbb9e136084b0d35164aff5eb2071ae (patch)
treefac5811feaa51f242da3fda09b95eae92476dd4b /src
parent74b2783877d5f6906a2e532828203f155054d8f9 (diff)
downloadrust-c7023d1c2fbb9e136084b0d35164aff5eb2071ae.tar.gz
rust-c7023d1c2fbb9e136084b0d35164aff5eb2071ae.zip
run MIR borrowck on the validated, not optimized, MIR
Diffstat (limited to 'src')
-rw-r--r--src/librustc/hir/map/mod.rs2
-rw-r--r--src/librustc_borrowck/borrowck/mir/mod.rs5
-rw-r--r--src/librustc_borrowck/borrowck/mod.rs13
-rw-r--r--src/librustc_mir/queries.rs4
4 files changed, 22 insertions, 2 deletions
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 48b8a819fff..abc967dec90 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -455,7 +455,7 @@ impl<'hir> Map<'hir> {
                 if let EntryExpr(_, expr) = entry {
                     BodyId { node_id: expr.id }
                 } else {
-                    span_bug!(self.span(id), "id `{}` has no associated body", id);
+                    span_bug!(self.span(id), "id `{}` has no associated body: {:?}", id, entry);
                 }
             }
         } else {
diff --git a/src/librustc_borrowck/borrowck/mir/mod.rs b/src/librustc_borrowck/borrowck/mir/mod.rs
index de5613dbfaa..47f708bf583 100644
--- a/src/librustc_borrowck/borrowck/mir/mod.rs
+++ b/src/librustc_borrowck/borrowck/mir/mod.rs
@@ -61,7 +61,10 @@ pub fn borrowck_mir(bcx: &mut BorrowckCtxt,
     let def_id = tcx.hir.local_def_id(id);
     debug!("borrowck_mir({}) UNIMPLEMENTED", tcx.item_path_str(def_id));
 
-    let mir = &tcx.item_mir(def_id);
+    // It is safe for us to borrow `mir_validated()`: `optimized_mir`
+    // steals it, but it forces the `borrowck` query.
+    let mir = &tcx.mir_validated(def_id).borrow();
+
     let param_env = ty::ParameterEnvironment::for_item(tcx, id);
     let move_data = MoveData::gather_moves(mir, tcx, &param_env);
     let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index 1259816639a..8a5f1fe3da0 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -86,6 +86,19 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) {
     debug!("borrowck(body_owner_def_id={:?})", owner_def_id);
 
     let owner_id = tcx.hir.as_local_node_id(owner_def_id).unwrap();
+
+    match tcx.hir.get(owner_id) {
+        hir_map::NodeStructCtor(_) |
+        hir_map::NodeVariant(_) => {
+            // We get invoked with anything that has MIR, but some of
+            // those things (notably the synthesized constructors from
+            // tuple structs/variants) do not have an associated body
+            // and do not need borrowchecking.
+            return;
+        }
+        _ => { }
+    }
+
     let body_id = tcx.hir.body_owned_by(owner_id);
     let attributes = tcx.get_attrs(owner_def_id);
     let tables = tcx.typeck_tables_of(owner_def_id);
diff --git a/src/librustc_mir/queries.rs b/src/librustc_mir/queries.rs
index b9d6e527e55..947b6df4bf0 100644
--- a/src/librustc_mir/queries.rs
+++ b/src/librustc_mir/queries.rs
@@ -110,6 +110,10 @@ fn mir_validated<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
 }
 
 fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Mir<'tcx> {
+    // Borrowck uses `mir_validated`, so we have to force it to
+    // execute before we can steal.
+    ty::queries::borrowck::force(tcx, DUMMY_SP, def_id);
+
     let mut mir = tcx.mir_validated(def_id).steal();
     let source = MirSource::from_local_def_id(tcx, def_id);
     transform::run_suite(tcx, source, MIR_OPTIMIZED, &mut mir);