1
Fork 0

Stabilize #[track_caller].

Does not yet make its constness stable, though. Use of
`Location::caller` in const contexts is still gated by
`#![feature(const_caller_location)]`.
This commit is contained in:
Adam Perry 2020-05-21 16:43:39 -07:00
parent d462551a86
commit f07d10db7c
38 changed files with 36 additions and 99 deletions

View file

@ -1,5 +0,0 @@
# `track_caller`
The tracking issue for this feature is: [#47809](https://github.com/rust-lang/rust/issues/47809).
------------------------

View file

@ -118,7 +118,7 @@
#![feature(staged_api)] #![feature(staged_api)]
#![feature(std_internals)] #![feature(std_internals)]
#![feature(stmt_expr_attributes)] #![feature(stmt_expr_attributes)]
#![feature(track_caller)] #![cfg_attr(bootstrap, feature(track_caller))]
#![feature(transparent_unions)] #![feature(transparent_unions)]
#![feature(unboxed_closures)] #![feature(unboxed_closures)]
#![feature(unsized_locals)] #![feature(unsized_locals)]

View file

@ -1,6 +1,6 @@
#[doc(include = "panic.md")] #[doc(include = "panic.md")]
#[macro_export] #[macro_export]
#[allow_internal_unstable(core_panic, track_caller)] #[allow_internal_unstable(core_panic, const_caller_location)]
#[stable(feature = "core", since = "1.6.0")] #[stable(feature = "core", since = "1.6.0")]
macro_rules! panic { macro_rules! panic {
() => ( () => (

View file

@ -190,7 +190,6 @@ impl<'a> Location<'a> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(track_caller)]
/// use core::panic::Location; /// use core::panic::Location;
/// ///
/// /// Returns the [`Location`] at which it is called. /// /// Returns the [`Location`] at which it is called.
@ -206,7 +205,7 @@ impl<'a> Location<'a> {
/// ///
/// let fixed_location = get_just_one_location(); /// let fixed_location = get_just_one_location();
/// assert_eq!(fixed_location.file(), file!()); /// assert_eq!(fixed_location.file(), file!());
/// assert_eq!(fixed_location.line(), 15); /// assert_eq!(fixed_location.line(), 14);
/// assert_eq!(fixed_location.column(), 5); /// assert_eq!(fixed_location.column(), 5);
/// ///
/// // running the same untracked function in a different location gives us the same result /// // running the same untracked function in a different location gives us the same result
@ -217,7 +216,7 @@ impl<'a> Location<'a> {
/// ///
/// let this_location = get_caller_location(); /// let this_location = get_caller_location();
/// assert_eq!(this_location.file(), file!()); /// assert_eq!(this_location.file(), file!());
/// assert_eq!(this_location.line(), 29); /// assert_eq!(this_location.line(), 28);
/// assert_eq!(this_location.column(), 21); /// assert_eq!(this_location.column(), 21);
/// ///
/// // running the tracked function in a different location produces a different value /// // running the tracked function in a different location produces a different value
@ -226,13 +225,8 @@ impl<'a> Location<'a> {
/// assert_ne!(this_location.line(), another_location.line()); /// assert_ne!(this_location.line(), another_location.line());
/// assert_ne!(this_location.column(), another_location.column()); /// assert_ne!(this_location.column(), another_location.column());
/// ``` /// ```
// FIXME: When stabilizing this method, please also update the documentation #[stable(feature = "track_caller", since = "1.46.0")]
// of `intrinsics::caller_location`. #[rustc_const_unstable(feature = "const_caller_location", issue = "47809")]
#[unstable(
feature = "track_caller",
reason = "uses #[track_caller] which is not yet stable",
issue = "47809"
)]
#[track_caller] #[track_caller]
pub const fn caller() -> &'static Location<'static> { pub const fn caller() -> &'static Location<'static> {
crate::intrinsics::caller_location() crate::intrinsics::caller_location()

View file

@ -3,8 +3,6 @@
Erroneous code example: Erroneous code example:
```compile_fail,E0736 ```compile_fail,E0736
#![feature(track_caller)]
#[naked] #[naked]
#[track_caller] #[track_caller]
fn foo() {} fn foo() {}

View file

@ -5,8 +5,6 @@ restrictions.
Erroneous code example: Erroneous code example:
```compile_fail,E0737 ```compile_fail,E0737
#![feature(track_caller)]
#[track_caller] #[track_caller]
extern "C" fn foo() {} extern "C" fn foo() {}
``` ```

View file

@ -3,7 +3,6 @@
Erroneous code example: Erroneous code example:
```compile_fail,E0739 ```compile_fail,E0739
#![feature(track_caller)]
#[track_caller] #[track_caller]
struct Bar { struct Bar {
a: u8, a: u8,

View file

@ -5,7 +5,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![feature(crate_visibility_modifier)] #![feature(crate_visibility_modifier)]
#![feature(nll)] #![feature(nll)]
#![feature(track_caller)] #![cfg_attr(bootstrap, feature(track_caller))]
pub use emitter::ColorConfig; pub use emitter::ColorConfig;

View file

@ -265,6 +265,9 @@ declare_features! (
(accepted, const_if_match, "1.45.0", Some(49146), None), (accepted, const_if_match, "1.45.0", Some(49146), None),
/// Allows the use of `loop` and `while` in constants. /// Allows the use of `loop` and `while` in constants.
(accepted, const_loop, "1.45.0", Some(52000), None), (accepted, const_loop, "1.45.0", Some(52000), None),
/// Allows `#[track_caller]` to be used which provides
/// accurate caller location reporting during panic (RFC 2091).
(accepted, track_caller, "1.46.0", Some(47809), None),
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// feature-group-end: accepted features // feature-group-end: accepted features

View file

@ -494,10 +494,6 @@ declare_features! (
/// Allows the use of raw-dylibs (RFC 2627). /// Allows the use of raw-dylibs (RFC 2627).
(active, raw_dylib, "1.40.0", Some(58713), None), (active, raw_dylib, "1.40.0", Some(58713), None),
/// Allows `#[track_caller]` to be used which provides
/// accurate caller location reporting during panic (RFC 2091).
(active, track_caller, "1.40.0", Some(47809), None),
/// Allows making `dyn Trait` well-formed even if `Trait` is not object safe. /// Allows making `dyn Trait` well-formed even if `Trait` is not object safe.
/// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and /// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and
/// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden. /// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden.

View file

@ -260,6 +260,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
ungated!(cold, Whitelisted, template!(Word)), ungated!(cold, Whitelisted, template!(Word)),
ungated!(no_builtins, Whitelisted, template!(Word)), ungated!(no_builtins, Whitelisted, template!(Word)),
ungated!(target_feature, Whitelisted, template!(List: r#"enable = "name""#)), ungated!(target_feature, Whitelisted, template!(List: r#"enable = "name""#)),
ungated!(track_caller, Whitelisted, template!(Word)),
gated!( gated!(
no_sanitize, Whitelisted, no_sanitize, Whitelisted,
template!(List: "address, memory, thread"), template!(List: "address, memory, thread"),
@ -333,7 +334,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
gated!(ffi_returns_twice, Whitelisted, template!(Word), experimental!(ffi_returns_twice)), gated!(ffi_returns_twice, Whitelisted, template!(Word), experimental!(ffi_returns_twice)),
gated!(ffi_pure, Whitelisted, template!(Word), experimental!(ffi_pure)), gated!(ffi_pure, Whitelisted, template!(Word), experimental!(ffi_pure)),
gated!(ffi_const, Whitelisted, template!(Word), experimental!(ffi_const)), gated!(ffi_const, Whitelisted, template!(Word), experimental!(ffi_const)),
gated!(track_caller, Whitelisted, template!(Word), experimental!(track_caller)),
gated!( gated!(
register_attr, CrateLevel, template!(List: "attr1, attr2, ..."), register_attr, CrateLevel, template!(List: "attr1, attr2, ..."),
experimental!(register_attr), experimental!(register_attr),

View file

@ -42,7 +42,7 @@
#![feature(or_patterns)] #![feature(or_patterns)]
#![feature(range_is_empty)] #![feature(range_is_empty)]
#![feature(min_specialization)] #![feature(min_specialization)]
#![feature(track_caller)] #![cfg_attr(bootstrap, feature(track_caller))]
#![feature(trusted_len)] #![feature(trusted_len)]
#![feature(stmt_expr_attributes)] #![feature(stmt_expr_attributes)]
#![feature(test)] #![feature(test)]

View file

@ -316,7 +316,7 @@
#![feature(toowned_clone_into)] #![feature(toowned_clone_into)]
#![feature(total_cmp)] #![feature(total_cmp)]
#![feature(trace_macros)] #![feature(trace_macros)]
#![feature(track_caller)] #![cfg_attr(bootstrap, feature(track_caller))]
#![feature(try_reserve)] #![feature(try_reserve)]
#![feature(unboxed_closures)] #![feature(unboxed_closures)]
#![feature(untagged_unions)] #![feature(untagged_unions)]

View file

@ -3,7 +3,7 @@
// only-linux // only-linux
// run-pass // run-pass
#![feature(asm, track_caller, thread_local)] #![feature(asm, thread_local)]
extern "C" fn f1() -> i32 { extern "C" fn f1() -> i32 {
111 111

View file

@ -1,5 +0,0 @@
#[track_caller]
fn f() {}
//~^^ ERROR the `#[track_caller]` attribute is an experimental feature
fn main() {}

View file

@ -1,12 +0,0 @@
error[E0658]: the `#[track_caller]` attribute is an experimental feature
--> $DIR/feature-gate-track_caller.rs:1:1
|
LL | #[track_caller]
| ^^^^^^^^^^^^^^^
|
= note: see issue #47809 <https://github.com/rust-lang/rust/issues/47809> for more information
= help: add `#![feature(track_caller)]` to the crate attributes to enable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.

View file

@ -1,5 +1,3 @@
#![feature(track_caller)]
fn main() { fn main() {
(0..) (0..)
.map( .map(

View file

@ -1,5 +1,5 @@
error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
--> $DIR/issue-68060.rs:6:13 --> $DIR/issue-68060.rs:4:13
| |
LL | #[target_feature(enable = "")] LL | #[target_feature(enable = "")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -11,13 +11,13 @@ LL | |_| (),
= help: add `#![feature(target_feature_11)]` to the crate attributes to enable = help: add `#![feature(target_feature_11)]` to the crate attributes to enable
error: the feature named `` is not valid for this target error: the feature named `` is not valid for this target
--> $DIR/issue-68060.rs:6:30 --> $DIR/issue-68060.rs:4:30
| |
LL | #[target_feature(enable = "")] LL | #[target_feature(enable = "")]
| ^^^^^^^^^^^ `` is not valid for this target | ^^^^^^^^^^^ `` is not valid for this target
error[E0737]: `#[track_caller]` requires Rust ABI error[E0737]: `#[track_caller]` requires Rust ABI
--> $DIR/issue-68060.rs:9:13 --> $DIR/issue-68060.rs:7:13
| |
LL | #[track_caller] LL | #[track_caller]
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^

View file

@ -9,7 +9,6 @@
// merged. // merged.
#![feature(test, stmt_expr_attributes)] #![feature(test, stmt_expr_attributes)]
#![feature(track_caller)]
#![deny(overflowing_literals)] #![deny(overflowing_literals)]
extern crate test; extern crate test;

View file

@ -1,7 +1,5 @@
// run-pass // run-pass
#![feature(track_caller)]
use std::panic::Location; use std::panic::Location;
struct Foo; struct Foo;

View file

@ -6,7 +6,7 @@
// run-pass // run-pass
// compile-flags: -Z unleash-the-miri-inside-of-you // compile-flags: -Z unleash-the-miri-inside-of-you
#![feature(core_intrinsics, const_caller_location, track_caller, const_fn)] #![feature(core_intrinsics, const_caller_location, const_fn)]
type L = &'static std::panic::Location<'static>; type L = &'static std::panic::Location<'static>;

View file

@ -1,7 +1,5 @@
// run-pass // run-pass
#![feature(track_caller)]
#[inline(never)] #[inline(never)]
#[track_caller] #[track_caller]
fn codegen_caller_loc() -> &'static core::panic::Location<'static> { fn codegen_caller_loc() -> &'static core::panic::Location<'static> {
@ -15,13 +13,13 @@ macro_rules! caller_location_from_macro {
fn main() { fn main() {
let loc = codegen_caller_loc(); let loc = codegen_caller_loc();
assert_eq!(loc.file(), file!()); assert_eq!(loc.file(), file!());
assert_eq!(loc.line(), 16); assert_eq!(loc.line(), 14);
assert_eq!(loc.column(), 15); assert_eq!(loc.column(), 15);
// `Location::caller()` in a macro should behave similarly to `file!` and `line!`, // `Location::caller()` in a macro should behave similarly to `file!` and `line!`,
// i.e. point to where the macro was invoked, instead of the macro itself. // i.e. point to where the macro was invoked, instead of the macro itself.
let loc2 = caller_location_from_macro!(); let loc2 = caller_location_from_macro!();
assert_eq!(loc2.file(), file!()); assert_eq!(loc2.file(), file!());
assert_eq!(loc2.line(), 23); assert_eq!(loc2.line(), 21);
assert_eq!(loc2.column(), 16); assert_eq!(loc2.column(), 16);
} }

View file

@ -1,6 +1,6 @@
// run-pass // run-pass
#![feature(const_fn, track_caller)] #![feature(const_caller_location, const_fn)]
use std::panic::Location; use std::panic::Location;

View file

@ -6,8 +6,6 @@
//! we don't inspect the location returned -- it would be difficult to distinguish between the //! we don't inspect the location returned -- it would be difficult to distinguish between the
//! explicit panic and a failed assertion. That it compiles and runs is enough for this one. //! explicit panic and a failed assertion. That it compiles and runs is enough for this one.
#![feature(track_caller)]
#[track_caller] #[track_caller]
fn doesnt_return() -> ! { fn doesnt_return() -> ! {
let _location = core::panic::Location::caller(); let _location = core::panic::Location::caller();

View file

@ -1,5 +1,3 @@
#![feature(track_caller)]
#[track_caller(1)] #[track_caller(1)]
fn f() {} fn f() {}
//~^^ ERROR malformed `track_caller` attribute input //~^^ ERROR malformed `track_caller` attribute input

View file

@ -1,5 +1,5 @@
error: malformed `track_caller` attribute input error: malformed `track_caller` attribute input
--> $DIR/error-odd-syntax.rs:3:1 --> $DIR/error-odd-syntax.rs:1:1
| |
LL | #[track_caller(1)] LL | #[track_caller(1)]
| ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[track_caller]` | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[track_caller]`

View file

@ -1,5 +1,3 @@
#![feature(track_caller)]
#[track_caller] #[track_caller]
extern "C" fn f() {} extern "C" fn f() {}
//~^^ ERROR `#[track_caller]` requires Rust ABI //~^^ ERROR `#[track_caller]` requires Rust ABI

View file

@ -1,11 +1,11 @@
error[E0737]: `#[track_caller]` requires Rust ABI error[E0737]: `#[track_caller]` requires Rust ABI
--> $DIR/error-with-invalid-abi.rs:3:1 --> $DIR/error-with-invalid-abi.rs:1:1
| |
LL | #[track_caller] LL | #[track_caller]
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
error[E0737]: `#[track_caller]` requires Rust ABI error[E0737]: `#[track_caller]` requires Rust ABI
--> $DIR/error-with-invalid-abi.rs:8:5 --> $DIR/error-with-invalid-abi.rs:6:5
| |
LL | #[track_caller] LL | #[track_caller]
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^

View file

@ -1,4 +1,4 @@
#![feature(naked_functions, track_caller)] #![feature(naked_functions)]
#[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]` #[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]`
#[naked] #[naked]

View file

@ -1,7 +1,5 @@
// run-pass // run-pass
#![feature(track_caller)]
macro_rules! caller_location_from_macro { macro_rules! caller_location_from_macro {
() => (core::panic::Location::caller()); () => (core::panic::Location::caller());
} }
@ -9,13 +7,13 @@ macro_rules! caller_location_from_macro {
fn main() { fn main() {
let loc = core::panic::Location::caller(); let loc = core::panic::Location::caller();
assert_eq!(loc.file(), file!()); assert_eq!(loc.file(), file!());
assert_eq!(loc.line(), 10); assert_eq!(loc.line(), 8);
assert_eq!(loc.column(), 15); assert_eq!(loc.column(), 15);
// `Location::caller()` in a macro should behave similarly to `file!` and `line!`, // `Location::caller()` in a macro should behave similarly to `file!` and `line!`,
// i.e. point to where the macro was invoked, instead of the macro itself. // i.e. point to where the macro was invoked, instead of the macro itself.
let loc2 = caller_location_from_macro!(); let loc2 = caller_location_from_macro!();
assert_eq!(loc2.file(), file!()); assert_eq!(loc2.file(), file!());
assert_eq!(loc2.line(), 17); assert_eq!(loc2.line(), 15);
assert_eq!(loc2.column(), 16); assert_eq!(loc2.column(), 16);
} }

View file

@ -1,5 +1,3 @@
#![feature(track_caller)]
#[track_caller] #[track_caller]
struct S; struct S;
//~^^ ERROR attribute should be applied to function //~^^ ERROR attribute should be applied to function

View file

@ -1,5 +1,5 @@
error[E0739]: attribute should be applied to function error[E0739]: attribute should be applied to function
--> $DIR/only-for-fns.rs:3:1 --> $DIR/only-for-fns.rs:1:1
| |
LL | #[track_caller] LL | #[track_caller]
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^

View file

@ -1,6 +1,4 @@
// run-pass // run-pass
#![feature(track_caller)]
#[track_caller] #[track_caller]
fn f() {} fn f() {}

View file

@ -1,7 +1,5 @@
// run-pass // run-pass
#![feature(track_caller)]
use std::panic::Location; use std::panic::Location;
#[track_caller] #[track_caller]
@ -20,21 +18,21 @@ fn nested_tracked() -> &'static Location<'static> {
fn main() { fn main() {
let location = Location::caller(); let location = Location::caller();
assert_eq!(location.file(), file!()); assert_eq!(location.file(), file!());
assert_eq!(location.line(), 21); assert_eq!(location.line(), 19);
assert_eq!(location.column(), 20); assert_eq!(location.column(), 20);
let tracked = tracked(); let tracked = tracked();
assert_eq!(tracked.file(), file!()); assert_eq!(tracked.file(), file!());
assert_eq!(tracked.line(), 26); assert_eq!(tracked.line(), 24);
assert_eq!(tracked.column(), 19); assert_eq!(tracked.column(), 19);
let nested = nested_intrinsic(); let nested = nested_intrinsic();
assert_eq!(nested.file(), file!()); assert_eq!(nested.file(), file!());
assert_eq!(nested.line(), 13); assert_eq!(nested.line(), 11);
assert_eq!(nested.column(), 5); assert_eq!(nested.column(), 5);
let contained = nested_tracked(); let contained = nested_tracked();
assert_eq!(contained.file(), file!()); assert_eq!(contained.file(), file!());
assert_eq!(contained.line(), 17); assert_eq!(contained.line(), 15);
assert_eq!(contained.column(), 5); assert_eq!(contained.column(), 5);
} }

View file

@ -1,7 +1,5 @@
// run-pass // run-pass
#![feature(track_caller)]
use std::panic::Location; use std::panic::Location;
extern "Rust" { extern "Rust" {
@ -30,21 +28,21 @@ mod provides {
fn main() { fn main() {
let location = Location::caller(); let location = Location::caller();
assert_eq!(location.file(), file!()); assert_eq!(location.file(), file!());
assert_eq!(location.line(), 31); assert_eq!(location.line(), 29);
assert_eq!(location.column(), 20); assert_eq!(location.column(), 20);
let tracked = unsafe { rust_track_caller_ffi_test_tracked() }; let tracked = unsafe { rust_track_caller_ffi_test_tracked() };
assert_eq!(tracked.file(), file!()); assert_eq!(tracked.file(), file!());
assert_eq!(tracked.line(), 36); assert_eq!(tracked.line(), 34);
assert_eq!(tracked.column(), 28); assert_eq!(tracked.column(), 28);
let untracked = unsafe { rust_track_caller_ffi_test_untracked() }; let untracked = unsafe { rust_track_caller_ffi_test_untracked() };
assert_eq!(untracked.file(), file!()); assert_eq!(untracked.file(), file!());
assert_eq!(untracked.line(), 26); assert_eq!(untracked.line(), 24);
assert_eq!(untracked.column(), 9); assert_eq!(untracked.column(), 9);
let contained = rust_track_caller_ffi_test_nested_tracked(); let contained = rust_track_caller_ffi_test_nested_tracked();
assert_eq!(contained.file(), file!()); assert_eq!(contained.file(), file!());
assert_eq!(contained.line(), 14); assert_eq!(contained.line(), 12);
assert_eq!(contained.column(), 14); assert_eq!(contained.column(), 14);
} }

View file

@ -1,7 +1,5 @@
// run-pass // run-pass
#![feature(track_caller)]
fn pass_to_ptr_call<T>(f: fn(T), x: T) { fn pass_to_ptr_call<T>(f: fn(T), x: T) {
f(x); f(x);
} }

View file

@ -1,7 +1,5 @@
// run-pass // run-pass
#![feature(track_caller)]
fn ptr_call(f: fn()) { fn ptr_call(f: fn()) {
f(); f();
} }

View file

@ -1,7 +1,5 @@
// run-pass // run-pass
#![feature(track_caller)]
macro_rules! assert_expansion_site_is_tracked { macro_rules! assert_expansion_site_is_tracked {
() => {{ () => {{
let location = std::panic::Location::caller(); let location = std::panic::Location::caller();