Rollup merge of #65037 - anp:track-caller, r=oli-obk
`#[track_caller]` feature gate (RFC 2091 1/N) RFC text: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md Tracking issue: https://github.com/rust-lang/rust/issues/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.
This commit is contained in:
commit
ae5bb7e289
28 changed files with 395 additions and 2 deletions
|
|
@ -2120,6 +2120,25 @@ 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.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0736
|
||||
#![feature(track_caller)]
|
||||
|
||||
#[naked]
|
||||
#[track_caller]
|
||||
fn foo() {}
|
||||
```
|
||||
|
||||
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
|
||||
|
|
@ -2179,4 +2198,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
|
||||
E0739, // invalid track_caller application/syntax
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
@ -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
|
||||
};
|
||||
|
|
@ -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,
|
||||
E0739,
|
||||
"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,
|
||||
|
|
|
|||
|
|
@ -2734,7 +2734,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue