1
Fork 0

ast::ItemKind::Fn: use ast::FnSig

This commit is contained in:
Mazdak Farrokhzad 2019-11-07 13:33:37 +01:00
parent 2cd48e8a3b
commit b4c6abcf9e
16 changed files with 51 additions and 63 deletions

View file

@ -306,7 +306,7 @@ impl LoweringContext<'_> {
self.lower_const_body(e) self.lower_const_body(e)
) )
} }
ItemKind::Fn(ref decl, header, ref generics, ref body) => { ItemKind::Fn(FnSig { ref decl, header }, ref generics, ref body) => {
let fn_def_id = self.resolver.definitions().local_def_id(id); let fn_def_id = self.resolver.definitions().local_def_id(id);
self.with_new_scopes(|this| { self.with_new_scopes(|this| {
this.current_item = Some(ident.span); this.current_item = Some(ident.span);

View file

@ -100,7 +100,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
// Pick the def data. This need not be unique, but the more // Pick the def data. This need not be unique, but the more
// information we encapsulate into, the better // information we encapsulate into, the better
let def_data = match i.kind { let def_data = match &i.kind {
ItemKind::Impl(..) => DefPathData::Impl, ItemKind::Impl(..) => DefPathData::Impl,
ItemKind::Mod(..) if i.ident.name == kw::Invalid => { ItemKind::Mod(..) if i.ident.name == kw::Invalid => {
return visit::walk_item(self, i); return visit::walk_item(self, i);
@ -109,19 +109,14 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) | ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) |
ItemKind::OpaqueTy(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::OpaqueTy(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) |
ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name), ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name),
ItemKind::Fn( ItemKind::Fn(sig, generics, body) if sig.header.asyncness.node.is_async() => {
ref decl,
ref header,
ref generics,
ref body,
) if header.asyncness.node.is_async() => {
return self.visit_async_fn( return self.visit_async_fn(
i.id, i.id,
i.ident.name, i.ident.name,
i.span, i.span,
header, &sig.header,
generics, generics,
decl, &sig.decl,
body, body,
) )
} }

View file

@ -786,14 +786,17 @@ impl<'a> ReplaceBodyWithLoop<'a> {
false false
} }
} }
fn is_sig_const(sig: &ast::FnSig) -> bool {
sig.header.constness.node == ast::Constness::Const || Self::should_ignore_fn(&sig.decl)
}
} }
impl<'a> MutVisitor for ReplaceBodyWithLoop<'a> { impl<'a> MutVisitor for ReplaceBodyWithLoop<'a> {
fn visit_item_kind(&mut self, i: &mut ast::ItemKind) { fn visit_item_kind(&mut self, i: &mut ast::ItemKind) {
let is_const = match i { let is_const = match i {
ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => true, ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => true,
ast::ItemKind::Fn(ref decl, ref header, _, _) => ast::ItemKind::Fn(ref sig, _, _) => Self::is_sig_const(sig),
header.constness.node == ast::Constness::Const || Self::should_ignore_fn(decl),
_ => false, _ => false,
}; };
self.run(is_const, |s| noop_visit_item_kind(i, s)) self.run(is_const, |s| noop_visit_item_kind(i, s))
@ -802,8 +805,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a> {
fn flat_map_trait_item(&mut self, i: ast::TraitItem) -> SmallVec<[ast::TraitItem; 1]> { fn flat_map_trait_item(&mut self, i: ast::TraitItem) -> SmallVec<[ast::TraitItem; 1]> {
let is_const = match i.kind { let is_const = match i.kind {
ast::TraitItemKind::Const(..) => true, ast::TraitItemKind::Const(..) => true,
ast::TraitItemKind::Method(ast::FnSig { ref decl, ref header, .. }, _) => ast::TraitItemKind::Method(ref sig, _) => Self::is_sig_const(sig),
header.constness.node == ast::Constness::Const || Self::should_ignore_fn(decl),
_ => false, _ => false,
}; };
self.run(is_const, |s| noop_flat_map_trait_item(i, s)) self.run(is_const, |s| noop_flat_map_trait_item(i, s))
@ -812,8 +814,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a> {
fn flat_map_impl_item(&mut self, i: ast::ImplItem) -> SmallVec<[ast::ImplItem; 1]> { fn flat_map_impl_item(&mut self, i: ast::ImplItem) -> SmallVec<[ast::ImplItem; 1]> {
let is_const = match i.kind { let is_const = match i.kind {
ast::ImplItemKind::Const(..) => true, ast::ImplItemKind::Const(..) => true,
ast::ImplItemKind::Method(ast::FnSig { ref decl, ref header, .. }, _) => ast::ImplItemKind::Method(ref sig, _) => Self::is_sig_const(sig),
header.constness.node == ast::Constness::Const || Self::should_ignore_fn(decl),
_ => false, _ => false,
}; };
self.run(is_const, |s| noop_flat_map_impl_item(i, s)) self.run(is_const, |s| noop_flat_map_impl_item(i, s))

View file

@ -575,12 +575,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
.note("only trait implementations may be annotated with default").emit(); .note("only trait implementations may be annotated with default").emit();
} }
} }
ItemKind::Fn(ref decl, ref header, ref generics, _) => { ItemKind::Fn(ref sig, ref generics, _) => {
self.visit_fn_header(header); self.visit_fn_header(&sig.header);
self.check_fn_decl(decl); self.check_fn_decl(&sig.decl);
// We currently do not permit const generics in `const fn`, as // We currently do not permit const generics in `const fn`, as
// this is tantamount to allowing compile-time dependent typing. // this is tantamount to allowing compile-time dependent typing.
if header.constness.node == Constness::Const { if sig.header.constness.node == Constness::Const {
// Look for const generics and error if we find any. // Look for const generics and error if we find any.
for param in &generics.params { for param in &generics.params {
match param.kind { match param.kind {

View file

@ -731,7 +731,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
match item.kind { match item.kind {
ItemKind::TyAlias(_, ref generics) | ItemKind::TyAlias(_, ref generics) |
ItemKind::OpaqueTy(_, ref generics) | ItemKind::OpaqueTy(_, ref generics) |
ItemKind::Fn(_, _, ref generics, _) => { ItemKind::Fn(_, ref generics, _) => {
self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes),
|this| visit::walk_item(this, item)); |this| visit::walk_item(this, item));
} }

View file

@ -1334,8 +1334,8 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
); );
} }
} }
Fn(ref decl, ref header, ref ty_params, ref body) => { Fn(ref sig, ref ty_params, ref body) => {
self.process_fn(item, &decl, &header, ty_params, &body) self.process_fn(item, &sig.decl, &sig.header, ty_params, &body)
} }
Static(ref typ, _, ref expr) => self.process_static_or_const_item(item, typ, expr), Static(ref typ, _, ref expr) => self.process_static_or_const_item(item, typ, expr),
Const(ref typ, ref expr) => self.process_static_or_const_item(item, &typ, &expr), Const(ref typ, ref expr) => self.process_static_or_const_item(item, &typ, &expr),

View file

@ -180,7 +180,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> { pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
match item.kind { match item.kind {
ast::ItemKind::Fn(ref decl, .., ref generics, _) => { ast::ItemKind::Fn(ref sig, .., ref generics, _) => {
let qualname = format!("::{}", let qualname = format!("::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id))); self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
filter!(self.span_utils, item.ident.span); filter!(self.span_utils, item.ident.span);
@ -190,7 +190,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
span: self.span_from_span(item.ident.span), span: self.span_from_span(item.ident.span),
name: item.ident.to_string(), name: item.ident.to_string(),
qualname, qualname,
value: make_signature(decl, generics), value: make_signature(&sig.decl, generics),
parent: None, parent: None,
children: vec![], children: vec![],
decl_id: None, decl_id: None,

View file

@ -376,7 +376,7 @@ impl Sig for ast::Item {
Ok(extend_sig(ty, text, defs, vec![])) Ok(extend_sig(ty, text, defs, vec![]))
} }
ast::ItemKind::Fn(ref decl, header, ref generics, _) => { ast::ItemKind::Fn(ast::FnSig { ref decl, header }, ref generics, _) => {
let mut text = String::new(); let mut text = String::new();
if header.constness.node == ast::Constness::Const { if header.constness.node == ast::Constness::Const {
text.push_str("const "); text.push_str("const ");

View file

@ -2433,7 +2433,7 @@ pub enum ItemKind {
/// A function declaration (`fn`). /// A function declaration (`fn`).
/// ///
/// E.g., `fn foo(bar: usize) -> usize { .. }`. /// E.g., `fn foo(bar: usize) -> usize { .. }`.
Fn(P<FnDecl>, FnHeader, Generics, P<Block>), Fn(FnSig, Generics, P<Block>),
/// A module declaration (`mod`). /// A module declaration (`mod`).
/// ///
/// E.g., `mod foo;` or `mod foo { .. }`. /// E.g., `mod foo;` or `mod foo { .. }`.

View file

@ -357,7 +357,7 @@ pub fn visit_bounds<T: MutVisitor>(bounds: &mut GenericBounds, vis: &mut T) {
} }
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
pub fn visit_method_sig<T: MutVisitor>(FnSig { header, decl }: &mut FnSig, vis: &mut T) { pub fn visit_fn_sig<T: MutVisitor>(FnSig { header, decl }: &mut FnSig, vis: &mut T) {
vis.visit_fn_header(header); vis.visit_fn_header(header);
vis.visit_fn_decl(decl); vis.visit_fn_decl(decl);
} }
@ -878,9 +878,8 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
vis.visit_ty(ty); vis.visit_ty(ty);
vis.visit_expr(expr); vis.visit_expr(expr);
} }
ItemKind::Fn(decl, header, generics, body) => { ItemKind::Fn(sig, generics, body) => {
vis.visit_fn_decl(decl); visit_fn_sig(sig, vis);
vis.visit_fn_header(header);
vis.visit_generics(generics); vis.visit_generics(generics);
vis.visit_block(body); vis.visit_block(body);
} }
@ -938,7 +937,7 @@ pub fn noop_flat_map_trait_item<T: MutVisitor>(mut item: TraitItem, vis: &mut T)
visit_opt(default, |default| vis.visit_expr(default)); visit_opt(default, |default| vis.visit_expr(default));
} }
TraitItemKind::Method(sig, body) => { TraitItemKind::Method(sig, body) => {
visit_method_sig(sig, vis); visit_fn_sig(sig, vis);
visit_opt(body, |body| vis.visit_block(body)); visit_opt(body, |body| vis.visit_block(body));
} }
TraitItemKind::Type(bounds, default) => { TraitItemKind::Type(bounds, default) => {
@ -970,7 +969,7 @@ pub fn noop_flat_map_impl_item<T: MutVisitor>(mut item: ImplItem, visitor: &mut
visitor.visit_expr(expr); visitor.visit_expr(expr);
} }
ImplItemKind::Method(sig, body) => { ImplItemKind::Method(sig, body) => {
visit_method_sig(sig, visitor); visit_fn_sig(sig, visitor);
visitor.visit_block(body); visitor.visit_block(body);
} }
ImplItemKind::TyAlias(ty) => visitor.visit_ty(ty), ImplItemKind::TyAlias(ty) => visitor.visit_ty(ty),

View file

@ -1800,7 +1800,7 @@ impl<'a> Parser<'a> {
is_name_required: |_| true, is_name_required: |_| true,
})?; })?;
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
let kind = ItemKind::Fn(decl, header, generics, body); let kind = ItemKind::Fn(FnSig { decl, header }, generics, body);
self.mk_item_with_info(attrs, lo, vis, (ident, kind, Some(inner_attrs))) self.mk_item_with_info(attrs, lo, vis, (ident, kind, Some(inner_attrs)))
} }

View file

@ -1199,11 +1199,11 @@ impl<'a> State<'a> {
self.s.word(";"); self.s.word(";");
self.end(); // end the outer cbox self.end(); // end the outer cbox
} }
ast::ItemKind::Fn(ref decl, header, ref param_names, ref body) => { ast::ItemKind::Fn(ref sig, ref param_names, ref body) => {
self.head(""); self.head("");
self.print_fn( self.print_fn(
decl, &sig.decl,
header, sig.header,
Some(item.ident), Some(item.ident),
param_names, param_names,
&item.vis &item.vis

View file

@ -244,12 +244,11 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
visitor.visit_ty(typ); visitor.visit_ty(typ);
visitor.visit_expr(expr); visitor.visit_expr(expr);
} }
ItemKind::Fn(ref declaration, ref header, ref generics, ref body) => { ItemKind::Fn(ref sig, ref generics, ref body) => {
visitor.visit_generics(generics); visitor.visit_generics(generics);
visitor.visit_fn_header(header); visitor.visit_fn_header(&sig.header);
visitor.visit_fn(FnKind::ItemFn(item.ident, header, visitor.visit_fn(FnKind::ItemFn(item.ident, &sig.header, &item.vis, body),
&item.vis, body), &sig.decl,
declaration,
item.span, item.span,
item.id) item.id)
} }

View file

@ -1,7 +1,7 @@
use crate::util::check_builtin_macro_attribute; use crate::util::check_builtin_macro_attribute;
use syntax::ast::{ItemKind, Mutability, Stmt, Ty, TyKind, Unsafety}; use syntax::ast::{ItemKind, Mutability, Stmt, Ty, TyKind, Unsafety};
use syntax::ast::{self, Param, Attribute, Expr, FnHeader, Generics, Ident}; use syntax::ast::{self, Param, Attribute, Expr, FnSig, FnHeader, Generics, Ident};
use syntax::expand::allocator::{AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS}; use syntax::expand::allocator::{AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS};
use syntax::ptr::P; use syntax::ptr::P;
use syntax::symbol::{kw, sym, Symbol}; use syntax::symbol::{kw, sym, Symbol};
@ -73,15 +73,10 @@ impl AllocFnFactory<'_, '_> {
.collect(); .collect();
let result = self.call_allocator(method.name, args); let result = self.call_allocator(method.name, args);
let (output_ty, output_expr) = self.ret_ty(&method.output, result); let (output_ty, output_expr) = self.ret_ty(&method.output, result);
let kind = ItemKind::Fn( let decl = self.cx.fn_decl(abi_args, ast::FunctionRetTy::Ty(output_ty));
self.cx.fn_decl(abi_args, ast::FunctionRetTy::Ty(output_ty)), let header = FnHeader { unsafety: Unsafety::Unsafe, ..FnHeader::default() };
FnHeader { let sig = FnSig { decl, header };
unsafety: Unsafety::Unsafe, let kind = ItemKind::Fn(sig, Generics::default(), self.cx.block_expr(output_expr));
..FnHeader::default()
},
Generics::default(),
self.cx.block_expr(output_expr),
);
let item = self.cx.item( let item = self.cx.item(
self.span, self.span,
self.cx.ident_of(&self.kind.fn_name(method.name), self.span), self.cx.ident_of(&self.kind.fn_name(method.name), self.span),

View file

@ -310,15 +310,15 @@ fn test_type(cx: &ExtCtxt<'_>) -> TestType {
fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool { fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
let has_should_panic_attr = attr::contains_name(&i.attrs, sym::should_panic); let has_should_panic_attr = attr::contains_name(&i.attrs, sym::should_panic);
let ref sd = cx.parse_sess.span_diagnostic; let ref sd = cx.parse_sess.span_diagnostic;
if let ast::ItemKind::Fn(ref decl, ref header, ref generics, _) = i.kind { if let ast::ItemKind::Fn(ref sig, ref generics, _) = i.kind {
if header.unsafety == ast::Unsafety::Unsafe { if sig.header.unsafety == ast::Unsafety::Unsafe {
sd.span_err( sd.span_err(
i.span, i.span,
"unsafe functions cannot be used for tests" "unsafe functions cannot be used for tests"
); );
return false return false
} }
if header.asyncness.node.is_async() { if sig.header.asyncness.node.is_async() {
sd.span_err( sd.span_err(
i.span, i.span,
"async functions cannot be used for tests" "async functions cannot be used for tests"
@ -329,13 +329,13 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
// 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 decl.output { let has_output = match sig.decl.output {
ast::FunctionRetTy::Default(..) => false, ast::FunctionRetTy::Default(..) => false,
ast::FunctionRetTy::Ty(ref t) if t.kind.is_unit() => false, ast::FunctionRetTy::Ty(ref t) if t.kind.is_unit() => false,
_ => true _ => true
}; };
if !decl.inputs.is_empty() { if !sig.decl.inputs.is_empty() {
sd.span_err(i.span, "functions used as tests can not have any arguments"); sd.span_err(i.span, "functions used as tests can not have any arguments");
return false; return false;
} }
@ -361,10 +361,10 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
} }
fn has_bench_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool { fn has_bench_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
let has_sig = if let ast::ItemKind::Fn(ref decl, _, _, _) = i.kind { let has_sig = if let ast::ItemKind::Fn(ref sig, _, _) = i.kind {
// N.B., inadequate check, but we're running // N.B., inadequate check, but we're running
// well before resolve, can't get too deep. // well before resolve, can't get too deep.
decl.inputs.len() == 1 sig.decl.inputs.len() == 1
} else { } else {
false false
}; };

View file

@ -306,10 +306,9 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
ecx.block(sp, vec![call_test_main]) ecx.block(sp, vec![call_test_main])
}; };
let main = ast::ItemKind::Fn(ecx.fn_decl(vec![], ast::FunctionRetTy::Ty(main_ret_ty)), let decl = ecx.fn_decl(vec![], ast::FunctionRetTy::Ty(main_ret_ty));
ast::FnHeader::default(), let sig = ast::FnSig { decl, header: ast::FnHeader::default() };
ast::Generics::default(), let main = ast::ItemKind::Fn(sig, ast::Generics::default(), main_body);
main_body);
// Honor the reexport_test_harness_main attribute // Honor the reexport_test_harness_main attribute
let main_id = match cx.reexport_test_harness_main { let main_id = match cx.reexport_test_harness_main {