Auto merge of #112117 - bryangarza:track-caller-feature-gate, r=compiler-errors

Add separate feature gate for async fn track caller

This patch adds a feature gate `async_fn_track_caller` that is separate from `closure_track_caller`. This is to allow enabling `async_fn_track_caller` separately.

Fixes #110009
This commit is contained in:
bors 2023-08-04 22:17:59 +00:00
commit e173a8e663
20 changed files with 326 additions and 63 deletions

View File

@ -657,14 +657,14 @@ pub(super) fn make_async_expr(
}
/// Forwards a possible `#[track_caller]` annotation from `outer_hir_id` to
/// `inner_hir_id` in case the `closure_track_caller` feature is enabled.
/// `inner_hir_id` in case the `async_fn_track_caller` feature is enabled.
pub(super) fn maybe_forward_track_caller(
&mut self,
span: Span,
outer_hir_id: hir::HirId,
inner_hir_id: hir::HirId,
) {
if self.tcx.features().closure_track_caller
if self.tcx.features().async_fn_track_caller
&& let Some(attrs) = self.attrs.get(&outer_hir_id.local_id)
&& attrs.into_iter().any(|attr| attr.has_name(sym::track_caller))
{

View File

@ -56,6 +56,11 @@ fn with_lctx(
owner: NodeId,
f: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::OwnerNode<'hir>,
) {
let allow_gen_future = Some(if self.tcx.features().async_fn_track_caller {
[sym::gen_future, sym::closure_track_caller][..].into()
} else {
[sym::gen_future][..].into()
});
let mut lctx = LoweringContext {
// Pseudo-globals.
tcx: self.tcx,
@ -83,7 +88,7 @@ fn with_lctx(
impl_trait_defs: Vec::new(),
impl_trait_bounds: Vec::new(),
allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()),
allow_gen_future: Some([sym::gen_future, sym::closure_track_caller][..].into()),
allow_gen_future,
generics_def_id_map: Default::default(),
};
lctx.with_hir_id_owner(owner, |lctx| f(lctx));

View File

@ -215,14 +215,19 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
}
sym::thread_local => codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL,
sym::track_caller => {
if !tcx.is_closure(did.to_def_id())
let is_closure = tcx.is_closure(did.to_def_id());
if !is_closure
&& let Some(fn_sig) = fn_sig()
&& fn_sig.skip_binder().abi() != abi::Abi::Rust
{
struct_span_err!(tcx.sess, attr.span, E0737, "`#[track_caller]` requires Rust ABI")
.emit();
}
if tcx.is_closure(did.to_def_id()) && !tcx.features().closure_track_caller {
if is_closure
&& !tcx.features().closure_track_caller
&& !attr.span.allows_unstable(sym::closure_track_caller)
{
feature_err(
&tcx.sess.parse_sess,
sym::closure_track_caller,

View File

@ -339,6 +339,8 @@ pub fn set(&self, features: &mut Features, span: Span) {
(active, async_closure, "1.37.0", Some(62290), None),
/// Allows async functions to be declared, implemented, and used in traits.
(active, async_fn_in_trait, "1.66.0", Some(91611), None),
/// Allows `#[track_caller]` on async functions.
(active, async_fn_track_caller, "CURRENT_RUSTC_VERSION", Some(110011), None),
/// Allows builtin # foo() syntax
(active, builtin_syntax, "1.71.0", Some(110680), None),
/// Allows `c"foo"` literals.

View File

@ -1259,8 +1259,8 @@ fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) {
declare_lint! {
/// The `ungated_async_fn_track_caller` lint warns when the
/// `#[track_caller]` attribute is used on an async function, method, or
/// closure, without enabling the corresponding unstable feature flag.
/// `#[track_caller]` attribute is used on an async function
/// without enabling the corresponding unstable feature flag.
///
/// ### Example
///
@ -1274,13 +1274,13 @@ fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) {
/// ### Explanation
///
/// The attribute must be used in conjunction with the
/// [`closure_track_caller` feature flag]. Otherwise, the `#[track_caller]`
/// [`async_fn_track_caller` feature flag]. Otherwise, the `#[track_caller]`
/// annotation will function as a no-op.
///
/// [`closure_track_caller` feature flag]: https://doc.rust-lang.org/beta/unstable-book/language-features/closure-track-caller.html
/// [`async_fn_track_caller` feature flag]: https://doc.rust-lang.org/beta/unstable-book/language-features/async-fn-track-caller.html
UNGATED_ASYNC_FN_TRACK_CALLER,
Warn,
"enabling track_caller on an async fn is a no-op unless the closure_track_caller feature is enabled"
"enabling track_caller on an async fn is a no-op unless the async_fn_track_caller feature is enabled"
}
declare_lint_pass!(
@ -1300,7 +1300,7 @@ fn check_fn(
def_id: LocalDefId,
) {
if fn_kind.asyncness() == IsAsync::Async
&& !cx.tcx.features().closure_track_caller
&& !cx.tcx.features().async_fn_track_caller
// Now, check if the function has the `#[track_caller]` attribute
&& let Some(attr) = cx.tcx.get_attr(def_id, sym::track_caller)
{

View File

@ -250,7 +250,7 @@ fn decorate_lint<'b>(
rustc_session::parse::add_feature_diagnostics(
diag,
&self.parse_sess,
sym::closure_track_caller,
sym::async_fn_track_caller,
);
diag
}

View File

@ -400,6 +400,7 @@
async_await,
async_closure,
async_fn_in_trait,
async_fn_track_caller,
atomic,
atomic_mod,
atomics,

View File

@ -0,0 +1,30 @@
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-block.rs:8:13
|
LL | let _ = #[track_caller] async {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-block.rs:15:13
|
LL | let _ = #[track_caller] async {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-block.rs:23:17
|
LL | let _ = #[track_caller] async {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -0,0 +1,30 @@
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-block.rs:8:13
|
LL | let _ = #[track_caller] async {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-block.rs:15:13
|
LL | let _ = #[track_caller] async {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-block.rs:23:17
|
LL | let _ = #[track_caller] async {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -1,9 +1,27 @@
// edition:2021
// revisions: afn nofeat
#![feature(stmt_expr_attributes)]
#![cfg_attr(afn, feature(async_fn_track_caller))]
fn main() {
let _ = #[track_caller] async {
//~^ ERROR `#[track_caller]` on closures is currently unstable [E0658]
};
}
#[track_caller]
async fn foo() {
let _ = #[track_caller] async {
//~^ ERROR `#[track_caller]` on closures is currently unstable [E0658]
};
}
#[track_caller]
async fn foo2() {
let _ = async {
let _ = #[track_caller] async {
//~^ ERROR `#[track_caller]` on closures is currently unstable [E0658]
};
};
}

View File

@ -1,12 +0,0 @@
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-block.rs:6:13
|
LL | let _ = #[track_caller] async {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_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

@ -0,0 +1,57 @@
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-closure-gate.rs:8:13
|
LL | let _ = #[track_caller] async || {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-closure-gate.rs:15:13
|
LL | let _ = #[track_caller] async || {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-closure-gate.rs:21:13
|
LL | let _ = #[track_caller] || {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-closure-gate.rs:28:17
|
LL | let _ = #[track_caller] || {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-closure-gate.rs:36:9
|
LL | #[track_caller] || {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-closure-gate.rs:45:13
|
LL | #[track_caller] || {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -0,0 +1,57 @@
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-closure-gate.rs:8:13
|
LL | let _ = #[track_caller] async || {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-closure-gate.rs:15:13
|
LL | let _ = #[track_caller] async || {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-closure-gate.rs:21:13
|
LL | let _ = #[track_caller] || {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-closure-gate.rs:28:17
|
LL | let _ = #[track_caller] || {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-closure-gate.rs:36:9
|
LL | #[track_caller] || {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-closure-gate.rs:45:13
|
LL | #[track_caller] || {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -1,9 +1,50 @@
// edition:2021
// revisions: afn nofeat
#![feature(async_closure, stmt_expr_attributes)]
#![cfg_attr(afn, feature(async_fn_track_caller))]
fn main() {
let _ = #[track_caller] async || {
//~^ ERROR `#[track_caller]` on closures is currently unstable [E0658]
};
}
#[track_caller]
async fn foo() {
let _ = #[track_caller] async || {
//~^ ERROR `#[track_caller]` on closures is currently unstable [E0658]
};
}
async fn foo2() {
let _ = #[track_caller] || {
//~^ ERROR `#[track_caller]` on closures is currently unstable [E0658]
};
}
fn foo3() {
async {
let _ = #[track_caller] || {
//~^ ERROR `#[track_caller]` on closures is currently unstable [E0658]
};
}
}
async fn foo4() {
let _ = || {
#[track_caller] || {
//~^ ERROR `#[track_caller]` on closures is currently unstable [E0658]
};
};
}
fn foo5() {
async {
let _ = || {
#[track_caller] || {
//~^ ERROR `#[track_caller]` on closures is currently unstable [E0658]
};
};
}
}

