Address code review feedback

This commit is contained in:
Eric Holk 2023-12-04 13:43:38 -08:00
parent 26f9954971
commit 50ef8006eb
No known key found for this signature in database
GPG key ID: 8EA6B43ED4CE0911
10 changed files with 53 additions and 36 deletions

View file

@ -873,8 +873,9 @@ pub fn noop_visit_closure_binder<T: MutVisitor>(binder: &mut ClosureBinder, vis:
pub fn noop_visit_coro_kind<T: MutVisitor>(coro_kind: &mut CoroutineKind, vis: &mut T) { pub fn noop_visit_coro_kind<T: MutVisitor>(coro_kind: &mut CoroutineKind, vis: &mut T) {
match coro_kind { match coro_kind {
CoroutineKind::Async { span: _, closure_id, return_impl_trait_id } CoroutineKind::Async { span, closure_id, return_impl_trait_id }
| CoroutineKind::Gen { span: _, closure_id, return_impl_trait_id } => { | CoroutineKind::Gen { span, closure_id, return_impl_trait_id } => {
vis.visit_span(span);
vis.visit_id(closure_id); vis.visit_id(closure_id);
vis.visit_id(return_impl_trait_id); vis.visit_id(return_impl_trait_id);
} }

View file

@ -1922,7 +1922,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
span, span,
opaque_ty_span, opaque_ty_span,
|this| { |this| {
let future_bound = this.lower_coroutine_fn_output_type_to_future_bound( let bound = this.lower_coroutine_fn_output_type_to_bound(
output, output,
coro, coro,
span, span,
@ -1931,7 +1931,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn_kind, fn_kind,
}, },
); );
arena_vec![this; future_bound] arena_vec![this; bound]
}, },
); );
@ -1940,7 +1940,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
/// Transforms `-> T` into `Future<Output = T>`. /// Transforms `-> T` into `Future<Output = T>`.
fn lower_coroutine_fn_output_type_to_future_bound( fn lower_coroutine_fn_output_type_to_bound(
&mut self, &mut self,
output: &FnRetTy, output: &FnRetTy,
coro: CoroutineKind, coro: CoroutineKind,
@ -1958,21 +1958,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])), FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
}; };
// "<Output|Item = T>" // "<$assoc_ty_name = T>"
let (symbol, lang_item) = match coro { let (assoc_ty_name, trait_lang_item) = match coro {
CoroutineKind::Async { .. } => (hir::FN_OUTPUT_NAME, hir::LangItem::Future), CoroutineKind::Async { .. } => (hir::FN_OUTPUT_NAME, hir::LangItem::Future),
CoroutineKind::Gen { .. } => (hir::ITERATOR_ITEM_NAME, hir::LangItem::Iterator), CoroutineKind::Gen { .. } => (hir::ITERATOR_ITEM_NAME, hir::LangItem::Iterator),
}; };
let future_args = self.arena.alloc(hir::GenericArgs { let future_args = self.arena.alloc(hir::GenericArgs {
args: &[], args: &[],
bindings: arena_vec![self; self.assoc_ty_binding(symbol, span, output_ty)], bindings: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, span, output_ty)],
parenthesized: hir::GenericArgsParentheses::No, parenthesized: hir::GenericArgsParentheses::No,
span_ext: DUMMY_SP, span_ext: DUMMY_SP,
}); });
hir::GenericBound::LangItemTrait( hir::GenericBound::LangItemTrait(
lang_item, trait_lang_item,
self.lower_span(span), self.lower_span(span),
self.next_id(), self.next_id(),
future_args, future_args,

View file

@ -401,14 +401,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
) )
} }
/// An associated type binding `$symbol = $ty`. /// An associated type binding `$assoc_ty_name = $ty`.
pub(crate) fn assoc_ty_binding( pub(crate) fn assoc_ty_binding(
&mut self, &mut self,
symbol: rustc_span::Symbol, assoc_ty_name: rustc_span::Symbol,
span: Span, span: Span,
ty: &'hir hir::Ty<'hir>, ty: &'hir hir::Ty<'hir>,
) -> hir::TypeBinding<'hir> { ) -> hir::TypeBinding<'hir> {
let ident = Ident::with_dummy_span(symbol); let ident = Ident::with_dummy_span(assoc_ty_name);
let kind = hir::TypeBindingKind::Equality { term: ty.into() }; let kind = hir::TypeBindingKind::Equality { term: ty.into() };
let args = arena_vec![self;]; let args = arena_vec![self;];
let bindings = arena_vec![self;]; let bindings = arena_vec![self;];

View file

@ -1279,7 +1279,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
.. ..
}) = fk.header() }) = fk.header()
{ {
// FIXME(eholk): Report a different error for `const gen` // FIXME(gen_blocks): Report a different error for `const gen`
self.err_handler().emit_err(errors::ConstAndAsync { self.err_handler().emit_err(errors::ConstAndAsync {
spans: vec![cspan, aspan], spans: vec![cspan, aspan],
cspan, cspan,

View file

@ -545,6 +545,10 @@ fn check_test_signature(
return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "async" })); return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "async" }));
} }
if let Some(ast::CoroutineKind::Gen { span, .. }) = f.sig.header.coro_kind {
return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "gen" }));
}
// If the termination trait is active, the compiler will check that the output // If the termination trait is active, the compiler will check that the output
// type implements the `Termination` trait as `libtest` enforces that. // type implements the `Termination` trait as `libtest` enforces that.
let has_output = match &f.sig.decl.output { let has_output = match &f.sig.decl.output {

View file

@ -2544,7 +2544,7 @@ impl<'a> Parser<'a> {
} }
} }
// FIXME(eholk): add keyword recovery logic for genness // FIXME(gen_blocks): add keyword recovery logic for genness
if wrong_kw.is_some() if wrong_kw.is_some()
&& self.may_recover() && self.may_recover()

