about summary refs log tree commit diff
path: root/compiler/rustc_ast/src/ast.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_ast/src/ast.rs')
-rw-r--r--compiler/rustc_ast/src/ast.rs805
1 files changed, 373 insertions, 432 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 8c2b521c560..3e8fddd9954 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -23,22 +23,22 @@ use std::{cmp, fmt};
 
 pub use GenericArgs::*;
 pub use UnsafeSource::*;
-pub use rustc_ast_ir::{Movability, Mutability, Pinnedness};
+pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy};
 use rustc_data_structures::packed::Pu128;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_data_structures::tagged_ptr::Tag;
-use rustc_macros::{Decodable, Encodable, HashStable_Generic};
+use rustc_macros::{Decodable, Encodable, HashStable_Generic, Walkable};
 pub use rustc_span::AttrId;
 use rustc_span::source_map::{Spanned, respan};
 use rustc_span::{ByteSymbol, DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
 use thin_vec::{ThinVec, thin_vec};
 
 pub use crate::format::*;
-use crate::ptr::P;
 use crate::token::{self, CommentKind, Delimiter};
 use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
 use crate::util::parser::{ExprPrecedence, Fixity};
+use crate::visit::{AssocCtxt, BoundKind, LifetimeCtxt};
 
 /// A "Label" is an identifier of some point in sources,
 /// e.g. in the following code:
@@ -50,7 +50,7 @@ use crate::util::parser::{ExprPrecedence, Fixity};
 /// ```
 ///
 /// `'outer` is a label.
-#[derive(Clone, Encodable, Decodable, Copy, HashStable_Generic, Eq, PartialEq)]
+#[derive(Clone, Encodable, Decodable, Copy, HashStable_Generic, Eq, PartialEq, Walkable)]
 pub struct Label {
     pub ident: Ident,
 }
@@ -63,7 +63,7 @@ impl fmt::Debug for Label {
 
 /// A "Lifetime" is an annotation of the scope in which variable
 /// can be used, e.g. `'a` in `&'a i32`.
-#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq, Hash)]
+#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq, Hash, Walkable)]
 pub struct Lifetime {
     pub id: NodeId,
     pub ident: Ident,
@@ -87,7 +87,7 @@ impl fmt::Display for Lifetime {
 /// along with a bunch of supporting information.
 ///
 /// E.g., `std::cmp::PartialEq`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct Path {
     pub span: Span,
     /// The segments in the path: the things separated by `::`.
@@ -211,7 +211,7 @@ pub fn join_path_idents(path: impl IntoIterator<Item = impl Borrow<Ident>>) -> S
 /// A segment of a path: an identifier, an optional lifetime, and a set of types.
 ///
 /// E.g., `std`, `String` or `Box<T>`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct PathSegment {
     /// The identifier portion of this path segment.
     pub ident: Ident,
@@ -224,7 +224,7 @@ pub struct PathSegment {
     /// `Some` means that parameter list is supplied (`Path<X, Y>`)
     /// but it can be empty (`Path<>`).
     /// `P` is used as a size optimization for the common case with no parameters.
-    pub args: Option<P<GenericArgs>>,
+    pub args: Option<Box<GenericArgs>>,
 }
 
 // Succeeds if the path segment is arg-free and matches the given symbol.
@@ -255,7 +255,7 @@ impl PathSegment {
 /// The generic arguments and associated item constraints of a path segment.
 ///
 /// E.g., `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum GenericArgs {
     /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`.
     AngleBracketed(AngleBracketedArgs),
@@ -280,12 +280,12 @@ impl GenericArgs {
 }
 
 /// Concrete argument in the sequence of generic args.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum GenericArg {
     /// `'a` in `Foo<'a>`.
-    Lifetime(Lifetime),
+    Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
     /// `Bar` in `Foo<Bar>`.
-    Type(P<Ty>),
+    Type(Box<Ty>),
     /// `1` in `Foo<1>`.
     Const(AnonConst),
 }
@@ -301,7 +301,7 @@ impl GenericArg {
 }
 
 /// A path like `Foo<'a, T>`.
-#[derive(Clone, Encodable, Decodable, Debug, Default)]
+#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
 pub struct AngleBracketedArgs {
     /// The overall span.
     pub span: Span,
@@ -310,7 +310,7 @@ pub struct AngleBracketedArgs {
 }
 
 /// Either an argument for a generic parameter or a constraint on an associated item.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum AngleBracketedArg {
     /// A generic argument for a generic parameter.
     Arg(GenericArg),
@@ -327,20 +327,20 @@ impl AngleBracketedArg {
     }
 }
 
-impl From<AngleBracketedArgs> for P<GenericArgs> {
+impl From<AngleBracketedArgs> for Box<GenericArgs> {
     fn from(val: AngleBracketedArgs) -> Self {
-        P(GenericArgs::AngleBracketed(val))
+        Box::new(GenericArgs::AngleBracketed(val))
     }
 }
 
-impl From<ParenthesizedArgs> for P<GenericArgs> {
+impl From<ParenthesizedArgs> for Box<GenericArgs> {
     fn from(val: ParenthesizedArgs) -> Self {
-        P(GenericArgs::Parenthesized(val))
+        Box::new(GenericArgs::Parenthesized(val))
     }
 }
 
 /// A path like `Foo(A, B) -> C`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct ParenthesizedArgs {
     /// ```text
     /// Foo(A, B) -> C
@@ -349,7 +349,7 @@ pub struct ParenthesizedArgs {
     pub span: Span,
 
     /// `(A, B)`
-    pub inputs: ThinVec<P<Ty>>,
+    pub inputs: ThinVec<Box<Ty>>,
 
     /// ```text
     /// Foo(A, B) -> C
@@ -376,7 +376,7 @@ impl ParenthesizedArgs {
 pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
 
 /// Modifiers on a trait bound like `[const]`, `?` and `!`.
-#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Walkable)]
 pub struct TraitBoundModifiers {
     pub constness: BoundConstness,
     pub asyncness: BoundAsyncness,
@@ -391,10 +391,10 @@ impl TraitBoundModifiers {
     };
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum GenericBound {
     Trait(PolyTraitRef),
-    Outlives(Lifetime),
+    Outlives(#[visitable(extra = LifetimeCtxt::Bound)] Lifetime),
     /// Precise capturing syntax: `impl Sized + use<'a>`
     Use(ThinVec<PreciseCapturingArg>, Span),
 }
@@ -429,15 +429,15 @@ impl fmt::Display for ParamKindOrd {
     }
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum GenericParamKind {
     /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
     Lifetime,
     Type {
-        default: Option<P<Ty>>,
+        default: Option<Box<Ty>>,
     },
     Const {
-        ty: P<Ty>,
+        ty: Box<Ty>,
         /// Span of the whole parameter definition, including default.
         span: Span,
         /// Optional default value for the const generic param.
@@ -445,11 +445,12 @@ pub enum GenericParamKind {
     },
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct GenericParam {
     pub id: NodeId,
     pub ident: Ident,
     pub attrs: AttrVec,
+    #[visitable(extra = BoundKind::Bound)]
     pub bounds: GenericBounds,
     pub is_placeholder: bool,
     pub kind: GenericParamKind,
@@ -470,7 +471,7 @@ impl GenericParam {
 
 /// Represents lifetime, type and const parameters attached to a declaration of
 /// a function, enum, trait, etc.
-#[derive(Clone, Encodable, Decodable, Debug, Default)]
+#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
 pub struct Generics {
     pub params: ThinVec<GenericParam>,
     pub where_clause: WhereClause,
@@ -478,7 +479,7 @@ pub struct Generics {
 }
 
 /// A where-clause in a definition.
-#[derive(Clone, Encodable, Decodable, Debug, Default)]
+#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
 pub struct WhereClause {
     /// `true` if we ate a `where` token.
     ///
@@ -496,7 +497,7 @@ impl WhereClause {
 }
 
 /// A single predicate in a where-clause.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct WherePredicate {
     pub attrs: AttrVec,
     pub kind: WherePredicateKind,
@@ -506,7 +507,7 @@ pub struct WherePredicate {
 }
 
 /// Predicate kind in where-clause.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum WherePredicateKind {
     /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
     BoundPredicate(WhereBoundPredicate),
@@ -519,42 +520,45 @@ pub enum WherePredicateKind {
 /// A type bound.
 ///
 /// E.g., `for<'c> Foo: Send + Clone + 'c`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct WhereBoundPredicate {
     /// Any generics from a `for` binding.
     pub bound_generic_params: ThinVec<GenericParam>,
     /// The type being bounded.
-    pub bounded_ty: P<Ty>,
+    pub bounded_ty: Box<Ty>,
     /// Trait and lifetime bounds (`Clone + Send + 'static`).
+    #[visitable(extra = BoundKind::Bound)]
     pub bounds: GenericBounds,
 }
 
 /// A lifetime predicate.
 ///
 /// E.g., `'a: 'b + 'c`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct WhereRegionPredicate {
+    #[visitable(extra = LifetimeCtxt::Bound)]
     pub lifetime: Lifetime,
+    #[visitable(extra = BoundKind::Bound)]
     pub bounds: GenericBounds,
 }
 
 /// An equality predicate (unsupported).
 ///
 /// E.g., `T = int`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct WhereEqPredicate {
-    pub lhs_ty: P<Ty>,
-    pub rhs_ty: P<Ty>,
+    pub lhs_ty: Box<Ty>,
+    pub rhs_ty: Box<Ty>,
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct Crate {
-    pub attrs: AttrVec,
-    pub items: ThinVec<P<Item>>,
-    pub spans: ModSpans,
     /// Must be equal to `CRATE_NODE_ID` after the crate root is expanded, but may hold
     /// expansion placeholders or an unassigned value (`DUMMY_NODE_ID`) before that.
     pub id: NodeId,
+    pub attrs: AttrVec,
+    pub items: ThinVec<Box<Item>>,
+    pub spans: ModSpans,
     pub is_placeholder: bool,
 }
 
@@ -608,7 +612,7 @@ pub enum MetaItemInner {
 /// A block (`{ .. }`).
 ///
 /// E.g., `{ .. }` as in `fn foo() { .. }`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct Block {
     /// The statements in the block.
     pub stmts: ThinVec<Stmt>,
@@ -622,7 +626,7 @@ pub struct Block {
 /// A match pattern.
 ///
 /// Patterns appear in match statements and some other contexts, such as `let` and `if let`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct Pat {
     pub id: NodeId,
     pub kind: PatKind,
@@ -633,7 +637,7 @@ pub struct Pat {
 impl Pat {
     /// Attempt reparsing the pattern as a type.
     /// This is intended for use by diagnostics.
-    pub fn to_ty(&self) -> Option<P<Ty>> {
+    pub fn to_ty(&self) -> Option<Box<Ty>> {
         let kind = match &self.kind {
             PatKind::Missing => unreachable!(),
             // In a type expression `_` is an inference variable.
@@ -666,7 +670,7 @@ impl Pat {
             _ => return None,
         };
 
-        Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
+        Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None }))
     }
 
     /// Walk top-down and call `it` in each place where a pattern occurs
@@ -759,8 +763,8 @@ impl Pat {
     }
 }
 
-impl From<P<Pat>> for Pat {
-    fn from(value: P<Pat>) -> Self {
+impl From<Box<Pat>> for Pat {
+    fn from(value: Box<Pat>) -> Self {
         *value
     }
 }
@@ -770,12 +774,12 @@ impl From<P<Pat>> for Pat {
 /// Patterns like the fields of `Foo { x, ref y, ref mut z }`
 /// are treated the same as `x: x, y: ref y, z: ref mut z`,
 /// except when `is_shorthand` is true.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct PatField {
     /// The identifier for the field.
     pub ident: Ident,
     /// The pattern the field is destructured to.
-    pub pat: P<Pat>,
+    pub pat: Box<Pat>,
     pub is_shorthand: bool,
     pub attrs: AttrVec,
     pub id: NodeId,
@@ -784,7 +788,7 @@ pub struct PatField {
 }
 
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
-#[derive(Encodable, Decodable, HashStable_Generic)]
+#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
 pub enum ByRef {
     Yes(Mutability),
     No,
@@ -806,7 +810,7 @@ impl ByRef {
 /// `.0` is the by-reference mode (`ref`, `ref mut`, or by value),
 /// `.1` is the mutability of the binding.
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
-#[derive(Encodable, Decodable, HashStable_Generic)]
+#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
 pub struct BindingMode(pub ByRef, pub Mutability);
 
 impl BindingMode {
@@ -829,7 +833,7 @@ impl BindingMode {
     }
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum RangeEnd {
     /// `..=` or `...`
     Included(RangeSyntax),
@@ -837,7 +841,7 @@ pub enum RangeEnd {
     Excluded,
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum RangeSyntax {
     /// `...`
     DotDotDot,
@@ -848,7 +852,7 @@ pub enum RangeSyntax {
 /// All the different flavors of pattern that Rust recognizes.
 //
 // Adding a new variant? Please update `test_pat` in `tests/ui/macros/stringify.rs`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum PatKind {
     /// A missing pattern, e.g. for an anonymous param in a bare fn like `fn f(u32)`.
     Missing,
@@ -860,44 +864,44 @@ pub enum PatKind {
     /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
     /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
     /// during name resolution.
-    Ident(BindingMode, Ident, Option<P<Pat>>),
+    Ident(BindingMode, Ident, Option<Box<Pat>>),
 
     /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
-    Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
+    Struct(Option<Box<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
 
     /// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
-    TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>),
+    TupleStruct(Option<Box<QSelf>>, Path, ThinVec<Box<Pat>>),
 
     /// An or-pattern `A | B | C`.
     /// Invariant: `pats.len() >= 2`.
-    Or(ThinVec<P<Pat>>),
+    Or(ThinVec<Box<Pat>>),
 
     /// A possibly qualified path pattern.
     /// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants
     /// or associated constants. Qualified path patterns `<A>::B::C`/`<A as Trait>::B::C` can
     /// only legally refer to associated constants.
-    Path(Option<P<QSelf>>, Path),
+    Path(Option<Box<QSelf>>, Path),
 
     /// A tuple pattern (`(a, b)`).
-    Tuple(ThinVec<P<Pat>>),
+    Tuple(ThinVec<Box<Pat>>),
 
     /// A `box` pattern.
-    Box(P<Pat>),
+    Box(Box<Pat>),
 
     /// A `deref` pattern (currently `deref!()` macro-based syntax).
-    Deref(P<Pat>),
+    Deref(Box<Pat>),
 
     /// A reference pattern (e.g., `&mut (a, b)`).
-    Ref(P<Pat>, Mutability),
+    Ref(Box<Pat>, Mutability),
 
     /// A literal, const block or path.
-    Expr(P<Expr>),
+    Expr(Box<Expr>),
 
     /// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
-    Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>),
+    Range(Option<Box<Expr>>, Option<Box<Expr>>, Spanned<RangeEnd>),
 
     /// A slice pattern `[a, b, c]`.
-    Slice(ThinVec<P<Pat>>),
+    Slice(ThinVec<Box<Pat>>),
 
     /// A rest pattern `..`.
     ///
@@ -917,23 +921,23 @@ pub enum PatKind {
     Never,
 
     /// A guard pattern (e.g., `x if guard(x)`).
-    Guard(P<Pat>, P<Expr>),
+    Guard(Box<Pat>, Box<Expr>),
 
     /// Parentheses in patterns used for grouping (i.e., `(PAT)`).
-    Paren(P<Pat>),
+    Paren(Box<Pat>),
 
     /// A macro pattern; pre-expansion.
-    MacCall(P<MacCall>),
+    MacCall(Box<MacCall>),
 
     /// Placeholder for a pattern that wasn't syntactically well formed in some way.
     Err(ErrorGuaranteed),
 }
 
 /// Whether the `..` is present in a struct fields pattern.
-#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
+#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
 pub enum PatFieldsRest {
     /// `module::StructName { field, ..}`
-    Rest,
+    Rest(Span),
     /// `module::StructName { field, syntax error }`
     Recovered(ErrorGuaranteed),
     /// `module::StructName { field }`
@@ -943,7 +947,7 @@ pub enum PatFieldsRest {
 /// The kind of borrow in an `AddrOf` expression,
 /// e.g., `&place` or `&raw const place`.
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-#[derive(Encodable, Decodable, HashStable_Generic)]
+#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
 pub enum BorrowKind {
     /// A normal borrow, `&$expr` or `&mut $expr`.
     /// The resulting type is either `&'a T` or `&'a mut T`
@@ -959,7 +963,7 @@ pub enum BorrowKind {
     Pin,
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
+#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
 pub enum BinOpKind {
     /// The `+` operator (addition)
     Add,
@@ -1089,7 +1093,7 @@ impl From<AssignOpKind> for BinOpKind {
     }
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
+#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
 pub enum AssignOpKind {
     /// The `+=` operator (addition)
     AddAssign,
@@ -1141,7 +1145,7 @@ pub type AssignOp = Spanned<AssignOpKind>;
 /// Unary operator.
 ///
 /// Note that `&data` is not an operator, it's an `AddrOf` expression.
-#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
+#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
 pub enum UnOp {
     /// The `*` operator for dereferencing
     Deref,
@@ -1215,31 +1219,31 @@ impl Stmt {
 }
 
 // Adding a new variant? Please update `test_stmt` in `tests/ui/macros/stringify.rs`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum StmtKind {
     /// A local (let) binding.
-    Let(P<Local>),
+    Let(Box<Local>),
     /// An item definition.
-    Item(P<Item>),
+    Item(Box<Item>),
     /// Expr without trailing semi-colon.
-    Expr(P<Expr>),
+    Expr(Box<Expr>),
     /// Expr with a trailing semi-colon.
-    Semi(P<Expr>),
+    Semi(Box<Expr>),
     /// Just a trailing semi-colon.
     Empty,
     /// Macro.
-    MacCall(P<MacCallStmt>),
+    MacCall(Box<MacCallStmt>),
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct MacCallStmt {
-    pub mac: P<MacCall>,
+    pub mac: Box<MacCall>,
     pub style: MacStmtStyle,
     pub attrs: AttrVec,
     pub tokens: Option<LazyAttrTokenStream>,
 }
 
-#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
+#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
 pub enum MacStmtStyle {
     /// The macro statement had a trailing semicolon (e.g., `foo! { ... };`
     /// `foo!(...);`, `foo![...];`).
@@ -1253,12 +1257,12 @@ pub enum MacStmtStyle {
 }
 
 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct Local {
     pub id: NodeId,
     pub super_: Option<Span>,
-    pub pat: P<Pat>,
-    pub ty: Option<P<Ty>>,
+    pub pat: Box<Pat>,
+    pub ty: Option<Box<Ty>>,
     pub kind: LocalKind,
     pub span: Span,
     pub colon_sp: Option<Span>,
@@ -1266,17 +1270,17 @@ pub struct Local {
     pub tokens: Option<LazyAttrTokenStream>,
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum LocalKind {
     /// Local declaration.
     /// Example: `let x;`
     Decl,
     /// Local declaration with an initializer.
     /// Example: `let x = y;`
-    Init(P<Expr>),
+    Init(Box<Expr>),
     /// Local declaration with an initializer and an `else` clause.
     /// Example: `let Some(x) = y else { return };`
-    InitElse(P<Expr>, P<Block>),
+    InitElse(Box<Expr>, Box<Block>),
 }
 
 impl LocalKind {
@@ -1306,39 +1310,39 @@ impl LocalKind {
 ///     _ => { println!("no match!") },
 /// }
 /// ```
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct Arm {
     pub attrs: AttrVec,
     /// Match arm pattern, e.g. `10` in `match foo { 10 => {}, _ => {} }`.
-    pub pat: P<Pat>,
+    pub pat: Box<Pat>,
     /// Match arm guard, e.g. `n > 10` in `match foo { n if n > 10 => {}, _ => {} }`.
-    pub guard: Option<P<Expr>>,
+    pub guard: Option<Box<Expr>>,
     /// Match arm body. Omitted if the pattern is a never pattern.
-    pub body: Option<P<Expr>>,
+    pub body: Option<Box<Expr>>,
     pub span: Span,
     pub id: NodeId,
     pub is_placeholder: bool,
 }
 
 /// A single field in a struct expression, e.g. `x: value` and `y` in `Foo { x: value, y }`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct ExprField {
     pub attrs: AttrVec,
     pub id: NodeId,
     pub span: Span,
     pub ident: Ident,
-    pub expr: P<Expr>,
+    pub expr: Box<Expr>,
     pub is_shorthand: bool,
     pub is_placeholder: bool,
 }
 
-#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
+#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
 pub enum BlockCheckMode {
     Default,
     Unsafe(UnsafeSource),
 }
 
-#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
+#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
 pub enum UnsafeSource {
     CompilerGenerated,
     UserProvided,
@@ -1349,10 +1353,10 @@ pub enum UnsafeSource {
 /// These are usually found nested inside types (e.g., array lengths)
 /// or expressions (e.g., repeat counts), and also used to define
 /// explicit discriminant values for enum variants.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct AnonConst {
     pub id: NodeId,
-    pub value: P<Expr>,
+    pub value: Box<Expr>,
 }
 
 /// An expression.
@@ -1464,7 +1468,7 @@ impl Expr {
     }
 
     /// Attempts to reparse as `Ty` (for diagnostic purposes).
-    pub fn to_ty(&self) -> Option<P<Ty>> {
+    pub fn to_ty(&self) -> Option<Box<Ty>> {
         let kind = match &self.kind {
             // Trivial conversions.
             ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
@@ -1506,7 +1510,7 @@ impl Expr {
             _ => return None,
         };
 
-        Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
+        Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None }))
     }
 
     pub fn precedence(&self) -> ExprPrecedence {
@@ -1627,21 +1631,21 @@ impl Expr {
     }
 }
 
-impl From<P<Expr>> for Expr {
-    fn from(value: P<Expr>) -> Self {
+impl From<Box<Expr>> for Expr {
+    fn from(value: Box<Expr>) -> Self {
         *value
     }
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct Closure {
     pub binder: ClosureBinder,
     pub capture_clause: CaptureBy,
     pub constness: Const,
     pub coroutine_kind: Option<CoroutineKind>,
     pub movability: Movability,
-    pub fn_decl: P<FnDecl>,
-    pub body: P<Expr>,
+    pub fn_decl: Box<FnDecl>,
+    pub body: Box<Expr>,
     /// The span of the declaration block: 'move |...| -> ...'
     pub fn_decl_span: Span,
     /// The span of the argument block `|...|`
@@ -1649,7 +1653,7 @@ pub struct Closure {
 }
 
 /// Limit types of a range (inclusive or exclusive).
-#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
+#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, Walkable)]
 pub enum RangeLimits {
     /// Inclusive at the beginning, exclusive at the end.
     HalfOpen,
@@ -1672,27 +1676,27 @@ pub struct MethodCall {
     /// The method name and its generic arguments, e.g. `foo::<Bar, Baz>`.
     pub seg: PathSegment,
     /// The receiver, e.g. `x`.
-    pub receiver: P<Expr>,
+    pub receiver: Box<Expr>,
     /// The arguments, e.g. `a, b, c`.
-    pub args: ThinVec<P<Expr>>,
+    pub args: ThinVec<Box<Expr>>,
     /// The span of the function, without the dot and receiver e.g. `foo::<Bar,
     /// Baz>(a, b, c)`.
     pub span: Span,
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum StructRest {
     /// `..x`.
-    Base(P<Expr>),
+    Base(Box<Expr>),
     /// `..`.
     Rest(Span),
     /// No trailing `..` or expression.
     None,
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct StructExpr {
-    pub qself: Option<P<QSelf>>,
+    pub qself: Option<Box<QSelf>>,
     pub path: Path,
     pub fields: ThinVec<ExprField>,
     pub rest: StructRest,
@@ -1702,7 +1706,7 @@ pub struct StructExpr {
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub enum ExprKind {
     /// An array (e.g, `[a, b, c, d]`).
-    Array(ThinVec<P<Expr>>),
+    Array(ThinVec<Box<Expr>>),
     /// Allow anonymous constants from an inline `const` block.
     ConstBlock(AnonConst),
     /// A function call.
@@ -1711,90 +1715,90 @@ pub enum ExprKind {
     /// and the second field is the list of arguments.
     /// This also represents calling the constructor of
     /// tuple-like ADTs such as tuple structs and enum variants.
-    Call(P<Expr>, ThinVec<P<Expr>>),
+    Call(Box<Expr>, ThinVec<Box<Expr>>),
     /// A method call (e.g., `x.foo::<Bar, Baz>(a, b, c)`).
     MethodCall(Box<MethodCall>),
     /// A tuple (e.g., `(a, b, c, d)`).
-    Tup(ThinVec<P<Expr>>),
+    Tup(ThinVec<Box<Expr>>),
     /// A binary operation (e.g., `a + b`, `a * b`).
-    Binary(BinOp, P<Expr>, P<Expr>),
+    Binary(BinOp, Box<Expr>, Box<Expr>),
     /// A unary operation (e.g., `!x`, `*x`).
-    Unary(UnOp, P<Expr>),
+    Unary(UnOp, Box<Expr>),
     /// A literal (e.g., `1`, `"foo"`).
     Lit(token::Lit),
     /// A cast (e.g., `foo as f64`).
-    Cast(P<Expr>, P<Ty>),
+    Cast(Box<Expr>, Box<Ty>),
     /// A type ascription (e.g., `builtin # type_ascribe(42, usize)`).
     ///
     /// Usually not written directly in user code but
     /// indirectly via the macro `type_ascribe!(...)`.
-    Type(P<Expr>, P<Ty>),
+    Type(Box<Expr>, Box<Ty>),
     /// A `let pat = expr` expression that is only semantically allowed in the condition
     /// of `if` / `while` expressions. (e.g., `if let 0 = x { .. }`).
     ///
     /// `Span` represents the whole `let pat = expr` statement.
-    Let(P<Pat>, P<Expr>, Span, Recovered),
+    Let(Box<Pat>, Box<Expr>, Span, Recovered),
     /// An `if` block, with an optional `else` block.
     ///
     /// `if expr { block } else { expr }`
     ///
     /// If present, the "else" expr is always `ExprKind::Block` (for `else`) or
     /// `ExprKind::If` (for `else if`).
-    If(P<Expr>, P<Block>, Option<P<Expr>>),
+    If(Box<Expr>, Box<Block>, Option<Box<Expr>>),
     /// A while loop, with an optional label.
     ///
     /// `'label: while expr { block }`
-    While(P<Expr>, P<Block>, Option<Label>),
+    While(Box<Expr>, Box<Block>, Option<Label>),
     /// A `for` loop, with an optional label.
     ///
     /// `'label: for await? pat in iter { block }`
     ///
     /// This is desugared to a combination of `loop` and `match` expressions.
     ForLoop {
-        pat: P<Pat>,
-        iter: P<Expr>,
-        body: P<Block>,
+        pat: Box<Pat>,
+        iter: Box<Expr>,
+        body: Box<Block>,
         label: Option<Label>,
         kind: ForLoopKind,
     },
     /// Conditionless loop (can be exited with `break`, `continue`, or `return`).
     ///
     /// `'label: loop { block }`
-    Loop(P<Block>, Option<Label>, Span),
+    Loop(Box<Block>, Option<Label>, Span),
     /// A `match` block.
-    Match(P<Expr>, ThinVec<Arm>, MatchKind),
+    Match(Box<Expr>, ThinVec<Arm>, MatchKind),
     /// A closure (e.g., `move |a, b, c| a + b + c`).
     Closure(Box<Closure>),
     /// A block (`'label: { ... }`).
-    Block(P<Block>, Option<Label>),
+    Block(Box<Block>, Option<Label>),
     /// An `async` block (`async move { ... }`),
     /// or a `gen` block (`gen move { ... }`).
     ///
     /// The span is the "decl", which is the header before the body `{ }`
     /// including the `asyng`/`gen` keywords and possibly `move`.
-    Gen(CaptureBy, P<Block>, GenBlockKind, Span),
+    Gen(CaptureBy, Box<Block>, GenBlockKind, Span),
     /// An await expression (`my_future.await`). Span is of await keyword.
-    Await(P<Expr>, Span),
+    Await(Box<Expr>, Span),
     /// A use expression (`x.use`). Span is of use keyword.
-    Use(P<Expr>, Span),
+    Use(Box<Expr>, Span),
 
     /// A try block (`try { ... }`).
-    TryBlock(P<Block>),
+    TryBlock(Box<Block>),
 
     /// An assignment (`a = foo()`).
     /// The `Span` argument is the span of the `=` token.
-    Assign(P<Expr>, P<Expr>, Span),
+    Assign(Box<Expr>, Box<Expr>, Span),
     /// An assignment with an operator.
     ///
     /// E.g., `a += 1`.
-    AssignOp(AssignOp, P<Expr>, P<Expr>),
+    AssignOp(AssignOp, Box<Expr>, Box<Expr>),
     /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field.
-    Field(P<Expr>, Ident),
+    Field(Box<Expr>, Ident),
     /// An indexing operation (e.g., `foo[2]`).
     /// The span represents the span of the `[2]`, including brackets.
-    Index(P<Expr>, P<Expr>, Span),
+    Index(Box<Expr>, Box<Expr>, Span),
     /// A range (e.g., `1..2`, `1..`, `..2`, `1..=2`, `..=2`; and `..` in destructuring assignment).
-    Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
+    Range(Option<Box<Expr>>, Option<Box<Expr>>, RangeLimits),
     /// An underscore, used in destructuring assignment to ignore a value.
     Underscore,
 
@@ -1802,57 +1806,57 @@ pub enum ExprKind {
     /// parameters (e.g., `foo::bar::<baz>`).
     ///
     /// Optionally "qualified" (e.g., `<Vec<T> as SomeTrait>::SomeType`).
-    Path(Option<P<QSelf>>, Path),
+    Path(Option<Box<QSelf>>, Path),
 
     /// A referencing operation (`&a`, `&mut a`, `&raw const a` or `&raw mut a`).
-    AddrOf(BorrowKind, Mutability, P<Expr>),
+    AddrOf(BorrowKind, Mutability, Box<Expr>),
     /// A `break`, with an optional label to break, and an optional expression.
-    Break(Option<Label>, Option<P<Expr>>),
+    Break(Option<Label>, Option<Box<Expr>>),
     /// A `continue`, with an optional label.
     Continue(Option<Label>),
     /// A `return`, with an optional value to be returned.
-    Ret(Option<P<Expr>>),
+    Ret(Option<Box<Expr>>),
 
     /// Output of the `asm!()` macro.
-    InlineAsm(P<InlineAsm>),
+    InlineAsm(Box<InlineAsm>),
 
     /// An `offset_of` expression (e.g., `builtin # offset_of(Struct, field)`).
     ///
     /// Usually not written directly in user code but
     /// indirectly via the macro `core::mem::offset_of!(...)`.
-    OffsetOf(P<Ty>, Vec<Ident>),
+    OffsetOf(Box<Ty>, Vec<Ident>),
 
     /// A macro invocation; pre-expansion.
-    MacCall(P<MacCall>),
+    MacCall(Box<MacCall>),
 
     /// A struct literal expression.
     ///
     /// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. rest}`.
-    Struct(P<StructExpr>),
+    Struct(Box<StructExpr>),
 
     /// An array literal constructed from one repeated element.
     ///
     /// E.g., `[1; 5]`. The expression is the element to be
     /// repeated; the constant is the number of times to repeat it.
-    Repeat(P<Expr>, AnonConst),
+    Repeat(Box<Expr>, AnonConst),
 
     /// No-op: used solely so we can pretty-print faithfully.
-    Paren(P<Expr>),
+    Paren(Box<Expr>),
 
     /// A try expression (`expr?`).
-    Try(P<Expr>),
+    Try(Box<Expr>),
 
     /// A `yield`, with an optional value to be yielded.
     Yield(YieldKind),
 
     /// A `do yeet` (aka `throw`/`fail`/`bail`/`raise`/whatever),
     /// with an optional value to be returned.
-    Yeet(Option<P<Expr>>),
+    Yeet(Option<Box<Expr>>),
 
     /// A tail call return, with the value to be returned.
     ///
     /// While `.0` must be a function call, we check this later, after parsing.
-    Become(P<Expr>),
+    Become(Box<Expr>),
 
     /// Bytes included via `include_bytes!`
     ///
@@ -1868,9 +1872,9 @@ pub enum ExprKind {
     IncludedBytes(ByteSymbol),
 
     /// A `format_args!()` expression.
-    FormatArgs(P<FormatArgs>),
+    FormatArgs(Box<FormatArgs>),
 
-    UnsafeBinderCast(UnsafeBinderCastKind, P<Expr>, Option<P<Ty>>),
+    UnsafeBinderCast(UnsafeBinderCastKind, Box<Expr>, Option<Box<Ty>>),
 
     /// Placeholder for an expression that wasn't syntactically well formed in some way.
     Err(ErrorGuaranteed),
@@ -1880,14 +1884,14 @@ pub enum ExprKind {
 }
 
 /// Used to differentiate between `for` loops and `for await` loops.
-#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq)]
+#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
 pub enum ForLoopKind {
     For,
     ForAwait,
 }
 
 /// Used to differentiate between `async {}` blocks and `gen {}` blocks.
-#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
+#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
 pub enum GenBlockKind {
     Async,
     Gen,
@@ -1912,7 +1916,7 @@ impl GenBlockKind {
 
 /// Whether we're unwrapping or wrapping an unsafe binder
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-#[derive(Encodable, Decodable, HashStable_Generic)]
+#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
 pub enum UnsafeBinderCastKind {
     // e.g. `&i32` -> `unsafe<'a> &'a i32`
     Wrap,
@@ -1934,9 +1938,9 @@ pub enum UnsafeBinderCastKind {
 ///  ^~~~~    ^
 ///  ty       position = 0
 /// ```
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct QSelf {
-    pub ty: P<Ty>,
+    pub ty: Box<Ty>,
 
     /// The span of `a::b::Trait` in a path like `<Vec<T> as
     /// a::b::Trait>::AssociatedItem`; in the case where `position ==
@@ -1946,7 +1950,7 @@ pub struct QSelf {
 }
 
 /// A capture clause used in closures and `async` blocks.
-#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
+#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
 pub enum CaptureBy {
     /// `move |x| y + x`.
     Value {
@@ -1967,7 +1971,7 @@ pub enum CaptureBy {
 }
 
 /// Closure lifetime binder, `for<'a, 'b>` in `for<'a, 'b> |_: &'a (), _: &'b ()|`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum ClosureBinder {
     /// The binder is not present, all closure lifetimes are inferred.
     NotPresent,
@@ -1993,10 +1997,10 @@ pub enum ClosureBinder {
 
 /// Represents a macro invocation. The `path` indicates which macro
 /// is being invoked, and the `args` are arguments passed to it.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct MacCall {
     pub path: Path,
-    pub args: P<DelimArgs>,
+    pub args: Box<DelimArgs>,
 }
 
 impl MacCall {
@@ -2006,7 +2010,7 @@ impl MacCall {
 }
 
 /// Arguments passed to an attribute macro.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum AttrArgs {
     /// No arguments: `#[attr]`.
     Empty,
@@ -2016,7 +2020,7 @@ pub enum AttrArgs {
     Eq {
         /// Span of the `=` token.
         eq_span: Span,
-        expr: P<Expr>,
+        expr: Box<Expr>,
     },
 }
 
@@ -2041,7 +2045,7 @@ impl AttrArgs {
 }
 
 /// Delimited arguments, as used in `#[attr()/[]/{}]` or `mac!()/[]/{}`.
-#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
+#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
 pub struct DelimArgs {
     pub dspan: DelimSpan,
     pub delim: Delimiter, // Note: `Delimiter::Invisible` never occurs
@@ -2057,15 +2061,15 @@ impl DelimArgs {
 }
 
 /// Represents a macro definition.
-#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
+#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
 pub struct MacroDef {
-    pub body: P<DelimArgs>,
+    pub body: Box<DelimArgs>,
     /// `true` if macro was defined with `macro_rules`.
     pub macro_rules: bool,
 }
 
 #[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
-#[derive(HashStable_Generic)]
+#[derive(HashStable_Generic, Walkable)]
 pub enum StrStyle {
     /// A regular string, like `"foo"`.
     Cooked,
@@ -2076,7 +2080,7 @@ pub enum StrStyle {
 }
 
 /// The kind of match expression
-#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
+#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
 pub enum MatchKind {
     /// match expr { ... }
     Prefix,
@@ -2085,19 +2089,19 @@ pub enum MatchKind {
 }
 
 /// The kind of yield expression
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum YieldKind {
     /// yield expr { ... }
-    Prefix(Option<P<Expr>>),
+    Prefix(Option<Box<Expr>>),
     /// expr.yield { ... }
-    Postfix(P<Expr>),
+    Postfix(Box<Expr>),
 }
 
 impl YieldKind {
     /// Returns the expression inside the yield expression, if any.
     ///
     /// For postfix yields, this is guaranteed to be `Some`.
-    pub const fn expr(&self) -> Option<&P<Expr>> {
+    pub const fn expr(&self) -> Option<&Box<Expr>> {
         match self {
             YieldKind::Prefix(expr) => expr.as_ref(),
             YieldKind::Postfix(expr) => Some(expr),
@@ -2105,7 +2109,7 @@ impl YieldKind {
     }
 
     /// Returns a mutable reference to the expression being yielded, if any.
-    pub const fn expr_mut(&mut self) -> Option<&mut P<Expr>> {
+    pub const fn expr_mut(&mut self) -> Option<&mut Box<Expr>> {
         match self {
             YieldKind::Prefix(expr) => expr.as_mut(),
             YieldKind::Postfix(expr) => Some(expr),
@@ -2136,7 +2140,7 @@ pub struct MetaItemLit {
 }
 
 /// Similar to `MetaItemLit`, but restricted to string literals.
-#[derive(Clone, Copy, Encodable, Decodable, Debug)]
+#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
 pub struct StrLit {
     /// The original literal as written in source code.
     pub symbol: Symbol,
@@ -2265,9 +2269,9 @@ impl LitKind {
 
 // N.B., If you change this, you'll probably want to change the corresponding
 // type structure in `middle/ty.rs` as well.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct MutTy {
-    pub ty: P<Ty>,
+    pub ty: Box<Ty>,
     pub mutbl: Mutability,
 }
 
@@ -2276,106 +2280,55 @@ pub struct MutTy {
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct FnSig {
     pub header: FnHeader,
-    pub decl: P<FnDecl>,
+    pub decl: Box<FnDecl>,
     pub span: Span,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
-#[derive(Encodable, Decodable, HashStable_Generic)]
-pub enum FloatTy {
-    F16,
-    F32,
-    F64,
-    F128,
-}
-
-impl FloatTy {
-    pub fn name_str(self) -> &'static str {
-        match self {
-            FloatTy::F16 => "f16",
-            FloatTy::F32 => "f32",
-            FloatTy::F64 => "f64",
-            FloatTy::F128 => "f128",
-        }
-    }
-
-    pub fn name(self) -> Symbol {
-        match self {
-            FloatTy::F16 => sym::f16,
-            FloatTy::F32 => sym::f32,
-            FloatTy::F64 => sym::f64,
-            FloatTy::F128 => sym::f128,
+impl FnSig {
+    /// Return a span encompassing the header, or where to insert it if empty.
+    pub fn header_span(&self) -> Span {
+        match self.header.ext {
+            Extern::Implicit(span) | Extern::Explicit(_, span) => {
+                return self.span.with_hi(span.hi());
+            }
+            Extern::None => {}
         }
-    }
-}
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
-#[derive(Encodable, Decodable, HashStable_Generic)]
-pub enum IntTy {
-    Isize,
-    I8,
-    I16,
-    I32,
-    I64,
-    I128,
-}
+        match self.header.safety {
+            Safety::Unsafe(span) | Safety::Safe(span) => return self.span.with_hi(span.hi()),
+            Safety::Default => {}
+        };
 
-impl IntTy {
-    pub fn name_str(&self) -> &'static str {
-        match *self {
-            IntTy::Isize => "isize",
-            IntTy::I8 => "i8",
-            IntTy::I16 => "i16",
-            IntTy::I32 => "i32",
-            IntTy::I64 => "i64",
-            IntTy::I128 => "i128",
+        if let Some(coroutine_kind) = self.header.coroutine_kind {
+            return self.span.with_hi(coroutine_kind.span().hi());
         }
-    }
 
-    pub fn name(&self) -> Symbol {
-        match *self {
-            IntTy::Isize => sym::isize,
-            IntTy::I8 => sym::i8,
-            IntTy::I16 => sym::i16,
-            IntTy::I32 => sym::i32,
-            IntTy::I64 => sym::i64,
-            IntTy::I128 => sym::i128,
+        if let Const::Yes(span) = self.header.constness {
+            return self.span.with_hi(span.hi());
         }
+
+        self.span.shrink_to_lo()
     }
-}
 
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
-#[derive(Encodable, Decodable, HashStable_Generic)]
-pub enum UintTy {
-    Usize,
-    U8,
-    U16,
-    U32,
-    U64,
-    U128,
-}
+    /// The span of the header's safety, or where to insert it if empty.
+    pub fn safety_span(&self) -> Span {
+        match self.header.safety {
+            Safety::Unsafe(span) | Safety::Safe(span) => span,
+            Safety::Default => {
+                // Insert after the `coroutine_kind` if available.
+                if let Some(extern_span) = self.header.ext.span() {
+                    return extern_span.shrink_to_lo();
+                }
 
-impl UintTy {
-    pub fn name_str(&self) -> &'static str {
-        match *self {
-            UintTy::Usize => "usize",
-            UintTy::U8 => "u8",
-            UintTy::U16 => "u16",
-            UintTy::U32 => "u32",
-            UintTy::U64 => "u64",
-            UintTy::U128 => "u128",
+                // Insert right at the front of the signature.
+                self.header_span().shrink_to_hi()
+            }
         }
     }
 
-    pub fn name(&self) -> Symbol {
-        match *self {
-            UintTy::Usize => sym::usize,
-            UintTy::U8 => sym::u8,
-            UintTy::U16 => sym::u16,
-            UintTy::U32 => sym::u32,
-            UintTy::U64 => sym::u64,
-            UintTy::U128 => sym::u128,
-        }
+    /// The span of the header's extern, or where to insert it if empty.
+    pub fn extern_span(&self) -> Span {
+        self.header.ext.span().unwrap_or(self.safety_span().shrink_to_hi())
     }
 }
 
@@ -2389,7 +2342,7 @@ impl UintTy {
 /// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy`
 /// * the `C = { Ct }` in `Trait<C = { Ct }>` (feature `associated_const_equality`)
 /// * the `f(..): Bound` in `Trait<f(..): Bound>` (feature `return_type_notation`)
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct AssocItemConstraint {
     pub id: NodeId,
     pub ident: Ident,
@@ -2398,14 +2351,14 @@ pub struct AssocItemConstraint {
     pub span: Span,
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum Term {
-    Ty(P<Ty>),
+    Ty(Box<Ty>),
     Const(AnonConst),
 }
 
-impl From<P<Ty>> for Term {
-    fn from(v: P<Ty>) -> Self {
+impl From<Box<Ty>> for Term {
+    fn from(v: Box<Ty>) -> Self {
         Term::Ty(v)
     }
 }
@@ -2417,7 +2370,7 @@ impl From<AnonConst> for Term {
 }
 
 /// The kind of [associated item constraint][AssocItemConstraint].
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum AssocItemConstraintKind {
     /// An equality constraint for an associated item (e.g., `AssocTy = Ty` in `Trait<AssocTy = Ty>`).
     ///
@@ -2427,10 +2380,13 @@ pub enum AssocItemConstraintKind {
     /// bindings*. Similarly with associated const equality constraints and *associated const bindings*.
     Equality { term: Term },
     /// A bound on an associated type (e.g., `AssocTy: Bound` in `Trait<AssocTy: Bound>`).
-    Bound { bounds: GenericBounds },
+    Bound {
+        #[visitable(extra = BoundKind::Bound)]
+        bounds: GenericBounds,
+    },
 }
 
-#[derive(Encodable, Decodable, Debug)]
+#[derive(Encodable, Decodable, Debug, Walkable)]
 pub struct Ty {
     pub id: NodeId,
     pub kind: TyKind,
@@ -2449,8 +2405,8 @@ impl Clone for Ty {
     }
 }
 
-impl From<P<Ty>> for Ty {
-    fn from(value: P<Ty>) -> Self {
+impl From<Box<Ty>> for Ty {
+    fn from(value: Box<Ty>) -> Self {
         *value
     }
 }
@@ -2474,65 +2430,65 @@ impl Ty {
     }
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct FnPtrTy {
     pub safety: Safety,
     pub ext: Extern,
     pub generic_params: ThinVec<GenericParam>,
-    pub decl: P<FnDecl>,
+    pub decl: Box<FnDecl>,
     /// Span of the `[unsafe] [extern] fn(...) -> ...` part, i.e. everything
     /// after the generic params (if there are any, e.g. `for<'a>`).
     pub decl_span: Span,
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct UnsafeBinderTy {
     pub generic_params: ThinVec<GenericParam>,
-    pub inner_ty: P<Ty>,
+    pub inner_ty: Box<Ty>,
 }
 
 /// The various kinds of type recognized by the compiler.
 //
 // Adding a new variant? Please update `test_ty` in `tests/ui/macros/stringify.rs`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum TyKind {
     /// A variable-length slice (`[T]`).
-    Slice(P<Ty>),
+    Slice(Box<Ty>),
     /// A fixed length array (`[T; n]`).
-    Array(P<Ty>, AnonConst),
+    Array(Box<Ty>, AnonConst),
     /// A raw pointer (`*const T` or `*mut T`).
     Ptr(MutTy),
     /// A reference (`&'a T` or `&'a mut T`).
-    Ref(Option<Lifetime>, MutTy),
+    Ref(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
     /// A pinned reference (`&'a pin const T` or `&'a pin mut T`).
     ///
     /// Desugars into `Pin<&'a T>` or `Pin<&'a mut T>`.
-    PinnedRef(Option<Lifetime>, MutTy),
+    PinnedRef(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
     /// A function pointer type (e.g., `fn(usize) -> bool`).
-    FnPtr(P<FnPtrTy>),
+    FnPtr(Box<FnPtrTy>),
     /// An unsafe existential lifetime binder (e.g., `unsafe<'a> &'a ()`).
-    UnsafeBinder(P<UnsafeBinderTy>),
+    UnsafeBinder(Box<UnsafeBinderTy>),
     /// The never type (`!`).
     Never,
     /// A tuple (`(A, B, C, D,...)`).
-    Tup(ThinVec<P<Ty>>),
+    Tup(ThinVec<Box<Ty>>),
     /// A path (`module::module::...::Type`), optionally
     /// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
     ///
     /// Type parameters are stored in the `Path` itself.
-    Path(Option<P<QSelf>>, Path),
+    Path(Option<Box<QSelf>>, Path),
     /// A trait object type `Bound1 + Bound2 + Bound3`
     /// where `Bound` is a trait or a lifetime.
-    TraitObject(GenericBounds, TraitObjectSyntax),
+    TraitObject(#[visitable(extra = BoundKind::TraitObject)] GenericBounds, TraitObjectSyntax),
     /// An `impl Bound1 + Bound2 + Bound3` type
     /// where `Bound` is a trait or a lifetime.
     ///
     /// The `NodeId` exists to prevent lowering from having to
     /// generate `NodeId`s on the fly, which would complicate
     /// the generation of opaque `type Foo = impl Trait` items significantly.
-    ImplTrait(NodeId, GenericBounds),
+    ImplTrait(NodeId, #[visitable(extra = BoundKind::Impl)] GenericBounds),
     /// No-op; kept solely so that we can pretty-print faithfully.
-    Paren(P<Ty>),
+    Paren(Box<Ty>),
     /// Unused for now.
     Typeof(AnonConst),
     /// This means the type should be inferred instead of it having been
@@ -2541,12 +2497,12 @@ pub enum TyKind {
     /// Inferred type of a `self` or `&self` argument in a method.
     ImplicitSelf,
     /// A macro in the type position.
-    MacCall(P<MacCall>),
+    MacCall(Box<MacCall>),
     /// Placeholder for a `va_list`.
     CVarArgs,
     /// Pattern types like `pattern_type!(u32 is 1..=)`, which is the same as `NonZero<u32>`,
     /// just as part of the type system.
-    Pat(P<Ty>, P<TyPat>),
+    Pat(Box<Ty>, Box<TyPat>),
     /// Sometimes we need a dummy value when no error has occurred.
     Dummy,
     /// Placeholder for a kind that has failed to be defined.
@@ -2608,7 +2564,7 @@ impl TyKind {
 }
 
 /// A pattern type pattern.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct TyPat {
     pub id: NodeId,
     pub kind: TyPatKind,
@@ -2619,19 +2575,19 @@ pub struct TyPat {
 /// All the different flavors of pattern that Rust recognizes.
 //
 // Adding a new variant? Please update `test_pat` in `tests/ui/macros/stringify.rs`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum TyPatKind {
     /// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
-    Range(Option<P<AnonConst>>, Option<P<AnonConst>>, Spanned<RangeEnd>),
+    Range(Option<Box<AnonConst>>, Option<Box<AnonConst>>, Spanned<RangeEnd>),
 
-    Or(ThinVec<P<TyPat>>),
+    Or(ThinVec<Box<TyPat>>),
 
     /// Placeholder for a pattern that wasn't syntactically well formed in some way.
     Err(ErrorGuaranteed),
 }
 
 /// Syntax used to declare a trait object.
-#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
+#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
 #[repr(u8)]
 pub enum TraitObjectSyntax {
     // SAFETY: When adding new variants make sure to update the `Tag` impl.
@@ -2658,10 +2614,10 @@ unsafe impl Tag for TraitObjectSyntax {
     }
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum PreciseCapturingArg {
     /// Lifetime parameter.
-    Lifetime(Lifetime),
+    Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
     /// Type or const parameter.
     Arg(Path, NodeId),
 }
@@ -2669,7 +2625,7 @@ pub enum PreciseCapturingArg {
 /// Inline assembly operand explicit register or register class.
 ///
 /// E.g., `"eax"` as in `asm!("mov eax, 2", out("eax") result)`.
-#[derive(Clone, Copy, Encodable, Decodable, Debug)]
+#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
 pub enum InlineAsmRegOrRegClass {
     Reg(Symbol),
     RegClass(Symbol),
@@ -2738,7 +2694,7 @@ impl std::fmt::Debug for InlineAsmOptions {
     }
 }
 
-#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
+#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic, Walkable)]
 pub enum InlineAsmTemplatePiece {
     String(Cow<'static, str>),
     Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
@@ -2786,37 +2742,37 @@ impl InlineAsmTemplatePiece {
 /// `DefCollector`. Instead this is deferred until AST lowering where we
 /// lower it to an `AnonConst` (for functions) or a `Path` (for statics)
 /// depending on what the path resolves to.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct InlineAsmSym {
     pub id: NodeId,
-    pub qself: Option<P<QSelf>>,
+    pub qself: Option<Box<QSelf>>,
     pub path: Path,
 }
 
 /// Inline assembly operand.
 ///
 /// E.g., `out("eax") result` as in `asm!("mov eax, 2", out("eax") result)`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum InlineAsmOperand {
     In {
         reg: InlineAsmRegOrRegClass,
-        expr: P<Expr>,
+        expr: Box<Expr>,
     },
     Out {
         reg: InlineAsmRegOrRegClass,
         late: bool,
-        expr: Option<P<Expr>>,
+        expr: Option<Box<Expr>>,
     },
     InOut {
         reg: InlineAsmRegOrRegClass,
         late: bool,
-        expr: P<Expr>,
+        expr: Box<Expr>,
     },
     SplitInOut {
         reg: InlineAsmRegOrRegClass,
         late: bool,
-        in_expr: P<Expr>,
-        out_expr: Option<P<Expr>>,
+        in_expr: Box<Expr>,
+        out_expr: Option<Box<Expr>>,
     },
     Const {
         anon_const: AnonConst,
@@ -2825,7 +2781,7 @@ pub enum InlineAsmOperand {
         sym: InlineAsmSym,
     },
     Label {
-        block: P<Block>,
+        block: Box<Block>,
     },
 }
 
@@ -2841,7 +2797,7 @@ impl InlineAsmOperand {
     }
 }
 
-#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
+#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, Walkable, PartialEq, Eq)]
 pub enum AsmMacro {
     /// The `asm!` macro
     Asm,
@@ -2880,13 +2836,14 @@ impl AsmMacro {
 /// Inline assembly.
 ///
 /// E.g., `asm!("NOP");`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct InlineAsm {
     pub asm_macro: AsmMacro,
     pub template: Vec<InlineAsmTemplatePiece>,
     pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
     pub operands: Vec<(InlineAsmOperand, Span)>,
     pub clobber_abis: Vec<(Symbol, Span)>,
+    #[visitable(ignore)]
     pub options: InlineAsmOptions,
     pub line_spans: Vec<Span>,
 }
@@ -2894,11 +2851,11 @@ pub struct InlineAsm {
 /// A parameter in a function header.
 ///
 /// E.g., `bar: usize` as in `fn foo(bar: usize)`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct Param {
     pub attrs: AttrVec,
-    pub ty: P<Ty>,
-    pub pat: P<Pat>,
+    pub ty: Box<Ty>,
+    pub pat: Box<Pat>,
     pub id: NodeId,
     pub span: Span,
     pub is_placeholder: bool,
@@ -2916,7 +2873,7 @@ pub enum SelfKind {
     /// `&'lt pin const self`, `&'lt pin mut self`
     Pinned(Option<Lifetime>, Mutability),
     /// `self: TYPE`, `mut self: TYPE`
-    Explicit(P<Ty>, Mutability),
+    Explicit(Box<Ty>, Mutability),
 }
 
 impl SelfKind {
@@ -2972,7 +2929,7 @@ impl Param {
     /// Builds a `Param` object from `ExplicitSelf`.
     pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
         let span = eself.span.to(eself_ident.span);
-        let infer_ty = P(Ty {
+        let infer_ty = Box::new(Ty {
             id: DUMMY_NODE_ID,
             kind: TyKind::ImplicitSelf,
             span: eself_ident.span,
@@ -2983,7 +2940,7 @@ impl Param {
             SelfKind::Value(mutbl) => (mutbl, infer_ty),
             SelfKind::Region(lt, mutbl) => (
                 Mutability::Not,
-                P(Ty {
+                Box::new(Ty {
                     id: DUMMY_NODE_ID,
                     kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
                     span,
@@ -2992,7 +2949,7 @@ impl Param {
             ),
             SelfKind::Pinned(lt, mutbl) => (
                 mutbl,
-                P(Ty {
+                Box::new(Ty {
                     id: DUMMY_NODE_ID,
                     kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
                     span,
@@ -3002,7 +2959,7 @@ impl Param {
         };
         Param {
             attrs,
-            pat: P(Pat {
+            pat: Box::new(Pat {
                 id: DUMMY_NODE_ID,
                 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
                 span,
@@ -3022,7 +2979,7 @@ impl Param {
 ///
 /// Please note that it's different from `FnHeader` structure
 /// which contains metadata about function safety, asyncness, constness and ABI.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct FnDecl {
     pub inputs: ThinVec<Param>,
     pub output: FnRetTy,
@@ -3038,7 +2995,7 @@ impl FnDecl {
 }
 
 /// Is the trait definition an auto trait?
-#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
 pub enum IsAuto {
     Yes,
     No,
@@ -3046,7 +3003,7 @@ pub enum IsAuto {
 
 /// Safety of items.
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
-#[derive(HashStable_Generic)]
+#[derive(HashStable_Generic, Walkable)]
 pub enum Safety {
     /// `unsafe` an item is explicitly marked as `unsafe`.
     Unsafe(Span),
@@ -3062,7 +3019,7 @@ pub enum Safety {
 /// Coroutine markers are things that cause the function to generate a coroutine, such as `async`,
 /// which makes the function return `impl Future`, or `gen`, which makes the function return `impl
 /// Iterator`.
-#[derive(Copy, Clone, Encodable, Decodable, Debug)]
+#[derive(Copy, Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum CoroutineKind {
     /// `async`, which returns an `impl Future`.
     Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
@@ -3111,7 +3068,7 @@ impl CoroutineKind {
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
-#[derive(HashStable_Generic)]
+#[derive(HashStable_Generic, Walkable)]
 pub enum Const {
     Yes(Span),
     No,
@@ -3119,13 +3076,13 @@ pub enum Const {
 
 /// Item defaultness.
 /// For details see the [RFC #2532](https://github.com/rust-lang/rfcs/pull/2532).
-#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
 pub enum Defaultness {
     Default(Span),
     Final,
 }
 
-#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
 pub enum ImplPolarity {
     /// `impl Trait for Type`
     Positive,
@@ -3144,7 +3101,7 @@ impl fmt::Debug for ImplPolarity {
 
 /// The polarity of a trait bound.
 #[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
-#[derive(HashStable_Generic)]
+#[derive(HashStable_Generic, Walkable)]
 pub enum BoundPolarity {
     /// `Type: Trait`
     Positive,
@@ -3166,7 +3123,7 @@ impl BoundPolarity {
 
 /// The constness of a trait bound.
 #[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
-#[derive(HashStable_Generic)]
+#[derive(HashStable_Generic, Walkable)]
 pub enum BoundConstness {
     /// `Type: Trait`
     Never,
@@ -3188,7 +3145,7 @@ impl BoundConstness {
 
 /// The asyncness of a trait bound.
 #[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
-#[derive(HashStable_Generic)]
+#[derive(HashStable_Generic, Walkable)]
 pub enum BoundAsyncness {
     /// `Type: Trait`
     Normal,
@@ -3205,7 +3162,7 @@ impl BoundAsyncness {
     }
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum FnRetTy {
     /// Returns type is not specified.
     ///
@@ -3213,7 +3170,7 @@ pub enum FnRetTy {
     /// Span points to where return type would be inserted.
     Default(Span),
     /// Everything else.
-    Ty(P<Ty>),
+    Ty(Box<Ty>),
 }
 
 impl FnRetTy {
@@ -3225,25 +3182,25 @@ impl FnRetTy {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
+#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
 pub enum Inline {
     Yes,
-    No,
+    No { had_parse_error: Result<(), ErrorGuaranteed> },
 }
 
 /// Module item kind.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum ModKind {
     /// Module with inlined definition `mod foo { ... }`,
     /// or with definition outlined to a separate file `mod foo;` and already loaded from it.
     /// The inner span is from the first token past `{` to the last token until `}`,
     /// or from the first to the last token in the loaded file.
-    Loaded(ThinVec<P<Item>>, Inline, ModSpans, Result<(), ErrorGuaranteed>),
+    Loaded(ThinVec<Box<Item>>, Inline, ModSpans),
     /// Module with definition outlined to a separate file `mod foo;` but not yet loaded from it.
     Unloaded,
 }
 
-#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
+#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
 pub struct ModSpans {
     /// `inner_span` covers the body of the module; for a file module, its the whole file.
     /// For an inline module, its the span inside the `{ ... }`, not including the curly braces.
@@ -3254,7 +3211,7 @@ pub struct ModSpans {
 /// Foreign module declaration.
 ///
 /// E.g., `extern { .. }` or `extern "C" { .. }`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct ForeignMod {
     /// Span of the `extern` keyword.
     pub extern_span: Span,
@@ -3262,15 +3219,16 @@ pub struct ForeignMod {
     /// semantically by Rust.
     pub safety: Safety,
     pub abi: Option<StrLit>,
-    pub items: ThinVec<P<ForeignItem>>,
+    pub items: ThinVec<Box<ForeignItem>>,
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct EnumDef {
     pub variants: ThinVec<Variant>,
 }
+
 /// Enum variant.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct Variant {
     /// Attributes of the variant.
     pub attrs: AttrVec,
@@ -3292,7 +3250,7 @@ pub struct Variant {
 }
 
 /// Part of `use` item to the right of its prefix.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum UseTreeKind {
     /// `use prefix` or `use prefix as rename`
     Simple(Option<Ident>),
@@ -3311,7 +3269,7 @@ pub enum UseTreeKind {
 
 /// A tree of paths sharing common prefixes.
 /// Used in `use` items both at top-level and inside of braces in import groups.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct UseTree {
     pub prefix: Path,
     pub kind: UseTreeKind,
@@ -3333,7 +3291,7 @@ impl UseTree {
 /// Distinguishes between `Attribute`s that decorate items and Attributes that
 /// are contained as statements within items. These two cases need to be
 /// distinguished for pretty-printing.
-#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
+#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic, Walkable)]
 pub enum AttrStyle {
     Outer,
     Inner,
@@ -3343,7 +3301,7 @@ pub enum AttrStyle {
 pub type AttrVec = ThinVec<Attribute>;
 
 /// A syntax-level representation of an attribute.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct Attribute {
     pub kind: AttrKind,
     pub id: AttrId,
@@ -3353,10 +3311,10 @@ pub struct Attribute {
     pub span: Span,
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum AttrKind {
     /// A normal attribute.
-    Normal(P<NormalAttr>),
+    Normal(Box<NormalAttr>),
 
     /// A doc comment (e.g. `/// ...`, `//! ...`, `/** ... */`, `/*! ... */`).
     /// Doc attributes (e.g. `#[doc="..."]`) are represented with the `Normal`
@@ -3364,7 +3322,7 @@ pub enum AttrKind {
     DocComment(CommentKind, Symbol),
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct NormalAttr {
     pub item: AttrItem,
     // Tokens for the full attribute, e.g. `#[foo]`, `#![bar]`.
@@ -3385,7 +3343,7 @@ impl NormalAttr {
     }
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct AttrItem {
     pub unsafety: Safety,
     pub path: Path,
@@ -3411,20 +3369,20 @@ impl AttrItem {
 /// that the `ref_id` is for. The `impl_id` maps to the "self type" of this impl.
 /// If this impl is an `ItemKind::Impl`, the `impl_id` is redundant (it could be the
 /// same as the impl's `NodeId`).
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct TraitRef {
     pub path: Path,
     pub ref_id: NodeId,
 }
 
 /// Whether enclosing parentheses are present or not.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum Parens {
     Yes,
     No,
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct PolyTraitRef {
     /// The `'a` in `for<'a> Foo<&'a T>`.
     pub bound_generic_params: ThinVec<GenericParam>,
@@ -3460,17 +3418,17 @@ impl PolyTraitRef {
     }
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct Visibility {
     pub kind: VisibilityKind,
     pub span: Span,
     pub tokens: Option<LazyAttrTokenStream>,
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum VisibilityKind {
     Public,
-    Restricted { path: P<Path>, id: NodeId, shorthand: bool },
+    Restricted { path: Box<Path>, id: NodeId, shorthand: bool },
     Inherited,
 }
 
@@ -3483,7 +3441,7 @@ impl VisibilityKind {
 /// Field definition in a struct, variant or union.
 ///
 /// E.g., `bar: usize` as in `struct Foo { bar: usize }`.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct FieldDef {
     pub attrs: AttrVec,
     pub id: NodeId,
@@ -3492,20 +3450,20 @@ pub struct FieldDef {
     pub safety: Safety,
     pub ident: Option<Ident>,
 
-    pub ty: P<Ty>,
+    pub ty: Box<Ty>,
     pub default: Option<AnonConst>,
     pub is_placeholder: bool,
 }
 
 /// Was parsing recovery performed?
-#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
+#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic, Walkable)]
 pub enum Recovered {
     No,
     Yes(ErrorGuaranteed),
 }
 
 /// Fields and constructor ids of enum variants and structs.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum VariantData {
     /// Struct variant.
     ///
@@ -3591,7 +3549,7 @@ impl Item {
 }
 
 /// `extern` qualifier on a function item or function type.
-#[derive(Clone, Copy, Encodable, Decodable, Debug)]
+#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
 pub enum Extern {
     /// No explicit extern keyword was used.
     ///
@@ -3616,20 +3574,27 @@ impl Extern {
             None => Extern::Implicit(span),
         }
     }
+
+    pub fn span(self) -> Option<Span> {
+        match self {
+            Extern::None => None,
+            Extern::Implicit(span) | Extern::Explicit(_, span) => Some(span),
+        }
+    }
 }
 
 /// A function header.
 ///
 /// All the information between the visibility and the name of the function is
 /// included in this struct (e.g., `async unsafe fn` or `const extern "C" fn`).
-#[derive(Clone, Copy, Encodable, Decodable, Debug)]
+#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
 pub struct FnHeader {
-    /// Whether this is `unsafe`, or has a default safety.
-    pub safety: Safety,
-    /// Whether this is `async`, `gen`, or nothing.
-    pub coroutine_kind: Option<CoroutineKind>,
     /// The `const` keyword, if any
     pub constness: Const,
+    /// Whether this is `async`, `gen`, or nothing.
+    pub coroutine_kind: Option<CoroutineKind>,
+    /// Whether this is `unsafe`, or has a default safety.
+    pub safety: Safety,
     /// The `extern` keyword and corresponding ABI string, if any.
     pub ext: Extern,
 }
@@ -3643,38 +3608,6 @@ impl FnHeader {
             || matches!(constness, Const::Yes(_))
             || !matches!(ext, Extern::None)
     }
-
-    /// Return a span encompassing the header, or none if all options are default.
-    pub fn span(&self) -> Option<Span> {
-        fn append(a: &mut Option<Span>, b: Span) {
-            *a = match a {
-                None => Some(b),
-                Some(x) => Some(x.to(b)),
-            }
-        }
-
-        let mut full_span = None;
-
-        match self.safety {
-            Safety::Unsafe(span) | Safety::Safe(span) => append(&mut full_span, span),
-            Safety::Default => {}
-        };
-
-        if let Some(coroutine_kind) = self.coroutine_kind {
-            append(&mut full_span, coroutine_kind.span());
-        }
-
-        if let Const::Yes(span) = self.constness {
-            append(&mut full_span, span);
-        }
-
-        match self.ext {
-            Extern::Implicit(span) | Extern::Explicit(_, span) => append(&mut full_span, span),
-            Extern::None => {}
-        }
-
-        full_span
-    }
 }
 
 impl Default for FnHeader {
@@ -3688,15 +3621,17 @@ impl Default for FnHeader {
     }
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct Trait {
     pub constness: Const,
     pub safety: Safety,
     pub is_auto: IsAuto,
     pub ident: Ident,
     pub generics: Generics,
+    #[visitable(extra = BoundKind::SuperTraits)]
     pub bounds: GenericBounds,
-    pub items: ThinVec<P<AssocItem>>,
+    #[visitable(extra = AssocCtxt::Trait)]
+    pub items: ThinVec<Box<AssocItem>>,
 }
 
 /// The location of a where clause on a `TyAlias` (`Span`) and whether there was
@@ -3717,14 +3652,14 @@ pub struct Trait {
 /// ```
 ///
 /// If there is no where clause, then this is `false` with `DUMMY_SP`.
-#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
+#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
 pub struct TyAliasWhereClause {
     pub has_where_token: bool,
     pub span: Span,
 }
 
 /// The span information for the two where clauses on a `TyAlias`.
-#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
+#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
 pub struct TyAliasWhereClauses {
     /// Before the equals sign.
     pub before: TyAliasWhereClause,
@@ -3736,33 +3671,38 @@ pub struct TyAliasWhereClauses {
     pub split: usize,
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct TyAlias {
     pub defaultness: Defaultness,
     pub ident: Ident,
     pub generics: Generics,
     pub where_clauses: TyAliasWhereClauses,
+    #[visitable(extra = BoundKind::Bound)]
     pub bounds: GenericBounds,
-    pub ty: Option<P<Ty>>,
+    pub ty: Option<Box<Ty>>,
 }
 
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Impl {
+    pub generics: Generics,
+    pub of_trait: Option<Box<TraitImplHeader>>,
+    pub self_ty: Box<Ty>,
+    pub items: ThinVec<Box<AssocItem>>,
+}
+
+#[derive(Clone, Encodable, Decodable, Debug)]
+pub struct TraitImplHeader {
     pub defaultness: Defaultness,
     pub safety: Safety,
-    pub generics: Generics,
     pub constness: Const,
     pub polarity: ImplPolarity,
-    /// The trait being implemented, if any.
-    pub of_trait: Option<TraitRef>,
-    pub self_ty: P<Ty>,
-    pub items: ThinVec<P<AssocItem>>,
+    pub trait_ref: TraitRef,
 }
 
-#[derive(Clone, Encodable, Decodable, Debug, Default)]
+#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
 pub struct FnContract {
-    pub requires: Option<P<Expr>>,
-    pub ensures: Option<P<Expr>>,
+    pub requires: Option<Box<Expr>>,
+    pub ensures: Option<Box<Expr>>,
 }
 
 #[derive(Clone, Encodable, Decodable, Debug)]
@@ -3771,50 +3711,50 @@ pub struct Fn {
     pub ident: Ident,
     pub generics: Generics,
     pub sig: FnSig,
-    pub contract: Option<P<FnContract>>,
+    pub contract: Option<Box<FnContract>>,
     pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
-    pub body: Option<P<Block>>,
+    pub body: Option<Box<Block>>,
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct Delegation {
     /// Path resolution id.
     pub id: NodeId,
-    pub qself: Option<P<QSelf>>,
+    pub qself: Option<Box<QSelf>>,
     pub path: Path,
     pub ident: Ident,
     pub rename: Option<Ident>,
-    pub body: Option<P<Block>>,
+    pub body: Option<Box<Block>>,
     /// The item was expanded from a glob delegation item.
     pub from_glob: bool,
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct DelegationMac {
-    pub qself: Option<P<QSelf>>,
+    pub qself: Option<Box<QSelf>>,
     pub prefix: Path,
     // Some for list delegation, and None for glob delegation.
     pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
-    pub body: Option<P<Block>>,
+    pub body: Option<Box<Block>>,
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct StaticItem {
     pub ident: Ident,
-    pub ty: P<Ty>,
+    pub ty: Box<Ty>,
     pub safety: Safety,
     pub mutability: Mutability,
-    pub expr: Option<P<Expr>>,
+    pub expr: Option<Box<Expr>>,
     pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
 }
 
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct ConstItem {
     pub defaultness: Defaultness,
     pub ident: Ident,
     pub generics: Generics,
-    pub ty: P<Ty>,
-    pub expr: Option<P<Expr>>,
+    pub ty: Box<Ty>,
+    pub expr: Option<Box<Expr>>,
     pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
 }
 
@@ -3880,11 +3820,11 @@ pub enum ItemKind {
     /// An implementation.
     ///
     /// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
-    Impl(Box<Impl>),
+    Impl(Impl),
     /// A macro invocation.
     ///
     /// E.g., `foo!(..)`.
-    MacCall(P<MacCall>),
+    MacCall(Box<MacCall>),
     /// A macro definition.
     MacroDef(Ident, MacroDef),
     /// A single delegation item (`reuse`).
@@ -3967,7 +3907,7 @@ impl ItemKind {
             | Self::Union(_, generics, _)
             | Self::Trait(box Trait { generics, .. })
             | Self::TraitAlias(_, generics, _)
-            | Self::Impl(box Impl { generics, .. }) => Some(generics),
+            | Self::Impl(Impl { generics, .. }) => Some(generics),
             _ => None,
         }
     }
@@ -3994,7 +3934,7 @@ pub enum AssocItemKind {
     /// An associated type.
     Type(Box<TyAlias>),
     /// A macro expanding to associated items.
-    MacCall(P<MacCall>),
+    MacCall(Box<MacCall>),
     /// An associated delegation item.
     Delegation(Box<Delegation>),
     /// An associated list or glob delegation item.
@@ -4064,7 +4004,7 @@ pub enum ForeignItemKind {
     /// A foreign type.
     TyAlias(Box<TyAlias>),
     /// A macro expanding to foreign items.
-    MacCall(P<MacCall>),
+    MacCall(Box<MacCall>),
 }
 
 impl ForeignItemKind {
@@ -4127,19 +4067,20 @@ mod size_asserts {
     static_assert_size!(GenericArg, 24);
     static_assert_size!(GenericBound, 88);
     static_assert_size!(Generics, 40);
-    static_assert_size!(Impl, 136);
+    static_assert_size!(Impl, 64);
     static_assert_size!(Item, 144);
     static_assert_size!(ItemKind, 80);
     static_assert_size!(LitKind, 24);
     static_assert_size!(Local, 96);
     static_assert_size!(MetaItemLit, 40);
     static_assert_size!(Param, 40);
-    static_assert_size!(Pat, 72);
-    static_assert_size!(PatKind, 48);
+    static_assert_size!(Pat, 80);
+    static_assert_size!(PatKind, 56);
     static_assert_size!(Path, 24);
     static_assert_size!(PathSegment, 24);
     static_assert_size!(Stmt, 32);
     static_assert_size!(StmtKind, 16);
+    static_assert_size!(TraitImplHeader, 80);
     static_assert_size!(Ty, 64);
     static_assert_size!(TyKind, 40);
     // tidy-alphabetical-end