Skip to content

Commit fa99cb8

Browse files
committed
Allow and add track_caller to generators
This patch allows the usage of the `track_caller` annotation on generators, as well as sets them conditionally if the parent also has `track_caller` set. Also add this annotation on the `GenFuture`'s `poll()` function.
1 parent 3db41d1 commit fa99cb8

File tree

3 files changed

+40
-25
lines changed

3 files changed

+40
-25
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+37-23
Original file line numberDiff line numberDiff line change
@@ -617,33 +617,47 @@ impl<'hir> LoweringContext<'_, 'hir> {
617617

618618
hir::ExprKind::Closure(c)
619619
};
620-
let generator_hir_id = self.lower_node_id(closure_node_id);
621-
// FIXME: only add track caller if the parent is track_caller
622-
self.lower_attrs(
623-
generator_hir_id,
624-
&[Attribute {
625-
kind: AttrKind::Normal(ptr::P(NormalAttr {
626-
item: AttrItem {
627-
path: Path::from_ident(Ident::new(sym::track_caller, span)),
628-
args: MacArgs::Empty,
620+
let mut parent_has_track_caller = false;
621+
for attrs in self.attrs.values() {
622+
for attr in attrs.into_iter() {
623+
if attr.has_name(sym::track_caller) {
624+
parent_has_track_caller = true;
625+
break;
626+
}
627+
}
628+
if parent_has_track_caller {
629+
break;
630+
}
631+
}
632+
let unstable_span =
633+
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
634+
635+
let hir_id = if parent_has_track_caller {
636+
let generator_hir_id = self.lower_node_id(closure_node_id);
637+
self.lower_attrs(
638+
generator_hir_id,
639+
&[Attribute {
640+
kind: AttrKind::Normal(ptr::P(NormalAttr {
641+
item: AttrItem {
642+
path: Path::from_ident(Ident::new(sym::track_caller, span)),
643+
args: MacArgs::Empty,
644+
tokens: None,
645+
},
629646
tokens: None,
630-
},
631-
tokens: None,
632-
})),
633-
id: self.tcx.sess.parse_sess.attr_id_generator.mk_attr_id(),
634-
style: AttrStyle::Outer,
635-
span,
636-
}],
637-
);
638-
let generator = hir::Expr {
639-
hir_id: generator_hir_id,
640-
kind: generator_kind,
641-
span: self.lower_span(span),
647+
})),
648+
id: self.tcx.sess.parse_sess.attr_id_generator.mk_attr_id(),
649+
style: AttrStyle::Outer,
650+
span: unstable_span,
651+
}],
652+
);
653+
generator_hir_id
654+
} else {
655+
self.lower_node_id(closure_node_id)
642656
};
643657

658+
let generator = hir::Expr { hir_id, kind: generator_kind, span: self.lower_span(span) };
659+
644660
// `future::from_generator`:
645-
let unstable_span =
646-
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
647661
let gen_future = self.expr_lang_item_path(
648662
unstable_span,
649663
hir::LangItem::FromGenerator,

library/core/src/future/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ where
8282

8383
impl<T: Generator<ResumeTy, Yield = ()>> Future for GenFuture<T> {
8484
type Output = T::Return;
85+
#[track_caller]
8586
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
8687
// SAFETY: Safe because we're !Unpin + !Drop, and this is just a field projection.
8788
let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) };

src/test/ui/async-await/panic-track-caller.rs renamed to src/test/ui/async-await/track-caller/panic-track-caller.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,6 @@ fn panicked_at(f: impl FnOnce() + panic::UnwindSafe) -> u32 {
7070
}
7171

7272
fn main() {
73-
assert_eq!(panicked_at(|| block_on(foo())), 39);
74-
assert_eq!(panicked_at(|| block_on(foo_track_caller())), 52);
73+
assert_eq!(panicked_at(|| block_on(foo())), 40);
74+
assert_eq!(panicked_at(|| block_on(foo_track_caller())), 53);
7575
}

0 commit comments

Comments
 (0)