Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -881,15 +881,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
}

/// Forwards a possible `#[track_caller]` annotation from `outer_hir_id` to
/// `inner_hir_id` in case the `async_fn_track_caller` feature is enabled.
/// `inner_hir_id`.
pub(super) fn maybe_forward_track_caller(
&mut self,
span: Span,
outer_hir_id: HirId,
inner_hir_id: HirId,
) {
if self.tcx.features().async_fn_track_caller()
&& let Some(attrs) = self.attrs.get(&outer_hir_id.local_id)
if let Some(attrs) = self.attrs.get(&outer_hir_id.local_id)
&& find_attr!(*attrs, TrackCaller(_))
{
let unstable_span = self.mark_span_with_reason(
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1460,7 +1460,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::CoroutineSource::Fn,
);

// FIXME(async_fn_track_caller): Can this be moved above?

@theemathas theemathas Aug 29, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what this is saying, so I removed it. Am I supposed to do something with it?

View changes since the review

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming it means "can this be reordered to happen before the lowering_coroutine_body call"?

But lower_block_expr has this comment:

Lowers a block directly to an expression, presuming that it has no attributes and is not targeted by a break.

I don't know if that actually matters or whether this fixme should exist.

let hir_id = expr.hir_id;
this.maybe_forward_track_caller(body.span, fn_id, hir_id);

Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,11 +276,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
]
.into(),
allow_pattern_type: [sym::pattern_types, sym::pattern_type_range_trait].into(),
allow_gen_future: if tcx.features().async_fn_track_caller() {
[sym::gen_future, sym::closure_track_caller].into()
} else {
[sym::gen_future].into()
},
allow_gen_future: [sym::gen_future, sym::closure_track_caller].into(),
allow_for_await: [sym::async_gen_internals, sym::async_iterator].into(),
allow_async_fn_traits: [sym::async_fn_traits].into(),
allow_async_gen: [sym::async_gen_internals].into(),
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ declare_features! (
(accepted, async_closure, "1.85.0", Some(62290)),
/// Allows async functions to be declared, implemented, and used in traits.
(accepted, async_fn_in_trait, "1.75.0", Some(91611)),
/// Allows `#[track_caller]` on async functions.
(accepted, async_fn_track_caller, "CURRENT_RUSTC_VERSION", Some(110011)),
/// Allows all literals in attribute lists and values of key-value pairs.
(accepted, attr_literals, "1.30.0", Some(34981)),
/// Allows overloading augmented assignment operations like `a += b`.
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,6 @@ declare_features! (
(incomplete, async_drop, "1.88.0", Some(126482)),
/// Allows async functions to be called from `dyn Trait`.
(incomplete, async_fn_in_dyn_trait, "1.85.0", Some(133119)),
/// Allows `#[track_caller]` on async functions.
(unstable, async_fn_track_caller, "1.73.0", Some(110011)),
/// Allows `for await` loops.
(unstable, async_for_loop, "1.77.0", Some(118898)),
/// Allows `async` trait bound modifier.
Expand Down
66 changes: 4 additions & 62 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ use rustc_hir::attrs::lang_items::LangItem;
use rustc_hir::attrs::{AttributeKind, DocAttribute};
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
use rustc_hir::intravisit::FnKind as HirFnKind;
use rustc_hir::{self as hir, Body, FnDecl, ImplItemImplKind, PatKind, PredicateOrigin, find_attr};
use rustc_hir::{self as hir, ImplItemImplKind, PatKind, PredicateOrigin, find_attr};
// Lints from rustc_lint_defs
pub use rustc_lint_defs::builtin::*;
use rustc_lint_defs::{declare_lint, declare_lint_pass, fcw, impl_lint_pass};
Expand All @@ -55,10 +54,9 @@ use crate::diagnostics::{
BuiltinIncompleteFeaturesHelp, BuiltinInternalFeatures, BuiltinKeywordIdents,
BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc, BuiltinMutablesTransmutes,
BuiltinNonShorthandFieldPatterns, BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds,
BuiltinTypeAliasBounds, BuiltinUngatedAsyncFnTrackCaller, BuiltinUnpermittedTypeInit,
BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub, BuiltinUnsafe, BuiltinUnstableFeatures,
BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub, BuiltinWhileTrue,
EqInternalMethodImplemented, InvalidAsmLabel,
BuiltinTypeAliasBounds, BuiltinUnpermittedTypeInit, BuiltinUnpermittedTypeInitSub,
BuiltinUnreachablePub, BuiltinUnsafe, BuiltinUnstableFeatures, BuiltinUnusedDocComment,
BuiltinUnusedDocCommentSub, BuiltinWhileTrue, EqInternalMethodImplemented, InvalidAsmLabel,
};
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};

Expand Down Expand Up @@ -1042,62 +1040,6 @@ impl<'tcx> LateLintPass<'tcx> for UnstableFeatures {
}
}

declare_lint! {
/// The `ungated_async_fn_track_caller` lint warns when the
/// `#[track_caller]` attribute is used on an async function
/// 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
/// [`async_fn_track_caller` feature flag]. Otherwise, the `#[track_caller]`
/// annotation will function as a no-op.
///
/// [`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 async_fn_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,
def_id: LocalDefId,
) {
if fn_kind.asyncness().is_async()
&& !cx.tcx.features().async_fn_track_caller()
// Now, check if the function has the `#[track_caller]` attribute
&& let Some(attr_span) = find_attr!(cx.tcx, def_id, TrackCaller(span) => *span)
{
cx.emit_span_lint(
UNGATED_ASYNC_FN_TRACK_CALLER,
attr_span,
BuiltinUngatedAsyncFnTrackCaller { label: span, session: &cx.tcx.sess },
);
}
}
}

