diff options
| author | Without Boats <boats@mozilla.com> | 2018-05-16 22:55:18 -0700 |
|---|---|---|
| committer | Taylor Cramer <cramertj@google.com> | 2018-06-21 22:29:47 -0700 |
| commit | 18ff7d091a07706b87c131bf3efc226993916f88 (patch) | |
| tree | 733af2f6f405efc1f1c3f79471a61c9c1d128cd4 /src/libsyntax | |
| parent | 4b17d31f1147f840231c43b1ac1478a497af20df (diff) | |
Parse async fn header.
This is gated on edition 2018 & the `async_await` feature gate. The parser will accept `async fn` and `async unsafe fn` as fn items. Along the same lines as `const fn`, only `async unsafe fn` is permitted, not `unsafe async fn`.The parser will not accept `async` functions as trait methods. To do a little code clean up, four fields of the function type struct have been merged into the new `FnHeader` struct: constness, asyncness, unsafety, and ABI. Also, a small bug in HIR printing is fixed: it previously printed `const unsafe fn` as `unsafe const fn`, which is grammatically incorrect.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 37 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 41 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 13 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 50 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 47 | ||||
| -rw-r--r-- | src/libsyntax/test.rs | 46 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 12 |
9 files changed, 160 insertions, 103 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index c6de2c4da39..55c21c64c83 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -17,7 +17,7 @@ pub use util::ThinVec; pub use util::parser::ExprPrecedence; use syntax_pos::{Span, DUMMY_SP}; -use codemap::{respan, Spanned}; +use codemap::{dummy_spanned, respan, Spanned}; use rustc_target::spec::abi::Abi; use ext::hygiene::{Mark, SyntaxContext}; use print::pprust; @@ -1325,9 +1325,7 @@ pub struct MutTy { /// or in an implementation. #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct MethodSig { - pub unsafety: Unsafety, - pub constness: Spanned<Constness>, - pub abi: Abi, + pub header: FnHeader, pub decl: P<FnDecl>, } @@ -1709,6 +1707,12 @@ pub enum Unsafety { } #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum IsAsync { + Async, + NotAsync, +} + +#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum Constness { Const, NotConst, @@ -2009,6 +2013,29 @@ pub struct Item { pub tokens: Option<TokenStream>, } +/// A function header +/// +/// All the information between the visibility & the name of the function is +/// included in this struct (e.g. `async unsafe fn` or `const extern "C" fn`) +#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct FnHeader { + pub unsafety: Unsafety, + pub asyncness: IsAsync, + pub constness: Spanned<Constness>, + pub abi: Abi, +} + +impl Default for FnHeader { + fn default() -> FnHeader { + FnHeader { + unsafety: Unsafety::Normal, + asyncness: IsAsync::NotAsync, + constness: dummy_spanned(Constness::NotConst), + abi: Abi::Rust, + } + } +} + #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum ItemKind { /// An `extern crate` item, with optional *original* crate name if the crate was renamed. @@ -2030,7 +2057,7 @@ pub enum ItemKind { /// A function declaration (`fn` or `pub fn`). /// /// E.g. `fn foo(bar: usize) -> usize { .. }` - Fn(P<FnDecl>, Unsafety, Spanned<Constness>, Abi, Generics, P<Block>), + Fn(P<FnDecl>, FnHeader, Generics, P<Block>), /// A module declaration (`mod` or `pub mod`). /// /// E.g. `mod foo;` or `mod foo { .. }` diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 9044cab05d6..6bb7535544b 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -1008,9 +1008,12 @@ impl<'a> AstBuilder for ExtCtxt<'a> { name, Vec::new(), ast::ItemKind::Fn(self.fn_decl(inputs, ast::FunctionRetTy::Ty(output)), - ast::Unsafety::Normal, - dummy_spanned(ast::Constness::NotConst), - Abi::Rust, + ast::FnHeader { + unsafety: ast::Unsafety::Normal, + asyncness: ast::IsAsync::NotAsync, + constness: dummy_spanned(ast::Constness::NotConst), + abi: Abi::Rust, + }, generics, body)) } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index be4cf197be4..a9679f86ddb 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -29,7 +29,6 @@ use rustc_target::spec::abi::Abi; use ast::{self, NodeId, PatKind, RangeEnd}; use attr; use edition::{ALL_EDITIONS, Edition}; -use codemap::Spanned; use syntax_pos::{Span, DUMMY_SP}; use errors::{DiagnosticBuilder, Handler, FatalError}; use visit::{self, FnKind, Visitor}; @@ -468,12 +467,14 @@ declare_features! ( // 'a: { break 'a; } (active, label_break_value, "1.28.0", Some(48594), None), - // #[panic_implementation] (active, panic_implementation, "1.28.0", Some(44489), None), // #[doc(keyword = "...")] (active, doc_keyword, "1.28.0", Some(51315), None), + + // Allows async and await syntax + (active, async_await, "1.28.0", Some(0), Some(Edition::Edition2018)), ); declare_features! ( @@ -1760,20 +1761,24 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn_decl: &'a ast::FnDecl, span: Span, _node_id: NodeId) { - // check for const fn declarations - if let FnKind::ItemFn(_, _, Spanned { node: ast::Constness::Const, .. }, _, _, _) = - fn_kind { - gate_feature_post!(&self, const_fn, span, "const fn is unstable"); - } - // stability of const fn methods are covered in - // visit_trait_item and visit_impl_item below; this is - // because default methods don't pass through this - // point. - match fn_kind { - FnKind::ItemFn(_, _, _, abi, _, _) | - FnKind::Method(_, &ast::MethodSig { abi, .. }, _, _) => { - self.check_abi(abi, span); + FnKind::ItemFn(_, header, _, _) => { + // check for const fn and async fn declarations + if header.asyncness == ast::IsAsync::Async { + gate_feature_post!(&self, async_await, span, "async fn is unstable"); + } + if header.constness.node == ast::Constness::Const { + gate_feature_post!(&self, const_fn, span, "const fn is unstable"); + } + // stability of const fn methods are covered in + // visit_trait_item and visit_impl_item below; this is + // because default methods don't pass through this + // point. + + self.check_abi(header.abi, span); + } + FnKind::Method(_, sig, _, _) => { + self.check_abi(sig.header.abi, span); } _ => {} } @@ -1784,9 +1789,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { match ti.node { ast::TraitItemKind::Method(ref sig, ref block) => { if block.is_none() { - self.check_abi(sig.abi, ti.span); + self.check_abi(sig.header.abi, ti.span); } - if sig.constness.node == ast::Constness::Const { + if sig.header.constness.node == ast::Constness::Const { gate_feature_post!(&self, const_fn, ti.span, "const fn is unstable"); } } @@ -1820,7 +1825,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { match ii.node { ast::ImplItemKind::Method(ref sig, _) => { - if sig.constness.node == ast::Constness::Const { + if sig.header.constness.node == ast::Constness::Const { gate_feature_post!(&self, const_fn, ii.span, "const fn is unstable"); } } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 93248fe3bfa..941d2180fd1 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -881,11 +881,11 @@ pub fn noop_fold_item_kind<T: Folder>(i: ItemKind, folder: &mut T) -> ItemKind { ItemKind::Const(t, e) => { ItemKind::Const(folder.fold_ty(t), folder.fold_expr(e)) } - ItemKind::Fn(decl, unsafety, constness, abi, generics, body) => { + ItemKind::Fn(decl, header, generics, body) => { let generics = folder.fold_generics(generics); let decl = folder.fold_fn_decl(decl); let body = folder.fold_block(body); - ItemKind::Fn(decl, unsafety, constness, abi, generics, body) + ItemKind::Fn(decl, header, generics, body) } ItemKind::Mod(m) => ItemKind::Mod(folder.fold_mod(m)), ItemKind::ForeignMod(nm) => ItemKind::ForeignMod(folder.fold_foreign_mod(nm)), @@ -1082,9 +1082,7 @@ pub fn noop_fold_foreign_item_simple<T: Folder>(ni: ForeignItem, folder: &mut T) pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> MethodSig { MethodSig { - abi: sig.abi, - unsafety: sig.unsafety, - constness: sig.constness, + header: sig.header, decl: folder.fold_fn_decl(sig.decl) } } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 0050434d42e..61f88f3a250 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -928,12 +928,15 @@ mod tests { output: ast::FunctionRetTy::Default(sp(15, 15)), variadic: false }), - ast::Unsafety::Normal, - Spanned { - span: sp(0,2), - node: ast::Constness::NotConst, + ast::FnHeader { + unsafety: ast::Unsafety::Normal, + asyncness: ast::IsAsync::NotAsync, + constness: Spanned { + span: sp(0,2), + node: ast::Constness::NotConst, + }, + abi: Abi::Rust, }, - Abi::Rust, ast::Generics{ params: Vec::new(), where_clause: ast::WhereClause { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 3955ccb4c42..d897aaadf43 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -19,11 +19,11 @@ use ast::{Constness, Crate}; use ast::Defaultness; use ast::EnumDef; use ast::{Expr, ExprKind, RangeLimits}; -use ast::{Field, FnDecl}; +use ast::{Field, FnDecl, FnHeader}; use ast::{ForeignItem, ForeignItemKind, FunctionRetTy}; use ast::{GenericParam, GenericParamKind}; use ast::GenericArg; -use ast::{Ident, ImplItem, IsAuto, Item, ItemKind}; +use ast::{Ident, ImplItem, IsAsync, IsAuto, Item, ItemKind}; use ast::{Label, Lifetime, Lit, LitKind}; use ast::Local; use ast::MacStmtStyle; @@ -1356,10 +1356,13 @@ impl<'a> Parser<'a> { generics.where_clause = self.parse_where_clause()?; let sig = ast::MethodSig { - unsafety, - constness, + header: FnHeader { + unsafety, + constness, + abi, + asyncness: IsAsync::NotAsync, + }, decl: d, - abi, }; let body = match self.token { @@ -5349,6 +5352,7 @@ impl<'a> Parser<'a> { /// Parse an item-position function declaration. fn parse_item_fn(&mut self, unsafety: Unsafety, + asyncness: IsAsync, constness: Spanned<Constness>, abi: Abi) -> PResult<'a, ItemInfo> { @@ -5356,7 +5360,8 @@ impl<'a> Parser<'a> { let decl = self.parse_fn_decl(false)?; generics.where_clause = self.parse_where_clause()?; let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; - Ok((ident, ItemKind::Fn(decl, unsafety, constness, abi, generics, body), Some(inner_attrs))) + let header = FnHeader { unsafety, asyncness, constness, abi }; + Ok((ident, ItemKind::Fn(decl, header, generics, body), Some(inner_attrs))) } /// true if we are looking at `const ID`, false for things like `const fn` etc @@ -5531,12 +5536,11 @@ impl<'a> Parser<'a> { generics.where_clause = self.parse_where_clause()?; *at_end = true; let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; - Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(ast::MethodSig { - abi, - unsafety, - constness, - decl, - }, body))) + let header = ast::FnHeader { abi, unsafety, constness, asyncness: IsAsync::NotAsync }; + Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method( + ast::MethodSig { header, decl }, + body + ))) } } @@ -6622,6 +6626,7 @@ impl<'a> Parser<'a> { let abi = opt_abi.unwrap_or(Abi::C); let (ident, item_, extra_attrs) = self.parse_item_fn(Unsafety::Normal, + IsAsync::NotAsync, respan(fn_span, Constness::NotConst), abi)?; let prev_span = self.prev_span; @@ -6665,6 +6670,7 @@ impl<'a> Parser<'a> { self.bump(); let (ident, item_, extra_attrs) = self.parse_item_fn(unsafety, + IsAsync::NotAsync, respan(const_span, Constness::Const), Abi::Rust)?; let prev_span = self.prev_span; @@ -6692,6 +6698,24 @@ impl<'a> Parser<'a> { maybe_append(attrs, extra_attrs)); return Ok(Some(item)); } + if self.eat_keyword(keywords::Async) { + // ASYNC FUNCTION ITEM + let unsafety = self.parse_unsafety(); + self.expect_keyword(keywords::Fn)?; + let fn_span = self.prev_span; + let (ident, item_, extra_attrs) = + self.parse_item_fn(unsafety, + IsAsync::Async, + respan(fn_span, Constness::NotConst), + Abi::Rust)?; + let prev_span = self.prev_span; + let item = self.mk_item(lo.to(prev_span), + ident, + item_, + visibility, + maybe_append(attrs, extra_attrs)); + return Ok(Some(item)); + } if self.check_keyword(keywords::Unsafe) && (self.look_ahead(1, |t| t.is_keyword(keywords::Trait)) || self.look_ahead(1, |t| t.is_keyword(keywords::Auto))) @@ -6737,6 +6761,7 @@ impl<'a> Parser<'a> { let fn_span = self.prev_span; let (ident, item_, extra_attrs) = self.parse_item_fn(Unsafety::Normal, + IsAsync::NotAsync, respan(fn_span, Constness::NotConst), Abi::Rust)?; let prev_span = self.prev_span; @@ -6762,6 +6787,7 @@ impl<'a> Parser<'a> { let fn_span = self.prev_span; let (ident, item_, extra_attrs) = self.parse_item_fn(Unsafety::Unsafe, + IsAsync::NotAsync, respan(fn_span, Constness::NotConst), abi)?; let prev_span = self.prev_span; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 7a55919f422..210742c55a5 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -373,14 +373,13 @@ pub fn vis_to_string(v: &ast::Visibility) -> String { } pub fn fun_to_string(decl: &ast::FnDecl, - unsafety: ast::Unsafety, - constness: ast::Constness, + header: ast::FnHeader, name: ast::Ident, generics: &ast::Generics) -> String { to_string(|s| { s.head("")?; - s.print_fn(decl, unsafety, constness, Abi::Rust, Some(name), + s.print_fn(decl, header, Some(name), generics, &codemap::dummy_spanned(ast::VisibilityKind::Inherited))?; s.end()?; // Close the head box s.end() // Close the outer box @@ -1118,9 +1117,8 @@ impl<'a> State<'a> { match item.node { ast::ForeignItemKind::Fn(ref decl, ref generics) => { self.head("")?; - self.print_fn(decl, ast::Unsafety::Normal, - ast::Constness::NotConst, - Abi::Rust, Some(item.ident), + self.print_fn(decl, ast::FnHeader::default(), + Some(item.ident), generics, &item.vis)?; self.end()?; // end head-ibox self.s.word(";")?; @@ -1249,13 +1247,11 @@ impl<'a> State<'a> { self.s.word(";")?; self.end()?; // end the outer cbox } - ast::ItemKind::Fn(ref decl, unsafety, constness, abi, ref typarams, ref body) => { + ast::ItemKind::Fn(ref decl, header, ref typarams, ref body) => { self.head("")?; self.print_fn( decl, - unsafety, - constness.node, - abi, + header, Some(item.ident), typarams, &item.vis @@ -1582,9 +1578,7 @@ impl<'a> State<'a> { vis: &ast::Visibility) -> io::Result<()> { self.print_fn(&m.decl, - m.unsafety, - m.constness.node, - m.abi, + m.header, Some(ident), &generics, vis) @@ -2740,13 +2734,11 @@ impl<'a> State<'a> { pub fn print_fn(&mut self, decl: &ast::FnDecl, - unsafety: ast::Unsafety, - constness: ast::Constness, - abi: abi::Abi, + header: ast::FnHeader, name: Option<ast::Ident>, generics: &ast::Generics, vis: &ast::Visibility) -> io::Result<()> { - self.print_fn_header_info(unsafety, constness, abi, vis)?; + self.print_fn_header_info(header, vis)?; if let Some(name) = name { self.nbsp()?; @@ -3058,9 +3050,7 @@ impl<'a> State<'a> { span: syntax_pos::DUMMY_SP, }; self.print_fn(decl, - unsafety, - ast::Constness::NotConst, - abi, + ast::FnHeader { unsafety, abi, ..ast::FnHeader::default() }, name, &generics, &codemap::dummy_spanned(ast::VisibilityKind::Inherited))?; @@ -3123,22 +3113,25 @@ impl<'a> State<'a> { } pub fn print_fn_header_info(&mut self, - unsafety: ast::Unsafety, - constness: ast::Constness, - abi: Abi, + header: ast::FnHeader, vis: &ast::Visibility) -> io::Result<()> { self.s.word(&visibility_qualified(vis, ""))?; - match constness { + match header.constness.node { ast::Constness::NotConst => {} ast::Constness::Const => self.word_nbsp("const")? } - self.print_unsafety(unsafety)?; + match header.asyncness { + ast::IsAsync::NotAsync => {} + ast::IsAsync::Async => self.word_nbsp("async")? + } + + self.print_unsafety(header.unsafety)?; - if abi != Abi::Rust { + if header.abi != Abi::Rust { self.word_nbsp("extern")?; - self.word_nbsp(&abi.to_string())?; + self.word_nbsp(&header.abi.to_string())?; } self.s.word("fn") diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index f896fa351b0..cfb29f562d7 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -124,24 +124,30 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { if is_test_fn(&self.cx, &i) || is_bench_fn(&self.cx, &i) { match i.node { - ast::ItemKind::Fn(_, ast::Unsafety::Unsafe, _, _, _, _) => { - let diag = self.cx.span_diagnostic; - diag.span_fatal(i.span, "unsafe functions cannot be used for tests").raise(); - } - _ => { - debug!("this is a test function"); - let test = Test { - span: i.span, - path: self.cx.path.clone(), - bench: is_bench_fn(&self.cx, &i), - ignore: is_ignored(&i), - should_panic: should_panic(&i, &self.cx), - allow_fail: is_allowed_fail(&i), - }; - self.cx.testfns.push(test); - self.tests.push(i.ident); + ast::ItemKind::Fn(_, header, _, _) => { + if header.unsafety == ast::Unsafety::Unsafe { + let diag = self.cx.span_diagnostic; + diag.span_fatal(i.span, "unsafe functions cannot be used for tests").raise(); + } + if header.asyncness == ast::IsAsync::Async { + let diag = self.cx.span_diagnostic; + diag.span_fatal(i.span, "async functions cannot be used for tests").raise(); + } } + _ => {}, } + + debug!("this is a test function"); + let test = Test { + span: i.span, + path: self.cx.path.clone(), + bench: is_bench_fn(&self.cx, &i), + ignore: is_ignored(&i), + should_panic: should_panic(&i, &self.cx), + allow_fail: is_allowed_fail(&i), + }; + self.cx.testfns.push(test); + self.tests.push(i.ident); } let mut item = i.into_inner(); @@ -338,7 +344,7 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { fn has_test_signature(_cx: &TestCtxt, i: &ast::Item) -> HasTestSignature { let has_should_panic_attr = attr::contains_name(&i.attrs, "should_panic"); match i.node { - ast::ItemKind::Fn(ref decl, _, _, _, ref generics, _) => { + ast::ItemKind::Fn(ref decl, _, ref generics, _) => { // If the termination trait is active, the compiler will check that the output // type implements the `Termination` trait as `libtest` enforces that. let has_output = match decl.output { @@ -396,7 +402,7 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool { fn has_bench_signature(_cx: &TestCtxt, i: &ast::Item) -> bool { match i.node { - ast::ItemKind::Fn(ref decl, _, _, _, _, _) => { + ast::ItemKind::Fn(ref decl, _, _, _) => { // NB: inadequate check, but we're running // well before resolve, can't get too deep. decl.inputs.len() == 1 @@ -537,9 +543,7 @@ fn mk_main(cx: &mut TestCtxt) -> P<ast::Item> { let main_ret_ty = ecx.ty(sp, ast::TyKind::Tup(vec![])); let main_body = ecx.block(sp, vec![call_test_main]); let main = ast::ItemKind::Fn(ecx.fn_decl(vec![], ast::FunctionRetTy::Ty(main_ret_ty)), - ast::Unsafety::Normal, - dummy_spanned(ast::Constness::NotConst), - ::rustc_target::spec::abi::Abi::Rust, + ast::FnHeader::default(), ast::Generics::default(), main_body); P(ast::Item { diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 613f1a4f113..3df96ff07c5 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -23,17 +23,15 @@ //! instance, a walker looking for item names in a module will miss all of //! those that are created by the expansion of a macro. -use rustc_target::spec::abi::Abi; use ast::*; use syntax_pos::Span; -use codemap::Spanned; use parse::token::Token; use tokenstream::{TokenTree, TokenStream}; #[derive(Copy, Clone, PartialEq, Eq)] pub enum FnKind<'a> { /// fn foo() or extern "Abi" fn foo() - ItemFn(Ident, Unsafety, Spanned<Constness>, Abi, &'a Visibility, &'a Block), + ItemFn(Ident, FnHeader, &'a Visibility, &'a Block), /// fn foo(&self) Method(Ident, &'a MethodSig, Option<&'a Visibility>, &'a Block), @@ -235,10 +233,10 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { visitor.visit_ty(typ); visitor.visit_expr(expr); } - ItemKind::Fn(ref declaration, unsafety, constness, abi, ref generics, ref body) => { + ItemKind::Fn(ref declaration, header, ref generics, ref body) => { visitor.visit_generics(generics); - visitor.visit_fn(FnKind::ItemFn(item.ident, unsafety, - constness, abi, &item.vis, body), + visitor.visit_fn(FnKind::ItemFn(item.ident, header, + &item.vis, body), declaration, item.span, item.id) @@ -544,7 +542,7 @@ pub fn walk_fn<'a, V>(visitor: &mut V, kind: FnKind<'a>, declaration: &'a FnDecl where V: Visitor<'a>, { match kind { - FnKind::ItemFn(_, _, _, _, _, body) => { + FnKind::ItemFn(_, _, _, body) => { walk_fn_decl(visitor, declaration); visitor.visit_block(body); } |
