about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-05-06 08:31:58 -0700
committerbors <bors@rust-lang.org>2016-05-06 08:31:58 -0700
commit102bab3d6811eb2ca672730e853add3b568c6210 (patch)
treea973a7cef5da11e75a023ffeabb7d3ecbcd38964
parent5158f3b282287624232ac6935569e440bb182664 (diff)
parentbb0e5254ae59ef135f3feb82964a918b36d6d13d (diff)
downloadrust-102bab3d6811eb2ca672730e853add3b568c6210.tar.gz
rust-102bab3d6811eb2ca672730e853add3b568c6210.zip
Auto merge of #33225 - michaelwoerister:fix-debuginfo-struct-ns, r=eddyb
debuginfo: Fix regression in namespace handling for struct types.

Fixes a small regression that has been introduced in recent refactorings.

Fixes #33193

r? @eddyb
-rw-r--r--src/librustc_trans/debuginfo/metadata.rs6
-rw-r--r--src/test/debuginfo/struct-namespace.rs70
-rw-r--r--src/tools/compiletest/src/runtest.rs98
3 files changed, 124 insertions, 50 deletions
diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs
index de403732269..cc20751a0b0 100644
--- a/src/librustc_trans/debuginfo/metadata.rs
+++ b/src/librustc_trans/debuginfo/metadata.rs
@@ -1159,12 +1159,12 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let struct_name = compute_debuginfo_type_name(cx, struct_type, false);
     let struct_llvm_type = type_of::in_memory_type_of(cx, struct_type);
 
-    let (variant, substs) = match struct_type.sty {
-        ty::TyStruct(def, substs) => (def.struct_variant(), substs),
+    let (struct_def_id, variant, substs) = match struct_type.sty {
+        ty::TyStruct(def, substs) => (def.did, def.struct_variant(), substs),
         _ => bug!("prepare_struct_metadata on a non-struct")
     };
 
-    let (containing_scope, _) = get_namespace_and_span_for_item(cx, variant.did);
+    let (containing_scope, _) = get_namespace_and_span_for_item(cx, struct_def_id);
 
     let struct_metadata_stub = create_struct_stub(cx,
                                                   struct_llvm_type,
diff --git a/src/test/debuginfo/struct-namespace.rs b/src/test/debuginfo/struct-namespace.rs
new file mode 100644
index 00000000000..3fd4cf57b2a
--- /dev/null
+++ b/src/test/debuginfo/struct-namespace.rs
@@ -0,0 +1,70 @@
+// Copyright 2013-2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-gdb
+// compile-flags:-g
+// min-lldb-version: 310
+
+// Check that structs get placed in the correct namespace
+
+// lldb-command:run
+// lldb-command:p struct1
+// lldb-check:(struct_namespace::Struct1) $0 = [...]
+// lldb-command:p struct2
+// lldb-check:(struct_namespace::Struct2) $1 = [...]
+
+// lldb-command:p mod1_struct1
+// lldb-check:(struct_namespace::mod1::Struct1) $2 = [...]
+// lldb-command:p mod1_struct2
+// lldb-check:(struct_namespace::mod1::Struct2) $3 = [...]
+
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![feature(omit_gdb_pretty_printer_section)]
+#![omit_gdb_pretty_printer_section]
+
+struct Struct1 {
+    a: u32,
+    b: u64,
+}
+
+struct Struct2(u32);
+
+mod mod1 {
+
+    pub struct Struct1 {
+        pub a: u32,
+        pub b: u64,
+    }
+
+    pub struct Struct2(pub u32);
+}
+
+
+fn main() {
+    let struct1 = Struct1 {
+        a: 0,
+        b: 1,
+    };
+
+    let struct2 = Struct2(2);
+
+    let mod1_struct1 = mod1::Struct1 {
+        a: 3,
+        b: 4,
+    };
+
+    let mod1_struct2 = mod1::Struct2(5);
+
+    zzz(); // #break
+}
+
+#[inline(never)]
+fn zzz() {()}
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index acaec0b5199..19f706dc1d7 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -880,58 +880,62 @@ fn cleanup_debug_info_options(options: &Option<String>) -> Option<String> {
 
 fn check_debugger_output(debugger_run_result: &ProcRes, check_lines: &[String]) {
     let num_check_lines = check_lines.len();
-    if num_check_lines > 0 {
+
+    let mut check_line_index = 0;
+    for line in debugger_run_result.stdout.lines() {
+        if check_line_index >= num_check_lines {
+            break;
+        }
+
+        if check_single_line(line, &(check_lines[check_line_index])[..]) {
+            check_line_index += 1;
+        }
+    }
+    if check_line_index != num_check_lines && num_check_lines > 0 {
+        fatal_proc_rec(None, &format!("line not found in debugger output: {}",
+                                check_lines[check_line_index]),
+                      debugger_run_result);
+    }
+
+    fn check_single_line(line: &str, check_line: &str) -> bool {
         // Allow check lines to leave parts unspecified (e.g., uninitialized
-        // bits in the wrong case of an enum) with the notation "[...]".
-        let check_fragments: Vec<Vec<String>> =
-            check_lines.iter().map(|s| {
-                s
-                 .trim()
-                 .split("[...]")
-                 .map(str::to_owned)
-                 .collect()
-            }).collect();
-        // check if each line in props.check_lines appears in the
-        // output (in order)
-        let mut i = 0;
-        for line in debugger_run_result.stdout.lines() {
-            let mut rest = line.trim();
-            let mut first = true;
-            let mut failed = false;
-            for frag in &check_fragments[i] {
-                let found = if first {
-                    if rest.starts_with(frag) {
-                        Some(0)
-                    } else {
-                        None
-                    }
-                } else {
-                    rest.find(frag)
-                };
-                match found {
-                    None => {
-                        failed = true;
-                        break;
-                    }
-                    Some(i) => {
-                        rest = &rest[(i + frag.len())..];
-                    }
-                }
-                first = false;
-            }
-            if !failed && rest.is_empty() {
-                i += 1;
+        // bits in the  wrong case of an enum) with the notation "[...]".
+        let line = line.trim();
+        let check_line = check_line.trim();
+        let can_start_anywhere = check_line.starts_with("[...]");
+        let can_end_anywhere = check_line.ends_with("[...]");
+
+        let check_fragments: Vec<&str> = check_line.split("[...]")
+                                                   .filter(|frag| !frag.is_empty())
+                                                   .collect();
+        if check_fragments.is_empty() {
+            return true;
+        }
+
+        let (mut rest, first_fragment) = if can_start_anywhere {
+            match line.find(check_fragments[0]) {
+                Some(pos) => (&line[pos + check_fragments[0].len() ..], 1),
+                None => return false
             }
-            if i == num_check_lines {
-                // all lines checked
-                break;
+        } else {
+            (line, 0)
+        };
+
+        for fragment_index in first_fragment .. check_fragments.len() {
+            let current_fragment = check_fragments[fragment_index];
+            match rest.find(current_fragment) {
+                Some(pos) => {
+                    rest = &rest[pos + current_fragment.len() .. ];
+                }
+                None => return false
             }
         }
-        if i != num_check_lines {
-            fatal_proc_rec(None, &format!("line not found in debugger output: {}",
-                                    check_lines.get(i).unwrap()),
-                          debugger_run_result);
+
+        if !can_end_anywhere && !rest.is_empty() {
+            return false;
         }
+
+        return true;
     }
 }