about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2018-11-26 21:40:05 +0200
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2019-04-23 23:35:21 +0300
commit1525dc2146e3b85123f57e59adcee1908e57013f (patch)
tree49733b00e4e0192f9fa4b76b2d9d66a75cb496e3 /src
parente6ec968485080a704a4edc1e96c89359bd81550d (diff)
downloadrust-1525dc2146e3b85123f57e59adcee1908e57013f.tar.gz
rust-1525dc2146e3b85123f57e59adcee1908e57013f.zip
rustc: dissuade compiler developers from misusing upvar debuginfo.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/mir/mod.rs18
-rw-r--r--src/librustc_codegen_ssa/mir/mod.rs11
-rw-r--r--src/librustc_mir/build/mod.rs18
-rw-r--r--src/librustc_mir/transform/inline.rs6
4 files changed, 29 insertions, 24 deletions
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 7c432c9c7eb..bf2a1eaafd6 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -146,7 +146,11 @@ pub struct Mir<'tcx> {
 
     /// Names and capture modes of all the closure upvars, assuming
     /// the first argument is either the closure or a reference to it.
-    pub upvar_decls: Vec<UpvarDecl>,
+    // NOTE(eddyb) This is *strictly* a temporary hack for codegen
+    // debuginfo generation, and will be removed at some point.
+    // Do **NOT** use it for anything else, upvar information should not be
+    // in the MIR, please rely on local crate HIR or other side-channels.
+    pub __upvar_debuginfo_codegen_only_do_not_use: Vec<UpvarDebuginfo>,
 
     /// Mark this MIR of a const context other than const functions as having converted a `&&` or
     /// `||` expression into `&` or `|` respectively. This is problematic because if we ever stop
