Skip to content

Commit

Permalink
Rollup merge of #65037 - anp:track-caller, r=oli-obk
Browse files Browse the repository at this point in the history
`#[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.
  • Loading branch information
Centril authored Oct 3, 2019
2 parents f7aa421 + 9e301d1 commit 6487d5f
Show file tree
Hide file tree
Showing 24 changed files with 251 additions and 2 deletions.
5 changes: 5 additions & 0 deletions src/doc/unstable-book/src/language-features/track-caller.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# `track_caller`

The tracking issue for this feature is: [#47809](https://github.com/rust-lang/rust/issues/47809).

------------------------
10 changes: 10 additions & 0 deletions src/librustc/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2234,6 +2234,15 @@ These attributes are meant to only be used by the standard library and are
rejected in your own crates.
"##,

E0736: r##"
#[track_caller] and #[naked] cannot be applied to the same function.
This is primarily due to ABI incompatibilities between the two attributes.
See [RFC 2091] for details on this and other limitations.
[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md
"##,

;
// E0006, // merged with E0005
// E0101, // replaced with E0282
Expand Down Expand Up @@ -2296,4 +2305,5 @@ rejected in your own crates.
E0726, // non-explicit (not `'_`) elided lifetime in unsupported position
E0727, // `async` generators are not yet supported
E0728, // `await` must be in an `async` function or block
E0735, // invalid track_caller application/syntax
}
30 changes: 29 additions & 1 deletion src/librustc/hir/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::ty::TyCtxt;
use crate::ty::query::Providers;

use std::fmt::{self, Display};
use syntax::symbol::sym;
use syntax::{attr, symbol::sym};
use syntax_pos::Span;

#[derive(Copy, Clone, PartialEq)]
Expand Down Expand Up @@ -103,6 +103,8 @@ impl CheckAttrVisitor<'tcx> {
self.check_marker(attr, item, target)
} else if attr.check_name(sym::target_feature) {
self.check_target_feature(attr, item, target)
} else if attr.check_name(sym::track_caller) {
self.check_track_caller(attr, &item, target)
} else {
true
};
Expand Down Expand Up @@ -135,6 +137,32 @@ impl CheckAttrVisitor<'tcx> {
}
}

/// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid.
fn check_track_caller(&self, attr: &hir::Attribute, item: &hir::Item, target: Target) -> bool {
if target != Target::Fn {
struct_span_err!(
self.tcx.sess,
attr.span,
E0735,
"attribute should be applied to function"
)
.span_label(item.span, "not a function")
.emit();
false
} else if attr::contains_name(&item.attrs, sym::naked) {
struct_span_err!(
self.tcx.sess,
attr.span,
E0736,
"cannot use `#[track_caller]` with `#[naked]`",
)
.emit();
false
} else {
true
}
}

/// Checks if the `#[non_exhaustive]` attribute on an `item` is valid. Returns `true` if valid.
fn check_non_exhaustive(
&self,
Expand Down
4 changes: 3 additions & 1 deletion src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2716,7 +2716,9 @@ bitflags! {
const USED = 1 << 9;
/// #[ffi_returns_twice], indicates that an extern function can return
/// multiple times
const FFI_RETURNS_TWICE = 1 << 10;
const FFI_RETURNS_TWICE = 1 << 10;
/// #[track_caller]: allow access to the caller location
const TRACK_CALLER = 1 << 11;
}
}

Expand Down
12 changes: 12 additions & 0 deletions src/librustc_typeck/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,18 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: DefId) {
_ => None
};
check_associated_item(tcx, trait_item.hir_id, trait_item.span, method_sig);

// Prohibits applying `#[track_caller]` to trait methods
for attr in &trait_item.attrs {
if attr.check_name(sym::track_caller) {
struct_span_err!(
tcx.sess,
attr.span,
E0738,
"`#[track_caller]` is not supported for trait items yet."
).emit();
}
}
}

