Do not store attrs in FnKind.

This commit is contained in:
Camille GILLOT 2020-11-27 09:24:42 +01:00
parent f5dc5dcca3
commit 8e816056a5
16 changed files with 51 additions and 70 deletions

View file

@ -101,29 +101,21 @@ where
#[derive(Copy, Clone)]
pub enum FnKind<'a> {
/// `#[xxx] pub async/const/extern "Abi" fn foo()`
ItemFn(Ident, &'a Generics<'a>, FnHeader, &'a Visibility<'a>, &'a [Attribute]),
ItemFn(Ident, &'a Generics<'a>, FnHeader, &'a Visibility<'a>),
/// `fn foo(&self)`
Method(Ident, &'a FnSig<'a>, Option<&'a Visibility<'a>>, &'a [Attribute]),
Method(Ident, &'a FnSig<'a>, Option<&'a Visibility<'a>>),
/// `|x, y| {}`
Closure(&'a [Attribute]),
Closure,
}
impl<'a> FnKind<'a> {
pub fn attrs(&self) -> &'a [Attribute] {
match *self {
FnKind::ItemFn(.., attrs) => attrs,
FnKind::Method(.., attrs) => attrs,
FnKind::Closure(attrs) => attrs,
}
}
pub fn header(&self) -> Option<&FnHeader> {
match *self {
FnKind::ItemFn(_, _, ref header, _, _) => Some(header),
FnKind::Method(_, ref sig, _, _) => Some(&sig.header),
FnKind::Closure(_) => None,
FnKind::ItemFn(_, _, ref header, _) => Some(header),
FnKind::Method(_, ref sig, _) => Some(&sig.header),
FnKind::Closure => None,
}
}
}
@ -579,7 +571,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
visitor.visit_nested_body(body);
}
ItemKind::Fn(ref sig, ref generics, body_id) => visitor.visit_fn(
FnKind::ItemFn(item.ident, generics, sig.header, &item.vis, &item.attrs),
FnKind::ItemFn(item.ident, generics, sig.header, &item.vis),
&sig.decl,
body_id,
item.span,
@ -940,7 +932,7 @@ pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'
FnKind::ItemFn(_, generics, ..) => {
visitor.visit_generics(generics);
}
FnKind::Method(..) | FnKind::Closure(_) => {}
FnKind::Method(..) | FnKind::Closure => {}
}
}
@ -977,7 +969,7 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
}
TraitItemKind::Fn(ref sig, TraitFn::Provided(body_id)) => {
visitor.visit_fn(
FnKind::Method(trait_item.ident, sig, None, &trait_item.attrs),
FnKind::Method(trait_item.ident, sig, None),
&sig.decl,
body_id,
trait_item.span,
@ -1027,7 +1019,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
}
ImplItemKind::Fn(ref sig, body_id) => {
visitor.visit_fn(
FnKind::Method(impl_item.ident, sig, Some(&impl_item.vis), &impl_item.attrs),
FnKind::Method(impl_item.ident, sig, Some(&impl_item.vis)),
&sig.decl,
body_id,
impl_item.span,
@ -1162,7 +1154,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
}
ExprKind::Closure(_, ref function_declaration, body, _fn_decl_span, _gen) => visitor
.visit_fn(
FnKind::Closure(&expression.attrs),
FnKind::Closure,
function_declaration,
body,
expression.span,

View file

@ -400,14 +400,15 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
}
_ => (),
},
FnKind::ItemFn(ident, _, header, _, attrs) => {
FnKind::ItemFn(ident, _, header, _) => {
let attrs = cx.tcx.hir().attrs(id);
// Skip foreign-ABI #[no_mangle] functions (Issue #31924)
if header.abi != Abi::Rust && cx.sess().contains_name(attrs, sym::no_mangle) {
return;
}
self.check_snake_case(cx, "function", ident);
}
FnKind::Closure(_) => (),
FnKind::Closure => (),
}
}

View file

