Panic position is not the function call position

fn main() {
    let mut a = 0u8;
    let mut c = || {
        a += 1;
        if a == 3 {
            panic!()
        }
    };
    c();
    c();
    c()
}

The result is:
thread 'main' panicked at src/main.rs:6:13
But I think it should say it panicked at the 11th line, i.e., the 3rd c() function call.

Well, it doesn't. At least, not in general. It reports the location based on where the panic starts, not at an arbitrary depth above that. If you want to see more than the immediate parent of the panic, you can run your program with RUST_BACKTRACE=1 in the environment variables, and check the call stack.

If you want the c function specifically to be skipped when reporting panic location, you need to change the code a bit.

fn main() {
    let mut a = 0u8;
    c(&mut a);
    c(&mut a);
    c(&mut a);
}

#[track_caller]
fn c(a: &mut u8) {
    *a += 1;
    if *a == 3 {
        panic!()
    }
}

#[track_caller] causes the tagged function to be ignored when determining "where" a panic started. Note that this doesn't work on closures (at least, not yet), so c has to be a named function.

4 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.