From d4aeff711ec748c0316d9a44db13e1540f01ec5e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?=
 <jieyouxu@outlook.com>
Date: Sun, 31 Mar 2024 02:59:34 +0100
Subject: [PATCH] Port over backtrace's `line-tables-only` test to a ui test

---
 .../auxiliary/line-tables-only-helper.rs      | 22 +++++++++
 .../debuginfo/backtrace-line-tables-only.rs   | 49 +++++++++++++++++++
 2 files changed, 71 insertions(+)
 create mode 100644 tests/ui/debuginfo/auxiliary/line-tables-only-helper.rs
 create mode 100644 tests/ui/debuginfo/backtrace-line-tables-only.rs

diff --git a/tests/ui/debuginfo/auxiliary/line-tables-only-helper.rs b/tests/ui/debuginfo/auxiliary/line-tables-only-helper.rs
new file mode 100644
index 00000000000..65da2c3f5c7
--- /dev/null
+++ b/tests/ui/debuginfo/auxiliary/line-tables-only-helper.rs
@@ -0,0 +1,22 @@
+//@ compile-flags: -Cstrip=none -Cdebuginfo=line-tables-only
+
+#[no_mangle]
+pub fn baz<F>(mut cb: F, data: u32) where F: FnMut(u32) {
+    cb(data);
+}
+
+#[no_mangle]
+pub fn bar<F>(cb: F, data: u32) where F: FnMut(u32) {
+    baz(cb, data);
+}
+
+#[no_mangle]
+pub fn foo<F>(cb: F, data: u32) where F: FnMut(u32) {
+    bar(cb, data);
+}
+
+pub fn capture_backtrace() -> std::backtrace::Backtrace {
+    let mut bt = None;
+    foo(|_| bt = Some(std::backtrace::Backtrace::capture()), 42);
+    bt.unwrap()
+}
diff --git a/tests/ui/debuginfo/backtrace-line-tables-only.rs b/tests/ui/debuginfo/backtrace-line-tables-only.rs
new file mode 100644
index 00000000000..044f59e483a
--- /dev/null
+++ b/tests/ui/debuginfo/backtrace-line-tables-only.rs
@@ -0,0 +1,49 @@
+// Test that when debug info only includes line tables that backtrace is still generated
+// successfully.
+// Original test:
+// <https://github.com/rust-lang/backtrace-rs/tree/6fa4b85b9962c3e1be8c2e5cc605cd078134152b/crates/line-tables-only>.
+// Part of <https://github.com/rust-lang/rust/issues/122899> porting some backtrace tests to rustc.
+// This test diverges from the original test in that it now uses a Rust library auxiliary because
+// rustc now has `-Cdebuginfo=line-tables-only`.
+// ignore-tidy-linelength
+//@ run-pass
+//@ compile-flags: -Cstrip=none -Cdebuginfo=line-tables-only
+//@ ignore-android FIXME #17520
+//@ ignore-fuchsia Backtraces not symbolized
+//@ needs-unwind
+//@ aux-build: line-tables-only-helper.rs
+
+#![feature(backtrace_frames)]
+
+extern crate line_tables_only_helper;
+
+use std::backtrace::Backtrace;
+
+fn assert_contains(
+    backtrace: &Backtrace,
+    expected_name: &str,
+    expected_file: &str,
+    expected_line: u32,
+) {
+    // FIXME(jieyouxu): fix this ugly fragile test when `BacktraceFrame` has accessors like...
+    // `symbols()`.
+    let backtrace = format!("{:#?}", backtrace);
+    eprintln!("{}", backtrace);
+    assert!(backtrace.contains(expected_name), "backtrace does not contain expected name {}", expected_name);
+    assert!(backtrace.contains(expected_file), "backtrace does not contain expected file {}", expected_file);
+    assert!(backtrace.contains(&expected_line.to_string()), "backtrace does not contain expected line {}", expected_line);
+}
+
+fn main() {
+    std::env::set_var("RUST_BACKTRACE", "1");
+    let backtrace = line_tables_only_helper::capture_backtrace();
+
+    // FIXME(jieyouxu): for some forsaken reason on i686-msvc `foo` doesn't have an entry in the
+    // line tables?
+    #[cfg(not(all(target_pointer_width = "32", target_env = "msvc")))]
+    {
+        assert_contains(&backtrace, "foo", "line-tables-only-helper.rs", 5);
+    }
+    assert_contains(&backtrace, "bar", "line-tables-only-helper.rs", 10);
+    assert_contains(&backtrace, "baz", "line-tables-only-helper.rs", 15);
+}