Visit generics inside visit_fn.
This commit is contained in:
parent
aa2b5ef635
commit
e47f66dc0d
@ -35,7 +35,7 @@ pub enum FnCtxt {
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum FnKind<'a> {
|
||||
/// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`.
|
||||
Fn(FnCtxt, Ident, &'a FnSig, &'a Visibility, Option<&'a Block>),
|
||||
Fn(FnCtxt, Ident, &'a FnSig, &'a Visibility, &'a Generics, Option<&'a Block>),
|
||||
|
||||
/// E.g., `|x, y| body`.
|
||||
Closure(&'a FnDecl, &'a Expr),
|
||||
@ -44,7 +44,7 @@ pub enum FnKind<'a> {
|
||||
impl<'a> FnKind<'a> {
|
||||
pub fn header(&self) -> Option<&'a FnHeader> {
|
||||
match *self {
|
||||
FnKind::Fn(_, _, sig, _, _) => Some(&sig.header),
|
||||
FnKind::Fn(_, _, sig, _, _, _) => Some(&sig.header),
|
||||
FnKind::Closure(_, _) => None,
|
||||
}
|
||||
}
|
||||
@ -58,7 +58,7 @@ pub fn ident(&self) -> Option<&Ident> {
|
||||
|
||||
pub fn decl(&self) -> &'a FnDecl {
|
||||
match self {
|
||||
FnKind::Fn(_, _, sig, _, _) => &sig.decl,
|
||||
FnKind::Fn(_, _, sig, _, _, _) => &sig.decl,
|
||||
FnKind::Closure(decl, _) => decl,
|
||||
}
|
||||
}
|
||||
@ -295,8 +295,8 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
|
||||
walk_list!(visitor, visit_expr, expr);
|
||||
}
|
||||
ItemKind::Fn(box Fn { defaultness: _, ref generics, ref sig, ref body }) => {
|
||||
visitor.visit_generics(generics);
|
||||
let kind = FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, body.as_deref());
|
||||
let kind =
|
||||
FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, generics, body.as_deref());
|
||||
visitor.visit_fn(kind, item.span, item.id)
|
||||
}
|
||||
ItemKind::Mod(_unsafety, ref mod_kind) => match mod_kind {
|
||||
@ -561,8 +561,7 @@ pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignI
|
||||
walk_list!(visitor, visit_expr, expr);
|
||||
}
|
||||
ForeignItemKind::Fn(box Fn { defaultness: _, ref generics, ref sig, ref body }) => {
|
||||
visitor.visit_generics(generics);
|
||||
let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, body.as_deref());
|
||||
let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body.as_deref());
|
||||
visitor.visit_fn(kind, span, id);
|
||||
}
|
||||
ForeignItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
|
||||
@ -644,7 +643,8 @@ pub fn walk_fn_decl<'a, V: Visitor<'a>>(visitor: &mut V, function_declaration: &
|
||||
|
||||
pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>, _span: Span) {
|
||||
match kind {
|
||||
FnKind::Fn(_, _, sig, _, body) => {
|
||||
FnKind::Fn(_, _, sig, _, generics, body) => {
|
||||
visitor.visit_generics(generics);
|
||||
visitor.visit_fn_header(&sig.header);
|
||||
walk_fn_decl(visitor, &sig.decl);
|
||||
walk_list!(visitor, visit_block, body);
|
||||
@ -667,8 +667,7 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem,
|
||||
walk_list!(visitor, visit_expr, expr);
|
||||
}
|
||||
AssocItemKind::Fn(box Fn { defaultness: _, ref generics, ref sig, ref body }) => {
|
||||
visitor.visit_generics(generics);
|
||||
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, body.as_deref());
|
||||
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref());
|
||||
visitor.visit_fn(kind, span, id);
|
||||
}
|
||||
AssocItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
|
||||
|
@ -91,16 +91,18 @@ fn with_banned_impl_trait(&mut self, f: impl FnOnce(&mut Self)) {
|
||||
self.is_impl_trait_banned = old;
|
||||
}
|
||||
|
||||
fn with_tilde_const_allowed(&mut self, f: impl FnOnce(&mut Self)) {
|
||||
let old = mem::replace(&mut self.is_tilde_const_allowed, true);
|
||||
fn with_tilde_const(&mut self, allowed: bool, f: impl FnOnce(&mut Self)) {
|
||||
let old = mem::replace(&mut self.is_tilde_const_allowed, allowed);
|
||||
f(self);
|
||||
self.is_tilde_const_allowed = old;
|
||||
}
|
||||
|
||||
fn with_tilde_const_allowed(&mut self, f: impl FnOnce(&mut Self)) {
|
||||
self.with_tilde_const(true, f)
|
||||
}
|
||||
|
||||
fn with_banned_tilde_const(&mut self, f: impl FnOnce(&mut Self)) {
|
||||
let old = mem::replace(&mut self.is_tilde_const_allowed, false);
|
||||
f(self);
|
||||
self.is_tilde_const_allowed = old;
|
||||
self.with_tilde_const(false, f)
|
||||
}
|
||||
|
||||
fn with_let_management(
|
||||
@ -1202,12 +1204,8 @@ fn visit_item(&mut self, item: &'a Item) {
|
||||
}
|
||||
self.visit_vis(&item.vis);
|
||||
self.visit_ident(item.ident);
|
||||
if let Const::Yes(_) = sig.header.constness {
|
||||
self.with_tilde_const_allowed(|this| this.visit_generics(generics));
|
||||
} else {
|
||||
self.visit_generics(generics);
|
||||
}
|
||||
let kind = FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, body.as_deref());
|
||||
let kind =
|
||||
FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, generics, body.as_deref());
|
||||
self.visit_fn(kind, item.span, item.id);
|
||||
walk_list!(self, visit_attribute, &item.attrs);
|
||||
return; // Avoid visiting again.
|
||||
@ -1555,13 +1553,14 @@ fn visit_fn(&mut self, fk: FnKind<'a>, span: Span, id: NodeId) {
|
||||
FnSig { span: sig_span, header: FnHeader { ext: Extern::Implicit, .. }, .. },
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
) = fk
|
||||
{
|
||||
self.maybe_lint_missing_abi(*sig_span, id);
|
||||
}
|
||||
|
||||
// Functions without bodies cannot have patterns.
|
||||
if let FnKind::Fn(ctxt, _, sig, _, None) = fk {
|
||||
if let FnKind::Fn(ctxt, _, sig, _, _, None) = fk {
|
||||
Self::check_decl_no_pat(&sig.decl, |span, ident, mut_ident| {
|
||||
let (code, msg, label) = match ctxt {
|
||||
FnCtxt::Foreign => (
|
||||
@ -1596,7 +1595,11 @@ fn visit_fn(&mut self, fk: FnKind<'a>, span: Span, id: NodeId) {
|
||||
});
|
||||
}
|
||||
|
||||
visit::walk_fn(self, fk, span);
|
||||
let tilde_const_allowed =
|
||||
matches!(fk.header(), Some(FnHeader { constness: Const::Yes(_), .. }))
|
||||
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)));
|
||||
|
||||
self.with_tilde_const(tilde_const_allowed, |this| visit::walk_fn(this, fk, span));
|
||||
}
|
||||
|
||||
fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
|
||||
@ -1670,9 +1673,14 @@ fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
|
||||
{
|
||||
self.visit_vis(&item.vis);
|
||||
self.visit_ident(item.ident);
|
||||
self.with_tilde_const_allowed(|this| this.visit_generics(generics));
|
||||
let kind =
|
||||
FnKind::Fn(FnCtxt::Assoc(ctxt), item.ident, sig, &item.vis, body.as_deref());
|
||||
let kind = FnKind::Fn(
|
||||
FnCtxt::Assoc(ctxt),
|
||||
item.ident,
|
||||
sig,
|
||||
&item.vis,
|
||||
generics,
|
||||
body.as_deref(),
|
||||
);
|
||||
self.visit_fn(kind, item.span, item.id);
|
||||
}
|
||||
_ => self
|
||||
|
@ -441,6 +441,7 @@ fn check_fn(&mut self, cx: &EarlyContext<'_>, fk: FnKind<'_>, span: Span, _: ast
|
||||
_,
|
||||
ast::FnSig { header: ast::FnHeader { unsafety: ast::Unsafe::Yes(_), .. }, .. },
|
||||
_,
|
||||
_,
|
||||
body,
|
||||
) = fk
|
||||
{
|
||||
|
@ -158,7 +158,7 @@ fn visit_fn(&mut self, fk: ast_visit::FnKind<'a>, span: Span, id: ast::NodeId) {
|
||||
|
||||
// Explicitly check for lints associated with 'closure_id', since
|
||||
// it does not have a corresponding AST node
|
||||
if let ast_visit::FnKind::Fn(_, _, sig, _, _) = fk {
|
||||
if let ast_visit::FnKind::Fn(_, _, sig, _, _, _) = fk {
|
||||
if let ast::Async::Yes { closure_id, .. } = sig.header.asyncness {
|
||||
self.check_id(closure_id);
|
||||
}
|
||||
|
@ -133,8 +133,10 @@ fn visit_item(&mut self, i: &'a Item) {
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
|
||||
if let FnKind::Fn(_, _, sig, _, body) = fn_kind {
|
||||
if let FnKind::Fn(_, _, sig, _, generics, body) = fn_kind {
|
||||
if let Async::Yes { closure_id, return_impl_trait_id, .. } = sig.header.asyncness {
|
||||
self.visit_generics(generics);
|
||||
|
||||
let return_impl_trait_id =
|
||||
self.create_def(return_impl_trait_id, DefPathData::ImplTrait, span);
|
||||
|
||||
|
@ -537,10 +537,12 @@ fn visit_fn(&mut self, fn_kind: FnKind<'ast>, sp: Span, _: NodeId) {
|
||||
let rib_kind = match fn_kind {
|
||||
// Bail if the function is foreign, and thus cannot validly have
|
||||
// a body, or if there's no body for some other reason.
|
||||
FnKind::Fn(FnCtxt::Foreign, _, sig, ..) | FnKind::Fn(_, _, sig, .., None) => {
|
||||
FnKind::Fn(FnCtxt::Foreign, _, sig, _, generics, _)
|
||||
| FnKind::Fn(_, _, sig, _, generics, None) => {
|
||||
// We don't need to deal with patterns in parameters, because
|
||||
// they are not possible for foreign or bodiless functions.
|
||||
self.visit_fn_header(&sig.header);
|
||||
self.visit_generics(generics);
|
||||
visit::walk_fn_decl(self, &sig.decl);
|
||||
return;
|
||||
}
|
||||
@ -559,6 +561,10 @@ fn visit_fn(&mut self, fn_kind: FnKind<'ast>, sp: Span, _: NodeId) {
|
||||
self.with_rib(ValueNS, rib_kind, |this| {
|
||||
// Create a label rib for the function.
|
||||
this.with_label_rib(rib_kind, |this| {
|
||||
if let FnKind::Fn(_, _, _, _, generics, _) = fn_kind {
|
||||
this.visit_generics(generics);
|
||||
}
|
||||
|
||||
// Add each argument to the rib.
|
||||
this.resolve_params(&declaration.inputs);
|
||||
|
||||
|
@ -204,12 +204,11 @@ pub(crate) fn from_method_sig(
|
||||
|
||||
pub(crate) fn from_fn_kind(
|
||||
fn_kind: &'a visit::FnKind<'_>,
|
||||
generics: &'a ast::Generics,
|
||||
decl: &'a ast::FnDecl,
|
||||
defaultness: ast::Defaultness,
|
||||
) -> FnSig<'a> {
|
||||
match *fn_kind {
|
||||
visit::FnKind::Fn(fn_ctxt, _, fn_sig, vis, _) => match fn_ctxt {
|
||||
visit::FnKind::Fn(fn_ctxt, _, fn_sig, vis, generics, _) => match fn_ctxt {
|
||||
visit::FnCtxt::Assoc(..) => {
|
||||
let mut fn_sig = FnSig::from_method_sig(fn_sig, generics, vis);
|
||||
fn_sig.defaultness = defaultness;
|
||||
@ -3180,8 +3179,14 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
|
||||
let inner_attrs = inner_attributes(&self.attrs);
|
||||
let fn_ctxt = visit::FnCtxt::Foreign;
|
||||
visitor.visit_fn(
|
||||
visit::FnKind::Fn(fn_ctxt, self.ident, sig, &self.vis, Some(body)),
|
||||
generics,
|
||||
visit::FnKind::Fn(
|
||||
fn_ctxt,
|
||||
self.ident,
|
||||
sig,
|
||||
&self.vis,
|
||||
generics,
|
||||
Some(body),
|
||||
),
|
||||
&sig.decl,
|
||||
self.span,
|
||||
defaultness,
|
||||
|
@ -382,7 +382,6 @@ fn unindent_comment_on_closing_brace(&self, b: &ast::Block) -> bool {
|
||||
pub(crate) fn visit_fn(
|
||||
&mut self,
|
||||
fk: visit::FnKind<'_>,
|
||||
generics: &ast::Generics,
|
||||
fd: &ast::FnDecl,
|
||||
s: Span,
|
||||
defaultness: ast::Defaultness,
|
||||
@ -391,12 +390,12 @@ pub(crate) fn visit_fn(
|
||||
let indent = self.block_indent;
|
||||
let block;
|
||||
let rewrite = match fk {
|
||||
visit::FnKind::Fn(_, ident, _, _, Some(ref b)) => {
|
||||
visit::FnKind::Fn(_, ident, _, _, _, Some(ref b)) => {
|
||||
block = b;
|
||||
self.rewrite_fn_before_block(
|
||||
indent,
|
||||
ident,
|
||||
&FnSig::from_fn_kind(&fk, generics, fd, defaultness),
|
||||
&FnSig::from_fn_kind(&fk, fd, defaultness),
|
||||
mk_sp(s.lo(), b.span.lo()),
|
||||
)
|
||||
}
|
||||
@ -552,8 +551,14 @@ pub(crate) fn visit_item(&mut self, item: &ast::Item) {
|
||||
_ => visit::FnCtxt::Foreign,
|
||||
};
|
||||
self.visit_fn(
|
||||
visit::FnKind::Fn(fn_ctxt, item.ident, sig, &item.vis, Some(body)),
|
||||
generics,
|
||||
visit::FnKind::Fn(
|
||||
fn_ctxt,
|
||||
item.ident,
|
||||
sig,
|
||||
&item.vis,
|
||||
generics,
|
||||
Some(body),
|
||||
),
|
||||
&sig.decl,
|
||||
item.span,
|
||||
defaultness,
|
||||
@ -642,8 +647,7 @@ fn visit_assoc_item(&mut self, visitor_kind: &ItemVisitorKind<'_>) {
|
||||
let inner_attrs = inner_attributes(&ai.attrs);
|
||||
let fn_ctxt = visit::FnCtxt::Assoc(assoc_ctxt);
|
||||
self.visit_fn(
|
||||
visit::FnKind::Fn(fn_ctxt, ai.ident, sig, &ai.vis, Some(body)),
|
||||
generics,
|
||||
visit::FnKind::Fn(fn_ctxt, ai.ident, sig, &ai.vis, generics, Some(body)),
|
||||
&sig.decl,
|
||||
ai.span,
|
||||
defaultness,
|
||||
|
Loading…
Reference in New Issue
Block a user