View File

@ -1,12 +0,0 @@
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-closure-gate.rs:6:13
|
LL | let _ = #[track_caller] async || {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_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

@ -0,0 +1,31 @@
warning: `#[track_caller]` on async functions is a no-op
--> $DIR/panic-track-caller.rs:53:1
|
LL | #[track_caller]
| ^^^^^^^^^^^^^^^
...
LL | / async fn bar_track_caller() {
LL | | panic!()
LL | | }
| |_- this function will not propagate the caller location
|
= note: see issue #110011 <https://github.com/rust-lang/rust/issues/110011> for more information
= help: add `#![feature(async_fn_track_caller)]` to the crate attributes to enable
= note: `#[warn(ungated_async_fn_track_caller)]` on by default
warning: `#[track_caller]` on async functions is a no-op
--> $DIR/panic-track-caller.rs:67:5
|
LL | #[track_caller]
| ^^^^^^^^^^^^^^^
...
LL | / async fn bar_assoc() {
LL | | panic!();
LL | | }
| |_____- this function will not propagate the caller location
|
= note: see issue #110011 <https://github.com/rust-lang/rust/issues/110011> for more information
= help: add `#![feature(async_fn_track_caller)]` to the crate attributes to enable
warning: 2 warnings emitted

View File

@ -1,29 +1,31 @@
warning: `#[track_caller]` on async functions is a no-op
--> $DIR/panic-track-caller.rs:50:1
--> $DIR/panic-track-caller.rs:53:1
|
LL | #[track_caller]
| ^^^^^^^^^^^^^^^
...
LL | / async fn bar_track_caller() {
LL | | panic!()
LL | | }
| |_- this function will not propagate the caller location
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
= note: see issue #110011 <https://github.com/rust-lang/rust/issues/110011> for more information
= help: add `#![feature(async_fn_track_caller)]` to the crate attributes to enable
= note: `#[warn(ungated_async_fn_track_caller)]` on by default
warning: `#[track_caller]` on async functions is a no-op
--> $DIR/panic-track-caller.rs:62:5
--> $DIR/panic-track-caller.rs:67:5
|
LL | #[track_caller]
| ^^^^^^^^^^^^^^^
...
LL | / async fn bar_assoc() {
LL | | panic!();
LL | | }
| |_____- this function will not propagate the caller location
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
= note: see issue #110011 <https://github.com/rust-lang/rust/issues/110011> for more information
= help: add `#![feature(async_fn_track_caller)]` to the crate attributes to enable
warning: 2 warnings emitted

