Skip to content

Commit 18ce550

Browse files
authored
Rollup merge of #65037 - anp:track-caller, r=oli-obk
`#[track_caller]` feature gate (RFC 2091) RFC text: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md Tracking issue: #47809 I started with @ayosec's commit to add the feature gate with tests and rebased it onto current master. I fixed up some tidy lints and added a test.
2 parents 83adae8 + 9e301d1 commit 18ce550

24 files changed

+251
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# `track_caller`
2+
3+
The tracking issue for this feature is: [#47809](https://github.com/rust-lang/rust/issues/47809).
4+
5+
------------------------

src/librustc/error_codes.rs

+10
Original file line numberDiff line numberDiff line change
@@ -2234,6 +2234,15 @@ These attributes are meant to only be used by the standard library and are
22342234
rejected in your own crates.
22352235
"##,
22362236

2237+
E0736: r##"
2238+
#[track_caller] and #[naked] cannot be applied to the same function.
2239+
2240+
This is primarily due to ABI incompatibilities between the two attributes.
2241+
See [RFC 2091] for details on this and other limitations.
2242+
2243+
[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md
2244+
"##,
2245+
22372246
;
22382247
// E0006, // merged with E0005
22392248
// E0101, // replaced with E0282
@@ -2296,4 +2305,5 @@ rejected in your own crates.
22962305
E0726, // non-explicit (not `'_`) elided lifetime in unsupported position
22972306
E0727, // `async` generators are not yet supported
22982307
E0728, // `await` must be in an `async` function or block
2308+
E0735, // invalid track_caller application/syntax
22992309
}

src/librustc/hir/check_attr.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::ty::TyCtxt;
1111
use crate::ty::query::Providers;
1212

1313
use std::fmt::{self, Display};
14-
use syntax::symbol::sym;
14+
use syntax::{attr, symbol::sym};
1515
use syntax_pos::Span;
1616

1717
#[derive(Copy, Clone, PartialEq)]
@@ -103,6 +103,8 @@ impl CheckAttrVisitor<'tcx> {
103103
self.check_marker(attr, item, target)
104104
} else if attr.check_name(sym::target_feature) {
105105
self.check_target_feature(attr, item, target)
106+
} else if attr.check_name(sym::track_caller) {
107+
self.check_track_caller(attr, &item, target)
106108
} else {
107109
true
108110
};
@@ -135,6 +137,32 @@ impl CheckAttrVisitor<'tcx> {
135137
}
136138
}
137139

140+
/// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid.
141+
fn check_track_caller(&self, attr: &hir::Attribute, item: &hir::Item, target: Target) -> bool {
142+
if target != Target::Fn {
143+
struct_span_err!(
144+
self.tcx.sess,
145+
attr.span,
146+
E0735,
147+
"attribute should be applied to function"
148+
)
149+
.span_label(item.span, "not a function")
150+
.emit();
151+
false
152+
} else if attr::contains_name(&item.attrs, sym::naked) {
153+
struct_span_err!(
154+
self.tcx.sess,
155+
attr.span,
156+
E0736,
157+
"cannot use `#[track_caller]` with `#[naked]`",
158+
)
159+
.emit();
160+
false
161+
} else {
162+
true
163+
}
164+
}
165+
138166
/// Checks if the `#[non_exhaustive]` attribute on an `item` is valid. Returns `true` if valid.
139167
fn check_non_exhaustive(
140168
&self,

src/librustc/hir/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -2716,7 +2716,9 @@ bitflags! {
27162716
const USED = 1 << 9;
27172717
/// #[ffi_returns_twice], indicates that an extern function can return
27182718
/// multiple times
2719-
const FFI_RETURNS_TWICE = 1 << 10;
2719+
const FFI_RETURNS_TWICE = 1 << 10;
2720+
/// #[track_caller]: allow access to the caller location
2721+
const TRACK_CALLER = 1 << 11;
27202722
}
27212723
}
27222724

src/librustc_typeck/check/wfcheck.rs

