Rollup merge of #104741 - bryangarza:bug-104588-async-track-caller, r=compiler-errors
Switch `#[track_caller]` back to a no-op unless feature gate is enabled This patch fixes a regression, in which `#[track_caller]`, which was previously a no-op, was changed to actually turn on the behavior. This should instead only happen behind the `closure_track_caller` feature gate. Also, add a warning for the user to understand how their code will compile depending on the feature gate being turned on or not. Fixes #104588
This commit is contained in:
commit
0adf9e046b
@ -656,18 +656,14 @@ pub(super) fn make_async_expr(
|
||||
hir::ExprKind::Closure(c)
|
||||
};
|
||||
|
||||
let track_caller = self
|
||||
.attrs
|
||||
.get(&outer_hir_id.local_id)
|
||||
.map_or(false, |attrs| attrs.into_iter().any(|attr| attr.has_name(sym::track_caller)));
|
||||
|
||||
let hir_id = self.lower_node_id(closure_node_id);
|
||||
if track_caller {
|
||||
let unstable_span = self.mark_span_with_reason(
|
||||
DesugaringKind::Async,
|
||||
span,
|
||||
self.allow_gen_future.clone(),
|
||||
);
|
||||
let unstable_span =
|
||||
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
|
||||
|
||||
if self.tcx.features().closure_track_caller
|
||||
&& let Some(attrs) = self.attrs.get(&outer_hir_id.local_id)
|
||||
&& attrs.into_iter().any(|attr| attr.has_name(sym::track_caller))
|
||||
{
|
||||
self.lower_attrs(
|
||||
hir_id,
|
||||
&[Attribute {
|
||||
|
@ -350,6 +350,9 @@ lint_builtin_mutable_transmutes =
|
||||
|
||||
lint_builtin_unstable_features = unstable feature
|
||||
|
||||
lint_ungated_async_fn_track_caller = `#[track_caller]` on async functions is a no-op
|
||||
.label = this function will not propagate the caller location
|
||||
|
||||
lint_builtin_unreachable_pub = unreachable `pub` {$what}
|
||||
.suggestion = consider restricting its visibility
|
||||
.help = or consider exporting it for use by other crates
|
||||
|
@ -25,6 +25,7 @@
|
||||
types::{transparent_newtype_field, CItemKind},
|
||||
EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext,
|
||||
};
|
||||
use hir::IsAsync;
|
||||
use rustc_ast::attr;
|
||||
use rustc_ast::tokenstream::{TokenStream, TokenTree};
|
||||
use rustc_ast::visit::{FnCtxt, FnKind};
|
||||
@ -40,7 +41,10 @@
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID};
|
||||
use rustc_hir::{ForeignItemKind, GenericParamKind, HirId, Node, PatKind, PredicateOrigin};
|
||||
use rustc_hir::intravisit::FnKind as HirFnKind;
|
||||
use rustc_hir::{
|
||||
Body, FnDecl, ForeignItemKind, GenericParamKind, HirId, Node, PatKind, PredicateOrigin,
|
||||
};
|
||||
use rustc_index::vec::Idx;
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::layout::{LayoutError, LayoutOf};
|
||||
@ -1370,6 +1374,72 @@ 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.
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust
|
||||
/// #[track_caller]
|
||||
/// async fn foo() {}
|
||||
/// ```
|
||||
///
|
||||
/// {{produces}}
|
||||
///
|
||||
/// ### Explanation
|
||||
///
|
||||
/// The attribute must be used in conjunction with the
|
||||
/// [`closure_track_caller` feature flag]. Otherwise, the `#[track_caller]`
|
||||
/// annotation will function as as no-op.
|
||||
///
|
||||
/// [`closure_track_caller` feature flag]: https://doc.rust-lang.org/beta/unstable-book/language-features/closure-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"
|
||||
}
|
||||
|
||||
declare_lint_pass!(
|
||||
/// Explains corresponding feature flag must be enabled for the `#[track_caller] attribute to
|
||||
/// do anything
|
||||
UngatedAsyncFnTrackCaller => [UNGATED_ASYNC_FN_TRACK_CALLER]
|
||||
);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for UngatedAsyncFnTrackCaller {
|
||||
fn check_fn(
|
||||
&mut self,
|
||||
cx: &LateContext<'_>,
|
||||
fn_kind: HirFnKind<'_>,
|
||||
_: &'tcx FnDecl<'_>,
|
||||
_: &'tcx Body<'_>,
|
||||
span: Span,
|
||||
hir_id: HirId,
|
||||
) {
|
||||
if fn_kind.asyncness() == IsAsync::Async
|
||||
&& !cx.tcx.features().closure_track_caller
|
||||
&& let attrs = cx.tcx.hir().attrs(hir_id)
|
||||
// Now, check if the function has the `#[track_caller]` attribute
|
||||
&& let Some(attr) = attrs.iter().find(|attr| attr.has_name(sym::track_caller))
|
||||
{
|
||||
cx.struct_span_lint(
|
||||
UNGATED_ASYNC_FN_TRACK_CALLER,
|
||||
attr.span,
|
||||
fluent::lint_ungated_async_fn_track_caller,
|
||||
|lint| {
|
||||
lint.span_label(span, fluent::label);
|
||||
rustc_session::parse::add_feature_diagnostics(
|
||||
lint,
|
||||
&cx.tcx.sess.parse_sess,
|
||||
sym::closure_track_caller,
|
||||
);
|
||||
lint
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
/// The `unreachable_pub` lint triggers for `pub` items not reachable from
|
||||
/// the crate root.
|
||||
|
@ -219,6 +219,7 @@ fn lint_mod(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
|
||||
// May Depend on constants elsewhere
|
||||
UnusedBrokenConst: UnusedBrokenConst,
|
||||
UnstableFeatures: UnstableFeatures,
|
||||
UngatedAsyncFnTrackCaller: UngatedAsyncFnTrackCaller,
|
||||
ArrayIntoIter: ArrayIntoIter::default(),
|
||||
DropTraitConstraints: DropTraitConstraints,
|
||||
TemporaryCStringAsPtr: TemporaryCStringAsPtr,
|
||||
|
@ -5,6 +5,5 @@
|
||||
fn main() {
|
||||
let _ = #[track_caller] async || {
|
||||
//~^ ERROR `#[track_caller]` on closures is currently unstable [E0658]
|
||||
//~| ERROR `#[track_caller]` on closures is currently unstable [E0658]
|
||||
};
|
||||
}
|
||||
|
@ -7,19 +7,6 @@ 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:6:38
|
||||
|
|
||||
LL | let _ = #[track_caller] async || {
|
||||
| ______________________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
= 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 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
@ -0,0 +1,29 @@
|
||||
warning: `#[track_caller]` on async functions is a no-op
|
||||
--> $DIR/panic-track-caller.rs:50: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: `#[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
|
||||
|
|
||||
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
|
||||
|
||||
warning: 2 warnings emitted
|
||||
|
@ -1,7 +1,9 @@
|
||||
// run-pass
|
||||
// edition:2021
|
||||
// revisions: feat nofeat
|
||||
// needs-unwind
|
||||
#![feature(closure_track_caller, async_closure, stmt_expr_attributes)]
|
||||
#![feature(async_closure, stmt_expr_attributes)]
|
||||
#![cfg_attr(feat, feature(closure_track_caller))]
|
||||
|
||||
use std::future::Future;
|
||||
use std::panic;
|
||||
@ -45,7 +47,7 @@ async fn foo() {
|
||||
bar().await
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[track_caller] //[nofeat]~ WARN `#[track_caller]` on async functions is a no-op
|
||||
async fn bar_track_caller() {
|
||||
panic!()
|
||||
}
|
||||
@ -57,7 +59,7 @@ async fn foo_track_caller() {
|
||||
struct Foo;
|
||||
|
||||
impl Foo {
|
||||
#[track_caller]
|
||||
#[track_caller] //[nofeat]~ WARN `#[track_caller]` on async functions is a no-op
|
||||
async fn bar_assoc() {
|
||||
panic!();
|
||||
}
|
||||
@ -67,6 +69,9 @@ async fn foo_assoc() {
|
||||
Foo::bar_assoc().await
|
||||
}
|
||||
|
||||
// Since compilation is expected to fail for this fn when using
|
||||
// `nofeat`, we test that separately in `async-closure-gate.rs`
|
||||
#[cfg(feat)]
|
||||
async fn foo_closure() {
|
||||
let c = #[track_caller] async || {
|
||||
panic!();
|
||||
@ -91,8 +96,18 @@ fn panicked_at(f: impl FnOnce() + panic::UnwindSafe) -> u32 {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(panicked_at(|| block_on(foo())), 41);
|
||||
assert_eq!(panicked_at(|| block_on(foo_track_caller())), 54);
|
||||
assert_eq!(panicked_at(|| block_on(foo_assoc())), 67);
|
||||
assert_eq!(panicked_at(|| block_on(foo_closure())), 74);
|
||||
assert_eq!(panicked_at(|| block_on(foo())), 43);
|
||||
|
||||
#[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(feat)]
|
||||
assert_eq!(panicked_at(|| block_on(foo_assoc())), 69);
|
||||
#[cfg(nofeat)]
|
||||
assert_eq!(panicked_at(|| block_on(foo_assoc())), 64);
|
||||
|
||||
#[cfg(feat)]
|
||||
assert_eq!(panicked_at(|| block_on(foo_closure())), 79);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user