View File

@ -1,9 +1,12 @@
// run-pass
// edition:2021
// revisions: feat nofeat
// revisions: afn cls nofeat
// needs-unwind
// gate-test-async_fn_track_caller
#![feature(async_closure, stmt_expr_attributes)]
#![cfg_attr(feat, feature(closure_track_caller))]
#![cfg_attr(afn, feature(async_fn_track_caller))]
#![cfg_attr(cls, feature(closure_track_caller))]
#![allow(unused)]
use std::future::Future;
use std::panic;
@ -47,7 +50,9 @@ async fn foo() {
bar().await
}
#[track_caller] //[nofeat]~ WARN `#[track_caller]` on async functions is a no-op
#[track_caller]
//[cls]~^ WARN `#[track_caller]` on async functions is a no-op
//[nofeat]~^^ WARN `#[track_caller]` on async functions is a no-op
async fn bar_track_caller() {
panic!()
}
@ -59,7 +64,9 @@ async fn foo_track_caller() {
struct Foo;
impl Foo {
#[track_caller] //[nofeat]~ WARN `#[track_caller]` on async functions is a no-op
#[track_caller]
//[cls]~^ WARN `#[track_caller]` on async functions is a no-op
//[nofeat]~^^ WARN `#[track_caller]` on async functions is a no-op
async fn bar_assoc() {
panic!();
}
@ -71,7 +78,7 @@ async fn foo_assoc() {
// Since compilation is expected to fail for this fn when using
// `nofeat`, we test that separately in `async-closure-gate.rs`
#[cfg(feat)]
#[cfg(cls)]
async fn foo_closure() {
let c = #[track_caller] async || {
panic!();
@ -81,7 +88,7 @@ async fn foo_closure() {
// Since compilation is expected to fail for this fn when using
// `nofeat`, we test that separately in `async-block.rs`
#[cfg(feat)]
#[cfg(cls)]
async fn foo_block() {
let a = #[track_caller] async {
panic!();
@ -106,21 +113,22 @@ fn panicked_at(f: impl FnOnce() + panic::UnwindSafe) -> u32 {
}
fn main() {
assert_eq!(panicked_at(|| block_on(foo())), 43);
assert_eq!(panicked_at(|| block_on(foo())), 46
);
#[cfg(feat)]
assert_eq!(panicked_at(|| block_on(foo_track_caller())), 56);
#[cfg(nofeat)]
assert_eq!(panicked_at(|| block_on(foo_track_caller())), 52);
#[cfg(afn)]
assert_eq!(panicked_at(|| block_on(foo_track_caller())), 61);
#[cfg(any(cls, nofeat))]
assert_eq!(panicked_at(|| block_on(foo_track_caller())), 57);
#[cfg(feat)]
assert_eq!(panicked_at(|| block_on(foo_assoc())), 69);
#[cfg(nofeat)]
assert_eq!(panicked_at(|| block_on(foo_assoc())), 64);
#[cfg(afn)]
assert_eq!(panicked_at(|| block_on(foo_assoc())), 76);
#[cfg(any(cls, nofeat))]
assert_eq!(panicked_at(|| block_on(foo_assoc())), 71);
#[cfg(feat)]
assert_eq!(panicked_at(|| block_on(foo_closure())), 79);
#[cfg(cls)]
assert_eq!(panicked_at(|| block_on(foo_closure())), 84);
#[cfg(feat)]
assert_eq!(panicked_at(|| block_on(foo_block())), 89);
#[cfg(cls)]
assert_eq!(panicked_at(|| block_on(foo_block())), 96);
}

View File

@ -18,7 +18,7 @@ Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro
use core /* 0#1 */::prelude /* 0#1 */::rust_2018 /* 0#1 */::*;
#[macro_use /* 0#1 */]
extern crate core /* 0#1 */;
extern crate compiler_builtins /* 443 */ as _ /* 0#1 */;
extern crate compiler_builtins /* 444 */ as _ /* 0#1 */;
// Don't load unnecessary hygiene information from std
extern crate std /* 0#0 */;

View File

@ -39,7 +39,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
use ::core /* 0#1 */::prelude /* 0#1 */::rust_2015 /* 0#1 */::*;
#[macro_use /* 0#1 */]
extern crate core /* 0#2 */;
extern crate compiler_builtins /* 443 */ as _ /* 0#2 */;
extern crate compiler_builtins /* 444 */ as _ /* 0#2 */;
// Don't load unnecessary hygiene information from std
extern crate std /* 0#0 */;