about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-07-29 16:28:59 +0000
committerbors <bors@rust-lang.org>2015-07-29 16:28:59 +0000
commit090ad6fde7e55c5a8e8969cc2983e25b92adc633 (patch)
tree037a3ae2c5fac0902ca1d443d6fd45d115e02be2
parentddbce1107bc95ea4ad0da6299ca31e313a39e0fc (diff)
parent218eccfa4e66acb13bbd420564066a22709eb7dd (diff)
downloadrust-090ad6fde7e55c5a8e8969cc2983e25b92adc633.tar.gz
rust-090ad6fde7e55c5a8e8969cc2983e25b92adc633.zip
Auto merge of #27346 - dotdash:closure_dbg, r=michaelwoerister
Closure variables represent the closure environment, not the closure
function, so the identifier used to ensure that the debuginfo is unique
for each kind of closure needs to be based on the closure upvars and not
the function signature.
-rw-r--r--src/librustc_trans/trans/debuginfo/metadata.rs62
-rw-r--r--src/test/debuginfo/basic-types-metadata.rs18
2 files changed, 30 insertions, 50 deletions
diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs
index 6ccf7ccfa08..b8feecd0a55 100644
--- a/src/librustc_trans/trans/debuginfo/metadata.rs
+++ b/src/librustc_trans/trans/debuginfo/metadata.rs
@@ -26,7 +26,6 @@ use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType};
 use metadata::csearch;
 use middle::pat_util;
 use middle::subst::{self, Substs};
-use middle::infer;
 use rustc::ast_map;
 use trans::{type_of, adt, machine, monomorphize};
 use trans::common::{self, CrateContext, FunctionContext, Block};
@@ -287,12 +286,18 @@ impl<'tcx> TypeMap<'tcx> {
                     }
                 }
             },
-            ty::TyClosure(def_id, ref substs) => {
-                let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables);
-                let closure_ty = infcx.closure_type(def_id, substs);
-                self.get_unique_type_id_of_closure_type(cx,
-                                                        closure_ty,
-                                                        &mut unique_type_id);
+            ty::TyClosure(_, ref substs) if substs.upvar_tys.is_empty() => {
+                push_debuginfo_type_name(cx, type_, false, &mut unique_type_id);
+            },
+            ty::TyClosure(_, ref substs) => {
+                unique_type_id.push_str("closure ");
+                for upvar_type in &substs.upvar_tys {
+                    let upvar_type_id =
+                        self.get_unique_type_id_of_type(cx, upvar_type);
+                    let upvar_type_id =
+                        self.get_unique_type_id_as_string(upvar_type_id);
+                    unique_type_id.push_str(&upvar_type_id[..]);
+                }
             },
             _ => {
                 cx.sess().bug(&format!("get_unique_type_id_of_type() - unexpected type: {:?}",
@@ -361,49 +366,6 @@ impl<'tcx> TypeMap<'tcx> {
         }
     }
 
-    fn get_unique_type_id_of_closure_type<'a>(&mut self,
-                                              cx: &CrateContext<'a, 'tcx>,
-                                              closure_ty: ty::ClosureTy<'tcx>,
-                                              unique_type_id: &mut String) {
-        let ty::ClosureTy { unsafety,
-                            ref sig,
-                            abi: _ } = closure_ty;
-
-        if unsafety == ast::Unsafety::Unsafe {
-            unique_type_id.push_str("unsafe ");
-        }
-
-        unique_type_id.push_str("|");
-
-        let sig = cx.tcx().erase_late_bound_regions(sig);
-
-        for &parameter_type in &sig.inputs {
-            let parameter_type_id =
-                self.get_unique_type_id_of_type(cx, parameter_type);
-            let parameter_type_id =
-                self.get_unique_type_id_as_string(parameter_type_id);
-            unique_type_id.push_str(&parameter_type_id[..]);
-            unique_type_id.push(',');
-        }
-
-        if sig.variadic {
-            unique_type_id.push_str("...");
-        }
-
-        unique_type_id.push_str("|->");
-
-        match sig.output {
-            ty::FnConverging(ret_ty) => {
-                let return_type_id = self.get_unique_type_id_of_type(cx, ret_ty);
-                let return_type_id = self.get_unique_type_id_as_string(return_type_id);
-                unique_type_id.push_str(&return_type_id[..]);
-            }
-            ty::FnDiverging => {
-                unique_type_id.push_str("!");
-            }
-        }
-    }
-
     // Get the UniqueTypeId for an enum variant. Enum variants are not really
     // types of their own, so they need special handling. We still need a
     // UniqueTypeId for them, since to debuginfo they *are* real types.
diff --git a/src/test/debuginfo/basic-types-metadata.rs b/src/test/debuginfo/basic-types-metadata.rs
index 2468150a6a5..3b662ae0264 100644
--- a/src/test/debuginfo/basic-types-metadata.rs
+++ b/src/test/debuginfo/basic-types-metadata.rs
@@ -46,6 +46,21 @@
 // gdb-check:type = [...] (*)([...])
 // gdb-command:info functions _yyy
 // gdb-check:[...]![...]_yyy([...]);
+// gdb-command:ptype closure_0
+// gdb-check: type = struct closure {
+// gdb-check:     <no data fields>
+// gdb-check: }
+// gdb-command:ptype closure_1
+// gdb-check: type = struct closure {
+// gdb-check:     bool *__0;
+// gdb-check: }
+// gdb-command:ptype closure_2
+// gdb-check: type = struct closure {
+// gdb-check:     bool *__0;
+// gdb-check:     isize *__1;
+// gdb-check: }
+
+//
 // gdb-command:continue
 
 #![allow(unused_variables)]
@@ -68,6 +83,9 @@ fn main() {
     let f32: f32 = 2.5;
     let f64: f64 = 3.5;
     let fnptr : fn() = _zzz;
+    let closure_0 = || {};
+    let closure_1 = || { b; };
+    let closure_2 = || { if b { i } else { i }; };
     _zzz(); // #break
     if 1 == 1 { _yyy(); }
 }