+12
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,18 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: DefId) {
172172
_ => None
173173
};
174174
check_associated_item(tcx, trait_item.hir_id, trait_item.span, method_sig);
175+
176+
// Prohibits applying `#[track_caller]` to trait methods
177+
for attr in &trait_item.attrs {
178+
if attr.check_name(sym::track_caller) {
179+
struct_span_err!(
180+
tcx.sess,
181+
attr.span,
182+
E0738,
183+
"`#[track_caller]` is not supported for trait items yet."
184+
).emit();
185+
}
186+
}
175187
}
176188

177189
pub fn check_impl_item(tcx: TyCtxt<'_>, def_id: DefId) {

src/librustc_typeck/collect.rs

+10
Original file line numberDiff line numberDiff line change
@@ -2596,6 +2596,16 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
25962596
codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED;
25972597
} else if attr.check_name(sym::thread_local) {
25982598
codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL;
2599+
} else if attr.check_name(sym::track_caller) {
2600+
if tcx.fn_sig(id).abi() != abi::Abi::Rust {
2601+
struct_span_err!(
2602+
tcx.sess,
2603+
attr.span,
2604+
E0737,
2605+
"rust ABI is required to use `#[track_caller]`"
2606+
).emit();
2607+
}
2608+
codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER;
25992609
} else if attr.check_name(sym::export_name) {
26002610
if let Some(s) = attr.value_str() {
26012611
if s.as_str().contains("\0") {

src/librustc_typeck/error_codes.rs

+15
Original file line numberDiff line numberDiff line change
@@ -4907,6 +4907,21 @@ fn foo_recursive(n: usize) -> Pin<Box<dyn Future<Output = ()>>> {
49074907
The `Box<...>` ensures that the result is of known size,
49084908
and the pin is required to keep it in the same place in memory.
49094909
"##,
4910+
4911+
E0737: r##"
4912+
#[track_caller] requires functions to have the "Rust" ABI for passing caller
4913+
location. See [RFC 2091] for details on this and other restrictions.
4914+
4915+
[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md
4916+
"##,
4917+
4918+
E0738: r##"
4919+
#[track_caller] cannot be applied to trait methods. See [RFC 2091]
4920+
for details on this and other restrictions.
4921+
4922+
[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md
4923+
"##,
4924+
49104925
;
49114926
// E0035, merged into E0087/E0089
49124927
// E0036, merged into E0087/E0089

src/libsyntax/feature_gate/active.rs

+4
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,9 @@ declare_features! (
519519
/// Allows the use of or-patterns (e.g., `0 | 1`).
520520
(active, or_patterns, "1.38.0", Some(54883), None),
521521

522+
/// Enable accurate caller location reporting during panic (RFC 2091).
523+
(active, track_caller, "1.40.0", Some(47809), None),
524+
522525
// -------------------------------------------------------------------------
523526
// feature-group-end: actual feature gates
524527
// -------------------------------------------------------------------------
@@ -533,4 +536,5 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
533536
sym::const_generics,
534537
sym::or_patterns,
535538
sym::let_chains,
539+
sym::track_caller,
536540
];

src/libsyntax/feature_gate/builtin_attrs.rs

+1
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
307307
),
308308

309309
gated!(ffi_returns_twice, Whitelisted, template!(Word), experimental!(ffi_returns_twice)),
310+
gated!(track_caller, Whitelisted, template!(Word), experimental!(track_caller)),
310311

311312
// ==========================================================================
312313
// Internal attributes: Stability, deprecation, and unsafe:

src/libsyntax_pos/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,7 @@ symbols! {
671671
tool_attributes,
672672
tool_lints,
673673
trace_macros,
674+
track_caller,
674675
trait_alias,
675676
transmute,
676677
transparent,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#[track_caller]
2+
fn f() {}
3+
//~^^ ERROR the `#[track_caller]` attribute is an experimental feature
4+
5+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0658]: the `#[track_caller]` attribute is an experimental feature
2+
--> $DIR/feature-gate-track_caller.rs:1:1
3+
|
4+
LL | #[track_caller]
5+
| ^^^^^^^^^^^^^^^
6+
|
7+
= note: for more information, see https://github.com/rust-lang/rust/issues/47809
8+
= help: add `#![feature(track_caller)]` to the crate attributes to enable
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0658`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete
2+
3+
#[track_caller(1)]
4+
fn f() {}
5+
//~^^ ERROR malformed `track_caller` attribute input
6+
7+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error: malformed `track_caller` attribute input
2+
--> $DIR/error-odd-syntax.rs:3:1
3+
|
4+
LL | #[track_caller(1)]
5+
| ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[track_caller]`
6+
7+
warning: the feature `track_caller` is incomplete and may cause the compiler to crash
8+
--> $DIR/error-odd-syntax.rs:1:12
9+
|
10+
LL | #![feature(track_caller)]
11+
| ^^^^^^^^^^^^
12+
|
13+
= note: `#[warn(incomplete_features)]` on by default
14+
15+
error: aborting due to previous error
16+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete
2+
3+
#[track_caller]
4+
extern "C" fn f() {}
5+
//~^^ ERROR rust ABI is required to use `#[track_caller]`
6+
7+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
warning: the feature `track_caller` is incomplete and may cause the compiler to crash
2+
--> $DIR/error-with-invalid-abi.rs:1:12
3+
|
4+
LL | #![feature(track_caller)]
5+
| ^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(incomplete_features)]` on by default
8+
9+
error[E0737]: rust ABI is required to use `#[track_caller]`
10+
--> $DIR/error-with-invalid-abi.rs:3:1
11+
|
12+
LL | #[track_caller]
13+
| ^^^^^^^^^^^^^^^
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0737`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#![feature(naked_functions, track_caller)] //~ WARN the feature `track_caller` is incomplete
2+
3+
#[track_caller]
4+
#[naked]
5+
fn f() {}
6+
//~^^^ ERROR cannot use `#[track_caller]` with `#[naked]`
7+
8+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
warning: the feature `track_caller` is incomplete and may cause the compiler to crash
2+
--> $DIR/error-with-naked.rs:1:29
3+
|
4+
LL | #![feature(naked_functions, track_caller)]
5+
| ^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(incomplete_features)]` on by default
8+
9+
error[E0736]: cannot use `#[track_caller]` with `#[naked]`
10+
--> $DIR/error-with-naked.rs:3:1
11+
|
12+
LL | #[track_caller]
13+
| ^^^^^^^^^^^^^^^
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0736`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete
2+
3+
trait Trait {
4+
#[track_caller]
5+
fn unwrap(&self);
6+
//~^^ ERROR: `#[track_caller]` is not supported for trait items yet.
7+
}
8+
9+
impl Trait for u64 {
10+
fn unwrap(&self) {}
11+
}
12+
13+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
warning: the feature `track_caller` is incomplete and may cause the compiler to crash
2+
--> $DIR/error-with-trait-fns.rs:1:12
3+
|
4+
LL | #![feature(track_caller)]
5+
| ^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(incomplete_features)]` on by default
8+
9+
error[E0738]: `#[track_caller]` is not supported for trait items yet.
10+
--> $DIR/error-with-trait-fns.rs:4:5
11+
|
12+
LL | #[track_caller]
13+
| ^^^^^^^^^^^^^^^
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0738`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete
2+
3+
#[track_caller]
4+
struct S;
5+
//~^^ ERROR attribute should be applied to function
6+
7+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
warning: the feature `track_caller` is incomplete and may cause the compiler to crash
2+
--> $DIR/only-for-fns.rs:1:12
3+
|
4+
LL | #![feature(track_caller)]
5+
| ^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(incomplete_features)]` on by default
8+
9+
error[E0735]: attribute should be applied to function
10+
--> $DIR/only-for-fns.rs:3:1
11+
|
12+
LL | #[track_caller]
13+
| ^^^^^^^^^^^^^^^
14+
LL | struct S;
15+
| --------- not a function
16+
17+
error: aborting due to previous error
18+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// run-pass
2+
#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete
3+
4+
#[track_caller]
5+
fn f() {}
6+
7+
fn main() {
8+
f();
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
warning: the feature `track_caller` is incomplete and may cause the compiler to crash
2+
--> $DIR/pass.rs:2:12
3+
|
4+
LL | #![feature(track_caller)]
5+
| ^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(incomplete_features)]` on by default
8+

0 commit comments

Comments
 (0)