about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Holk <ericholk@microsoft.com>2023-11-28 10:15:39 -0800
committerEric Holk <ericholk@microsoft.com>2023-12-04 11:22:49 -0800
commitbc0d10d4b0fefccda6aae0338a1935d76314736b (patch)
treead2b4910b507a3f1720d29da7006afda28647995
parente281163dc83dd747a817bdfbb81bf59c3747f7dc (diff)
downloadrust-bc0d10d4b0fefccda6aae0338a1935d76314736b.tar.gz
rust-bc0d10d4b0fefccda6aae0338a1935d76314736b.zip
Add genness to FnHeader
-rw-r--r--compiler/rustc_ast/src/ast.rs8
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs17
-rw-r--r--compiler/rustc_parse/src/parser/item.rs3
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs3
4 files changed, 26 insertions, 5 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index e8731cf20f2..4ef8d64c4c0 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2837,16 +2837,19 @@ pub struct FnHeader {
     pub constness: Const,
     /// The `extern` keyword and corresponding ABI string, if any
     pub ext: Extern,
+    /// The `gen` keyword, if any
+    pub genness: Gen,
 }
 
 impl FnHeader {
     /// Does this function header have any qualifiers or is it empty?
     pub fn has_qualifiers(&self) -> bool {
-        let Self { unsafety, asyncness, constness, ext } = self;
+        let Self { unsafety, asyncness, constness, ext, genness } = self;
         matches!(unsafety, Unsafe::Yes(_))
             || asyncness.is_async()
             || matches!(constness, Const::Yes(_))
             || !matches!(ext, Extern::None)
+            || matches!(genness, Gen::Yes { .. })
     }
 }
 
@@ -2857,6 +2860,7 @@ impl Default for FnHeader {
             asyncness: Async::No,
             constness: Const::No,
             ext: Extern::None,
+            genness: Gen::No,
         }
     }
 }
@@ -3177,7 +3181,7 @@ mod size_asserts {
     static_assert_size!(Block, 32);
     static_assert_size!(Expr, 72);
     static_assert_size!(ExprKind, 40);
-    static_assert_size!(Fn, 152);
+    static_assert_size!(Fn, 168);
     static_assert_size!(ForeignItem, 96);
     static_assert_size!(ForeignItemKind, 24);
     static_assert_size!(GenericArg, 24);
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 8ce86bf9ecf..7cdbb1a8c61 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -125,6 +125,10 @@ pub trait MutVisitor: Sized {
         noop_visit_asyncness(a, self);
     }
 
+    fn visit_genness(&mut self, a: &mut Gen) {
+        noop_visit_genness(a, self);
+    }
+
     fn visit_closure_binder(&mut self, b: &mut ClosureBinder) {
         noop_visit_closure_binder(b, self);
     }
@@ -881,6 +885,16 @@ pub fn noop_visit_asyncness<T: MutVisitor>(asyncness: &mut Async, vis: &mut T) {
     }
 }
 
+pub fn noop_visit_genness<T: MutVisitor>(genness: &mut Gen, vis: &mut T) {
+    match genness {
+        Gen::Yes { span: _, closure_id, return_impl_trait_id } => {
+            vis.visit_id(closure_id);
+            vis.visit_id(return_impl_trait_id);
+        }
+        Gen::No => {}
+    }
+}
+
 pub fn noop_visit_fn_decl<T: MutVisitor>(decl: &mut P<FnDecl>, vis: &mut T) {
     let FnDecl { inputs, output } = decl.deref_mut();
     inputs.flat_map_in_place(|param| vis.flat_map_param(param));
@@ -1170,9 +1184,10 @@ fn visit_const_item<T: MutVisitor>(
 }
 
 pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) {
-    let FnHeader { unsafety, asyncness, constness, ext: _ } = header;
+    let FnHeader { unsafety, asyncness, constness, ext: _, genness } = header;
     visit_constness(constness, vis);
     vis.visit_asyncness(asyncness);
+    vis.visit_genness(genness);
     visit_unsafety(unsafety, vis);
 }
 
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index a737f37a104..55f7310681f 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2543,6 +2543,7 @@ impl<'a> Parser<'a> {
                             constness: recover_constness,
                             unsafety: recover_unsafety,
                             asyncness: recover_asyncness,
+                            genness, // FIXME(eholk): add keyword recovery logic here too.
                             ext,
                         });
                     }
@@ -2552,7 +2553,7 @@ impl<'a> Parser<'a> {
             }
         }
 
-        Ok(FnHeader { constness, unsafety, asyncness, ext })
+        Ok(FnHeader { constness, unsafety, asyncness, ext, genness })
     }
 
     /// Parses the parameter list and result type of a function declaration.
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index b1a57c3dfd9..cf0dd39b562 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -596,7 +596,7 @@ impl<'a> Parser<'a> {
             tokens: None,
         };
         let span_start = self.token.span;
-        let ast::FnHeader { ext, unsafety, constness, asyncness } =
+        let ast::FnHeader { ext, unsafety, constness, asyncness, genness: _ } =
             self.parse_fn_front_matter(&inherited_vis, Case::Sensitive)?;
         if self.may_recover() && self.token.kind == TokenKind::Lt {
             self.recover_fn_ptr_with_generics(lo, &mut params, param_insertion_point)?;
@@ -612,6 +612,7 @@ impl<'a> Parser<'a> {
         if let ast::Async::Yes { span, .. } = asyncness {
             self.sess.emit_err(FnPointerCannotBeAsync { span: whole_span, qualifier: span });
         }
+        // FIXME(eholk): emit a similar error for `gen fn()`
         let decl_span = span_start.to(self.token.span);
         Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params: params, decl, decl_span })))
     }