From 2e9d573d3f6bc9808e01cef914084fac15f42cc2 Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Sat, 4 Jan 2020 19:30:44 -0800 Subject: [PATCH 1/4] Option's panics are all #[track_caller]. Also includes a simple test with a custom panic hook to ensure we don't regress. --- src/libcore/option.rs | 6 ++++ .../std-panic-locations.rs | 29 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 src/test/ui/rfc-2091-track-caller/std-panic-locations.rs diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 2066a484dac..fb534586fc6 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -341,6 +341,7 @@ impl Option { /// x.expect("the world is ending"); // panics with `the world is ending` /// ``` #[inline] + #[track_caller] #[stable(feature = "rust1", since = "1.0.0")] pub fn expect(self, msg: &str) -> T { match self { @@ -374,6 +375,7 @@ impl Option { /// assert_eq!(x.unwrap(), "air"); // fails /// ``` #[inline] + #[track_caller] #[stable(feature = "rust1", since = "1.0.0")] pub fn unwrap(self) -> T { match self { @@ -1015,6 +1017,7 @@ impl Option { /// } /// ``` #[inline] + #[track_caller] #[unstable(feature = "option_expect_none", reason = "newly added", issue = "62633")] pub fn expect_none(self, msg: &str) { if let Some(val) = self { @@ -1057,6 +1060,7 @@ impl Option { /// } /// ``` #[inline] + #[track_caller] #[unstable(feature = "option_unwrap_none", reason = "newly added", issue = "62633")] pub fn unwrap_none(self) { if let Some(val) = self { @@ -1184,6 +1188,7 @@ impl Option> { // This is a separate function to reduce the code size of .expect() itself. #[inline(never)] #[cold] +#[track_caller] fn expect_failed(msg: &str) -> ! { panic!("{}", msg) } @@ -1191,6 +1196,7 @@ fn expect_failed(msg: &str) -> ! { // This is a separate function to reduce the code size of .expect_none() itself. #[inline(never)] #[cold] +#[track_caller] fn expect_none_failed(msg: &str, value: &dyn fmt::Debug) -> ! { panic!("{}: {:?}", msg, value) } diff --git a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs new file mode 100644 index 00000000000..96620d6440f --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs @@ -0,0 +1,29 @@ +// run-pass + +#![feature(option_expect_none, option_unwrap_none)] + +//! Test that panic locations for `#[track_caller]` functions in std have the correct +//! location reported. + +fn main() { + // inspect the `PanicInfo` we receive to ensure the right file is the source + std::panic::set_hook(Box::new(|info| { + let actual = info.location().unwrap(); + if actual.file() != file!(){ + eprintln!("expected a location in the test file, found {:?}", actual); + panic!(); + } + })); + + fn assert_panicked(f: impl FnOnce() + std::panic::UnwindSafe) { + std::panic::catch_unwind(f).unwrap_err(); + } + + let nope: Option<()> = None; + assert_panicked(|| nope.unwrap()); + assert_panicked(|| nope.expect("")); + + let yep: Option<()> = Some(()); + assert_panicked(|| yep.unwrap_none()); + assert_panicked(|| yep.expect_none("")); +} From 7a6af7eb0ef685c2dfd907f7e76a876174c9f665 Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Sat, 4 Jan 2020 19:42:21 -0800 Subject: [PATCH 2/4] Result's panics have `#[track_caller]`. --- src/libcore/result.rs | 5 +++++ src/test/ui/rfc-2091-track-caller/std-panic-locations.rs | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 5cfc81097dd..b39abf91785 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -957,6 +957,7 @@ impl Result { /// x.unwrap(); // panics with `emergency failure` /// ``` #[inline] + #[track_caller] #[stable(feature = "rust1", since = "1.0.0")] pub fn unwrap(self) -> T { match self { @@ -984,6 +985,7 @@ impl Result { /// x.expect("Testing expect"); // panics with `Testing expect: emergency failure` /// ``` #[inline] + #[track_caller] #[stable(feature = "result_expect", since = "1.4.0")] pub fn expect(self, msg: &str) -> T { match self { @@ -1017,6 +1019,7 @@ impl Result { /// assert_eq!(x.unwrap_err(), "emergency failure"); /// ``` #[inline] + #[track_caller] #[stable(feature = "rust1", since = "1.0.0")] pub fn unwrap_err(self) -> E { match self { @@ -1044,6 +1047,7 @@ impl Result { /// x.expect_err("Testing expect_err"); // panics with `Testing expect_err: 10` /// ``` #[inline] + #[track_caller] #[stable(feature = "result_expect_err", since = "1.17.0")] pub fn expect_err(self, msg: &str) -> E { match self { @@ -1188,6 +1192,7 @@ impl Result, E> { // This is a separate function to reduce the code size of the methods #[inline(never)] #[cold] +#[track_caller] fn unwrap_failed(msg: &str, error: &dyn fmt::Debug) -> ! { panic!("{}: {:?}", msg, error) } diff --git a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs index 96620d6440f..c65027d9cac 100644 --- a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs +++ b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs @@ -26,4 +26,12 @@ fn main() { let yep: Option<()> = Some(()); assert_panicked(|| yep.unwrap_none()); assert_panicked(|| yep.expect_none("")); + + let oops: Result<(), ()> = Err(()); + assert_panicked(|| oops.unwrap()); + assert_panicked(|| oops.expect("")); + + let fine: Result<(), ()> = Ok(()); + assert_panicked(|| fine.unwrap_err()); + assert_panicked(|| fine.expect_err("")); } From b97ee0f07aca5a05bea8074d0cd1ecd73e54d1b7 Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Sat, 4 Jan 2020 22:54:09 -0800 Subject: [PATCH 3/4] Fix typo Co-Authored-By: lzutao --- src/test/ui/rfc-2091-track-caller/std-panic-locations.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs index c65027d9cac..0e622af815c 100644 --- a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs +++ b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs @@ -9,7 +9,7 @@ fn main() { // inspect the `PanicInfo` we receive to ensure the right file is the source std::panic::set_hook(Box::new(|info| { let actual = info.location().unwrap(); - if actual.file() != file!(){ + if actual.file() != file!() { eprintln!("expected a location in the test file, found {:?}", actual); panic!(); } From 3acd34659453a92fe28308105a7b95230215e380 Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Tue, 7 Jan 2020 07:22:49 -0800 Subject: [PATCH 4/4] Skip caller location test in wasm32. --- src/test/ui/rfc-2091-track-caller/std-panic-locations.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs index 0e622af815c..be13076b8af 100644 --- a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs +++ b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs @@ -1,4 +1,5 @@ // run-pass +// ignore-wasm32-bare compiled with panic=abort by default #![feature(option_expect_none, option_unwrap_none)]