@@ -173,7 +177,7 @@ impl<'tcx> Mir<'tcx> {
         local_decls: LocalDecls<'tcx>,
         user_type_annotations: CanonicalUserTypeAnnotations<'tcx>,
         arg_count: usize,
-        upvar_decls: Vec<UpvarDecl>,
+        __upvar_debuginfo_codegen_only_do_not_use: Vec<UpvarDebuginfo>,
         span: Span,
         control_flow_destroyed: Vec<(Span, String)>,
     ) -> Self {
@@ -197,7 +201,7 @@ impl<'tcx> Mir<'tcx> {
             local_decls,
             user_type_annotations,
             arg_count,
-            upvar_decls,
+            __upvar_debuginfo_codegen_only_do_not_use,
             spread_arg: None,
             span,
             cache: cache::Cache::new(),
@@ -431,7 +435,7 @@ impl_stable_hash_for!(struct Mir<'tcx> {
     local_decls,
     user_type_annotations,
     arg_count,
-    upvar_decls,
+    __upvar_debuginfo_codegen_only_do_not_use,
     spread_arg,
     control_flow_destroyed,
     span,
@@ -983,7 +987,7 @@ impl<'tcx> LocalDecl<'tcx> {
 
 /// A closure capture, with its name and mode.
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub struct UpvarDecl {
+pub struct UpvarDebuginfo {
     pub debug_name: Name,
 
     /// If true, the capture is behind a reference.
@@ -3151,7 +3155,7 @@ CloneTypeFoldableAndLiftImpls! {
     MirPhase,
     Mutability,
     SourceInfo,
-    UpvarDecl,
+    UpvarDebuginfo,
     FakeReadCause,
     RetagKind,
     SourceScope,
@@ -3173,7 +3177,7 @@ BraceStructTypeFoldableImpl! {
         local_decls,
         user_type_annotations,
         arg_count,
-        upvar_decls,
+        __upvar_debuginfo_codegen_only_do_not_use,
         spread_arg,
         control_flow_destroyed,
         span,
diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs
index c9a6ff1a0c0..621c4e5d448 100644
--- a/src/librustc_codegen_ssa/mir/mod.rs
+++ b/src/librustc_codegen_ssa/mir/mod.rs
@@ -598,9 +598,10 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
                 tmp
             }
         };
+        let upvar_debuginfo = &mir.__upvar_debuginfo_codegen_only_do_not_use;
         arg_scope.map(|scope| {
             // Is this a regular argument?
-            if arg_index > 0 || mir.upvar_decls.is_empty() {
+            if arg_index > 0 || upvar_debuginfo.is_empty() {
                 // The Rust ABI passes indirect variables using a pointer and a manual copy, so we
                 // need to insert a deref here, but the C ABI uses a pointer and a copy using the
                 // byval attribute, for which LLVM always does the deref itself,
@@ -638,16 +639,16 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
             let (def_id, upvar_substs) = match closure_layout.ty.sty {
                 ty::Closure(def_id, substs) => (def_id, UpvarSubsts::Closure(substs)),
                 ty::Generator(def_id, substs, _) => (def_id, UpvarSubsts::Generator(substs)),
-                _ => bug!("upvar_decls with non-closure arg0 type `{}`", closure_layout.ty)
+                _ => bug!("upvar debuginfo with non-closure arg0 type `{}`", closure_layout.ty)
             };
             let upvar_tys = upvar_substs.upvar_tys(def_id, tcx);
 
             let extra_locals = {
-                let upvars = mir.upvar_decls
+                let upvars = upvar_debuginfo
                     .iter()
                     .zip(upvar_tys)
                     .enumerate()
-                    .map(|(i, (decl, ty))| (i, decl.debug_name, decl.by_ref, ty));
+                    .map(|(i, (upvar, ty))| (i, upvar.debug_name, upvar.by_ref, ty));
 
                 let generator_fields = mir.generator_layout.as_ref().map(|generator_layout| {
                     let (def_id, gen_substs) = match closure_layout.ty.sty {
@@ -656,7 +657,7 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
                     };
                     let state_tys = gen_substs.state_tys(def_id, tcx);
 
-                    let upvar_count = mir.upvar_decls.len();
+                    let upvar_count = upvar_debuginfo.len();
                     generator_layout.fields
                         .iter()
                         .zip(state_tys)
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index cd2fa10927f..79e1d5daae1 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -375,7 +375,7 @@ struct Builder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     var_indices: HirIdMap<LocalsForNode>,
     local_decls: IndexVec<Local, LocalDecl<'tcx>>,
     canonical_user_type_annotations: ty::CanonicalUserTypeAnnotations<'tcx>,
-    upvar_decls: Vec<UpvarDecl>,
+    __upvar_debuginfo_codegen_only_do_not_use: Vec<UpvarDebuginfo>,
     upvar_mutbls: Vec<Mutability>,
     unit_temp: Option<Place<'tcx>>,
 
@@ -631,7 +631,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
     // closure and we stored in a map called upvar_list in TypeckTables indexed
     // with the closure's DefId. Here, we run through that vec of UpvarIds for
     // the given closure and use the necessary information to create UpvarDecl.
-    let upvar_decls: Vec<_> = hir_tables
+    let upvar_debuginfo: Vec<_> = hir_tables
         .upvar_list
         .get(&fn_def_id)
         .into_iter()
@@ -644,14 +644,14 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
                 ty::UpvarCapture::ByValue => false,
                 ty::UpvarCapture::ByRef(..) => true,
             };
-            let mut decl = UpvarDecl {
+            let mut debuginfo = UpvarDebuginfo {
                 debug_name: keywords::Invalid.name(),
                 by_ref,
             };
             let mut mutability = Mutability::Not;
             if let Some(Node::Binding(pat)) = tcx_hir.find(var_node_id) {
                 if let hir::PatKind::Binding(_, _, ident, _) = pat.node {
-                    decl.debug_name = ident.name;
+                    debuginfo.debug_name = ident.name;
                     if let Some(&bm) = hir.tables.pat_binding_modes().get(pat.hir_id) {
                         if bm == ty::BindByValue(hir::MutMutable) {
                             mutability = Mutability::Mut;
@@ -664,7 +664,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
                 }
             }
             upvar_mutbls.push(mutability);
-            decl
+            debuginfo
         })
         .collect();
 
@@ -674,7 +674,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
         safety,
         return_ty,
         return_ty_span,
-        upvar_decls,
+        upvar_debuginfo,
         upvar_mutbls);
 
     let call_site_scope = region::Scope {
@@ -778,7 +778,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
            safety: Safety,
            return_ty: Ty<'tcx>,
            return_span: Span,
-           upvar_decls: Vec<UpvarDecl>,
+           __upvar_debuginfo_codegen_only_do_not_use: Vec<UpvarDebuginfo>,
            upvar_mutbls: Vec<Mutability>)
            -> Builder<'a, 'gcx, 'tcx> {
         let lint_level = LintLevel::Explicit(hir.root_lint_level);
@@ -801,7 +801,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                 1,
             ),
             canonical_user_type_annotations: IndexVec::new(),
-            upvar_decls,
+            __upvar_debuginfo_codegen_only_do_not_use,
             upvar_mutbls,
             var_indices: Default::default(),
             unit_temp: None,
@@ -837,7 +837,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             self.local_decls,
             self.canonical_user_type_annotations,
             self.arg_count,
-            self.upvar_decls,
+            self.__upvar_debuginfo_codegen_only_do_not_use,
             self.fn_span,
             self.hir.control_flow_destroyed(),
         )
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 027ae70b06a..e96a40ad2f0 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -222,10 +222,10 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
         debug!("should_inline({:?})", callsite);
         let tcx = self.tcx;
 
-        // Don't inline closures that have captures
+        // Don't inline closures that have capture debuginfo
         // FIXME: Handle closures better
-        if callee_mir.upvar_decls.len() > 0 {
-            debug!("    upvar decls present - not inlining");
+        if callee_mir.__upvar_debuginfo_codegen_only_do_not_use.len() > 0 {
+            debug!("    upvar debuginfo present - not inlining");
             return false;
         }