View file

@ -612,7 +612,7 @@ impl<'a> Parser<'a> {
if let Some(ast::CoroutineKind::Async { span, .. }) = coro_kind { if let Some(ast::CoroutineKind::Async { span, .. }) = coro_kind {
self.sess.emit_err(FnPointerCannotBeAsync { span: whole_span, qualifier: span }); self.sess.emit_err(FnPointerCannotBeAsync { span: whole_span, qualifier: span });
} }
// FIXME(eholk): emit a similar error for `gen fn()` // FIXME(gen_blocks): emit a similar error for `gen fn()`
let decl_span = span_start.to(self.token.span); let decl_span = span_start.to(self.token.span);
Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params: params, decl, decl_span }))) Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params: params, decl, decl_span })))
} }

View file

@ -916,10 +916,10 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
&sig.decl.output, &sig.decl.output,
); );
if let Some((async_node_id, _)) = if let Some((coro_node_id, _)) =
sig.header.coro_kind.map(|coro_kind| coro_kind.return_id()) sig.header.coro_kind.map(|coro_kind| coro_kind.return_id())
{ {
this.record_lifetime_params_for_impl_trait(async_node_id); this.record_lifetime_params_for_impl_trait(coro_node_id);
} }
}, },
); );
@ -942,13 +942,13 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
this.visit_generics(generics); this.visit_generics(generics);
let declaration = &sig.decl; let declaration = &sig.decl;
let async_node_id = let coro_node_id =
sig.header.coro_kind.map(|coro_kind| coro_kind.return_id()); sig.header.coro_kind.map(|coro_kind| coro_kind.return_id());
this.with_lifetime_rib( this.with_lifetime_rib(
LifetimeRibKind::AnonymousCreateParameter { LifetimeRibKind::AnonymousCreateParameter {
binder: fn_id, binder: fn_id,
report_in_path: async_node_id.is_some(), report_in_path: coro_node_id.is_some(),
}, },
|this| { |this| {
this.resolve_fn_signature( this.resolve_fn_signature(
@ -961,7 +961,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
&declaration.output, &declaration.output,
); );
if let Some((async_node_id, _)) = async_node_id { if let Some((async_node_id, _)) = coro_node_id {
this.record_lifetime_params_for_impl_trait(async_node_id); this.record_lifetime_params_for_impl_trait(async_node_id);
} }
}, },
@ -4291,8 +4291,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
// `async |x| ...` gets desugared to `|x| async {...}`, so we need to // `async |x| ...` gets desugared to `|x| async {...}`, so we need to
// resolve the arguments within the proper scopes so that usages of them inside the // resolve the arguments within the proper scopes so that usages of them inside the
// closure are detected as upvars rather than normal closure arg usages. // closure are detected as upvars rather than normal closure arg usages.
//
// Similarly, `gen |x| ...` gets desugared to `|x| gen {...}`, so we handle that too.
ExprKind::Closure(box ast::Closure { ExprKind::Closure(box ast::Closure {
coro_kind: Some(CoroutineKind::Async { .. }), coro_kind: Some(_),
ref fn_decl, ref fn_decl,
ref body, ref body,
.. ..

View file

@ -263,12 +263,10 @@ fn rewrite_closure_fn_decl(
} else { } else {
"" ""
}; };
let (is_async, is_gen) = if let Some(coro_kind) = coro_kind { let coro = match coro_kind {
let is_async = if coro_kind.is_async() { "async " } else { "" }; Some(ast::CoroutineKind::Async { .. }) => "async ",
let is_gen = if coro_kind.is_gen() { "gen " } else { "" }; Some(ast::CoroutineKind::Gen { .. }) => "gen ",
(is_async, is_gen) None => "",
} else {
("", "")
}; };
let mover = if matches!(capture, ast::CaptureBy::Value { .. }) { let mover = if matches!(capture, ast::CaptureBy::Value { .. }) {
"move " "move "
@ -278,14 +276,7 @@ fn rewrite_closure_fn_decl(
// 4 = "|| {".len(), which is overconservative when the closure consists of // 4 = "|| {".len(), which is overconservative when the closure consists of
// a single expression. // a single expression.
let nested_shape = shape let nested_shape = shape
.shrink_left( .shrink_left(binder.len() + const_.len() + immovable.len() + coro.len() + mover.len())?
binder.len()
+ const_.len()
+ immovable.len()
+ is_async.len()
+ is_gen.len()
+ mover.len(),
)?
.sub_width(4)?; .sub_width(4)?;
// 1 = | // 1 = |
@ -323,7 +314,7 @@ fn rewrite_closure_fn_decl(
.tactic(tactic) .tactic(tactic)
.preserve_newline(true); .preserve_newline(true);
let list_str = write_list(&item_vec, &fmt)?; let list_str = write_list(&item_vec, &fmt)?;
let mut prefix = format!("{binder}{const_}{immovable}{is_async}{is_gen}{mover}|{list_str}|"); let mut prefix = format!("{binder}{const_}{immovable}{coro}{mover}|{list_str}|");
if !ret_str.is_empty() { if !ret_str.is_empty() {
if prefix.contains('\n') { if prefix.contains('\n') {

View file

@ -0,0 +1,19 @@
// edition: 2024
// compile-flags: -Zunstable-options
// check-pass
#![feature(gen_blocks)]
// make sure gen fn captures lifetimes in its signature
gen fn foo<'a, 'b>(x: &'a i32, y: &'b i32, z: &'b i32) -> &'b i32 {
yield y;
yield z;
}
fn main() {
let z = 3;
let mut iter = foo(&1, &2, &z);
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), None);
}