declare_lint! {
/// The `unreachable_pub` lint triggers for `pub` items not reachable from other crates - that
/// means neither directly accessible, nor reexported (with `pub use`), nor leaked through
Expand Down
22 changes: 1 addition & 21 deletions compiler/rustc_lint/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ use rustc_hir::intravisit::VisitorExt;
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_middle::ty::inhabitedness::InhabitedPredicate;
use rustc_middle::ty::{Clause, PolyExistentialTraitRef, Ty, TyCtxt};
use rustc_session::Session;
use rustc_span::edition::Edition;
use rustc_span::{Ident, Span, Symbol, sym};
use rustc_span::{Ident, Span, Symbol};

use crate::LateContext;
use crate::builtin::{InitError, ShorthandAssocTyCollector, TypeAliasBounds};
Expand Down Expand Up @@ -362,25 +361,6 @@ pub(crate) struct BuiltinMutablesTransmutes;
#[diag("use of an unstable feature")]
pub(crate) struct BuiltinUnstableFeatures;

// lint_ungated_async_fn_track_caller
pub(crate) struct BuiltinUngatedAsyncFnTrackCaller<'a> {
pub label: Span,
pub session: &'a Session,
}

impl<'a> Diagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
let mut diag = Diag::new(dcx, level, "`#[track_caller]` on async functions is a no-op")
.with_span_label(self.label, "this function will not propagate the caller location");
rustc_session::diagnostics::add_feature_diagnostics(
&mut diag,
self.session,
sym::async_fn_track_caller,
);
diag
}
}

#[derive(Diagnostic)]
#[diag("unreachable `pub` {$what}")]
pub(crate) struct BuiltinUnreachablePub<'a> {
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,6 @@ late_lint_methods!(
TrivialConstraints: TrivialConstraints,
TypeAliasBounds: TypeAliasBounds,
TypeLimits: TypeLimits::new(),
UngatedAsyncFnTrackCaller: UngatedAsyncFnTrackCaller,
UnitBindings: UnitBindings,
UnqualifiedLocalImports: UnqualifiedLocalImports,
// Depends on effective visibilities
Expand Down Expand Up @@ -718,6 +717,11 @@ fn register_builtins(store: &mut LintStore) {
"dependency_on_unit_never_type_fallback",
"the code warned by this lint no longer compiles",
);
store.register_removed(
"ungated_async_fn_track_caller",
"the `async_fn_track_caller` feature has stabilized, see \
<https://github.com/rust-lang/rust/issues/110011> for more information",
);
}

fn register_internals(store: &mut LintStore) {
Expand Down
33 changes: 0 additions & 33 deletions tests/ui/async-await/track-caller/async-block.afn.stderr

This file was deleted.

12 changes: 6 additions & 6 deletions tests/ui/async-await/track-caller/async-block.nofeat.stderr
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-block.rs:8:13
--> $DIR/async-block.rs:9:13
|
LL | let _ = #[track_caller] async {
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
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-block.rs:15:13
--> $DIR/async-block.rs:16:13
|
LL | let _ = #[track_caller] async {
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
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-block.rs:23:17
--> $DIR/async-block.rs:24:17
|
LL | let _ = #[track_caller] async {
LL | let _ = #[track_caller]
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
Expand Down
23 changes: 12 additions & 11 deletions tests/ui/async-await/track-caller/async-block.rs

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file previously tested the wrong feature gate, so I fixed that.

Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
//@ edition:2021
//@ revisions: afn nofeat
//@ revisions: cls nofeat
//@[cls] check-pass

#![feature(stmt_expr_attributes)]
#![cfg_attr(afn, feature(async_fn_track_caller))]
#![cfg_attr(cls, feature(closure_track_caller))]

fn main() {
let _ = #[track_caller] async {
//~^ ERROR `#[track_caller]` on closures is currently unstable [E0658]
};
let _ = #[track_caller]
//[nofeat]~^ ERROR `#[track_caller]` on closures is currently unstable [E0658]
async {};
}

#[track_caller]
async fn foo() {
let _ = #[track_caller] async {
//~^ ERROR `#[track_caller]` on closures is currently unstable [E0658]
};
let _ = #[track_caller]
//[nofeat]~^ ERROR `#[track_caller]` on closures is currently unstable [E0658]
async {};
}

#[track_caller]
async fn foo2() {
let _ = async {
let _ = #[track_caller] async {
//~^ ERROR `#[track_caller]` on closures is currently unstable [E0658]
};
let _ = #[track_caller]
//[nofeat]~^ ERROR `#[track_caller]` on closures is currently unstable [E0658]
async {};
};
}
Loading
Loading