ast: Standardize visiting order

Id, attributes, inner nodes in source order if possible, tokens, span.

Also always use exhaustive matching in visiting infra, and visit some missing nodes.
This commit is contained in:
Vadim Petrochenkov 2024-06-26 15:25:57 +03:00
parent 4bdf8d2d58
commit ba3f6812c1
3 changed files with 389 additions and 317 deletions

View File

@ -402,10 +402,10 @@ fn visit_attr_args<T: MutVisitor>(args: &mut AttrArgs, vis: &mut T) {
AttrArgs::Empty => {}
AttrArgs::Delimited(args) => visit_delim_args(args, vis),
AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => {
vis.visit_span(eq_span);
vis.visit_expr(expr);
vis.visit_span(eq_span);
}
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
AttrArgs::Eq(_eq_span, AttrArgsEq::Hir(lit)) => {
unreachable!("in literal form when visiting mac args eq: {:?}", lit)
}
}
@ -414,13 +414,13 @@ fn visit_attr_args<T: MutVisitor>(args: &mut AttrArgs, vis: &mut T) {
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
fn visit_delim_args<T: MutVisitor>(args: &mut DelimArgs, vis: &mut T) {
let DelimArgs { dspan, delim: _, tokens } = args;
visit_delim_span(dspan, vis);
visit_tts(tokens, vis);
visit_delim_span(dspan, vis);
}
pub fn visit_delim_span<T: MutVisitor>(dspan: &mut DelimSpan, vis: &mut T) {
vis.visit_span(&mut dspan.open);
vis.visit_span(&mut dspan.close);
pub fn visit_delim_span<T: MutVisitor>(DelimSpan { open, close }: &mut DelimSpan, vis: &mut T) {
vis.visit_span(open);
vis.visit_span(close);
}
pub fn noop_flat_map_pat_field<T: MutVisitor>(
@ -441,11 +441,12 @@ fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) {
vis.visit_path(prefix);
match kind {
UseTreeKind::Simple(rename) => visit_opt(rename, |rename| vis.visit_ident(rename)),
UseTreeKind::Nested { items, .. } => {
UseTreeKind::Nested { items, span } => {
for (tree, id) in items {
vis.visit_id(id);
vis.visit_use_tree(tree);
}
vis.visit_span(span);
}
UseTreeKind::Glob => {}
}
@ -486,12 +487,9 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
let Ty { id, kind, span, tokens } = ty.deref_mut();
vis.visit_id(id);
match kind {
TyKind::Infer
| TyKind::ImplicitSelf
| TyKind::Err(_)
| TyKind::Dummy
| TyKind::Never
| TyKind::CVarArgs => {}
TyKind::Err(_guar) => {}
TyKind::Infer | TyKind::ImplicitSelf | TyKind::Dummy | TyKind::Never | TyKind::CVarArgs => {
}
TyKind::Slice(ty) => vis.visit_ty(ty),
TyKind::Ptr(mt) => vis.visit_mt(mt),
TyKind::Ref(lt, mt) => {
@ -533,8 +531,8 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
fields.flat_map_in_place(|field| vis.flat_map_field_def(field));
}
}
vis.visit_span(span);
visit_lazy_tts(tokens, vis);
vis.visit_span(span);
}
fn noop_visit_foreign_mod<T: MutVisitor>(foreign_mod: &mut ForeignMod, vis: &mut T) {
@ -550,8 +548,8 @@ pub fn noop_flat_map_variant<T: MutVisitor>(
let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant;
visitor.visit_id(id);
visit_attrs(attrs, visitor);
visitor.visit_ident(ident);
visitor.visit_vis(vis);
visitor.visit_ident(ident);
visitor.visit_variant_data(data);
visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr));
visitor.visit_span(span);
@ -563,13 +561,13 @@ fn noop_visit_ident<T: MutVisitor>(Ident { name: _, span }: &mut Ident, vis: &mu
}
fn noop_visit_path<T: MutVisitor>(Path { segments, span, tokens }: &mut Path, vis: &mut T) {
vis.visit_span(span);
for PathSegment { ident, id, args } in segments {
vis.visit_id(id);
vis.visit_ident(ident);
visit_opt(args, |args| vis.visit_generic_args(args));
}
visit_lazy_tts(tokens, vis);
vis.visit_span(span);
}
fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<P<QSelf>>, vis: &mut T) {
@ -611,10 +609,11 @@ fn noop_visit_parenthesized_parameter_data<T: MutVisitor>(
args: &mut ParenthesizedArgs,
vis: &mut T,
) {
let ParenthesizedArgs { inputs, output, span, .. } = args;
let ParenthesizedArgs { inputs, output, span, inputs_span } = args;
visit_thin_vec(inputs, |input| vis.visit_ty(input));
noop_visit_fn_ret_ty(output, vis);
vis.visit_span(span);
vis.visit_span(inputs_span);
}
fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) {
@ -633,9 +632,9 @@ fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) {
vis.visit_block(els);
}
}
vis.visit_span(span);
visit_opt(colon_sp, |sp| vis.visit_span(sp));
visit_lazy_tts(tokens, vis);
visit_opt(colon_sp, |sp| vis.visit_span(sp));
vis.visit_span(span);
}
fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) {
@ -651,7 +650,7 @@ fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) {
visit_lazy_tts(tokens, vis);
visit_lazy_tts(attr_tokens, vis);
}
AttrKind::DocComment(..) => {}
AttrKind::DocComment(_kind, _sym) => {}
}
vis.visit_span(span);
}
@ -689,34 +688,24 @@ pub fn noop_flat_map_param<T: MutVisitor>(mut param: Param, vis: &mut T) -> Smal
vis.visit_id(id);
visit_attrs(attrs, vis);
vis.visit_pat(pat);
vis.visit_span(span);
vis.visit_ty(ty);
vis.visit_span(span);
smallvec![param]
}
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
fn visit_attr_tt<T: MutVisitor>(tt: &mut AttrTokenTree, vis: &mut T) {
match tt {
AttrTokenTree::Token(token, _) => {
AttrTokenTree::Token(token, _spacing) => {
visit_token(token, vis);
}
AttrTokenTree::Delimited(DelimSpan { open, close }, _spacing, _delim, tts) => {
vis.visit_span(open);
vis.visit_span(close);
AttrTokenTree::Delimited(dspan, _spacing, _delim, tts) => {
visit_attr_tts(tts, vis);
visit_delim_span(dspan, vis);
}
AttrTokenTree::Attributes(data) => {
for attr in &mut *data.attrs {
match &mut attr.kind {
AttrKind::Normal(normal) => {
visit_lazy_tts(&mut normal.tokens, vis);
}
AttrKind::DocComment(..) => {
vis.visit_span(&mut attr.span);
}
}
}
visit_lazy_tts_opt_mut(Some(&mut data.tokens), vis);
AttrTokenTree::Attributes(AttributesData { attrs, tokens }) => {
visit_attrs(attrs, vis);
visit_lazy_tts_opt_mut(Some(tokens), vis);
}
}
}
@ -724,13 +713,12 @@ fn visit_attr_tt<T: MutVisitor>(tt: &mut AttrTokenTree, vis: &mut T) {
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
fn visit_tt<T: MutVisitor>(tt: &mut TokenTree, vis: &mut T) {
match tt {
TokenTree::Token(token, _) => {
TokenTree::Token(token, _spacing) => {
visit_token(token, vis);
}
TokenTree::Delimited(DelimSpan { open, close }, _spacing, _delim, tts) => {
vis.visit_span(open);
vis.visit_span(close);
TokenTree::Delimited(dspan, _spacing, _delim, tts) => {
visit_tts(tts, vis);
visit_delim_span(dspan, vis);
}
}
}
@ -771,7 +759,7 @@ fn visit_lazy_tts<T: MutVisitor>(lazy_tts: &mut Option<LazyAttrTokenStream>, vis
pub fn visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) {
let Token { kind, span } = t;
match kind {
token::Ident(name, _) | token::Lifetime(name) => {
token::Ident(name, _ /*raw*/) | token::Lifetime(name) => {
let mut ident = Ident::new(*name, *span);
vis.visit_ident(&mut ident);
*name = ident.name;
@ -918,10 +906,11 @@ fn noop_visit_param_bound<T: MutVisitor>(pb: &mut GenericBound, vis: &mut T) {
match pb {
GenericBound::Trait(ty, _modifier) => vis.visit_poly_trait_ref(ty),
GenericBound::Outlives(lifetime) => noop_visit_lifetime(lifetime, vis),
GenericBound::Use(args, _) => {
GenericBound::Use(args, span) => {
for arg in args {
vis.visit_precise_capturing_arg(arg);
}
vis.visit_span(span);
}
}
}
@ -946,9 +935,6 @@ pub fn noop_flat_map_generic_param<T: MutVisitor>(
vis.visit_id(id);
visit_attrs(attrs, vis);
vis.visit_ident(ident);
if let Some(colon_span) = colon_span {
vis.visit_span(colon_span);
}
visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis));
match kind {
GenericParamKind::Lifetime => {}
@ -960,6 +946,9 @@ pub fn noop_flat_map_generic_param<T: MutVisitor>(
visit_opt(default, |default| vis.visit_anon_const(default));
}
}
if let Some(colon_span) = colon_span {
vis.visit_span(colon_span);
}
smallvec![param]
}
@ -979,6 +968,14 @@ fn noop_visit_generics<T: MutVisitor>(generics: &mut Generics, vis: &mut T) {
vis.visit_span(span);
}
fn noop_visit_ty_alias_where_clauses<T: MutVisitor>(tawcs: &mut TyAliasWhereClauses, vis: &mut T) {
let TyAliasWhereClauses { before, after, split: _ } = tawcs;
let TyAliasWhereClause { has_where_token: _, span: span_before } = before;
let TyAliasWhereClause { has_where_token: _, span: span_after } = after;
vis.visit_span(span_before);
vis.visit_span(span_after);
}
fn noop_visit_where_clause<T: MutVisitor>(wc: &mut WhereClause, vis: &mut T) {
let WhereClause { has_where_token: _, predicates, span } = wc;
visit_thin_vec(predicates, |predicate| vis.visit_where_predicate(predicate));
@ -989,29 +986,29 @@ fn noop_visit_where_predicate<T: MutVisitor>(pred: &mut WherePredicate, vis: &mu
match pred {
WherePredicate::BoundPredicate(bp) => {
let WhereBoundPredicate { span, bound_generic_params, bounded_ty, bounds } = bp;
vis.visit_span(span);
bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
vis.visit_ty(bounded_ty);
visit_vec(bounds, |bound| vis.visit_param_bound(bound));
vis.visit_span(span);
}
WherePredicate::RegionPredicate(rp) => {
let WhereRegionPredicate { span, lifetime, bounds } = rp;
vis.visit_span(span);
noop_visit_lifetime(lifetime, vis);
visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis));
vis.visit_span(span);
}
WherePredicate::EqPredicate(ep) => {
let WhereEqPredicate { span, lhs_ty, rhs_ty } = ep;
vis.visit_span(span);
vis.visit_ty(lhs_ty);
vis.visit_ty(rhs_ty);
vis.visit_span(span);
}
}
}
fn noop_visit_variant_data<T: MutVisitor>(vdata: &mut VariantData, vis: &mut T) {
match vdata {
VariantData::Struct { fields, .. } => {
VariantData::Struct { fields, recovered: _ } => {
fields.flat_map_in_place(|field| vis.flat_map_field_def(field));
}
VariantData::Tuple(fields, id) => {
@ -1041,10 +1038,10 @@ pub fn noop_flat_map_field_def<T: MutVisitor>(
let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = &mut fd;
visitor.visit_id(id);
visit_attrs(attrs, visitor);
visitor.visit_span(span);
visit_opt(ident, |ident| visitor.visit_ident(ident));
visitor.visit_vis(vis);
visit_opt(ident, |ident| visitor.visit_ident(ident));
visitor.visit_ty(ty);
visitor.visit_span(span);
smallvec![fd]
}
@ -1069,8 +1066,8 @@ pub fn noop_visit_block<T: MutVisitor>(block: &mut P<Block>, vis: &mut T) {
let Block { id, stmts, rules: _, span, tokens, could_be_bare_literal: _ } = block.deref_mut();
vis.visit_id(id);
stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt));
vis.visit_span(span);
visit_lazy_tts(tokens, vis);
vis.visit_span(span);
}
pub fn noop_visit_item_kind(kind: &mut impl NoopVisitItemKind, vis: &mut impl MutVisitor) {
@ -1091,45 +1088,37 @@ impl NoopVisitItemKind for ItemKind {
}
ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
visit_defaultness(defaultness, vis);
visit_fn_sig(sig, vis);
vis.visit_generics(generics);
visit_fn_sig(sig, vis);
visit_opt(body, |body| vis.visit_block(body));
}
ItemKind::Mod(safety, mod_kind) => {
visit_safety(safety, vis);
match mod_kind {
ModKind::Loaded(items, _inline, ModSpans { inner_span, inject_use_span }) => {
items.flat_map_in_place(|item| vis.flat_map_item(item));
vis.visit_span(inner_span);
vis.visit_span(inject_use_span);
items.flat_map_in_place(|item| vis.flat_map_item(item));
}
ModKind::Unloaded => {}
}
}
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm),
ItemKind::TyAlias(box TyAlias {
defaultness,
generics,
where_clauses,
bounds,
ty,
..
}) => {
ItemKind::TyAlias(box TyAlias { defaultness, generics, where_clauses, bounds, ty }) => {
visit_defaultness(defaultness, vis);
vis.visit_generics(generics);
vis.visit_span(&mut where_clauses.before.span);
vis.visit_span(&mut where_clauses.after.span);
visit_bounds(bounds, vis);
visit_opt(ty, |ty| vis.visit_ty(ty));
noop_visit_ty_alias_where_clauses(where_clauses, vis);
}
ItemKind::Enum(EnumDef { variants }, generics) => {
variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
vis.visit_generics(generics);
variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
}
ItemKind::Struct(variant_data, generics) | ItemKind::Union(variant_data, generics) => {
vis.visit_variant_data(variant_data);
vis.visit_generics(generics);
vis.visit_variant_data(variant_data);
}
ItemKind::Impl(box Impl {
defaultness,
@ -1217,14 +1206,12 @@ impl NoopVisitItemKind for AssocItemKind {
where_clauses,
bounds,
ty,
..
}) => {
visit_defaultness(defaultness, visitor);
visitor.visit_generics(generics);
visitor.visit_span(&mut where_clauses.before.span);
visitor.visit_span(&mut where_clauses.after.span);
visit_bounds(bounds, visitor);
visit_opt(ty, |ty| visitor.visit_ty(ty));
noop_visit_ty_alias_where_clauses(where_clauses, visitor);
}
AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac),
AssocItemKind::Delegation(box Delegation {
@ -1302,8 +1289,8 @@ pub fn noop_flat_map_item<K: NoopVisitItemKind>(
visitor.visit_vis(vis);
visitor.visit_ident(ident);
kind.noop_visit(visitor);
visitor.visit_span(span);
visit_lazy_tts(tokens, visitor);
visitor.visit_span(span);
smallvec![item]
}
@ -1326,14 +1313,12 @@ impl NoopVisitItemKind for ForeignItemKind {
where_clauses,
bounds,
ty,
..
}) => {
visit_defaultness(defaultness, visitor);
visitor.visit_generics(generics);
visitor.visit_span(&mut where_clauses.before.span);
visitor.visit_span(&mut where_clauses.after.span);
visit_bounds(bounds, visitor);
visit_opt(ty, |ty| visitor.visit_ty(ty));
noop_visit_ty_alias_where_clauses(where_clauses, visitor);
}
ForeignItemKind::MacCall(mac) => visitor.visit_mac_call(mac),
}
@ -1344,7 +1329,8 @@ pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
let Pat { id, kind, span, tokens } = pat.deref_mut();
vis.visit_id(id);
match kind {
PatKind::Wild | PatKind::Rest | PatKind::Never | PatKind::Err(_) => {}
PatKind::Err(_guar) => {}
PatKind::Wild | PatKind::Rest | PatKind::Never => {}
PatKind::Ident(_binding_mode, ident, sub) => {
vis.visit_ident(ident);
visit_opt(sub, |sub| vis.visit_pat(sub));
@ -1378,8 +1364,8 @@ pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
PatKind::Paren(inner) => vis.visit_pat(inner),
PatKind::MacCall(mac) => vis.visit_mac_call(mac),
}
vis.visit_span(span);
visit_lazy_tts(tokens, vis);
vis.visit_span(span);
}
fn noop_visit_anon_const<T: MutVisitor>(AnonConst { id, value }: &mut AnonConst, vis: &mut T) {
@ -1388,13 +1374,22 @@ fn noop_visit_anon_const<T: MutVisitor>(AnonConst { id, value }: &mut AnonConst,
}
fn noop_visit_inline_asm<T: MutVisitor>(asm: &mut InlineAsm, vis: &mut T) {
for (op, _) in &mut asm.operands {
// FIXME: Visit spans inside all this currently ignored stuff.
let InlineAsm {
template: _,
template_strs: _,
operands,
clobber_abis: _,
options: _,
line_spans: _,
} = asm;
for (op, span) in operands {
match op {
InlineAsmOperand::In { expr, .. }
| InlineAsmOperand::Out { expr: Some(expr), .. }
| InlineAsmOperand::InOut { expr, .. } => vis.visit_expr(expr),
InlineAsmOperand::Out { expr: None, .. } => {}
InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
InlineAsmOperand::In { expr, reg: _ }
| InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ }
| InlineAsmOperand::InOut { expr, reg: _, late: _ } => vis.visit_expr(expr),
InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {}
InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
vis.visit_expr(in_expr);
if let Some(out_expr) = out_expr {
vis.visit_expr(out_expr);
@ -1404,6 +1399,7 @@ fn noop_visit_inline_asm<T: MutVisitor>(asm: &mut InlineAsm, vis: &mut T) {
InlineAsmOperand::Sym { sym } => vis.visit_inline_asm_sym(sym),
InlineAsmOperand::Label { block } => vis.visit_block(block),
}
vis.visit_span(span);
}
}
@ -1417,12 +1413,18 @@ fn noop_visit_inline_asm_sym<T: MutVisitor>(
}
fn noop_visit_format_args<T: MutVisitor>(fmt: &mut FormatArgs, vis: &mut T) {
for arg in fmt.arguments.all_args_mut() {
if let FormatArgumentKind::Named(name) = &mut arg.kind {
vis.visit_ident(name);
// FIXME: visit the template exhaustively.
let FormatArgs { span, template: _, arguments } = fmt;
for FormatArgument { kind, expr } in arguments.all_args_mut() {
match kind {
FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => {
vis.visit_ident(ident)
}
FormatArgumentKind::Normal => {}
}
vis.visit_expr(&mut arg.expr);
vis.visit_expr(expr);
}
vis.visit_span(span);
}
pub fn noop_visit_expr<T: MutVisitor>(
@ -1451,10 +1453,10 @@ pub fn noop_visit_expr<T: MutVisitor>(
args: call_args,
span,
}) => {
vis.visit_method_receiver_expr(receiver);
vis.visit_id(id);
vis.visit_ident(ident);
visit_opt(seg_args, |args| vis.visit_generic_args(args));
vis.visit_method_receiver_expr(receiver);
visit_thin_exprs(call_args, vis);
vis.visit_span(span);
}
@ -1471,10 +1473,11 @@ pub fn noop_visit_expr<T: MutVisitor>(
vis.visit_expr(expr);
vis.visit_ty(ty);
}
ExprKind::AddrOf(_, _, ohs) => vis.visit_expr(ohs),
ExprKind::Let(pat, scrutinee, _, _) => {
ExprKind::AddrOf(_kind, _mut, ohs) => vis.visit_expr(ohs),
ExprKind::Let(pat, scrutinee, span, _recovered) => {
vis.visit_pat(pat);
vis.visit_expr(scrutinee);
vis.visit_span(span);
}
ExprKind::If(cond, tr, fl) => {
vis.visit_expr(cond);
@ -1482,19 +1485,19 @@ pub fn noop_visit_expr<T: MutVisitor>(
visit_opt(fl, |fl| ensure_sufficient_stack(|| vis.visit_expr(fl)));
}
ExprKind::While(cond, body, label) => {
visit_opt(label, |label| vis.visit_label(label));
vis.visit_expr(cond);
vis.visit_block(body);
visit_opt(label, |label| vis.visit_label(label));
}
ExprKind::ForLoop { pat, iter, body, label, kind: _ } => {
visit_opt(label, |label| vis.visit_label(label));
vis.visit_pat(pat);
vis.visit_expr(iter);
vis.visit_block(body);
visit_opt(label, |label| vis.visit_label(label));
}
ExprKind::Loop(body, label, span) => {
vis.visit_block(body);
visit_opt(label, |label| vis.visit_label(label));
vis.visit_block(body);
vis.visit_span(span);
}
ExprKind::Match(expr, arms, _kind) => {
@ -1522,10 +1525,10 @@ pub fn noop_visit_expr<T: MutVisitor>(
vis.visit_span(fn_arg_span);
}
ExprKind::Block(blk, label) => {
vis.visit_block(blk);
visit_opt(label, |label| vis.visit_label(label));
vis.visit_block(blk);
}
ExprKind::Gen(_capture_by, body, _) => {
ExprKind::Gen(_capture_by, body, _kind) => {
vis.visit_block(body);
}
ExprKind::Await(expr, await_kw_span) => {
@ -1601,10 +1604,13 @@ pub fn noop_visit_expr<T: MutVisitor>(
}
ExprKind::Try(expr) => vis.visit_expr(expr),
ExprKind::TryBlock(body) => vis.visit_block(body),
ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err(_) | ExprKind::Dummy => {}
ExprKind::Lit(_token) => {}
ExprKind::IncludedBytes(_bytes) => {}
ExprKind::Err(_guar) => {}
ExprKind::Dummy => {}
}
vis.visit_span(span);
visit_lazy_tts(tokens, vis);
vis.visit_span(span);
}
pub fn noop_filter_map_expr<T: MutVisitor>(mut e: P<Expr>, vis: &mut T) -> Option<P<Expr>> {
@ -1619,7 +1625,6 @@ pub fn noop_flat_map_stmt<T: MutVisitor>(
vis: &mut T,
) -> SmallVec<[Stmt; 1]> {
vis.visit_id(&mut id);
vis.visit_span(&mut span);
let stmts: SmallVec<_> = noop_flat_map_stmt_kind(kind, vis)
.into_iter()
.map(|kind| Stmt { id, kind, span })
@ -1630,6 +1635,7 @@ pub fn noop_flat_map_stmt<T: MutVisitor>(
the visitor should implement custom statement visiting"
);
}
vis.visit_span(&mut span);
stmts
}
@ -1654,14 +1660,16 @@ fn noop_flat_map_stmt_kind<T: MutVisitor>(kind: StmtKind, vis: &mut T) -> SmallV
}
fn noop_visit_vis<T: MutVisitor>(visibility: &mut Visibility, vis: &mut T) {
match &mut visibility.kind {
let Visibility { kind, span, tokens } = visibility;
match kind {
VisibilityKind::Public | VisibilityKind::Inherited => {}
VisibilityKind::Restricted { path, id, shorthand: _ } => {
vis.visit_id(id);
vis.visit_path(path);
}
}
vis.visit_span(&mut visibility.span);
visit_lazy_tts(tokens, vis);
vis.visit_span(span);
}
fn noop_visit_capture_by<T: MutVisitor>(capture_by: &mut CaptureBy, vis: &mut T) {

View File

@ -14,6 +14,7 @@
//! those that are created by the expansion of a macro.
use crate::ast::*;
use crate::ptr::P;
use rustc_span::symbol::Ident;
use rustc_span::Span;
@ -298,40 +299,45 @@ pub trait Visitor<'ast>: Sized {
}
pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) -> V::Result {
walk_list!(visitor, visit_attribute, &krate.attrs);
walk_list!(visitor, visit_item, &krate.items);
let Crate { attrs, items, spans: _, id: _, is_placeholder: _ } = krate;
walk_list!(visitor, visit_attribute, attrs);
walk_list!(visitor, visit_item, items);
V::Result::output()
}
pub fn walk_local<'a, V: Visitor<'a>>(visitor: &mut V, local: &'a Local) -> V::Result {
walk_list!(visitor, visit_attribute, &local.attrs);
try_visit!(visitor.visit_pat(&local.pat));
visit_opt!(visitor, visit_ty, &local.ty);
if let Some((init, els)) = local.kind.init_else_opt() {
let Local { id: _, pat, ty, kind, span: _, colon_sp: _, attrs, tokens: _ } = local;
walk_list!(visitor, visit_attribute, attrs);
try_visit!(visitor.visit_pat(pat));
visit_opt!(visitor, visit_ty, ty);
if let Some((init, els)) = kind.init_else_opt() {
try_visit!(visitor.visit_expr(init));
visit_opt!(visitor, visit_block, els);
}
V::Result::output()
}
pub fn walk_label<'a, V: Visitor<'a>>(visitor: &mut V, label: &'a Label) -> V::Result {
visitor.visit_ident(label.ident)
pub fn walk_label<'a, V: Visitor<'a>>(visitor: &mut V, Label { ident }: &'a Label) -> V::Result {
visitor.visit_ident(*ident)
}
pub fn walk_lifetime<'a, V: Visitor<'a>>(visitor: &mut V, lifetime: &'a Lifetime) -> V::Result {
visitor.visit_ident(lifetime.ident)
let Lifetime { id: _, ident } = lifetime;
visitor.visit_ident(*ident)
}
pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef) -> V::Result
where
V: Visitor<'a>,
{
walk_list!(visitor, visit_generic_param, &trait_ref.bound_generic_params);
visitor.visit_trait_ref(&trait_ref.trait_ref)
let PolyTraitRef { bound_generic_params, trait_ref, span: _ } = trait_ref;
walk_list!(visitor, visit_generic_param, bound_generic_params);
visitor.visit_trait_ref(trait_ref)
}
pub fn walk_trait_ref<'a, V: Visitor<'a>>(visitor: &mut V, trait_ref: &'a TraitRef) -> V::Result {
visitor.visit_path(&trait_ref.path, trait_ref.ref_id)
let TraitRef { path, ref_id } = trait_ref;
visitor.visit_path(path, *ref_id)
}
impl WalkItemKind for ItemKind {
@ -341,9 +347,10 @@ impl WalkItemKind for ItemKind {
_ctxt: AssocCtxt,
visitor: &mut V,
) -> V::Result {
let Item { id, span, vis, ident, .. } = item;
match self {
ItemKind::ExternCrate(_) => {}
ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, item.id, false)),
ItemKind::ExternCrate(_rename) => {}
ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, *id, false)),
ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => {
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
@ -354,9 +361,8 @@ impl WalkItemKind for ItemKind {
visit_opt!(visitor, visit_expr, expr);
}
ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
let kind =
FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, generics, body.as_deref());
try_visit!(visitor.visit_fn(kind, item.span, item.id));
let kind = FnKind::Fn(FnCtxt::Free, *ident, sig, vis, generics, body.as_deref());
try_visit!(visitor.visit_fn(kind, *span, *id));
}
ItemKind::Mod(_unsafety, mod_kind) => match mod_kind {
ModKind::Loaded(items, _inline, _inner_span) => {
@ -364,11 +370,17 @@ impl WalkItemKind for ItemKind {
}
ModKind::Unloaded => {}
},
ItemKind::ForeignMod(foreign_module) => {
walk_list!(visitor, visit_foreign_item, &foreign_module.items);
ItemKind::ForeignMod(ForeignMod { safety: _, abi: _, items }) => {
walk_list!(visitor, visit_foreign_item, items);
}
ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)),
ItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
ItemKind::TyAlias(box TyAlias {
generics,
bounds,
ty,
defaultness: _,
where_clauses: _,
}) => {
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
visit_opt!(visitor, visit_ty, ty);
@ -407,7 +419,7 @@ impl WalkItemKind for ItemKind {
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
}
ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
ItemKind::MacroDef(ts) => try_visit!(visitor.visit_mac_def(ts, item.id)),
ItemKind::MacroDef(ts) => try_visit!(visitor.visit_mac_def(ts, *id)),
ItemKind::Delegation(box Delegation {
id,
qself,
@ -416,18 +428,14 @@ impl WalkItemKind for ItemKind {
body,
from_glob: _,
}) => {
if let Some(qself) = qself {
try_visit!(visitor.visit_ty(&qself.ty));
}
try_visit!(walk_qself(visitor, qself));
try_visit!(visitor.visit_path(path, *id));
visit_opt!(visitor, visit_ident, *rename);
visit_opt!(visitor, visit_block, body);
}
ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
if let Some(qself) = qself {
try_visit!(visitor.visit_ty(&qself.ty));
}
try_visit!(visitor.visit_path(prefix, item.id));
try_visit!(walk_qself(visitor, qself));
try_visit!(visitor.visit_path(prefix, *id));
if let Some(suffixes) = suffixes {
for (ident, rename) in suffixes {
visitor.visit_ident(*ident);
@ -452,9 +460,9 @@ pub fn walk_item<'a, V: Visitor<'a>>(
pub fn walk_enum_def<'a, V: Visitor<'a>>(
visitor: &mut V,
enum_definition: &'a EnumDef,
EnumDef { variants }: &'a EnumDef,
) -> V::Result {
walk_list!(visitor, visit_variant, &enum_definition.variants);
walk_list!(visitor, visit_variant, variants);
V::Result::output()
}
@ -462,48 +470,52 @@ pub fn walk_variant<'a, V: Visitor<'a>>(visitor: &mut V, variant: &'a Variant) -
where
V: Visitor<'a>,
{
walk_list!(visitor, visit_attribute, &variant.attrs);
try_visit!(visitor.visit_ident(variant.ident));
try_visit!(visitor.visit_vis(&variant.vis));
try_visit!(visitor.visit_variant_data(&variant.data));
visit_opt!(visitor, visit_variant_discr, &variant.disr_expr);
let Variant { attrs, id: _, span: _, vis, ident, data, disr_expr, is_placeholder: _ } = variant;
walk_list!(visitor, visit_attribute, attrs);
try_visit!(visitor.visit_vis(vis));
try_visit!(visitor.visit_ident(*ident));
try_visit!(visitor.visit_variant_data(data));
visit_opt!(visitor, visit_variant_discr, disr_expr);
V::Result::output()
}
pub fn walk_expr_field<'a, V: Visitor<'a>>(visitor: &mut V, f: &'a ExprField) -> V::Result {
walk_list!(visitor, visit_attribute, &f.attrs);
try_visit!(visitor.visit_expr(&f.expr));
try_visit!(visitor.visit_ident(f.ident));
let ExprField { attrs, id: _, span: _, ident, expr, is_shorthand: _, is_placeholder: _ } = f;
walk_list!(visitor, visit_attribute, attrs);
try_visit!(visitor.visit_ident(*ident));
try_visit!(visitor.visit_expr(expr));
V::Result::output()
}
pub fn walk_pat_field<'a, V: Visitor<'a>>(visitor: &mut V, fp: &'a PatField) -> V::Result {
walk_list!(visitor, visit_attribute, &fp.attrs);
try_visit!(visitor.visit_ident(fp.ident));
try_visit!(visitor.visit_pat(&fp.pat));
let PatField { ident, pat, is_shorthand: _, attrs, id: _, span: _, is_placeholder: _ } = fp;
walk_list!(visitor, visit_attribute, attrs);
try_visit!(visitor.visit_ident(*ident));
try_visit!(visitor.visit_pat(pat));
V::Result::output()
}
pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result {
match &typ.kind {
let Ty { id, kind, span: _, tokens: _ } = typ;
match kind {
TyKind::Slice(ty) | TyKind::Paren(ty) => try_visit!(visitor.visit_ty(ty)),
TyKind::Ptr(mutable_type) => try_visit!(visitor.visit_ty(&mutable_type.ty)),
TyKind::Ref(opt_lifetime, mutable_type) => {
TyKind::Ptr(MutTy { ty, mutbl: _ }) => try_visit!(visitor.visit_ty(ty)),
TyKind::Ref(opt_lifetime, MutTy { ty, mutbl: _ }) => {
visit_opt!(visitor, visit_lifetime, opt_lifetime, LifetimeCtxt::Ref);
try_visit!(visitor.visit_ty(&mutable_type.ty));
try_visit!(visitor.visit_ty(ty));
}
TyKind::Tup(tuple_element_types) => {
walk_list!(visitor, visit_ty, tuple_element_types);
}
TyKind::BareFn(function_declaration) => {
walk_list!(visitor, visit_generic_param, &function_declaration.generic_params);
try_visit!(walk_fn_decl(visitor, &function_declaration.decl));
let BareFnTy { safety: _, ext: _, generic_params, decl, decl_span: _ } =
&**function_declaration;
walk_list!(visitor, visit_generic_param, generic_params);
try_visit!(walk_fn_decl(visitor, decl));
}
TyKind::Path(maybe_qself, path) => {
if let Some(qself) = maybe_qself {
try_visit!(visitor.visit_ty(&qself.ty));
}
try_visit!(visitor.visit_path(path, typ.id));
try_visit!(walk_qself(visitor, maybe_qself));
try_visit!(visitor.visit_path(path, *id));
}
TyKind::Pat(ty, pat) => {
try_visit!(visitor.visit_ty(ty));
@ -513,25 +525,35 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result {
try_visit!(visitor.visit_ty(ty));
try_visit!(visitor.visit_anon_const(length));
}
TyKind::TraitObject(bounds, ..) => {
TyKind::TraitObject(bounds, _syntax) => {
walk_list!(visitor, visit_param_bound, bounds, BoundKind::TraitObject);
}
TyKind::ImplTrait(_, bounds) => {
TyKind::ImplTrait(_id, bounds) => {
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Impl);
}
TyKind::Typeof(expression) => try_visit!(visitor.visit_anon_const(expression)),
TyKind::Infer | TyKind::ImplicitSelf | TyKind::Dummy | TyKind::Err(_) => {}
TyKind::Infer | TyKind::ImplicitSelf | TyKind::Dummy => {}
TyKind::Err(_guar) => {}
TyKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
TyKind::Never | TyKind::CVarArgs => {}
TyKind::AnonStruct(_, ref fields) | TyKind::AnonUnion(_, ref fields) => {
TyKind::AnonStruct(_id, ref fields) | TyKind::AnonUnion(_id, ref fields) => {
walk_list!(visitor, visit_field_def, fields);
}
}
V::Result::output()
}
fn walk_qself<'a, V: Visitor<'a>>(visitor: &mut V, qself: &'a Option<P<QSelf>>) -> V::Result {
if let Some(qself) = qself {
let QSelf { ty, path_span: _, position: _ } = &**qself;
try_visit!(visitor.visit_ty(ty));
}
V::Result::output()
}
pub fn walk_path<'a, V: Visitor<'a>>(visitor: &mut V, path: &'a Path) -> V::Result {
walk_list!(visitor, visit_path_segment, &path.segments);
let Path { span: _, segments, tokens: _ } = path;
walk_list!(visitor, visit_path_segment, segments);
V::Result::output()
}
@ -540,14 +562,15 @@ pub fn walk_use_tree<'a, V: Visitor<'a>>(
use_tree: &'a UseTree,
id: NodeId,
) -> V::Result {
try_visit!(visitor.visit_path(&use_tree.prefix, id));
match use_tree.kind {
let UseTree { prefix, kind, span: _ } = use_tree;
try_visit!(visitor.visit_path(prefix, id));
match kind {
UseTreeKind::Simple(rename) => {
// The extra IDs are handled during AST lowering.
visit_opt!(visitor, visit_ident, rename);
visit_opt!(visitor, visit_ident, *rename);
}
UseTreeKind::Glob => {}
UseTreeKind::Nested { ref items, .. } => {
UseTreeKind::Nested { ref items, span: _ } => {
for &(ref nested_tree, nested_id) in items {
try_visit!(visitor.visit_use_tree(nested_tree, nested_id, true));
}
@ -560,8 +583,9 @@ pub fn walk_path_segment<'a, V: Visitor<'a>>(
visitor: &mut V,
segment: &'a PathSegment,
) -> V::Result {
try_visit!(visitor.visit_ident(segment.ident));
visit_opt!(visitor, visit_generic_args, &segment.args);
let PathSegment { ident, id: _, args } = segment;
try_visit!(visitor.visit_ident(*ident));
visit_opt!(visitor, visit_generic_args, args);
V::Result::output()
}
@ -570,8 +594,8 @@ where
V: Visitor<'a>,
{
match generic_args {
GenericArgs::AngleBracketed(data) => {
for arg in &data.args {
GenericArgs::AngleBracketed(AngleBracketedArgs { span: _, args }) => {
for arg in args {
match arg {
AngleBracketedArg::Arg(a) => try_visit!(visitor.visit_generic_arg(a)),
AngleBracketedArg::Constraint(c) => {
@ -581,8 +605,9 @@ where
}
}
GenericArgs::Parenthesized(data) => {
walk_list!(visitor, visit_ty, &data.inputs);
try_visit!(visitor.visit_fn_ret_ty(&data.output));
let ParenthesizedArgs { span: _, inputs, inputs_span: _, output } = data;
walk_list!(visitor, visit_ty, inputs);
try_visit!(visitor.visit_fn_ret_ty(output));
}
}
V::Result::output()
@ -603,9 +628,10 @@ pub fn walk_assoc_item_constraint<'a, V: Visitor<'a>>(
visitor: &mut V,
constraint: &'a AssocItemConstraint,
) -> V::Result {
try_visit!(visitor.visit_ident(constraint.ident));
visit_opt!(visitor, visit_generic_args, &constraint.gen_args);
match &constraint.kind {
let AssocItemConstraint { id: _, ident, gen_args, kind, span: _ } = constraint;
try_visit!(visitor.visit_ident(*ident));
visit_opt!(visitor, visit_generic_args, gen_args);
match kind {
AssocItemConstraintKind::Equality { term } => match term {
Term::Ty(ty) => try_visit!(visitor.visit_ty(ty)),
Term::Const(c) => try_visit!(visitor.visit_anon_const(c)),
@ -618,43 +644,39 @@ pub fn walk_assoc_item_constraint<'a, V: Visitor<'a>>(
}
pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) -> V::Result {
match &pattern.kind {
let Pat { id, kind, span: _, tokens: _ } = pattern;
match kind {
PatKind::TupleStruct(opt_qself, path, elems) => {
if let Some(qself) = opt_qself {
try_visit!(visitor.visit_ty(&qself.ty));
}
try_visit!(visitor.visit_path(path, pattern.id));
try_visit!(walk_qself(visitor, opt_qself));
try_visit!(visitor.visit_path(path, *id));
walk_list!(visitor, visit_pat, elems);
}
PatKind::Path(opt_qself, path) => {
if let Some(qself) = opt_qself {
try_visit!(visitor.visit_ty(&qself.ty));
}
try_visit!(visitor.visit_path(path, pattern.id))
try_visit!(walk_qself(visitor, opt_qself));
try_visit!(visitor.visit_path(path, *id))
}
PatKind::Struct(opt_qself, path, fields, _) => {
if let Some(qself) = opt_qself {
try_visit!(visitor.visit_ty(&qself.ty));
}
try_visit!(visitor.visit_path(path, pattern.id));
PatKind::Struct(opt_qself, path, fields, _rest) => {
try_visit!(walk_qself(visitor, opt_qself));
try_visit!(visitor.visit_path(path, *id));
walk_list!(visitor, visit_pat_field, fields);
}
PatKind::Box(subpattern)
| PatKind::Deref(subpattern)
| PatKind::Ref(subpattern, _)
| PatKind::Paren(subpattern) => {
PatKind::Box(subpattern) | PatKind::Deref(subpattern) | PatKind::Paren(subpattern) => {
try_visit!(visitor.visit_pat(subpattern));
}
PatKind::Ident(_, ident, optional_subpattern) => {
PatKind::Ref(subpattern, _ /*mutbl*/) => {
try_visit!(visitor.visit_pat(subpattern));
}
PatKind::Ident(_bmode, ident, optional_subpattern) => {
try_visit!(visitor.visit_ident(*ident));
visit_opt!(visitor, visit_pat, optional_subpattern);
}
PatKind::Lit(expression) => try_visit!(visitor.visit_expr(expression)),
PatKind::Range(lower_bound, upper_bound, _) => {
PatKind::Range(lower_bound, upper_bound, _end) => {
visit_opt!(visitor, visit_expr, lower_bound);
visit_opt!(visitor, visit_expr, upper_bound);
}
PatKind::Wild | PatKind::Rest | PatKind::Never | PatKind::Err(_) => {}
PatKind::Wild | PatKind::Rest | PatKind::Never => {}
PatKind::Err(_guar) => {}
PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => {
walk_list!(visitor, visit_pat, elems);
}
@ -680,7 +702,13 @@ impl WalkItemKind for ForeignItemKind {
let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body.as_deref());
try_visit!(visitor.visit_fn(kind, span, id));
}
ForeignItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
ForeignItemKind::TyAlias(box TyAlias {
generics,
bounds,
ty,
defaultness: _,
where_clauses: _,
}) => {
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
visit_opt!(visitor, visit_ty, ty);
@ -697,7 +725,7 @@ pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericB
match bound {
GenericBound::Trait(typ, _modifier) => visitor.visit_poly_trait_ref(typ),
GenericBound::Outlives(lifetime) => visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound),
GenericBound::Use(args, _) => {
GenericBound::Use(args, _span) => {
walk_list!(visitor, visit_precise_capturing_arg, args);
V::Result::output()
}
@ -722,13 +750,15 @@ pub fn walk_generic_param<'a, V: Visitor<'a>>(
visitor: &mut V,
param: &'a GenericParam,
) -> V::Result {
walk_list!(visitor, visit_attribute, &param.attrs);
try_visit!(visitor.visit_ident(param.ident));
walk_list!(visitor, visit_param_bound, &param.bounds, BoundKind::Bound);
match &param.kind {
let GenericParam { id: _, ident, attrs, bounds, is_placeholder: _, kind, colon_span: _ } =
param;
walk_list!(visitor, visit_attribute, attrs);
try_visit!(visitor.visit_ident(*ident));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
match kind {
GenericParamKind::Lifetime => (),
GenericParamKind::Type { default } => visit_opt!(visitor, visit_ty, default),
GenericParamKind::Const { ty, default, .. } => {
GenericParamKind::Const { ty, default, kw_span: _ } => {
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_anon_const, default);
}
@ -737,8 +767,10 @@ pub fn walk_generic_param<'a, V: Visitor<'a>>(
}
pub fn walk_generics<'a, V: Visitor<'a>>(visitor: &mut V, generics: &'a Generics) -> V::Result {
walk_list!(visitor, visit_generic_param, &generics.params);
walk_list!(visitor, visit_where_predicate, &generics.where_clause.predicates);
let Generics { params, where_clause, span: _ } = generics;
let WhereClause { has_where_token: _, predicates, span: _ } = where_clause;
walk_list!(visitor, visit_generic_param, params);
walk_list!(visitor, visit_where_predicate, predicates);
V::Result::output()
}
@ -764,17 +796,17 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(
bounded_ty,
bounds,
bound_generic_params,
..
span: _,
}) => {
walk_list!(visitor, visit_generic_param, bound_generic_params);
try_visit!(visitor.visit_ty(bounded_ty));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
walk_list!(visitor, visit_generic_param, bound_generic_params);
}
WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, .. }) => {
WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, span: _ }) => {
try_visit!(visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
}
WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, .. }) => {
WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span: _ }) => {
try_visit!(visitor.visit_ty(lhs_ty));
try_visit!(visitor.visit_ty(rhs_ty));
}
@ -783,26 +815,28 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(
}
pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FnRetTy) -> V::Result {
if let FnRetTy::Ty(output_ty) = ret_ty {
try_visit!(visitor.visit_ty(output_ty));
match ret_ty {
FnRetTy::Default(_span) => {}
FnRetTy::Ty(output_ty) => try_visit!(visitor.visit_ty(output_ty)),
}
V::Result::output()
}
pub fn walk_fn_decl<'a, V: Visitor<'a>>(
visitor: &mut V,
function_declaration: &'a FnDecl,
FnDecl { inputs, output }: &'a FnDecl,
) -> V::Result {
walk_list!(visitor, visit_param, &function_declaration.inputs);
visitor.visit_fn_ret_ty(&function_declaration.output)
walk_list!(visitor, visit_param, inputs);
visitor.visit_fn_ret_ty(output)
}
pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Result {
match kind {
FnKind::Fn(_, _, sig, _, generics, body) => {
FnKind::Fn(_ctxt, _ident, FnSig { header, decl, span: _ }, _vis, generics, body) => {
// Identifier and visibility are visited as a part of the item.
try_visit!(visitor.visit_fn_header(header));
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_fn_header(&sig.header));
try_visit!(walk_fn_decl(visitor, &sig.decl));
try_visit!(walk_fn_decl(visitor, decl));
visit_opt!(visitor, visit_block, body);
}
FnKind::Closure(binder, decl, body) => {
@ -833,7 +867,13 @@ impl WalkItemKind for AssocItemKind {
FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref());
try_visit!(visitor.visit_fn(kind, span, id));
}
AssocItemKind::Type(box TyAlias { generics, bounds, ty, .. }) => {
AssocItemKind::Type(box TyAlias {
generics,
bounds,
ty,
defaultness: _,
where_clauses: _,
}) => {
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
visit_opt!(visitor, visit_ty, ty);
@ -849,18 +889,14 @@ impl WalkItemKind for AssocItemKind {
body,
from_glob: _,
}) => {
if let Some(qself) = qself {
try_visit!(visitor.visit_ty(&qself.ty));
}
try_visit!(walk_qself(visitor, qself));
try_visit!(visitor.visit_path(path, *id));
visit_opt!(visitor, visit_ident, *rename);
visit_opt!(visitor, visit_block, body);
}
AssocItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
if let Some(qself) = qself {
try_visit!(visitor.visit_ty(&qself.ty));
}
try_visit!(visitor.visit_path(prefix, item.id));
try_visit!(walk_qself(visitor, qself));
try_visit!(visitor.visit_path(prefix, id));
if let Some(suffixes) = suffixes {
for (ident, rename) in suffixes {
visitor.visit_ident(*ident);
@ -898,20 +934,23 @@ pub fn walk_struct_def<'a, V: Visitor<'a>>(
}
pub fn walk_field_def<'a, V: Visitor<'a>>(visitor: &mut V, field: &'a FieldDef) -> V::Result {
walk_list!(visitor, visit_attribute, &field.attrs);
try_visit!(visitor.visit_vis(&field.vis));
visit_opt!(visitor, visit_ident, field.ident);
try_visit!(visitor.visit_ty(&field.ty));
let FieldDef { attrs, id: _, span: _, vis, ident, ty, is_placeholder: _ } = field;
walk_list!(visitor, visit_attribute, attrs);
try_visit!(visitor.visit_vis(vis));
visit_opt!(visitor, visit_ident, *ident);
try_visit!(visitor.visit_ty(ty));
V::Result::output()
}
pub fn walk_block<'a, V: Visitor<'a>>(visitor: &mut V, block: &'a Block) -> V::Result {
walk_list!(visitor, visit_stmt, &block.stmts);
let Block { stmts, id: _, rules: _, span: _, tokens: _, could_be_bare_literal: _ } = block;
walk_list!(visitor, visit_stmt, stmts);
V::Result::output()
}
pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) -> V::Result {
match &statement.kind {
let Stmt { id: _, kind, span: _ } = statement;
match kind {
StmtKind::Let(local) => try_visit!(visitor.visit_local(local)),
StmtKind::Item(item) => try_visit!(visitor.visit_item(item)),
StmtKind::Expr(expr) | StmtKind::Semi(expr) => try_visit!(visitor.visit_expr(expr)),
@ -926,25 +965,37 @@ pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) -> V:
}
pub fn walk_mac<'a, V: Visitor<'a>>(visitor: &mut V, mac: &'a MacCall) -> V::Result {
visitor.visit_path(&mac.path, DUMMY_NODE_ID)
let MacCall { path, args: _ } = mac;
visitor.visit_path(path, DUMMY_NODE_ID)
}
pub fn walk_anon_const<'a, V: Visitor<'a>>(visitor: &mut V, constant: &'a AnonConst) -> V::Result {
visitor.visit_expr(&constant.value)
let AnonConst { id: _, value } = constant;
visitor.visit_expr(value)
}
pub fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) -> V::Result {
for (op, _) in &asm.operands {
let InlineAsm {
template: _,
template_strs: _,
operands,
clobber_abis: _,
options: _,
line_spans: _,
} = asm;
for (op, _span) in operands {
match op {
InlineAsmOperand::In { expr, .. }
| InlineAsmOperand::Out { expr: Some(expr), .. }
| InlineAsmOperand::InOut { expr, .. } => try_visit!(visitor.visit_expr(expr)),
InlineAsmOperand::Out { expr: None, .. } => {}
InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
InlineAsmOperand::In { expr, reg: _ }
| InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ }
| InlineAsmOperand::InOut { expr, reg: _, late: _ } => {
try_visit!(visitor.visit_expr(expr))
}
InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {}
InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
try_visit!(visitor.visit_expr(in_expr));
visit_opt!(visitor, visit_expr, out_expr);
}
InlineAsmOperand::Const { anon_const, .. } => {
InlineAsmOperand::Const { anon_const } => {
try_visit!(visitor.visit_anon_const(anon_const))
}
InlineAsmOperand::Sym { sym } => try_visit!(visitor.visit_inline_asm_sym(sym)),
@ -956,28 +1007,30 @@ pub fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm)
pub fn walk_inline_asm_sym<'a, V: Visitor<'a>>(
visitor: &mut V,
sym: &'a InlineAsmSym,
InlineAsmSym { id, qself, path }: &'a InlineAsmSym,
) -> V::Result {
if let Some(qself) = &sym.qself {
try_visit!(visitor.visit_ty(&qself.ty));
}
visitor.visit_path(&sym.path, sym.id)
try_visit!(walk_qself(visitor, qself));
visitor.visit_path(path, *id)
}
pub fn walk_format_args<'a, V: Visitor<'a>>(visitor: &mut V, fmt: &'a FormatArgs) -> V::Result {
for arg in fmt.arguments.all_args() {
if let FormatArgumentKind::Named(name) = arg.kind {
try_visit!(visitor.visit_ident(name));
let FormatArgs { span: _, template: _, arguments } = fmt;
for FormatArgument { kind, expr } in arguments.all_args() {
match kind {
FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => {
try_visit!(visitor.visit_ident(*ident))
}
FormatArgumentKind::Normal => {}
}
try_visit!(visitor.visit_expr(&arg.expr));
try_visit!(visitor.visit_expr(expr));
}
V::Result::output()
}
pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V::Result {
walk_list!(visitor, visit_attribute, &expression.attrs);
match &expression.kind {
let Expr { id, kind, span, attrs, tokens: _ } = expression;
walk_list!(visitor, visit_attribute, attrs);
match kind {
ExprKind::Array(subexpressions) => {
walk_list!(visitor, visit_expr, subexpressions);
}
@ -987,12 +1040,11 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
try_visit!(visitor.visit_anon_const(count));
}
ExprKind::Struct(se) => {
if let Some(qself) = &se.qself {
try_visit!(visitor.visit_ty(&qself.ty));
}
try_visit!(visitor.visit_path(&se.path, expression.id));
walk_list!(visitor, visit_expr_field, &se.fields);
match &se.rest {
let StructExpr { qself, path, fields, rest } = &**se;
try_visit!(walk_qself(visitor, qself));
try_visit!(visitor.visit_path(path, *id));
walk_list!(visitor, visit_expr_field, fields);
match rest {
StructRest::Base(expr) => try_visit!(visitor.visit_expr(expr)),
StructRest::Rest(_span) => {}
StructRest::None => {}
@ -1006,22 +1058,25 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
walk_list!(visitor, visit_expr, arguments);
}
ExprKind::MethodCall(box MethodCall { seg, receiver, args, span: _ }) => {
try_visit!(visitor.visit_path_segment(seg));
try_visit!(visitor.visit_expr(receiver));
try_visit!(visitor.visit_path_segment(seg));
walk_list!(visitor, visit_expr, args);
}
ExprKind::Binary(_, left_expression, right_expression) => {
ExprKind::Binary(_op, left_expression, right_expression) => {
try_visit!(visitor.visit_expr(left_expression));
try_visit!(visitor.visit_expr(right_expression));
}
ExprKind::AddrOf(_, _, subexpression) | ExprKind::Unary(_, subexpression) => {
ExprKind::AddrOf(_kind, _mutbl, subexpression) => {
try_visit!(visitor.visit_expr(subexpression));
}
ExprKind::Unary(_op, subexpression) => {
try_visit!(visitor.visit_expr(subexpression));
}
ExprKind::Cast(subexpression, typ) | ExprKind::Type(subexpression, typ) => {
try_visit!(visitor.visit_expr(subexpression));
try_visit!(visitor.visit_ty(typ));
}
ExprKind::Let(pat, expr, _, _) => {
ExprKind::Let(pat, expr, _span, _recovered) => {
try_visit!(visitor.visit_pat(pat));
try_visit!(visitor.visit_expr(expr));
}
@ -1041,7 +1096,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
try_visit!(visitor.visit_expr(iter));
try_visit!(visitor.visit_block(body));
}
ExprKind::Loop(block, opt_label, _) => {
ExprKind::Loop(block, opt_label, _span) => {
visit_opt!(visitor, visit_label, opt_label);
try_visit!(visitor.visit_block(block));
}
@ -1061,23 +1116,19 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
fn_arg_span: _,
}) => {
try_visit!(visitor.visit_capture_by(capture_clause));
try_visit!(visitor.visit_fn(
FnKind::Closure(binder, fn_decl, body),
expression.span,
expression.id
))
try_visit!(visitor.visit_fn(FnKind::Closure(binder, fn_decl, body), *span, *id))
}
ExprKind::Block(block, opt_label) => {
visit_opt!(visitor, visit_label, opt_label);
try_visit!(visitor.visit_block(block));
}
ExprKind::Gen(_, body, _) => try_visit!(visitor.visit_block(body)),
ExprKind::Await(expr, _) => try_visit!(visitor.visit_expr(expr)),
ExprKind::Assign(lhs, rhs, _) => {
ExprKind::Gen(_capt, body, _kind) => try_visit!(visitor.visit_block(body)),
ExprKind::Await(expr, _span) => try_visit!(visitor.visit_expr(expr)),
ExprKind::Assign(lhs, rhs, _span) => {
try_visit!(visitor.visit_expr(lhs));
try_visit!(visitor.visit_expr(rhs));
}
ExprKind::AssignOp(_, left_expression, right_expression) => {
ExprKind::AssignOp(_op, left_expression, right_expression) => {
try_visit!(visitor.visit_expr(left_expression));
try_visit!(visitor.visit_expr(right_expression));
}
@ -1085,20 +1136,18 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
try_visit!(visitor.visit_expr(subexpression));
try_visit!(visitor.visit_ident(*ident));
}
ExprKind::Index(main_expression, index_expression, _) => {
ExprKind::Index(main_expression, index_expression, _span) => {
try_visit!(visitor.visit_expr(main_expression));
try_visit!(visitor.visit_expr(index_expression));
}
ExprKind::Range(start, end, _) => {
ExprKind::Range(start, end, _limit) => {
visit_opt!(visitor, visit_expr, start);
visit_opt!(visitor, visit_expr, end);
}
ExprKind::Underscore => {}
ExprKind::Path(maybe_qself, path) => {
if let Some(qself) = maybe_qself {
try_visit!(visitor.visit_ty(&qself.ty));
}
try_visit!(visitor.visit_path(path, expression.id));
try_visit!(walk_qself(visitor, maybe_qself));
try_visit!(visitor.visit_path(path, *id));
}
ExprKind::Break(opt_label, opt_expr) => {
visit_opt!(visitor, visit_label, opt_label);
@ -1127,38 +1176,53 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
}
ExprKind::Try(subexpression) => try_visit!(visitor.visit_expr(subexpression)),
ExprKind::TryBlock(body) => try_visit!(visitor.visit_block(body)),
ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err(_) | ExprKind::Dummy => {}
ExprKind::Lit(_token) => {}
ExprKind::IncludedBytes(_bytes) => {}
ExprKind::Err(_guar) => {}
ExprKind::Dummy => {}
}
visitor.visit_expr_post(expression)
}
pub fn walk_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Param) -> V::Result {
walk_list!(visitor, visit_attribute, &param.attrs);
try_visit!(visitor.visit_pat(&param.pat));
try_visit!(visitor.visit_ty(&param.ty));
let Param { attrs, ty, pat, id: _, span: _, is_placeholder: _ } = param;
walk_list!(visitor, visit_attribute, attrs);
try_visit!(visitor.visit_pat(pat));
try_visit!(visitor.visit_ty(ty));
V::Result::output()
}
pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) -> V::Result {
walk_list!(visitor, visit_attribute, &arm.attrs);
try_visit!(visitor.visit_pat(&arm.pat));
visit_opt!(visitor, visit_expr, &arm.guard);
visit_opt!(visitor, visit_expr, &arm.body);
let Arm { attrs, pat, guard, body, span: _, id: _, is_placeholder: _ } = arm;
walk_list!(visitor, visit_attribute, attrs);
try_visit!(visitor.visit_pat(pat));
visit_opt!(visitor, visit_expr, guard);
visit_opt!(visitor, visit_expr, body);
V::Result::output()
}
pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) -> V::Result {
if let VisibilityKind::Restricted { ref path, id, shorthand: _ } = vis.kind {
try_visit!(visitor.visit_path(path, id));
let Visibility { kind, span: _, tokens: _ } = vis;
match kind {
VisibilityKind::Restricted { path, id, shorthand: _ } => {
try_visit!(visitor.visit_path(path, *id));
}
VisibilityKind::Public | VisibilityKind::Inherited => {}
}
V::Result::output()
}
pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) -> V::Result {
match &attr.kind {
AttrKind::Normal(normal) => try_visit!(walk_attr_args(visitor, &normal.item.args)),
AttrKind::DocComment(..) => {}
let Attribute { kind, id: _, style: _, span: _ } = attr;
match kind {
AttrKind::Normal(normal) => {
let NormalAttr { item, tokens: _ } = &**normal;
let AttrItem { unsafety: _, path, args, tokens: _ } = item;
try_visit!(visitor.visit_path(path, DUMMY_NODE_ID));
try_visit!(walk_attr_args(visitor, args));
}
AttrKind::DocComment(_kind, _sym) => {}
}
V::Result::output()
}
@ -1166,9 +1230,9 @@ pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute)
pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) -> V::Result {
match args {
AttrArgs::Empty => {}
AttrArgs::Delimited(_) => {}
AttrArgs::Delimited(_args) => {}
AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => try_visit!(visitor.visit_expr(expr)),
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
AttrArgs::Eq(_eq_span, AttrArgsEq::Hir(lit)) => {
unreachable!("in literal form when walking mac args eq: {:?}", lit)
}
}

View File

@ -13,13 +13,13 @@ ast-stats-1 - DocComment 32 ( 0.5%) 1
ast-stats-1 Local 80 ( 1.2%) 1 80
ast-stats-1 ForeignItem 88 ( 1.3%) 1 88
ast-stats-1 - Fn 88 ( 1.3%) 1
ast-stats-1 Arm 96 ( 1.5%) 2 48
ast-stats-1 Arm 96 ( 1.4%) 2 48
ast-stats-1 FnDecl 120 ( 1.8%) 5 24
ast-stats-1 FieldDef 160 ( 2.4%) 2 80
ast-stats-1 Stmt 160 ( 2.4%) 5 32
ast-stats-1 - Let 32 ( 0.5%) 1
ast-stats-1 - MacCall 32 ( 0.5%) 1
ast-stats-1 - Expr 96 ( 1.5%) 3
ast-stats-1 - Expr 96 ( 1.4%) 3
ast-stats-1 Param 160 ( 2.4%) 4 40
ast-stats-1 Block 192 ( 2.9%) 6 32
ast-stats-1 Variant 208 ( 3.1%) 2 104
@ -28,7 +28,7 @@ ast-stats-1 - Trait 352 ( 5.3%) 4
ast-stats-1 AssocItem 352 ( 5.3%) 4 88
ast-stats-1 - Type 176 ( 2.7%) 2
ast-stats-1 - Fn 176 ( 2.7%) 2
ast-stats-1 GenericParam 480 ( 7.3%) 5 96
ast-stats-1 GenericParam 480 ( 7.2%) 5 96
ast-stats-1 Pat 504 ( 7.6%) 7 72
ast-stats-1 - Struct 72 ( 1.1%) 1
ast-stats-1 - Wild 72 ( 1.1%) 1
@ -39,28 +39,28 @@ ast-stats-1 - Match 72 ( 1.1%) 1
ast-stats-1 - Struct 72 ( 1.1%) 1
ast-stats-1 - Lit 144 ( 2.2%) 2
ast-stats-1 - Block 216 ( 3.3%) 3
ast-stats-1 PathSegment 720 (10.9%) 30 24
ast-stats-1 PathSegment 744 (11.2%) 31 24
ast-stats-1 Ty 896 (13.5%) 14 64
ast-stats-1 - Ptr 64 ( 1.0%) 1
ast-stats-1 - Ref 64 ( 1.0%) 1
ast-stats-1 - ImplicitSelf 128 ( 1.9%) 2
ast-stats-1 - Path 640 ( 9.7%) 10
ast-stats-1 Item 1_224 (18.5%) 9 136
ast-stats-1 - Trait 136 ( 2.1%) 1
ast-stats-1 - Enum 136 ( 2.1%) 1
ast-stats-1 - ForeignMod 136 ( 2.1%) 1
ast-stats-1 - Impl 136 ( 2.1%) 1
ast-stats-1 - Path 640 ( 9.6%) 10
ast-stats-1 Item 1_224 (18.4%) 9 136
ast-stats-1 - Trait 136 ( 2.0%) 1
ast-stats-1 - Enum 136 ( 2.0%) 1
ast-stats-1 - ForeignMod 136 ( 2.0%) 1
ast-stats-1 - Impl 136 ( 2.0%) 1
ast-stats-1 - Fn 272 ( 4.1%) 2
ast-stats-1 - Use 408 ( 6.2%) 3
ast-stats-1 - Use 408 ( 6.1%) 3
ast-stats-1 ----------------------------------------------------------------
ast-stats-1 Total 6_616
ast-stats-1 Total 6_640
ast-stats-1
ast-stats-2 POST EXPANSION AST STATS
ast-stats-2 Name Accumulated Size Count Item Size
ast-stats-2 ----------------------------------------------------------------
ast-stats-2 GenericArgs 40 ( 0.6%) 1 40
ast-stats-2 - AngleBracketed 40 ( 0.6%) 1
ast-stats-2 Crate 40 ( 0.6%) 1 40
ast-stats-2 GenericArgs 40 ( 0.5%) 1 40
ast-stats-2 - AngleBracketed 40 ( 0.5%) 1
ast-stats-2 Crate 40 ( 0.5%) 1 40
ast-stats-2 ExprField 48 ( 0.7%) 1 48
ast-stats-2 WherePredicate 56 ( 0.8%) 1 56
ast-stats-2 - BoundPredicate 56 ( 0.8%) 1
@ -68,8 +68,8 @@ ast-stats-2 Local 80 ( 1.1%) 1 80
ast-stats-2 ForeignItem 88 ( 1.2%) 1 88
ast-stats-2 - Fn 88 ( 1.2%) 1
ast-stats-2 Arm 96 ( 1.3%) 2 48
ast-stats-2 InlineAsm 120 ( 1.7%) 1 120
ast-stats-2 FnDecl 120 ( 1.7%) 5 24
ast-stats-2 InlineAsm 120 ( 1.6%) 1 120
ast-stats-2 FnDecl 120 ( 1.6%) 5 24
ast-stats-2 Attribute 128 ( 1.8%) 4 32
ast-stats-2 - DocComment 32 ( 0.4%) 1
ast-stats-2 - Normal 96 ( 1.3%) 3
@ -79,41 +79,41 @@ ast-stats-2 - Let 32 ( 0.4%) 1
ast-stats-2 - Semi 32 ( 0.4%) 1
ast-stats-2 - Expr 96 ( 1.3%) 3
ast-stats-2 Param 160 ( 2.2%) 4 40
ast-stats-2 Block 192 ( 2.7%) 6 32
ast-stats-2 Block 192 ( 2.6%) 6 32
ast-stats-2 Variant 208 ( 2.9%) 2 104
ast-stats-2 GenericBound 352 ( 4.9%) 4 88
ast-stats-2 - Trait 352 ( 4.9%) 4
ast-stats-2 AssocItem 352 ( 4.9%) 4 88
ast-stats-2 GenericBound 352 ( 4.8%) 4 88
ast-stats-2 - Trait 352 ( 4.8%) 4
ast-stats-2 AssocItem 352 ( 4.8%) 4 88
ast-stats-2 - Type 176 ( 2.4%) 2
ast-stats-2 - Fn 176 ( 2.4%) 2
ast-stats-2 GenericParam 480 ( 6.7%) 5 96
ast-stats-2 Pat 504 ( 7.0%) 7 72
ast-stats-2 GenericParam 480 ( 6.6%) 5 96
ast-stats-2 Pat 504 ( 6.9%) 7 72
ast-stats-2 - Struct 72 ( 1.0%) 1
ast-stats-2 - Wild 72 ( 1.0%) 1
ast-stats-2 - Ident 360 ( 5.0%) 5
ast-stats-2 Expr 648 ( 9.0%) 9 72
ast-stats-2 - Ident 360 ( 4.9%) 5
ast-stats-2 Expr 648 ( 8.9%) 9 72
ast-stats-2 - Path 72 ( 1.0%) 1
ast-stats-2 - Match 72 ( 1.0%) 1
ast-stats-2 - Struct 72 ( 1.0%) 1
ast-stats-2 - InlineAsm 72 ( 1.0%) 1
ast-stats-2 - Lit 144 ( 2.0%) 2
ast-stats-2 - Block 216 ( 3.0%) 3
ast-stats-2 PathSegment 792 (11.0%) 33 24
ast-stats-2 Ty 896 (12.4%) 14 64
ast-stats-2 PathSegment 864 (11.9%) 36 24
ast-stats-2 Ty 896 (12.3%) 14 64
ast-stats-2 - Ptr 64 ( 0.9%) 1
ast-stats-2 - Ref 64 ( 0.9%) 1
ast-stats-2 - ImplicitSelf 128 ( 1.8%) 2
ast-stats-2 - Path 640 ( 8.9%) 10
ast-stats-2 Item 1_496 (20.7%) 11 136
ast-stats-2 - Path 640 ( 8.8%) 10
ast-stats-2 Item 1_496 (20.5%) 11 136
ast-stats-2 - Trait 136 ( 1.9%) 1
ast-stats-2 - Enum 136 ( 1.9%) 1
ast-stats-2 - ExternCrate 136 ( 1.9%) 1
ast-stats-2 - ForeignMod 136 ( 1.9%) 1
ast-stats-2 - Impl 136 ( 1.9%) 1
ast-stats-2 - Fn 272 ( 3.8%) 2
ast-stats-2 - Fn 272 ( 3.7%) 2
ast-stats-2 - Use 544 ( 7.5%) 4
ast-stats-2 ----------------------------------------------------------------
ast-stats-2 Total 7_216
ast-stats-2 Total 7_288
ast-stats-2
hir-stats HIR STATS
hir-stats Name Accumulated Size Count Item Size