pub fn check_impl_item(tcx: TyCtxt<'_>, def_id: DefId) {
Expand Down
10 changes: 10 additions & 0 deletions src/librustc_typeck/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2596,6 +2596,16 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED;
} else if attr.check_name(sym::thread_local) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL;
} else if attr.check_name(sym::track_caller) {
if tcx.fn_sig(id).abi() != abi::Abi::Rust {
struct_span_err!(
tcx.sess,
attr.span,
E0737,
"rust ABI is required to use `#[track_caller]`"
).emit();
}
codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER;
} else if attr.check_name(sym::export_name) {
if let Some(s) = attr.value_str() {
if s.as_str().contains("\0") {
Expand Down
15 changes: 15 additions & 0 deletions src/librustc_typeck/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4907,6 +4907,21 @@ fn foo_recursive(n: usize) -> Pin<Box<dyn Future<Output = ()>>> {
The `Box<...>` ensures that the result is of known size,
and the pin is required to keep it in the same place in memory.
"##,

E0737: r##"
#[track_caller] requires functions to have the "Rust" ABI for passing caller
location. See [RFC 2091] for details on this and other restrictions.
[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md
"##,

E0738: r##"
#[track_caller] cannot be applied to trait methods. See [RFC 2091]
for details on this and other restrictions.
[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md
"##,

;
// E0035, merged into E0087/E0089
// E0036, merged into E0087/E0089
Expand Down
4 changes: 4 additions & 0 deletions src/libsyntax/feature_gate/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,9 @@ declare_features! (
/// Allows the use of or-patterns (e.g., `0 | 1`).
(active, or_patterns, "1.38.0", Some(54883), None),

/// Enable accurate caller location reporting during panic (RFC 2091).
(active, track_caller, "1.40.0", Some(47809), None),

// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
Expand All @@ -533,4 +536,5 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
sym::const_generics,
sym::or_patterns,
sym::let_chains,
sym::track_caller,
];
1 change: 1 addition & 0 deletions src/libsyntax/feature_gate/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
),

gated!(ffi_returns_twice, Whitelisted, template!(Word), experimental!(ffi_returns_twice)),
gated!(track_caller, Whitelisted, template!(Word), experimental!(track_caller)),

// ==========================================================================
// Internal attributes: Stability, deprecation, and unsafe:
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax_pos/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@ symbols! {
tool_attributes,
tool_lints,
trace_macros,
track_caller,
trait_alias,
transmute,
transparent,
Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/feature-gates/feature-gate-track_caller.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#[track_caller]
fn f() {}
//~^^ ERROR the `#[track_caller]` attribute is an experimental feature

fn main() {}
12 changes: 12 additions & 0 deletions src/test/ui/feature-gates/feature-gate-track_caller.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0658]: the `#[track_caller]` attribute is an experimental feature
--> $DIR/feature-gate-track_caller.rs:1:1
|
LL | #[track_caller]
| ^^^^^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/47809
= 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`.
7 changes: 7 additions & 0 deletions src/test/ui/rfc-2091-track-caller/error-odd-syntax.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete

#[track_caller(1)]
fn f() {}
//~^^ ERROR malformed `track_caller` attribute input

fn main() {}
16 changes: 16 additions & 0 deletions src/test/ui/rfc-2091-track-caller/error-odd-syntax.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
error: malformed `track_caller` attribute input
--> $DIR/error-odd-syntax.rs:3:1
|
LL | #[track_caller(1)]
| ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[track_caller]`

warning: the feature `track_caller` is incomplete and may cause the compiler to crash
--> $DIR/error-odd-syntax.rs:1:12
|
LL | #![feature(track_caller)]
| ^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

error: aborting due to previous error

7 changes: 7 additions & 0 deletions src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete

#[track_caller]
extern "C" fn f() {}
//~^^ ERROR rust ABI is required to use `#[track_caller]`

fn main() {}
17 changes: 17 additions & 0 deletions src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
warning: the feature `track_caller` is incomplete and may cause the compiler to crash
--> $DIR/error-with-invalid-abi.rs:1:12
|
LL | #![feature(track_caller)]
| ^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

error[E0737]: rust ABI is required to use `#[track_caller]`
--> $DIR/error-with-invalid-abi.rs:3:1
|
LL | #[track_caller]
| ^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0737`.
8 changes: 8 additions & 0 deletions src/test/ui/rfc-2091-track-caller/error-with-naked.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#![feature(naked_functions, track_caller)] //~ WARN the feature `track_caller` is incomplete

#[track_caller]
#[naked]
fn f() {}
//~^^^ ERROR cannot use `#[track_caller]` with `#[naked]`

fn main() {}
17 changes: 17 additions & 0 deletions src/test/ui/rfc-2091-track-caller/error-with-naked.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
warning: the feature `track_caller` is incomplete and may cause the compiler to crash
--> $DIR/error-with-naked.rs:1:29
|
LL | #![feature(naked_functions, track_caller)]
| ^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

error[E0736]: cannot use `#[track_caller]` with `#[naked]`
--> $DIR/error-with-naked.rs:3:1
|
LL | #[track_caller]
| ^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0736`.
13 changes: 13 additions & 0 deletions src/test/ui/rfc-2091-track-caller/error-with-trait-fns.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete

trait Trait {
#[track_caller]
fn unwrap(&self);
//~^^ ERROR: `#[track_caller]` is not supported for trait items yet.
}

impl Trait for u64 {
fn unwrap(&self) {}
}

fn main() {}
17 changes: 17 additions & 0 deletions src/test/ui/rfc-2091-track-caller/error-with-trait-fns.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
warning: the feature `track_caller` is incomplete and may cause the compiler to crash
--> $DIR/error-with-trait-fns.rs:1:12
|
LL | #![feature(track_caller)]
| ^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

error[E0738]: `#[track_caller]` is not supported for trait items yet.
--> $DIR/error-with-trait-fns.rs:4:5
|
LL | #[track_caller]
| ^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0738`.
7 changes: 7 additions & 0 deletions src/test/ui/rfc-2091-track-caller/only-for-fns.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete

#[track_caller]
struct S;
//~^^ ERROR attribute should be applied to function

fn main() {}
18 changes: 18 additions & 0 deletions src/test/ui/rfc-2091-track-caller/only-for-fns.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
warning: the feature `track_caller` is incomplete and may cause the compiler to crash
--> $DIR/only-for-fns.rs:1:12
|
LL | #![feature(track_caller)]
| ^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

error[E0735]: attribute should be applied to function
--> $DIR/only-for-fns.rs:3:1
|
LL | #[track_caller]
| ^^^^^^^^^^^^^^^
LL | struct S;
| --------- not a function

error: aborting due to previous error

9 changes: 9 additions & 0 deletions src/test/ui/rfc-2091-track-caller/pass.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// run-pass
#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete

#[track_caller]
fn f() {}

fn main() {
f();
}
8 changes: 8 additions & 0 deletions src/test/ui/rfc-2091-track-caller/pass.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
warning: the feature `track_caller` is incomplete and may cause the compiler to crash
--> $DIR/pass.rs:2:12
|
LL | #![feature(track_caller)]
| ^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

0 comments on commit 6487d5f

Please sign in to comment.