Skip to content

Commit

Permalink
Allow and add track_caller to generators
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bryangarza committed Nov 9, 2022
1 parent 3db41d1 commit fa99cb8
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 25 deletions.
60 changes: 37 additions & 23 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -617,33 +617,47 @@ impl<'hir> LoweringContext<'_, 'hir> {

hir::ExprKind::Closure(c)
};
let generator_hir_id = self.lower_node_id(closure_node_id);
// FIXME: only add track caller if the parent is track_caller
self.lower_attrs(
generator_hir_id,
&[Attribute {
kind: AttrKind::Normal(ptr::P(NormalAttr {
item: AttrItem {
path: Path::from_ident(Ident::new(sym::track_caller, span)),
args: MacArgs::Empty,
let mut parent_has_track_caller = false;
for attrs in self.attrs.values() {
for attr in attrs.into_iter() {
if attr.has_name(sym::track_caller) {
parent_has_track_caller = true;
break;
}
}
if parent_has_track_caller {
break;
}
}
let unstable_span =
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());

let hir_id = if parent_has_track_caller {
let generator_hir_id = self.lower_node_id(closure_node_id);
self.lower_attrs(
generator_hir_id,
&[Attribute {
kind: AttrKind::Normal(ptr::P(NormalAttr {
item: AttrItem {
path: Path::from_ident(Ident::new(sym::track_caller, span)),
args: MacArgs::Empty,
tokens: None,
},
tokens: None,
},
tokens: None,
})),
id: self.tcx.sess.parse_sess.attr_id_generator.mk_attr_id(),
style: AttrStyle::Outer,
span,
}],
);
let generator = hir::Expr {
hir_id: generator_hir_id,
kind: generator_kind,
span: self.lower_span(span),
})),
id: self.tcx.sess.parse_sess.attr_id_generator.mk_attr_id(),
style: AttrStyle::Outer,
span: unstable_span,
}],
);
generator_hir_id
} else {
self.lower_node_id(closure_node_id)
};

let generator = hir::Expr { hir_id, kind: generator_kind, span: self.lower_span(span) };

// `future::from_generator`:
let unstable_span =
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
let gen_future = self.expr_lang_item_path(
unstable_span,
hir::LangItem::FromGenerator,
Expand Down
1 change: 1 addition & 0 deletions library/core/src/future/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ where

impl<T: Generator<ResumeTy, Yield = ()>> Future for GenFuture<T> {
type Output = T::Return;
#[track_caller]
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
// SAFETY: Safe because we're !Unpin + !Drop, and this is just a field projection.
let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,6 @@ fn panicked_at(f: impl FnOnce() + panic::UnwindSafe) -> u32 {
}

fn main() {
assert_eq!(panicked_at(|| block_on(foo())), 39);
assert_eq!(panicked_at(|| block_on(foo_track_caller())), 52);
assert_eq!(panicked_at(|| block_on(foo())), 40);
assert_eq!(panicked_at(|| block_on(foo_track_caller())), 53);
}

0 comments on commit fa99cb8

Please sign in to comment.