@ -12,7 +12,6 @@
//! for the `Code` associated with a particular NodeId.
use crate::hir::map::Map;
use rustc_ast::Attribute;
use rustc_hir as hir;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{Expr, FnDecl, Node};
@ -105,7 +104,6 @@ struct ItemFnParts<'a> {
body: hir::BodyId,
id: hir::HirId,
span: Span,
attrs: &'a [Attribute],
}
/// These are all the components one can extract from a closure expr
@ -115,18 +113,11 @@ struct ClosureParts<'a> {
body: hir::BodyId,
id: hir::HirId,
span: Span,
attrs: &'a [Attribute],
}
impl<'a> ClosureParts<'a> {
fn new(
d: &'a FnDecl<'a>,
b: hir::BodyId,
id: hir::HirId,
s: Span,
attrs: &'a [Attribute],
) -> Self {
ClosureParts { decl: d, body: b, id, span: s, attrs }
fn new(d: &'a FnDecl<'a>, b: hir::BodyId, id: hir::HirId, s: Span) -> Self {
ClosureParts { decl: d, body: b, id, span: s }
}
}
@ -146,7 +137,7 @@ impl<'a> FnLikeNode<'a> {
pub fn body(self) -> hir::BodyId {
self.handle(
|i: ItemFnParts<'a>| i.body,
|_, _, _: &'a hir::FnSig<'a>, _, body: hir::BodyId, _, _| body,
|_, _, _: &'a hir::FnSig<'a>, _, body: hir::BodyId, _| body,
|c: ClosureParts<'a>| c.body,
)
}
@ -154,7 +145,7 @@ impl<'a> FnLikeNode<'a> {
pub fn decl(self) -> &'a FnDecl<'a> {
self.handle(
|i: ItemFnParts<'a>| &*i.decl,
|_, _, sig: &'a hir::FnSig<'a>, _, _, _, _| &sig.decl,
|_, _, sig: &'a hir::FnSig<'a>, _, _, _| &sig.decl,
|c: ClosureParts<'a>| c.decl,
)
}
@ -162,7 +153,7 @@ impl<'a> FnLikeNode<'a> {
pub fn span(self) -> Span {
self.handle(
|i: ItemFnParts<'_>| i.span,
|_, _, _: &'a hir::FnSig<'a>, _, _, span, _| span,
|_, _, _: &'a hir::FnSig<'a>, _, _, span| span,
|c: ClosureParts<'_>| c.span,
)
}
@ -170,7 +161,7 @@ impl<'a> FnLikeNode<'a> {
pub fn id(self) -> hir::HirId {
self.handle(
|i: ItemFnParts<'_>| i.id,
|id, _, _: &'a hir::FnSig<'a>, _, _, _, _| id,
|id, _, _: &'a hir::FnSig<'a>, _, _, _| id,
|c: ClosureParts<'_>| c.id,
)
}
@ -189,12 +180,11 @@ impl<'a> FnLikeNode<'a> {
pub fn kind(self) -> FnKind<'a> {
let item = |p: ItemFnParts<'a>| -> FnKind<'a> {
FnKind::ItemFn(p.ident, p.generics, p.header, p.vis, p.attrs)
};
let closure = |c: ClosureParts<'a>| FnKind::Closure(c.attrs);
let method = |_, ident: Ident, sig: &'a hir::FnSig<'a>, vis, _, _, attrs| {
FnKind::Method(ident, sig, vis, attrs)
FnKind::ItemFn(p.ident, p.generics, p.header, p.vis)
};
let closure = |_: ClosureParts<'a>| FnKind::Closure;
let method =
|_, ident: Ident, sig: &'a hir::FnSig<'a>, vis, _, _| FnKind::Method(ident, sig, vis);
self.handle(item, method, closure)
}
@ -208,7 +198,6 @@ impl<'a> FnLikeNode<'a> {
Option<&'a hir::Visibility<'a>>,
hir::BodyId,
Span,
&'a [Attribute],
) -> A,
C: FnOnce(ClosureParts<'a>) -> A,
{
@ -221,7 +210,6 @@ impl<'a> FnLikeNode<'a> {
body: block,
vis: &i.vis,
span: i.span,
attrs: &i.attrs,
header: sig.header,
generics,
}),
@ -229,19 +217,19 @@ impl<'a> FnLikeNode<'a> {
},
Node::TraitItem(ti) => match ti.kind {
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
method(ti.hir_id(), ti.ident, sig, None, body, ti.span, &ti.attrs)
method(ti.hir_id(), ti.ident, sig, None, body, ti.span)
}
_ => bug!("trait method FnLikeNode that is not fn-like"),
},
Node::ImplItem(ii) => match ii.kind {
hir::ImplItemKind::Fn(ref sig, body) => {
method(ii.hir_id(), ii.ident, sig, Some(&ii.vis), body, ii.span, &ii.attrs)
method(ii.hir_id(), ii.ident, sig, Some(&ii.vis), body, ii.span)
}
_ => bug!("impl method FnLikeNode that is not fn-like"),
},
Node::Expr(e) => match e.kind {
hir::ExprKind::Closure(_, ref decl, block, _fn_decl_span, _gen) => {
closure(ClosureParts::new(&decl, block, e.hir_id, e.span, &e.attrs))
closure(ClosureParts::new(&decl, block, e.hir_id, e.span))
}
_ => bug!("expr FnLikeNode that is not fn-like"),
},

View file

@ -15,7 +15,7 @@ crate fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
if let Some(fn_like_node) = FnLikeNode::from_node(tcx.hir().get(hir_id)) {
if let FnKind::Closure(_) = fn_like_node.kind() {
if let FnKind::Closure = fn_like_node.kind() {
// closures can't recur, so they don't matter.
return;
}

View file

@ -46,7 +46,7 @@ impl<'tcx> Visitor<'tcx> for CheckNakedFunctions<'tcx> {
let fn_header;
match fk {
FnKind::Closure(..) => {
FnKind::Closure => {
// Closures with a naked attribute are rejected during attribute
// check. Don't validate them any further.
return;
@ -62,7 +62,8 @@ impl<'tcx> Visitor<'tcx> for CheckNakedFunctions<'tcx> {
}
}
let naked = fk.attrs().iter().any(|attr| attr.has_name(sym::naked));
let attrs = self.tcx.hir().attrs(hir_id);
let naked = attrs.iter().any(|attr| attr.has_name(sym::naked));
if naked {
let body = self.tcx.hir().body(body_id);
check_abi(self.tcx, hir_id, fn_header.abi, ident_span);

View file

@ -354,7 +354,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> {
hir_id: hir::HirId,
) {
assert!(
matches!(fk, intravisit::FnKind::Closure(..)),
matches!(fk, intravisit::FnKind::Closure),
"visit_fn invoked for something other than a closure"
);

View file

@ -76,8 +76,8 @@ impl CognitiveComplexity {
if rust_cc > self.limit.limit() {
let fn_span = match kind {
FnKind::ItemFn(ident, _, _, _, _) | FnKind::Method(ident, _, _, _) => ident.span,
FnKind::Closure(_) => {
FnKind::ItemFn(ident, _, _, _) | FnKind::Method(ident, _, _) => ident.span,
FnKind::Closure => {
let header_span = body_span.with_hi(decl.output.span().lo());
let pos = snippet_opt(cx, header_span).and_then(|snip| {
let low_offset = snip.find('|')?;

View file

@ -251,9 +251,9 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
hir_id: hir::HirId,
) {
let unsafety = match kind {
intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }, _, _) => unsafety,
intravisit::FnKind::Method(_, sig, _, _) => sig.header.unsafety,
intravisit::FnKind::Closure(_) => return,
intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }, _) => unsafety,
intravisit::FnKind::Method(_, sig, _) => sig.header.unsafety,
intravisit::FnKind::Closure => return,
};
// don't warn for implementations, it's not their fault
@ -267,9 +267,8 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
..
},
_,
_,
)
| intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }, _, _) => {
| intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }, _) => {
self.check_arg_number(cx, decl, span.with_hi(decl.output.span().hi()))
},
_ => {},

View file

@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
_: Span,
hir_id: HirId,
) {
if let FnKind::Closure(_) = kind {
if let FnKind::Closure = kind {
return;
}
let ret_ty = utils::return_ty(cx, hir_id);

View file

@ -278,7 +278,7 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints {
span: Span,
_: HirId,
) {
if let FnKind::Closure(_) = k {
if let FnKind::Closure = k {
// Does not apply to closures
return;
}

View file

@ -133,7 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
return;
}
},
FnKind::Closure(..) => return,
FnKind::Closure => return,
}
let mir = cx.tcx.optimized_mir(def_id);

View file

@ -80,13 +80,14 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
}
match kind {
FnKind::ItemFn(.., header, _, attrs) => {
FnKind::ItemFn(.., header, _) => {
let attrs = cx.tcx.hir().attrs(hir_id);
if header.abi != Abi::Rust || requires_exact_signature(attrs) {
return;
}
},
FnKind::Method(..) => (),
FnKind::Closure(..) => return,
FnKind::Closure => return,
}
// Exclude non-inherent impls

View file

@ -43,9 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for PanicInResultFn {
span: Span,
hir_id: hir::HirId,
) {
if !matches!(fn_kind, FnKind::Closure(_))
&& is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym::result_type)
{
if !matches!(fn_kind, FnKind::Closure) && is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym::result_type) {
lint_impl_body(cx, span, body);
}
}

View file

@ -224,10 +224,11 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue {
}
match kind {
FnKind::ItemFn(.., header, _, attrs) => {
FnKind::ItemFn(.., header, _) => {
if header.abi != Abi::Rust {
return;
}
let attrs = cx.tcx.hir().attrs(hir_id);
for a in attrs {
if let Some(meta_items) = a.meta_item_list() {
if a.has_name(sym::proc_macro_derive)
@ -239,7 +240,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue {
}
},
FnKind::Method(..) => (),
FnKind::Closure(..) => return,
FnKind::Closure => return,
}
// Exclude non-inherent impls

View file

@ -131,7 +131,7 @@ impl<'tcx> LateLintPass<'tcx> for Return {
_: HirId,
) {
match kind {
FnKind::Closure(_) => {
FnKind::Closure => {
// when returning without value in closure, replace this `return`
// with an empty block to prevent invalid suggestion (see #6501)
let replacement = if let ExprKind::Ret(None) = &body.value.kind {

View file

@ -66,12 +66,12 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
) {
// Abort if public function/method or closure.
match fn_kind {
FnKind::ItemFn(.., visibility, _) | FnKind::Method(.., Some(visibility), _) => {
FnKind::ItemFn(.., visibility) | FnKind::Method(.., Some(visibility)) => {
if visibility.node.is_pub() {
return;
}
},
FnKind::Closure(..) => return,
FnKind::Closure => return,
_ => (),
}