Rust: #[track_caller] functions don't track location when called from an inlined function

Created on 25 Jun 2020  路  3Comments  路  Source: rust-lang/rust

To reproduce

cargo new --bin main
cargo new --lib lib

cat <<END >lib/src/lib.rs
#[inline(always)]
pub fn f() {
    assert!(false)
}
END

echo "lib = { path = \"../lib\" }" >>main/Cargo.toml

cat <<END >main/src/main.rs
fn main() {
    lib::f();
}
END

cd main
cargo run

Expected result

     Running `target/debug/main`
thread 'main' panicked at 'assertion failed: false', /tmp/lib/src/lib.rs:3:5

Actual result

     Running `target/debug/main`
thread 'main' panicked at 'assertion failed: false', /rustc/ff5b446d2fdbd898bc97a751f2f72858de185cf1/src/libstd/macros.rs:13:23

Backtrace is also not helpful:

$ RUST_BACKTRACE=1 cargo run
...
  11: std::panicking::begin_panic
             at /rustc/ff5b446d2fdbd898bc97a751f2f72858de185cf1/src/libstd/panicking.rs:403
  12: lib::f
             at /rustc/ff5b446d2fdbd898bc97a751f2f72858de185cf1/src/libstd/macros.rs:13
  13: main::main
             at src/main.rs:2
...

Version info

This happens both on Windows and on Linux.

$ cargo version --verbose
cargo 1.46.0-nightly (089cbb80b 2020-06-15)
release: 1.46.0
commit-hash: 089cbb80b73ba242efdcf5430e89f63fa3b5328d
commit-date: 2020-06-15

$ rustc --version --verbose
rustc 1.46.0-nightly (ff5b446d2 2020-06-23)
binary: rustc
commit-hash: ff5b446d2fdbd898bc97a751f2f72858de185cf1
commit-date: 2020-06-23
host: x86_64-unknown-linux-gnu
release: 1.46.0-nightly
LLVM version: 10.0
C-bug F-track_caller T-compiler

Most helpful comment

As @nagisa said, the location used by panic! will never point into main, since #[track_caller] and #[inline] are orthogonal.

However, reporting a location in libstd is definitely a bug. It will be fixed by https://github.com/rust-lang/rust/pull/72121 (see #70963). The correct location should be inside f().

All 3 comments

i鈥檓 not sure it is a bug. Your reproducer does not contain a #[track_caller].

#[inline] attributes are specified to be an optimisation hint and by definition of optimisation implies that there must not be any user-observable difference regardless of whether the optimisation is applied or not.

#[track_caller] is, on the other hand, a semantic-altering annotation and therefore can鈥檛 be implied by #[inline] hints.

As @nagisa said, the location used by panic! will never point into main, since #[track_caller] and #[inline] are orthogonal.

However, reporting a location in libstd is definitely a bug. It will be fixed by https://github.com/rust-lang/rust/pull/72121 (see #70963). The correct location should be inside f().

72121 has landed and this indeed appears to be fixed:

     Created binary (application) `main` package
     Created library `lib` package
   Compiling lib v0.1.0 (/tmp/lib)
   Compiling main v0.1.0 (/tmp/main)
    Finished dev [unoptimized + debuginfo] target(s) in 0.33s
     Running `target/debug/main`
thread 'main' panicked at 'assertion failed: false', /tmp/lib/src/lib.rs:3:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Was this page helpful?
0 / 5 - 0 ratings