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.
This commit is contained in:
parent
3db41d13f0
commit
fa99cb8269
3 changed files with 42 additions and 27 deletions
|
@ -617,33 +617,47 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
|
|
||||||
hir::ExprKind::Closure(c)
|
hir::ExprKind::Closure(c)
|
||||||
};
|
};
|
||||||
let generator_hir_id = self.lower_node_id(closure_node_id);
|
let mut parent_has_track_caller = false;
|
||||||
// FIXME: only add track caller if the parent is track_caller
|
for attrs in self.attrs.values() {
|
||||||
self.lower_attrs(
|
for attr in attrs.into_iter() {
|
||||||
generator_hir_id,
|
if attr.has_name(sym::track_caller) {
|
||||||
&[Attribute {
|
parent_has_track_caller = true;
|
||||||
kind: AttrKind::Normal(ptr::P(NormalAttr {
|
break;
|
||||||
item: AttrItem {
|
}
|
||||||
path: Path::from_ident(Ident::new(sym::track_caller, span)),
|
}
|
||||||
args: MacArgs::Empty,
|
if parent_has_track_caller {
|
||||||
tokens: None,
|
break;
|
||||||
},
|
}
|
||||||
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),
|
|
||||||
};
|
|
||||||
|
|
||||||
// `future::from_generator`:
|
|
||||||
let unstable_span =
|
let unstable_span =
|
||||||
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
|
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,
|
||||||
|
})),
|
||||||
|
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 gen_future = self.expr_lang_item_path(
|
let gen_future = self.expr_lang_item_path(
|
||||||
unstable_span,
|
unstable_span,
|
||||||
hir::LangItem::FromGenerator,
|
hir::LangItem::FromGenerator,
|
||||||
|
|
|
@ -82,6 +82,7 @@ where
|
||||||
|
|
||||||
impl<T: Generator<ResumeTy, Yield = ()>> Future for GenFuture<T> {
|
impl<T: Generator<ResumeTy, Yield = ()>> Future for GenFuture<T> {
|
||||||
type Output = T::Return;
|
type Output = T::Return;
|
||||||
|
#[track_caller]
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
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.
|
// 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) };
|
let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) };
|
||||||
|
|
|
@ -70,6 +70,6 @@ fn panicked_at(f: impl FnOnce() + panic::UnwindSafe) -> u32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
assert_eq!(panicked_at(|| block_on(foo())), 39);
|
assert_eq!(panicked_at(|| block_on(foo())), 40);
|
||||||
assert_eq!(panicked_at(|| block_on(foo_track_caller())), 52);
|
assert_eq!(panicked_at(|| block_on(foo_track_caller())), 53);
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue