remove `P`
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index fdff18f..8160ed3 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -35,7 +35,6 @@
 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};
@@ -225,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.
@@ -286,7 +285,7 @@ pub enum GenericArg {
     /// `'a` in `Foo<'a>`.
     Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
     /// `Bar` in `Foo<Bar>`.
-    Type(P<Ty>),
+    Type(Box<Ty>),
     /// `1` in `Foo<1>`.
     Const(AnonConst),
 }
@@ -328,15 +327,15 @@ pub fn span(&self) -> Span {
     }
 }
 
-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))
     }
 }
 
@@ -350,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
@@ -435,10 +434,10 @@ 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.
@@ -526,7 +525,7 @@ 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,
@@ -548,8 +547,8 @@ pub struct WhereRegionPredicate {
 /// E.g., `T = int`.
 #[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, Walkable)]
@@ -558,7 +557,7 @@ pub struct Crate {
     /// expansion placeholders or an unassigned value (`DUMMY_NODE_ID`) before that.
     pub id: NodeId,
     pub attrs: AttrVec,
-    pub items: ThinVec<P<Item>>,
+    pub items: ThinVec<Box<Item>>,
     pub spans: ModSpans,
     pub is_placeholder: bool,
 }
@@ -638,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.
@@ -671,7 +670,7 @@ pub fn to_ty(&self) -> Option<P<Ty>> {
             _ => 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
@@ -764,8 +763,8 @@ pub fn descr(&self) -> Option<String> {
     }
 }
 
-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
     }
 }
@@ -780,7 +779,7 @@ 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,
@@ -865,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 `..`.
     ///
@@ -922,13 +921,13 @@ 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),
@@ -1223,22 +1222,22 @@ pub fn is_expr(&self) -> bool {
 #[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, Walkable)]
 pub struct MacCallStmt {
-    pub mac: P<MacCall>,
+    pub mac: Box<MacCall>,
     pub style: MacStmtStyle,
     pub attrs: AttrVec,
     pub tokens: Option<LazyAttrTokenStream>,
@@ -1262,8 +1261,8 @@ pub enum MacStmtStyle {
 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>,
@@ -1278,10 +1277,10 @@ pub enum LocalKind {
     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 {
@@ -1315,11 +1314,11 @@ pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
 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,
@@ -1332,7 +1331,7 @@ pub struct ExprField {
     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,
 }
@@ -1357,7 +1356,7 @@ pub enum UnsafeSource {
 #[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct AnonConst {
     pub id: NodeId,
-    pub value: P<Expr>,
+    pub value: Box<Expr>,
 }
 
 /// An expression.
@@ -1469,7 +1468,7 @@ pub fn peel_parens_and_refs(&self) -> &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()),
@@ -1511,7 +1510,7 @@ pub fn to_ty(&self) -> Option<P<Ty>> {
             _ => 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 {
@@ -1632,8 +1631,8 @@ pub fn dummy() -> 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
     }
 }
@@ -1645,8 +1644,8 @@ pub struct Closure {
     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 `|...|`
@@ -1677,9 +1676,9 @@ 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,
@@ -1688,7 +1687,7 @@ pub struct MethodCall {
 #[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub enum StructRest {
     /// `..x`.
-    Base(P<Expr>),
+    Base(Box<Expr>),
     /// `..`.
     Rest(Span),
     /// No trailing `..` or expression.
@@ -1697,7 +1696,7 @@ pub enum StructRest {
 
 #[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,
@@ -1707,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.
@@ -1716,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,
 
@@ -1807,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!`
     ///
@@ -1873,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),
@@ -1941,7 +1940,7 @@ pub enum UnsafeBinderCastKind {
 /// ```
 #[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 ==
@@ -2001,7 +2000,7 @@ pub enum ClosureBinder {
 #[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct MacCall {
     pub path: Path,
-    pub args: P<DelimArgs>,
+    pub args: Box<DelimArgs>,
 }
 
 impl MacCall {
@@ -2021,7 +2020,7 @@ pub enum AttrArgs {
     Eq {
         /// Span of the `=` token.
         eq_span: Span,
-        expr: P<Expr>,
+        expr: Box<Expr>,
     },
 }
 
@@ -2064,7 +2063,7 @@ pub fn need_semicolon(&self) -> bool {
 /// Represents a macro definition.
 #[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,
 }
@@ -2093,16 +2092,16 @@ pub enum MatchKind {
 #[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),
@@ -2110,7 +2109,7 @@ pub const fn expr(&self) -> Option<&P<Expr>> {
     }
 
     /// 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),
@@ -2272,7 +2271,7 @@ pub fn is_suffixed(&self) -> bool {
 // type structure in `middle/ty.rs` as well.
 #[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct MutTy {
-    pub ty: P<Ty>,
+    pub ty: Box<Ty>,
     pub mutbl: Mutability,
 }
 
@@ -2281,7 +2280,7 @@ 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,
 }
 
@@ -2306,12 +2305,12 @@ pub struct AssocItemConstraint {
 
 #[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)
     }
 }
@@ -2358,8 +2357,8 @@ fn clone(&self) -> Self {
     }
 }
 
-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
     }
 }
@@ -2388,7 +2387,7 @@ 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,
@@ -2397,7 +2396,7 @@ pub struct FnPtrTy {
 #[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.
@@ -2406,9 +2405,9 @@ pub struct UnsafeBinderTy {
 #[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`).
@@ -2418,18 +2417,18 @@ pub enum TyKind {
     /// Desugars into `Pin<&'a T>` or `Pin<&'a mut T>`.
     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(#[visitable(extra = BoundKind::TraitObject)] GenericBounds, TraitObjectSyntax),
@@ -2441,7 +2440,7 @@ pub enum TyKind {
     /// the generation of opaque `type Foo = impl Trait` items significantly.
     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
@@ -2450,12 +2449,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.
@@ -2531,9 +2530,9 @@ pub struct TyPat {
 #[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),
@@ -2698,7 +2697,7 @@ pub fn to_string(s: &[Self]) -> String {
 #[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,
 }
 
@@ -2709,23 +2708,23 @@ pub struct InlineAsmSym {
 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,
@@ -2734,7 +2733,7 @@ pub enum InlineAsmOperand {
         sym: InlineAsmSym,
     },
     Label {
-        block: P<Block>,
+        block: Box<Block>,
     },
 }
 
@@ -2807,8 +2806,8 @@ pub struct InlineAsm {
 #[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,
@@ -2826,7 +2825,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 {
@@ -2882,7 +2881,7 @@ pub fn is_self(&self) -> bool {
     /// 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,
@@ -2893,7 +2892,7 @@ pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Par
             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,
@@ -2902,7 +2901,7 @@ pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Par
             ),
             SelfKind::Pinned(lt, mutbl) => (
                 mutbl,
-                P(Ty {
+                Box::new(Ty {
                     id: DUMMY_NODE_ID,
                     kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
                     span,
@@ -2912,7 +2911,7 @@ pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Par
         };
         Param {
             attrs,
-            pat: P(Pat {
+            pat: Box::new(Pat {
                 id: DUMMY_NODE_ID,
                 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
                 span,
@@ -3123,7 +3122,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 {
@@ -3148,7 +3147,7 @@ pub enum ModKind {
     /// 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, Result<(), ErrorGuaranteed>),
     /// Module with definition outlined to a separate file `mod foo;` but not yet loaded from it.
     Unloaded,
 }
@@ -3172,7 +3171,7 @@ 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, Walkable)]
@@ -3267,7 +3266,7 @@ pub struct Attribute {
 #[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`
@@ -3381,7 +3380,7 @@ pub struct Visibility {
 #[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,
 }
 
@@ -3403,7 +3402,7 @@ 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,
 }
@@ -3609,7 +3608,7 @@ pub struct Trait {
     #[visitable(extra = BoundKind::SuperTraits)]
     pub bounds: GenericBounds,
     #[visitable(extra = AssocCtxt::Trait)]
-    pub items: ThinVec<P<AssocItem>>,
+    pub items: ThinVec<Box<AssocItem>>,
 }
 
 /// The location of a where clause on a `TyAlias` (`Span`) and whether there was
@@ -3657,7 +3656,7 @@ pub struct TyAlias {
     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)]
@@ -3669,14 +3668,14 @@ pub struct Impl {
     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 self_ty: Box<Ty>,
+    pub items: ThinVec<Box<AssocItem>>,
 }
 
 #[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)]
@@ -3685,40 +3684,40 @@ 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, 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, 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, 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)>>,
 }
 
@@ -3727,8 +3726,8 @@ 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)>>,
 }
 
@@ -3798,7 +3797,7 @@ pub enum ItemKind {
     /// A macro invocation.
     ///
     /// E.g., `foo!(..)`.
-    MacCall(P<MacCall>),
+    MacCall(Box<MacCall>),
     /// A macro definition.
     MacroDef(Ident, MacroDef),
     /// A single delegation item (`reuse`).
@@ -3908,7 +3907,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.
@@ -3978,7 +3977,7 @@ pub enum ForeignItemKind {
     /// A foreign type.
     TyAlias(Box<TyAlias>),
     /// A macro expanding to foreign items.
-    MacCall(P<MacCall>),
+    MacCall(Box<MacCall>),
 }
 
 impl ForeignItemKind {
diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs
index 9d91f41..3d2477e 100644
--- a/compiler/rustc_ast/src/ast_traits.rs
+++ b/compiler/rustc_ast/src/ast_traits.rs
@@ -5,7 +5,6 @@
 use std::fmt;
 use std::marker::PhantomData;
 
-use crate::ptr::P;
 use crate::tokenstream::LazyAttrTokenStream;
 use crate::{
     Arm, AssocItem, AttrItem, AttrKind, AttrVec, Attribute, Block, Crate, Expr, ExprField,
@@ -53,7 +52,7 @@ fn node_id_mut(&mut self) -> &mut NodeId {
     WherePredicate,
 );
 
-impl<T: HasNodeId> HasNodeId for P<T> {
+impl<T: HasNodeId> HasNodeId for Box<T> {
     fn node_id(&self) -> NodeId {
         (**self).node_id()
     }
@@ -119,7 +118,7 @@ fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
     }
 }
 
-impl<T: HasTokens> HasTokens for P<T> {
+impl<T: HasTokens> HasTokens for Box<T> {
     fn tokens(&self) -> Option<&LazyAttrTokenStream> {
         (**self).tokens()
     }
@@ -245,7 +244,7 @@ fn visit_attrs(&mut self, _f: impl FnOnce(&mut AttrVec)) {}
 );
 impl_has_attrs_none!(Attribute, AttrItem, Block, Pat, Path, Ty, Visibility);
 
-impl<T: HasAttrs> HasAttrs for P<T> {
+impl<T: HasAttrs> HasAttrs for Box<T> {
     const SUPPORTS_CUSTOM_INNER_ATTRS: bool = T::SUPPORTS_CUSTOM_INNER_ATTRS;
     fn attrs(&self) -> &[Attribute] {
         (**self).attrs()
@@ -322,8 +321,8 @@ pub fn from_mut(wrapped: &mut Wrapped, _tag: Tag) -> &mut AstNodeWrapper<Wrapped
 }
 
 // FIXME: remove after `stmt_expr_attributes` is stabilized.
-impl<T, Tag> From<AstNodeWrapper<P<T>, Tag>> for AstNodeWrapper<T, Tag> {
-    fn from(value: AstNodeWrapper<P<T>, Tag>) -> Self {
+impl<T, Tag> From<AstNodeWrapper<Box<T>, Tag>> for AstNodeWrapper<T, Tag> {
+    fn from(value: AstNodeWrapper<Box<T>, Tag>) -> Self {
         AstNodeWrapper { wrapped: *value.wrapped, tag: value.tag }
     }
 }
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index 4348a4b..6ada93b 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -13,7 +13,6 @@
     Expr, ExprKind, LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, NormalAttr, Path,
     PathSegment, Safety,
 };
-use crate::ptr::P;
 use crate::token::{self, CommentKind, Delimiter, InvisibleOrigin, MetaVarKind, Token};
 use crate::tokenstream::{
     DelimSpan, LazyAttrTokenStream, Spacing, TokenStream, TokenStreamIter, TokenTree,
@@ -660,7 +659,7 @@ pub fn mk_attr_from_item(
     span: Span,
 ) -> Attribute {
     Attribute {
-        kind: AttrKind::Normal(P(NormalAttr { item, tokens })),
+        kind: AttrKind::Normal(Box::new(NormalAttr { item, tokens })),
         id: g.mk_attr_id(),
         style,
         span,
@@ -710,7 +709,7 @@ pub fn mk_attr_name_value_str(
     span: Span,
 ) -> Attribute {
     let lit = token::Lit::new(token::Str, escape_string_symbol(val), None);
-    let expr = P(Expr {
+    let expr = Box::new(Expr {
         id: DUMMY_NODE_ID,
         kind: ExprKind::Lit(lit),
         span,
diff --git a/compiler/rustc_ast/src/expand/autodiff_attrs.rs b/compiler/rustc_ast/src/expand/autodiff_attrs.rs
index 2f918fa..33451f9 100644
--- a/compiler/rustc_ast/src/expand/autodiff_attrs.rs
+++ b/compiler/rustc_ast/src/expand/autodiff_attrs.rs
@@ -7,7 +7,6 @@
 use std::str::FromStr;
 
 use crate::expand::{Decodable, Encodable, HashStable_Generic};
-use crate::ptr::P;
 use crate::{Ty, TyKind};
 
 /// Forward and Reverse Mode are well known names for automatic differentiation implementations.
@@ -162,7 +161,7 @@ pub fn valid_ret_activity(mode: DiffMode, activity: DiffActivity) -> bool {
 /// since Duplicated expects a mutable ref/ptr and we would thus end up with a shadow value
 /// who is an indirect type, which doesn't match the primal scalar type. We can't prevent
 /// users here from marking scalars as Duplicated, due to type aliases.
-pub fn valid_ty_for_activity(ty: &P<Ty>, activity: DiffActivity) -> bool {
+pub fn valid_ty_for_activity(ty: &Box<Ty>, activity: DiffActivity) -> bool {
     use DiffActivity::*;
     // It's always allowed to mark something as Const, since we won't compute derivatives wrt. it.
     // Dual variants also support all types.
diff --git a/compiler/rustc_ast/src/format.rs b/compiler/rustc_ast/src/format.rs
index c2a1de6..cadebb2 100644
--- a/compiler/rustc_ast/src/format.rs
+++ b/compiler/rustc_ast/src/format.rs
@@ -3,7 +3,6 @@
 use rustc_span::{Ident, Span, Symbol};
 
 use crate::Expr;
-use crate::ptr::P;
 use crate::token::LitKind;
 
 // Definitions:
@@ -147,7 +146,7 @@ pub fn all_args_mut(&mut self) -> &mut Vec<FormatArgument> {
 #[derive(Clone, Encodable, Decodable, Debug, Walkable)]
 pub struct FormatArgument {
     pub kind: FormatArgumentKind,
-    pub expr: P<Expr>,
+    pub expr: Box<Expr>,
 }
 
 #[derive(Clone, Encodable, Decodable, Debug, Walkable)]
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index 896d1e1..f195104 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -37,7 +37,6 @@ pub mod util {
 pub mod format;
 pub mod mut_visit;
 pub mod node_id;
-pub mod ptr;
 pub mod token;
 pub mod tokenstream;
 pub mod visit;
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 06708e2..be8e1d2 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -17,7 +17,6 @@
 use thin_vec::ThinVec;
 
 use crate::ast::*;
-use crate::ptr::P;
 use crate::tokenstream::*;
 use crate::visit::{AssocCtxt, BoundKind, FnCtxt, LifetimeCtxt, VisitorResult, try_visit};
 
@@ -41,7 +40,7 @@ pub(crate) trait MutVisitable<V: MutVisitor> {
     fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra);
 }
 
-impl<V: MutVisitor, T: ?Sized> MutVisitable<V> for P<T>
+impl<V: MutVisitor, T: ?Sized> MutVisitable<V> for Box<T>
 where
     T: MutVisitable<V>,
 {
@@ -293,15 +292,15 @@ fn $name<V: MutVisitor>(
 }
 
 generate_flat_map_visitor_fns! {
-    visit_items, P<Item>, flat_map_item;
-    visit_foreign_items, P<ForeignItem>, flat_map_foreign_item;
+    visit_items, Box<Item>, flat_map_item;
+    visit_foreign_items, Box<ForeignItem>, flat_map_foreign_item;
     visit_generic_params, GenericParam, flat_map_generic_param;
     visit_stmts, Stmt, flat_map_stmt;
-    visit_exprs, P<Expr>, filter_map_expr;
+    visit_exprs, Box<Expr>, filter_map_expr;
     visit_expr_fields, ExprField, flat_map_expr_field;
     visit_pat_fields, PatField, flat_map_pat_field;
     visit_variants, Variant, flat_map_variant;
-    visit_assoc_items, P<AssocItem>, flat_map_assoc_item, ctxt: AssocCtxt;
+    visit_assoc_items, Box<AssocItem>, flat_map_assoc_item, ctxt: AssocCtxt;
     visit_where_predicates, WherePredicate, flat_map_where_predicate;
     visit_params, Param, flat_map_param;
     visit_field_defs, FieldDef, flat_map_field_def;
@@ -333,12 +332,12 @@ macro_rules! generate_walk_flat_map_fns {
     walk_flat_map_where_predicate(WherePredicate) => visit_where_predicate;
     walk_flat_map_field_def(FieldDef) => visit_field_def;
     walk_flat_map_expr_field(ExprField) => visit_expr_field;
-    walk_flat_map_item(P<Item>) => visit_item;
-    walk_flat_map_foreign_item(P<ForeignItem>) => visit_foreign_item;
-    walk_flat_map_assoc_item(P<AssocItem>, ctxt: AssocCtxt) => visit_assoc_item;
+    walk_flat_map_item(Box<Item>) => visit_item;
+    walk_flat_map_foreign_item(Box<ForeignItem>) => visit_foreign_item;
+    walk_flat_map_assoc_item(Box<AssocItem>, ctxt: AssocCtxt) => visit_assoc_item;
 }
 
-pub fn walk_filter_map_expr<T: MutVisitor>(vis: &mut T, mut e: P<Expr>) -> Option<P<Expr>> {
+pub fn walk_filter_map_expr<T: MutVisitor>(vis: &mut T, mut e: Box<Expr>) -> Option<Box<Expr>> {
     vis.visit_expr(&mut e);
     Some(e)
 }
diff --git a/compiler/rustc_ast/src/ptr.rs b/compiler/rustc_ast/src/ptr.rs
deleted file mode 100644
index fffeab8..0000000
--- a/compiler/rustc_ast/src/ptr.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-/// A pointer type that uniquely owns a heap allocation of type T.
-///
-/// This used to be its own type, but now it's just a typedef for `Box` and we are planning to
-/// remove it soon.
-pub type P<T> = Box<T>;
-
-/// Construct a `P<T>` from a `T` value.
-#[allow(non_snake_case)]
-pub fn P<T>(value: T) -> P<T> {
-    Box::new(value)
-}
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index ab15cb2..5fdce27 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -20,7 +20,6 @@
 use thin_vec::ThinVec;
 
 use crate::ast::*;
-use crate::ptr::P;
 use crate::tokenstream::DelimSpan;
 
 #[derive(Copy, Clone, Debug, PartialEq)]
@@ -82,7 +81,7 @@ pub(crate) trait Visitable<'a, V: Visitor<'a>> {
     fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result;
 }
 
-impl<'a, V: Visitor<'a>, T: ?Sized> Visitable<'a, V> for P<T>
+impl<'a, V: Visitor<'a>, T: ?Sized> Visitable<'a, V> for Box<T>
 where
     T: Visitable<'a, V>,
 {
@@ -322,7 +321,7 @@ pub enum FnKind<'a> {
             Fn(FnCtxt, &'a $($mut)? Visibility, &'a $($mut)? Fn),
 
             /// E.g., `|x, y| body`.
-            Closure(&'a $($mut)? ClosureBinder, &'a $($mut)? Option<CoroutineKind>, &'a $($mut)? P<FnDecl>, &'a $($mut)? P<Expr>),
+            Closure(&'a $($mut)? ClosureBinder, &'a $($mut)? Option<CoroutineKind>, &'a $($mut)? Box<FnDecl>, &'a $($mut)? Box<Expr>),
         }
 
         impl<'a> FnKind<'a> {
@@ -390,9 +389,9 @@ pub fn ctxt(&self) -> Option<FnCtxt> {
             ThinVec<(NodeId, Path)>,
             ThinVec<PathSegment>,
             ThinVec<PreciseCapturingArg>,
-            ThinVec<P<Pat>>,
-            ThinVec<P<Ty>>,
-            ThinVec<P<TyPat>>,
+            ThinVec<Box<Pat>>,
+            ThinVec<Box<Ty>>,
+            ThinVec<Box<TyPat>>,
         );
 
         // This macro generates `impl Visitable` and `impl MutVisitable` that forward to `Walkable`
@@ -676,11 +675,11 @@ fn visit_span(&mut self, _sp: &$mut Span) {
                     // Do nothing.
                 }
 
-                fn flat_map_foreign_item(&mut self, ni: P<ForeignItem>) -> SmallVec<[P<ForeignItem>; 1]> {
+                fn flat_map_foreign_item(&mut self, ni: Box<ForeignItem>) -> SmallVec<[Box<ForeignItem>; 1]> {
                     walk_flat_map_foreign_item(self, ni)
                 }
 
-                fn flat_map_item(&mut self, i: P<Item>) -> SmallVec<[P<Item>; 1]> {
+                fn flat_map_item(&mut self, i: Box<Item>) -> SmallVec<[Box<Item>; 1]> {
                     walk_flat_map_item(self, i)
                 }
 
@@ -690,9 +689,9 @@ fn visit_span(&mut self, _sp: &$mut Span) {
 
                 fn flat_map_assoc_item(
                     &mut self,
-                    i: P<AssocItem>,
+                    i: Box<AssocItem>,
                     ctxt: AssocCtxt,
-                ) -> SmallVec<[P<AssocItem>; 1]> {
+                ) -> SmallVec<[Box<AssocItem>; 1]> {
                     walk_flat_map_assoc_item(self, i, ctxt)
                 }
 
@@ -704,7 +703,7 @@ fn flat_map_assoc_item(
                     walk_flat_map_arm(self, arm)
                 }
 
-                fn filter_map_expr(&mut self, e: P<Expr>) -> Option<P<Expr>> {
+                fn filter_map_expr(&mut self, e: Box<Expr>) -> Option<Box<Expr>> {
                     walk_filter_map_expr(self, e)
                 }
 
@@ -1144,15 +1143,15 @@ fn $name<'a, V: Visitor<'a>>(
 }
 
 generate_list_visit_fns! {
-    visit_items, P<Item>, visit_item;
-    visit_foreign_items, P<ForeignItem>, visit_foreign_item;
+    visit_items, Box<Item>, visit_item;
+    visit_foreign_items, Box<ForeignItem>, visit_foreign_item;
     visit_generic_params, GenericParam, visit_generic_param;
     visit_stmts, Stmt, visit_stmt;
-    visit_exprs, P<Expr>, visit_expr;
+    visit_exprs, Box<Expr>, visit_expr;
     visit_expr_fields, ExprField, visit_expr_field;
     visit_pat_fields, PatField, visit_pat_field;
     visit_variants, Variant, visit_variant;
-    visit_assoc_items, P<AssocItem>, visit_assoc_item, ctxt: AssocCtxt;
+    visit_assoc_items, Box<AssocItem>, visit_assoc_item, ctxt: AssocCtxt;
     visit_where_predicates, WherePredicate, visit_where_predicate;
     visit_params, Param, visit_param;
     visit_field_defs, FieldDef, visit_field_def;
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index fb42cfe..2ddbf08 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -1,7 +1,6 @@
 use std::ops::ControlFlow;
 use std::sync::Arc;
 
-use rustc_ast::ptr::P as AstP;
 use rustc_ast::*;
 use rustc_ast_pretty::pprust::expr_to_string;
 use rustc_data_structures::stack::ensure_sufficient_stack;
@@ -53,7 +52,7 @@ fn visit_expr(&mut self, ex: &'v Expr) -> Self::Result {
 }
 
 impl<'hir> LoweringContext<'_, 'hir> {
-    fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> &'hir [hir::Expr<'hir>] {
+    fn lower_exprs(&mut self, exprs: &[Box<Expr>]) -> &'hir [hir::Expr<'hir>] {
         self.arena.alloc_from_iter(exprs.iter().map(|x| self.lower_expr_mut(x)))
     }
 
@@ -455,7 +454,7 @@ fn lower_assign_op(&mut self, a: AssignOp) -> AssignOp {
     fn lower_legacy_const_generics(
         &mut self,
         mut f: Expr,
-        args: ThinVec<AstP<Expr>>,
+        args: ThinVec<Box<Expr>>,
         legacy_args_idx: &[usize],
     ) -> hir::ExprKind<'hir> {
         let ExprKind::Path(None, path) = &mut f.kind else {
@@ -495,7 +494,7 @@ fn lower_legacy_const_generics(
                 self.create_def(node_id, None, DefKind::AnonConst, f.span);
                 let mut visitor = WillCreateDefIdsVisitor {};
                 let const_value = if let ControlFlow::Break(span) = visitor.visit_expr(&arg) {
-                    AstP(Expr {
+                    Box::new(Expr {
                         id: self.next_node_id(),
                         kind: ExprKind::Err(invalid_expr_error(self.tcx, span)),
                         span: f.span,
@@ -516,7 +515,7 @@ fn lower_legacy_const_generics(
         // Add generic args to the last element of the path.
         let last_segment = path.segments.last_mut().unwrap();
         assert!(last_segment.args.is_none());
-        last_segment.args = Some(AstP(GenericArgs::AngleBracketed(AngleBracketedArgs {
+        last_segment.args = Some(Box::new(GenericArgs::AngleBracketed(AngleBracketedArgs {
             span: DUMMY_SP,
             args: generic_args,
         })));
@@ -812,7 +811,7 @@ pub(super) fn maybe_forward_track_caller(
             self.lower_attrs(
                 inner_hir_id,
                 &[Attribute {
-                    kind: AttrKind::Normal(ptr::P(NormalAttr::from_ident(Ident::new(
+                    kind: AttrKind::Normal(Box::new(NormalAttr::from_ident(Ident::new(
                         sym::track_caller,
                         span,
                     )))),
@@ -1285,7 +1284,7 @@ fn is_ordinary(lower_ctx: &mut LoweringContext<'_, '_>, lhs: &Expr) -> bool {
     fn extract_tuple_struct_path<'a>(
         &mut self,
         expr: &'a Expr,
-    ) -> Option<(&'a Option<AstP<QSelf>>, &'a Path)> {
+    ) -> Option<(&'a Option<Box<QSelf>>, &'a Path)> {
         if let ExprKind::Path(qself, path) = &expr.kind {
             // Does the path resolve to something disallowed in a tuple struct/variant pattern?
             if let Some(partial_res) = self.resolver.get_partial_res(expr.id) {
@@ -1307,7 +1306,7 @@ fn extract_tuple_struct_path<'a>(
     fn extract_unit_struct_path<'a>(
         &mut self,
         expr: &'a Expr,
-    ) -> Option<(&'a Option<AstP<QSelf>>, &'a Path)> {
+    ) -> Option<(&'a Option<Box<QSelf>>, &'a Path)> {
         if let ExprKind::Path(qself, path) = &expr.kind {
             // Does the path resolve to something disallowed in a unit struct/variant pattern?
             if let Some(partial_res) = self.resolver.get_partial_res(expr.id) {
@@ -1478,7 +1477,7 @@ fn destructure_assign_mut(
     /// Each sub-assignment is recorded in `assignments`.
     fn destructure_sequence(
         &mut self,
-        elements: &[AstP<Expr>],
+        elements: &[Box<Expr>],
         ctx: &str,
         eq_sign_span: Span,
         assignments: &mut Vec<hir::Stmt<'hir>>,
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 9f54af5..ac6fac4 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1,5 +1,4 @@
 use rustc_abi::ExternAbi;
-use rustc_ast::ptr::P;
 use rustc_ast::visit::AssocCtxt;
 use rustc_ast::*;
 use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err};
@@ -102,7 +101,7 @@ pub(super) fn lower_node(&mut self, def_id: LocalDefId) {
 impl<'hir> LoweringContext<'_, 'hir> {
     pub(super) fn lower_mod(
         &mut self,
-        items: &[P<Item>],
+        items: &[Box<Item>],
         spans: &ModSpans,
     ) -> &'hir hir::Mod<'hir> {
         self.arena.alloc(hir::Mod {
@@ -462,7 +461,7 @@ fn lower_item_kind(
             }
             ItemKind::MacroDef(ident, MacroDef { body, macro_rules }) => {
                 let ident = self.lower_ident(*ident);
-                let body = P(self.lower_delim_args(body));
+                let body = Box::new(self.lower_delim_args(body));
                 let def_id = self.local_def_id(id);
                 let def_kind = self.tcx.def_kind(def_id);
                 let DefKind::Macro(macro_kind) = def_kind else {
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index d097e3c..64c1b53 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1217,7 +1217,7 @@ fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {
     fn lower_path_ty(
         &mut self,
         t: &Ty,
-        qself: &Option<ptr::P<QSelf>>,
+        qself: &Option<Box<QSelf>>,
         path: &Path,
         param_mode: ParamMode,
         itctx: ImplTraitContext,
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index e444062..b653306 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -1,6 +1,5 @@
 use std::sync::Arc;
 
-use rustc_ast::ptr::P;
 use rustc_ast::*;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_hir::def::{DefKind, Res};
@@ -154,7 +153,7 @@ fn lower_pat_mut(&mut self, mut pattern: &Pat) -> hir::Pat<'hir> {
 
     fn lower_pat_tuple(
         &mut self,
-        pats: &[P<Pat>],
+        pats: &[Box<Pat>],
         ctx: &str,
     ) -> (&'hir [hir::Pat<'hir>], hir::DotDotPos) {
         let mut elems = Vec::with_capacity(pats.len());
@@ -209,7 +208,7 @@ fn lower_pat_tuple(
     /// When encountering `($binding_mode $ident @)? ..` (`slice`),
     /// this is interpreted as a sub-slice pattern semantically.
     /// Patterns that follow, which are not like `slice` -- or an error occurs, are in `after`.
-    fn lower_pat_slice(&mut self, pats: &[P<Pat>]) -> hir::PatKind<'hir> {
+    fn lower_pat_slice(&mut self, pats: &[Box<Pat>]) -> hir::PatKind<'hir> {
         let mut before = Vec::new();
         let mut after = Vec::new();
         let mut slice = None;
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index c80ef27..3322e0f 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -24,7 +24,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     pub(crate) fn lower_qpath(
         &mut self,
         id: NodeId,
-        qself: &Option<ptr::P<QSelf>>,
+        qself: &Option<Box<QSelf>>,
         p: &Path,
         param_mode: ParamMode,
         allow_return_type_notation: AllowReturnTypeNotation,
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 1c1c5f8..9d3b096 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -22,7 +22,6 @@
 
 use itertools::{Either, Itertools};
 use rustc_abi::{CanonAbi, ExternAbi, InterruptKind};
-use rustc_ast::ptr::P;
 use rustc_ast::visit::{AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor, walk_list};
 use rustc_ast::*;
 use rustc_ast_pretty::pprust::{self, State};
@@ -719,7 +718,7 @@ fn deny_where_clause(&self, where_clause: &WhereClause, ident: Span) {
         }
     }
 
-    fn deny_items(&self, trait_items: &[P<AssocItem>], ident_span: Span) {
+    fn deny_items(&self, trait_items: &[Box<AssocItem>], ident_span: Span) {
         if !trait_items.is_empty() {
             let spans: Vec<_> = trait_items.iter().map(|i| i.kind.ident().unwrap().span).collect();
             let total = trait_items.first().unwrap().span.to(trait_items.last().unwrap().span);
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index f0cf0c1..85f7603 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -10,7 +10,6 @@
 use std::sync::Arc;
 
 use rustc_ast::attr::AttrIdGenerator;
-use rustc_ast::ptr::P;
 use rustc_ast::token::{self, CommentKind, Delimiter, IdentIsRaw, Token, TokenKind};
 use rustc_ast::tokenstream::{Spacing, TokenStream, TokenTree};
 use rustc_ast::util::classify;
@@ -1178,7 +1177,7 @@ fn commasep_cmnt<T, F, G>(&mut self, b: Breaks, elts: &[T], mut op: F, mut get_s
         self.end(rb);
     }
 
-    fn commasep_exprs(&mut self, b: Breaks, exprs: &[P<ast::Expr>]) {
+    fn commasep_exprs(&mut self, b: Breaks, exprs: &[Box<ast::Expr>]) {
         self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e, FixupContext::default()), |e| e.span)
     }
 
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index 8a2cb64..bdf73ac 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -2,7 +2,6 @@
 
 use ast::{ForLoopKind, MatchKind};
 use itertools::{Itertools, Position};
-use rustc_ast::ptr::P;
 use rustc_ast::util::classify;
 use rustc_ast::util::literal::escape_byte_str_symbol;
 use rustc_ast::util::parser::{self, ExprPrecedence, Fixity};
@@ -54,7 +53,7 @@ fn print_if(&mut self, test: &ast::Expr, blk: &ast::Block, elseopt: Option<&ast:
         self.print_else(elseopt)
     }
 
-    fn print_call_post(&mut self, args: &[P<ast::Expr>]) {
+    fn print_call_post(&mut self, args: &[Box<ast::Expr>]) {
         self.popen();
         self.commasep_exprs(Inconsistent, args);
         self.pclose()
@@ -111,7 +110,7 @@ pub(super) fn print_expr_cond_paren(
         }
     }
 
-    fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>]) {
+    fn print_expr_vec(&mut self, exprs: &[Box<ast::Expr>]) {
         let ib = self.ibox(INDENT_UNIT);
         self.word("[");
         self.commasep_exprs(Inconsistent, exprs);
@@ -149,7 +148,7 @@ fn print_expr_repeat(&mut self, element: &ast::Expr, count: &ast::AnonConst) {
 
     fn print_expr_struct(
         &mut self,
-        qself: &Option<P<ast::QSelf>>,
+        qself: &Option<Box<ast::QSelf>>,
         path: &ast::Path,
         fields: &[ast::ExprField],
         rest: &ast::StructRest,
@@ -204,7 +203,7 @@ fn print_expr_struct(
         self.word("}");
     }
 
-    fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>]) {
+    fn print_expr_tup(&mut self, exprs: &[Box<ast::Expr>]) {
         self.popen();
         self.commasep_exprs(Inconsistent, exprs);
         if exprs.len() == 1 {
@@ -213,7 +212,7 @@ fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>]) {
         self.pclose()
     }
 
-    fn print_expr_call(&mut self, func: &ast::Expr, args: &[P<ast::Expr>], fixup: FixupContext) {
+    fn print_expr_call(&mut self, func: &ast::Expr, args: &[Box<ast::Expr>], fixup: FixupContext) {
         // Independent of parenthesization related to precedence, we must
         // parenthesize `func` if this is a statement context in which without
         // parentheses, a statement boundary would occur inside `func` or
@@ -247,7 +246,7 @@ fn print_expr_method_call(
         &mut self,
         segment: &ast::PathSegment,
         receiver: &ast::Expr,
-        base_args: &[P<ast::Expr>],
+        base_args: &[Box<ast::Expr>],
         fixup: FixupContext,
     ) {
         // The fixup here is different than in `print_expr_call` because
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
index 11c97a5..6e34d1b 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
@@ -2,7 +2,6 @@
 use itertools::{Itertools, Position};
 use rustc_ast as ast;
 use rustc_ast::ModKind;
-use rustc_ast::ptr::P;
 use rustc_span::Ident;
 
 use crate::pp::BoxMarker;
@@ -628,10 +627,10 @@ fn print_delegation(
         &mut self,
         attrs: &[ast::Attribute],
         vis: &ast::Visibility,
-        qself: &Option<P<ast::QSelf>>,
+        qself: &Option<Box<ast::QSelf>>,
         path: &ast::Path,
         kind: DelegationKind<'_>,
-        body: &Option<P<ast::Block>>,
+        body: &Option<Box<ast::Block>>,
     ) {
         let body_cb_ib = body.as_ref().map(|body| (body, self.head("")));
         self.print_visibility(vis);
diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
index e75bc94..35ef6be 100644
--- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
+++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
@@ -1,4 +1,3 @@
-use rustc_ast::ptr::P;
 use rustc_ast::{
     self as ast, Fn, FnHeader, FnSig, Generics, ItemKind, Safety, Stmt, StmtKind, TyKind,
 };
@@ -46,7 +45,7 @@ pub(crate) fn expand(
     let const_body = ecx.expr_block(ecx.block(span, stmts));
     let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body);
     let const_item = if is_stmt {
-        Annotatable::Stmt(P(ecx.stmt_item(span, const_item)))
+        Annotatable::Stmt(Box::new(ecx.stmt_item(span, const_item)))
     } else {
         Annotatable::Item(const_item)
     };
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 1fb9981..86b8e1f 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -1,5 +1,4 @@
 use lint::BuiltinLintDiag;
-use rustc_ast::ptr::P;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::{AsmMacro, token};
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
@@ -19,7 +18,7 @@
 
 /// Validated assembly arguments, ready for macro expansion.
 struct ValidatedAsmArgs {
-    pub templates: Vec<P<ast::Expr>>,
+    pub templates: Vec<Box<ast::Expr>>,
     pub operands: Vec<(ast::InlineAsmOperand, Span)>,
     named_args: FxIndexMap<Symbol, usize>,
     reg_args: GrowableBitSet<usize>,
@@ -600,9 +599,9 @@ pub(super) fn expand_asm<'cx>(
                 return ExpandResult::Retry(());
             };
             let expr = match mac {
-                Ok(inline_asm) => P(ast::Expr {
+                Ok(inline_asm) => Box::new(ast::Expr {
                     id: ast::DUMMY_NODE_ID,
-                    kind: ast::ExprKind::InlineAsm(P(inline_asm)),
+                    kind: ast::ExprKind::InlineAsm(Box::new(inline_asm)),
                     span: sp,
                     attrs: ast::AttrVec::new(),
                     tokens: None,
@@ -630,9 +629,9 @@ pub(super) fn expand_naked_asm<'cx>(
                 return ExpandResult::Retry(());
             };
             let expr = match mac {
-                Ok(inline_asm) => P(ast::Expr {
+                Ok(inline_asm) => Box::new(ast::Expr {
                     id: ast::DUMMY_NODE_ID,
-                    kind: ast::ExprKind::InlineAsm(P(inline_asm)),
+                    kind: ast::ExprKind::InlineAsm(Box::new(inline_asm)),
                     span: sp,
                     attrs: ast::AttrVec::new(),
                     tokens: None,
@@ -660,7 +659,7 @@ pub(super) fn expand_global_asm<'cx>(
                 return ExpandResult::Retry(());
             };
             match mac {
-                Ok(inline_asm) => MacEager::items(smallvec![P(ast::Item {
+                Ok(inline_asm) => MacEager::items(smallvec![Box::new(ast::Item {
                     attrs: ast::AttrVec::new(),
                     id: ast::DUMMY_NODE_ID,
                     kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)),
diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs
index c659b1c..855da5c 100644
--- a/compiler/rustc_builtin_macros/src/assert.rs
+++ b/compiler/rustc_builtin_macros/src/assert.rs
@@ -1,6 +1,5 @@
 mod context;
 
-use rustc_ast::ptr::P;
 use rustc_ast::token::Delimiter;
 use rustc_ast::tokenstream::{DelimSpan, TokenStream};
 use rustc_ast::{DelimArgs, Expr, ExprKind, MacCall, Path, PathSegment, UnOp, token};
@@ -55,9 +54,9 @@ pub(crate) fn expand_assert<'cx>(
     let expr = if let Some(tokens) = custom_message {
         let then = cx.expr(
             call_site_span,
-            ExprKind::MacCall(P(MacCall {
+            ExprKind::MacCall(Box::new(MacCall {
                 path: panic_path(),
-                args: P(DelimArgs {
+                args: Box::new(DelimArgs {
                     dspan: DelimSpan::from_single(call_site_span),
                     delim: Delimiter::Parenthesis,
                     tokens,
@@ -96,7 +95,7 @@ pub(crate) fn expand_assert<'cx>(
 }
 
 struct Assert {
-    cond_expr: P<Expr>,
+    cond_expr: Box<Expr>,
     custom_message: Option<TokenStream>,
 }
 
@@ -104,10 +103,10 @@ struct Assert {
 fn expr_if_not(
     cx: &ExtCtxt<'_>,
     span: Span,
-    cond: P<Expr>,
-    then: P<Expr>,
-    els: Option<P<Expr>>,
-) -> P<Expr> {
+    cond: Box<Expr>,
+    then: Box<Expr>,
+    els: Option<Box<Expr>>,
+) -> Box<Expr> {
     cx.expr_if(span, cx.expr(span, ExprKind::Unary(UnOp::Not, cond)), then, els)
 }
 
diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs
index ea7248c..31855cb 100644
--- a/compiler/rustc_builtin_macros/src/assert/context.rs
+++ b/compiler/rustc_builtin_macros/src/assert/context.rs
@@ -1,4 +1,3 @@
-use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter, IdentIsRaw};
 use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
 use rustc_ast::{
@@ -70,7 +69,7 @@ pub(super) fn new(cx: &'cx ExtCtxt<'a>, span: Span) -> Self {
     ///   }
     /// }
     /// ```
-    pub(super) fn build(mut self, mut cond_expr: P<Expr>, panic_path: Path) -> P<Expr> {
+    pub(super) fn build(mut self, mut cond_expr: Box<Expr>, panic_path: Path) -> Box<Expr> {
         let expr_str = pprust::expr_to_string(&cond_expr);
         self.manage_cond_expr(&mut cond_expr);
         let initial_imports = self.build_initial_imports();
@@ -129,7 +128,7 @@ fn build_initial_imports(&self) -> Stmt {
     }
 
     /// Takes the conditional expression of `assert!` and then wraps it inside `unlikely`
-    fn build_unlikely(&self, cond_expr: P<Expr>) -> P<Expr> {
+    fn build_unlikely(&self, cond_expr: Box<Expr>) -> Box<Expr> {
         let unlikely_path = self.cx.std_path(&[sym::intrinsics, sym::unlikely]);
         self.cx.expr_call(
             self.span,
@@ -145,7 +144,7 @@ fn build_unlikely(&self, cond_expr: P<Expr>) -> P<Expr> {
     ///     __capture0,
     ///     ...
     /// );
-    fn build_panic(&self, expr_str: &str, panic_path: Path) -> P<Expr> {
+    fn build_panic(&self, expr_str: &str, panic_path: Path) -> Box<Expr> {
         let escaped_expr_str = escape_to_fmt(expr_str);
         let initial = [
             TokenTree::token_joint(
@@ -176,9 +175,9 @@ fn build_panic(&self, expr_str: &str, panic_path: Path) -> P<Expr> {
         });
         self.cx.expr(
             self.span,
-            ExprKind::MacCall(P(MacCall {
+            ExprKind::MacCall(Box::new(MacCall {
                 path: panic_path,
-                args: P(DelimArgs {
+                args: Box::new(DelimArgs {
                     dspan: DelimSpan::from_single(self.span),
                     delim: Delimiter::Parenthesis,
                     tokens: initial.into_iter().chain(captures).collect::<TokenStream>(),
@@ -190,7 +189,7 @@ fn build_panic(&self, expr_str: &str, panic_path: Path) -> P<Expr> {
     /// Recursive function called until `cond_expr` and `fmt_str` are fully modified.
     ///
     /// See [Self::manage_initial_capture] and [Self::manage_try_capture]
-    fn manage_cond_expr(&mut self, expr: &mut P<Expr>) {
+    fn manage_cond_expr(&mut self, expr: &mut Box<Expr>) {
         match &mut expr.kind {
             ExprKind::AddrOf(_, mutability, local_expr) => {
                 self.with_is_consumed_management(matches!(mutability, Mutability::Mut), |this| {
@@ -331,7 +330,7 @@ fn manage_cond_expr(&mut self, expr: &mut P<Expr>) {
     ///
     /// `fmt_str`, the formatting string used for debugging, is constructed to show possible
     /// captured variables.
-    fn manage_initial_capture(&mut self, expr: &mut P<Expr>, path_ident: Ident) {
+    fn manage_initial_capture(&mut self, expr: &mut Box<Expr>, path_ident: Ident) {
         if self.paths.contains(&path_ident) {
             return;
         } else {
@@ -360,7 +359,12 @@ fn manage_initial_capture(&mut self, expr: &mut P<Expr>, path_ident: Ident) {
     ///    (&Wrapper(__local_bindN)).try_capture(&mut __captureN);
     ///    __local_bindN
     /// }
-    fn manage_try_capture(&mut self, capture: Ident, curr_capture_idx: usize, expr: &mut P<Expr>) {
+    fn manage_try_capture(
+        &mut self,
+        capture: Ident,
+        curr_capture_idx: usize,
+        expr: &mut Box<Expr>,
+    ) {
         let local_bind_string = format!("__local_bind{curr_capture_idx}");
         let local_bind = Ident::new(Symbol::intern(&local_bind_string), self.span);
         self.local_bind_decls.push(self.cx.stmt_let(
@@ -441,20 +445,20 @@ fn escape_to_fmt(s: &str) -> String {
     rslt
 }
 
-fn expr_addr_of_mut(cx: &ExtCtxt<'_>, sp: Span, e: P<Expr>) -> P<Expr> {
+fn expr_addr_of_mut(cx: &ExtCtxt<'_>, sp: Span, e: Box<Expr>) -> Box<Expr> {
     cx.expr(sp, ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, e))
 }
 
 fn expr_method_call(
     cx: &ExtCtxt<'_>,
     seg: PathSegment,
-    receiver: P<Expr>,
-    args: ThinVec<P<Expr>>,
+    receiver: Box<Expr>,
+    args: ThinVec<Box<Expr>>,
     span: Span,
-) -> P<Expr> {
+) -> Box<Expr> {
     cx.expr(span, ExprKind::MethodCall(Box::new(MethodCall { seg, receiver, args, span })))
 }
 
-fn expr_paren(cx: &ExtCtxt<'_>, sp: Span, e: P<Expr>) -> P<Expr> {
+fn expr_paren(cx: &ExtCtxt<'_>, sp: Span, e: Box<Expr>) -> Box<Expr> {
     cx.expr(sp, ExprKind::Paren(e))
 }
diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs
index c784477..a662840 100644
--- a/compiler/rustc_builtin_macros/src/autodiff.rs
+++ b/compiler/rustc_builtin_macros/src/autodiff.rs
@@ -11,7 +11,6 @@ mod llvm_enzyme {
         AutoDiffAttrs, DiffActivity, DiffMode, valid_input_activity, valid_ret_activity,
         valid_ty_for_activity,
     };
-    use rustc_ast::ptr::P;
     use rustc_ast::token::{Lit, LitKind, Token, TokenKind};
     use rustc_ast::tokenstream::*;
     use rustc_ast::visit::AssocCtxt::*;
@@ -27,7 +26,7 @@ mod llvm_enzyme {
     use crate::errors;
 
     pub(crate) fn outer_normal_attr(
-        kind: &P<rustc_ast::NormalAttr>,
+        kind: &Box<rustc_ast::NormalAttr>,
         id: rustc_ast::AttrId,
         span: Span,
     ) -> rustc_ast::Attribute {
@@ -73,7 +72,7 @@ fn width(x: &MetaItemInner) -> Option<u128> {
     }
 
     // Get information about the function the macro is applied to
-    fn extract_item_info(iitem: &P<ast::Item>) -> Option<(Visibility, FnSig, Ident, Generics)> {
+    fn extract_item_info(iitem: &Box<ast::Item>) -> Option<(Visibility, FnSig, Ident, Generics)> {
         match &iitem.kind {
             ItemKind::Fn(box ast::Fn { sig, ident, generics, .. }) => {
                 Some((iitem.vis.clone(), sig.clone(), ident.clone(), generics.clone()))
@@ -346,7 +345,7 @@ pub(crate) fn expand_with_mode(
             define_opaque: None,
         });
         let mut rustc_ad_attr =
-            P(ast::NormalAttr::from_ident(Ident::with_dummy_span(sym::rustc_autodiff)));
+            Box::new(ast::NormalAttr::from_ident(Ident::with_dummy_span(sym::rustc_autodiff)));
 
         let ts2: Vec<TokenTree> = vec![TokenTree::Token(
             Token::new(TokenKind::Ident(sym::never, false.into()), span),
@@ -363,7 +362,7 @@ pub(crate) fn expand_with_mode(
             args: ast::AttrArgs::Delimited(never_arg),
             tokens: None,
         };
-        let inline_never_attr = P(ast::NormalAttr { item: inline_item, tokens: None });
+        let inline_never_attr = Box::new(ast::NormalAttr { item: inline_item, tokens: None });
         let new_id = ecx.sess.psess.attr_id_generator.mk_attr_id();
         let attr = outer_normal_attr(&rustc_ad_attr, new_id, span);
         let new_id = ecx.sess.psess.attr_id_generator.mk_attr_id();
@@ -433,7 +432,7 @@ fn same_attribute(attr: &ast::AttrKind, item: &ast::AttrKind) -> bool {
         let d_annotatable = match &item {
             Annotatable::AssocItem(_, _) => {
                 let assoc_item: AssocItemKind = ast::AssocItemKind::Fn(asdf);
-                let d_fn = P(ast::AssocItem {
+                let d_fn = Box::new(ast::AssocItem {
                     attrs: thin_vec![d_attr, inline_never],
                     id: ast::DUMMY_NODE_ID,
                     span,
@@ -453,7 +452,7 @@ fn same_attribute(attr: &ast::AttrKind, item: &ast::AttrKind) -> bool {
                 let mut d_fn = ecx.item(span, thin_vec![d_attr, inline_never], ItemKind::Fn(asdf));
                 d_fn.vis = vis;
 
-                Annotatable::Stmt(P(ast::Stmt {
+                Annotatable::Stmt(Box::new(ast::Stmt {
                     id: ast::DUMMY_NODE_ID,
                     kind: ast::StmtKind::Item(d_fn),
                     span,
@@ -506,7 +505,7 @@ fn init_body_helper(
         idents: &[Ident],
         errored: bool,
         generics: &Generics,
-    ) -> (P<ast::Block>, P<ast::Expr>, P<ast::Expr>, P<ast::Expr>) {
+    ) -> (Box<ast::Block>, Box<ast::Expr>, Box<ast::Expr>, Box<ast::Expr>) {
         let blackbox_path = ecx.std_path(&[sym::hint, sym::black_box]);
         let noop = ast::InlineAsm {
             asm_macro: ast::AsmMacro::Asm,
@@ -517,7 +516,7 @@ fn init_body_helper(
             options: ast::InlineAsmOptions::PURE | ast::InlineAsmOptions::NOMEM,
             line_spans: vec![],
         };
-        let noop_expr = ecx.expr_asm(span, P(noop));
+        let noop_expr = ecx.expr_asm(span, Box::new(noop));
         let unsf = ast::BlockCheckMode::Unsafe(ast::UnsafeSource::CompilerGenerated);
         let unsf_block = ast::Block {
             stmts: thin_vec![ecx.stmt_semi(noop_expr)],
@@ -526,7 +525,7 @@ fn init_body_helper(
             rules: unsf,
             span,
         };
-        let unsf_expr = ecx.expr_block(P(unsf_block));
+        let unsf_expr = ecx.expr_block(Box::new(unsf_block));
         let blackbox_call_expr = ecx.expr_path(ecx.path(span, blackbox_path));
         let primal_call = gen_primal_call(ecx, span, primal, idents, generics);
         let black_box_primal_call = ecx.expr_call(
@@ -578,7 +577,7 @@ fn gen_enzyme_body(
         idents: Vec<Ident>,
         errored: bool,
         generics: &Generics,
-    ) -> P<ast::Block> {
+    ) -> Box<ast::Block> {
         let new_decl_span = d_sig.span;
 
         // Just adding some default inline-asm and black_box usages to prevent early inlining
@@ -634,7 +633,7 @@ fn gen_enzyme_body(
             return body;
         }
 
-        let mut exprs: P<ast::Expr> = primal_call;
+        let mut exprs: Box<ast::Expr> = primal_call;
         let d_ret_ty = match d_sig.decl.output {
             FnRetTy::Ty(ref ty) => ty.clone(),
             FnRetTy::Default(span) => {
@@ -653,7 +652,7 @@ fn gen_enzyme_body(
             } else {
                 let q = QSelf { ty: d_ret_ty, path_span: span, position: 0 };
                 let y = ExprKind::Path(
-                    Some(P(q)),
+                    Some(Box::new(q)),
                     ecx.path_ident(span, Ident::with_dummy_span(kw::Default)),
                 );
                 let default_call_expr = ecx.expr(span, y);
@@ -703,7 +702,7 @@ fn gen_primal_call(
         primal: Ident,
         idents: &[Ident],
         generics: &Generics,
-    ) -> P<ast::Expr> {
+    ) -> Box<ast::Expr> {
         let has_self = idents.len() > 0 && idents[0].name == kw::SelfLower;
 
         if has_self {
@@ -740,7 +739,7 @@ fn gen_primal_call(
                                 },
                             );
 
-                            ast::AngleBracketedArg::Arg(ast::GenericArg::Type(P(ast::Ty {
+                            ast::AngleBracketedArg::Arg(ast::GenericArg::Type(Box::new(ast::Ty {
                                 id: type_param.id,
                                 span,
                                 kind: generic_param,
@@ -750,7 +749,7 @@ fn gen_primal_call(
                         .collect();
 
                     function_path.args =
-                        Some(P(ast::GenericArgs::AngleBracketed(ast::AngleBracketedArgs {
+                        Some(Box::new(ast::GenericArgs::AngleBracketed(ast::AngleBracketedArgs {
                             span,
                             args: generated_generic_types,
                         })));
@@ -856,7 +855,7 @@ fn gen_enzyme_decl(
                     for i in 0..x.width {
                         let mut shadow_arg = arg.clone();
                         // We += into the shadow in reverse mode.
-                        shadow_arg.ty = P(assure_mut_ref(&arg.ty));
+                        shadow_arg.ty = Box::new(assure_mut_ref(&arg.ty));
                         let old_name = if let PatKind::Ident(_, ident, _) = arg.pat.kind {
                             ident.name
                         } else {
@@ -866,7 +865,7 @@ fn gen_enzyme_decl(
                         let name: String = format!("d{}_{}", old_name, i);
                         new_inputs.push(name.clone());
                         let ident = Ident::from_str_and_span(&name, shadow_arg.pat.span);
-                        shadow_arg.pat = P(ast::Pat {
+                        shadow_arg.pat = Box::new(ast::Pat {
                             id: ast::DUMMY_NODE_ID,
                             kind: PatKind::Ident(BindingMode::NONE, ident, None),
                             span: shadow_arg.pat.span,
@@ -898,7 +897,7 @@ fn gen_enzyme_decl(
                         let name: String = format!("b{}_{}", old_name, i);
                         new_inputs.push(name.clone());
                         let ident = Ident::from_str_and_span(&name, shadow_arg.pat.span);
-                        shadow_arg.pat = P(ast::Pat {
+                        shadow_arg.pat = Box::new(ast::Pat {
                             id: ast::DUMMY_NODE_ID,
                             kind: PatKind::Ident(BindingMode::NONE, ident, None),
                             span: shadow_arg.pat.span,
@@ -942,7 +941,7 @@ fn gen_enzyme_decl(
                     let shadow_arg = ast::Param {
                         attrs: ThinVec::new(),
                         ty: ty.clone(),
-                        pat: P(ast::Pat {
+                        pat: Box::new(ast::Pat {
                             id: ast::DUMMY_NODE_ID,
                             kind: PatKind::Ident(BindingMode::NONE, ident, None),
                             span: ty.span,
@@ -966,7 +965,12 @@ fn gen_enzyme_decl(
                 FnRetTy::Default(span) => {
                     // We want to return std::hint::black_box(()).
                     let kind = TyKind::Tup(ThinVec::new());
-                    let ty = P(rustc_ast::Ty { kind, id: ast::DUMMY_NODE_ID, span, tokens: None });
+                    let ty = Box::new(rustc_ast::Ty {
+                        kind,
+                        id: ast::DUMMY_NODE_ID,
+                        span,
+                        tokens: None,
+                    });
                     d_decl.output = FnRetTy::Ty(ty.clone());
                     assert!(matches!(x.ret_activity, DiffActivity::None));
                     // this won't be used below, so any type would be fine.
@@ -987,7 +991,7 @@ fn gen_enzyme_decl(
                     };
                     TyKind::Array(ty.clone(), anon_const)
                 };
-                let ty = P(rustc_ast::Ty { kind, id: ty.id, span: ty.span, tokens: None });
+                let ty = Box::new(rustc_ast::Ty { kind, id: ty.id, span: ty.span, tokens: None });
                 d_decl.output = FnRetTy::Ty(ty);
             }
             if matches!(x.ret_activity, DiffActivity::DualOnly | DiffActivity::DualvOnly) {
@@ -1000,7 +1004,8 @@ fn gen_enzyme_decl(
                         value: ecx.expr_usize(span, x.width as usize),
                     };
                     let kind = TyKind::Array(ty.clone(), anon_const);
-                    let ty = P(rustc_ast::Ty { kind, id: ty.id, span: ty.span, tokens: None });
+                    let ty =
+                        Box::new(rustc_ast::Ty { kind, id: ty.id, span: ty.span, tokens: None });
                     d_decl.output = FnRetTy::Ty(ty);
                 }
             }
@@ -1022,14 +1027,14 @@ fn gen_enzyme_decl(
                         act_ret.insert(0, ty.clone());
                     }
                     let kind = TyKind::Tup(act_ret);
-                    P(rustc_ast::Ty { kind, id: ty.id, span: ty.span, tokens: None })
+                    Box::new(rustc_ast::Ty { kind, id: ty.id, span: ty.span, tokens: None })
                 }
                 FnRetTy::Default(span) => {
                     if act_ret.len() == 1 {
                         act_ret[0].clone()
                     } else {
                         let kind = TyKind::Tup(act_ret.iter().map(|arg| arg.clone()).collect());
-                        P(rustc_ast::Ty { kind, id: ast::DUMMY_NODE_ID, span, tokens: None })
+                        Box::new(rustc_ast::Ty { kind, id: ast::DUMMY_NODE_ID, span, tokens: None })
                     }
                 }
             };
diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs
index ec3b874..dd770fe 100644
--- a/compiler/rustc_builtin_macros/src/cfg_eval.rs
+++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs
@@ -2,7 +2,6 @@
 
 use rustc_ast as ast;
 use rustc_ast::mut_visit::MutVisitor;
-use rustc_ast::ptr::P;
 use rustc_ast::visit::{AssocCtxt, Visitor};
 use rustc_ast::{Attribute, HasAttrs, HasTokens, NodeId, mut_visit, visit};
 use rustc_errors::PResult;
@@ -132,7 +131,7 @@ fn configure_annotatable(mut self, annotatable: Annotatable) -> Annotatable {
                     let stmt = parser
                         .parse_stmt_without_recovery(false, ForceCollect::Yes, false)?
                         .unwrap();
-                    Annotatable::Stmt(P(self.flat_map_stmt(stmt).pop().unwrap()))
+                    Annotatable::Stmt(Box::new(self.flat_map_stmt(stmt).pop().unwrap()))
                 }
                 Annotatable::Expr(_) => {
                     let mut expr = parser.parse_expr_force_collect()?;
@@ -166,7 +165,7 @@ fn visit_method_receiver_expr(&mut self, expr: &mut ast::Expr) {
         mut_visit::walk_expr(self, expr);
     }
 
-    fn filter_map_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
+    fn filter_map_expr(&mut self, expr: Box<ast::Expr>) -> Option<Box<ast::Expr>> {
         let mut expr = configure!(self, expr);
         mut_visit::walk_expr(self, &mut expr);
         Some(expr)
@@ -185,24 +184,24 @@ fn flat_map_generic_param(
         mut_visit::walk_flat_map_stmt(self, stmt)
     }
 
-    fn flat_map_item(&mut self, item: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
+    fn flat_map_item(&mut self, item: Box<ast::Item>) -> SmallVec<[Box<ast::Item>; 1]> {
         let item = configure!(self, item);
         mut_visit::walk_flat_map_item(self, item)
     }
 
     fn flat_map_assoc_item(
         &mut self,
-        item: P<ast::AssocItem>,
+        item: Box<ast::AssocItem>,
         ctxt: AssocCtxt,
-    ) -> SmallVec<[P<ast::AssocItem>; 1]> {
+    ) -> SmallVec<[Box<ast::AssocItem>; 1]> {
         let item = configure!(self, item);
         mut_visit::walk_flat_map_assoc_item(self, item, ctxt)
     }
 
     fn flat_map_foreign_item(
         &mut self,
-        foreign_item: P<ast::ForeignItem>,
-    ) -> SmallVec<[P<ast::ForeignItem>; 1]> {
+        foreign_item: Box<ast::ForeignItem>,
+    ) -> SmallVec<[Box<ast::ForeignItem>; 1]> {
         let foreign_item = configure!(self, foreign_item);
         mut_visit::walk_flat_map_foreign_item(self, foreign_item)
     }
diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs
index fd2d740..8885017 100644
--- a/compiler/rustc_builtin_macros/src/concat_bytes.rs
+++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs
@@ -1,4 +1,3 @@
-use rustc_ast::ptr::P;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::{ExprKind, LitIntType, LitKind, StrStyle, UintTy, token};
 use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
@@ -90,7 +89,7 @@ fn handle_array_element(
     cx: &ExtCtxt<'_>,
     guar: &mut Option<ErrorGuaranteed>,
     missing_literals: &mut Vec<rustc_span::Span>,
-    expr: &P<rustc_ast::Expr>,
+    expr: &Box<rustc_ast::Expr>,
 ) -> Option<u8> {
     let dcx = cx.dcx();
 
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
index 990835f..a0f71a1 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
@@ -1,4 +1,3 @@
-use rustc_ast::ptr::P;
 use rustc_ast::{BinOpKind, BorrowKind, Expr, ExprKind, MetaItem, Mutability};
 use rustc_expand::base::{Annotatable, ExtCtxt};
 use rustc_span::{Span, sym};
@@ -119,7 +118,7 @@ fn get_substructure_equality_expr(
     cx: &ExtCtxt<'_>,
     span: Span,
     substructure: &Substructure<'_>,
-) -> P<Expr> {
+) -> Box<Expr> {
     use SubstructureFields::*;
 
     match substructure.fields {
@@ -180,7 +179,7 @@ fn get_substructure_equality_expr(
 ///
 /// Panics if there are not exactly two arguments to compare (should be `self`
 /// and `other`).
-fn get_field_equality_expr(cx: &ExtCtxt<'_>, field: &FieldInfo) -> P<Expr> {
+fn get_field_equality_expr(cx: &ExtCtxt<'_>, field: &FieldInfo) -> Box<Expr> {
     let [rhs] = &field.other_selflike_exprs[..] else {
         cx.dcx().span_bug(field.span, "not exactly 2 arguments in `derive(PartialEq)`");
     };
@@ -198,7 +197,7 @@ fn get_field_equality_expr(cx: &ExtCtxt<'_>, field: &FieldInfo) -> P<Expr> {
 /// This is used to strip away any number of leading `&` from an expression
 /// (e.g., `&&&T` becomes `T`). Only removes immutable references; mutable
 /// references are preserved.
-fn peel_refs(mut expr: &P<Expr>) -> P<Expr> {
+fn peel_refs(mut expr: &Box<Expr>) -> Box<Expr> {
     while let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = &expr.kind {
         expr = &inner;
     }
@@ -210,7 +209,7 @@ fn peel_refs(mut expr: &P<Expr>) -> P<Expr> {
 ///
 /// If the given expression is a block, it is wrapped in parentheses; otherwise,
 /// it is returned unchanged.
-fn wrap_block_expr(cx: &ExtCtxt<'_>, expr: P<Expr>) -> P<Expr> {
+fn wrap_block_expr(cx: &ExtCtxt<'_>, expr: Box<Expr>) -> Box<Expr> {
     if matches!(&expr.kind, ExprKind::Block(..)) {
         return cx.expr_paren(expr.span, expr);
     }
diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs
index 1d63ce7..597af0e 100644
--- a/compiler/rustc_builtin_macros/src/deriving/debug.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs
@@ -94,7 +94,7 @@ fn expr_for_field(
         field: &FieldInfo,
         index: usize,
         len: usize,
-    ) -> ast::ptr::P<ast::Expr> {
+    ) -> Box<ast::Expr> {
         if index < len - 1 {
             field.self_expr.clone()
         } else {
diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index b4e2d27..2462114e 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -56,7 +56,7 @@ pub(crate) fn expand_deriving_default(
     trait_def.expand(cx, mitem, item, push)
 }
 
-fn default_call(cx: &ExtCtxt<'_>, span: Span) -> ast::ptr::P<ast::Expr> {
+fn default_call(cx: &ExtCtxt<'_>, span: Span) -> Box<ast::Expr> {
     // Note that `kw::Default` is "default" and `sym::Default` is "Default"!
     let default_ident = cx.std_path(&[kw::Default, sym::Default, kw::Default]);
     cx.expr_call_global(span, default_ident, ThinVec::new())
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index fc9eed2..3f4b471 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -180,7 +180,6 @@
 
 pub(crate) use StaticFields::*;
 pub(crate) use SubstructureFields::*;
-use rustc_ast::ptr::P;
 use rustc_ast::token::{IdentIsRaw, LitKind, Token, TokenKind};
 use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenTree};
 use rustc_ast::{
@@ -272,7 +271,7 @@ pub(crate) struct Substructure<'a> {
     pub type_ident: Ident,
     /// Verbatim access to any non-selflike arguments, i.e. arguments that
     /// don't have type `&Self`.
-    pub nonselflike_args: &'a [P<Expr>],
+    pub nonselflike_args: &'a [Box<Expr>],
     pub fields: &'a SubstructureFields<'a>,
 }
 
@@ -284,10 +283,10 @@ pub(crate) struct FieldInfo {
     pub name: Option<Ident>,
     /// The expression corresponding to this field of `self`
     /// (specifically, a reference to it).
-    pub self_expr: P<Expr>,
+    pub self_expr: Box<Expr>,
     /// The expressions corresponding to references to this field in
     /// the other selflike arguments.
-    pub other_selflike_exprs: Vec<P<Expr>>,
+    pub other_selflike_exprs: Vec<Box<Expr>>,
     pub maybe_scalar: bool,
 }
 
@@ -323,7 +322,7 @@ pub(crate) enum SubstructureFields<'a> {
     /// The discriminant of an enum. The first field is a `FieldInfo` for the discriminants, as
     /// if they were fields. The second field is the expression to combine the
     /// discriminant expression with; it will be `None` if no match is necessary.
-    EnumDiscr(FieldInfo, Option<P<Expr>>),
+    EnumDiscr(FieldInfo, Option<Box<Expr>>),
 
     /// A static method where `Self` is a struct.
     StaticStruct(&'a ast::VariantData, StaticFields),
@@ -345,7 +344,7 @@ pub(crate) fn combine_substructure(
 
 struct TypeParameter {
     bound_generic_params: ThinVec<ast::GenericParam>,
-    ty: P<ast::Ty>,
+    ty: Box<ast::Ty>,
 }
 
 /// The code snippets built up for derived code are sometimes used as blocks
@@ -354,23 +353,23 @@ struct TypeParameter {
 /// avoiding the insertion of any unnecessary blocks.
 ///
 /// The statements come before the expression.
-pub(crate) struct BlockOrExpr(ThinVec<ast::Stmt>, Option<P<Expr>>);
+pub(crate) struct BlockOrExpr(ThinVec<ast::Stmt>, Option<Box<Expr>>);
 
 impl BlockOrExpr {
     pub(crate) fn new_stmts(stmts: ThinVec<ast::Stmt>) -> BlockOrExpr {
         BlockOrExpr(stmts, None)
     }
 
-    pub(crate) fn new_expr(expr: P<Expr>) -> BlockOrExpr {
+    pub(crate) fn new_expr(expr: Box<Expr>) -> BlockOrExpr {
         BlockOrExpr(ThinVec::new(), Some(expr))
     }
 
-    pub(crate) fn new_mixed(stmts: ThinVec<ast::Stmt>, expr: Option<P<Expr>>) -> BlockOrExpr {
+    pub(crate) fn new_mixed(stmts: ThinVec<ast::Stmt>, expr: Option<Box<Expr>>) -> BlockOrExpr {
         BlockOrExpr(stmts, expr)
     }
 
     // Converts it into a block.
-    fn into_block(mut self, cx: &ExtCtxt<'_>, span: Span) -> P<ast::Block> {
+    fn into_block(mut self, cx: &ExtCtxt<'_>, span: Span) -> Box<ast::Block> {
         if let Some(expr) = self.1 {
             self.0.push(cx.stmt_expr(expr));
         }
@@ -378,7 +377,7 @@ fn into_block(mut self, cx: &ExtCtxt<'_>, span: Span) -> P<ast::Block> {
     }
 
     // Converts it into an expression.
-    fn into_expr(self, cx: &ExtCtxt<'_>, span: Span) -> P<Expr> {
+    fn into_expr(self, cx: &ExtCtxt<'_>, span: Span) -> Box<Expr> {
         if self.0.is_empty() {
             match self.1 {
                 None => cx.expr_block(cx.block(span, ThinVec::new())),
@@ -432,7 +431,7 @@ fn visit_ty(&mut self, ty: &'a ast::Ty) {
             {
                 self.type_params.push(TypeParameter {
                     bound_generic_params: self.bound_generic_params_stack.clone(),
-                    ty: P(ty.clone()),
+                    ty: Box::new(ty.clone()),
                 });
             }
 
@@ -544,7 +543,7 @@ pub(crate) fn expand_ext(
                         })
                         .cloned(),
                 );
-                push(Annotatable::Item(P(ast::Item { attrs, ..(*newitem).clone() })))
+                push(Annotatable::Item(Box::new(ast::Item { attrs, ..(*newitem).clone() })))
             }
             _ => unreachable!(),
         }
@@ -590,15 +589,15 @@ fn create_derived_impl(
         cx: &ExtCtxt<'_>,
         type_ident: Ident,
         generics: &Generics,
-        field_tys: Vec<P<ast::Ty>>,
-        methods: Vec<P<ast::AssocItem>>,
+        field_tys: Vec<Box<ast::Ty>>,
+        methods: Vec<Box<ast::AssocItem>>,
         is_packed: bool,
-    ) -> P<ast::Item> {
+    ) -> Box<ast::Item> {
         let trait_path = self.path.to_path(cx, self.span, type_ident, generics);
 
         // Transform associated types from `deriving::ty::Ty` into `ast::AssocItem`
         let associated_types = self.associated_types.iter().map(|&(ident, ref type_def)| {
-            P(ast::AssocItem {
+            Box::new(ast::AssocItem {
                 id: ast::DUMMY_NODE_ID,
                 span: self.span,
                 vis: ast::Visibility {
@@ -853,8 +852,8 @@ fn expand_struct_def(
         generics: &Generics,
         from_scratch: bool,
         is_packed: bool,
-    ) -> P<ast::Item> {
-        let field_tys: Vec<P<ast::Ty>> =
+    ) -> Box<ast::Item> {
+        let field_tys: Vec<Box<ast::Ty>> =
             struct_def.fields().iter().map(|field| field.ty.clone()).collect();
 
         let methods = self
@@ -906,7 +905,7 @@ fn expand_enum_def(
         type_ident: Ident,
         generics: &Generics,
         from_scratch: bool,
-    ) -> P<ast::Item> {
+    ) -> Box<ast::Item> {
         let mut field_tys = Vec::new();
 
         for variant in &enum_def.variants {
@@ -962,7 +961,7 @@ fn call_substructure_method(
         cx: &ExtCtxt<'_>,
         trait_: &TraitDef<'_>,
         type_ident: Ident,
-        nonselflike_args: &[P<Expr>],
+        nonselflike_args: &[Box<Expr>],
         fields: &SubstructureFields<'_>,
     ) -> BlockOrExpr {
         let span = trait_.span;
@@ -978,7 +977,7 @@ fn get_ret_ty(
         trait_: &TraitDef<'_>,
         generics: &Generics,
         type_ident: Ident,
-    ) -> P<ast::Ty> {
+    ) -> Box<ast::Ty> {
         self.ret_ty.to_ty(cx, trait_.span, type_ident, generics)
     }
 
@@ -999,7 +998,8 @@ fn extract_arg_details(
         trait_: &TraitDef<'_>,
         type_ident: Ident,
         generics: &Generics,
-    ) -> (Option<ast::ExplicitSelf>, ThinVec<P<Expr>>, Vec<P<Expr>>, Vec<(Ident, P<ast::Ty>)>) {
+    ) -> (Option<ast::ExplicitSelf>, ThinVec<Box<Expr>>, Vec<Box<Expr>>, Vec<(Ident, Box<ast::Ty>)>)
+    {
         let mut selflike_args = ThinVec::new();
         let mut nonselflike_args = Vec::new();
         let mut nonself_arg_tys = Vec::new();
@@ -1036,9 +1036,9 @@ fn create_method(
         type_ident: Ident,
         generics: &Generics,
         explicit_self: Option<ast::ExplicitSelf>,
-        nonself_arg_tys: Vec<(Ident, P<ast::Ty>)>,
+        nonself_arg_tys: Vec<(Ident, Box<ast::Ty>)>,
         body: BlockOrExpr,
-    ) -> P<ast::AssocItem> {
+    ) -> Box<ast::AssocItem> {
         let span = trait_.span;
         // Create the generics that aren't for `Self`.
         let fn_generics = self.generics.to_generics(cx, span, type_ident, generics);
@@ -1065,7 +1065,7 @@ fn create_method(
         let defaultness = ast::Defaultness::Final;
 
         // Create the method.
-        P(ast::AssocItem {
+        Box::new(ast::AssocItem {
             id: ast::DUMMY_NODE_ID,
             attrs: self.attributes.clone(),
             span,
@@ -1128,8 +1128,8 @@ fn expand_struct_method_body<'b>(
         trait_: &TraitDef<'b>,
         struct_def: &'b VariantData,
         type_ident: Ident,
-        selflike_args: &[P<Expr>],
-        nonselflike_args: &[P<Expr>],
+        selflike_args: &[Box<Expr>],
+        nonselflike_args: &[Box<Expr>],
         is_packed: bool,
     ) -> BlockOrExpr {
         assert!(selflike_args.len() == 1 || selflike_args.len() == 2);
@@ -1151,7 +1151,7 @@ fn expand_static_struct_method_body(
         trait_: &TraitDef<'_>,
         struct_def: &VariantData,
         type_ident: Ident,
-        nonselflike_args: &[P<Expr>],
+        nonselflike_args: &[Box<Expr>],
     ) -> BlockOrExpr {
         let summary = trait_.summarise_struct(cx, struct_def);
 
@@ -1205,8 +1205,8 @@ fn expand_enum_method_body<'b>(
         trait_: &TraitDef<'b>,
         enum_def: &'b EnumDef,
         type_ident: Ident,
-        mut selflike_args: ThinVec<P<Expr>>,
-        nonselflike_args: &[P<Expr>],
+        mut selflike_args: ThinVec<Box<Expr>>,
+        nonselflike_args: &[Box<Expr>],
     ) -> BlockOrExpr {
         assert!(
             !selflike_args.is_empty(),
@@ -1418,7 +1418,7 @@ fn expand_enum_method_body<'b>(
         //          ...
         //          _ => ::core::intrinsics::unreachable(),
         //      }
-        let get_match_expr = |mut selflike_args: ThinVec<P<Expr>>| {
+        let get_match_expr = |mut selflike_args: ThinVec<Box<Expr>>| {
             let match_arg = if selflike_args.len() == 1 {
                 selflike_args.pop().unwrap()
             } else {
@@ -1454,7 +1454,7 @@ fn expand_static_enum_method_body(
         trait_: &TraitDef<'_>,
         enum_def: &EnumDef,
         type_ident: Ident,
-        nonselflike_args: &[P<Expr>],
+        nonselflike_args: &[Box<Expr>],
     ) -> BlockOrExpr {
         self.call_substructure_method(
             cx,
@@ -1503,7 +1503,7 @@ fn create_struct_patterns(
         struct_def: &'a VariantData,
         prefixes: &[String],
         by_ref: ByRef,
-    ) -> ThinVec<P<ast::Pat>> {
+    ) -> ThinVec<Box<ast::Pat>> {
         prefixes
             .iter()
             .map(|prefix| {
@@ -1558,7 +1558,7 @@ fn create_struct_patterns(
 
     fn create_fields<F>(&self, struct_def: &'a VariantData, mk_exprs: F) -> Vec<FieldInfo>
     where
-        F: Fn(usize, &ast::FieldDef, Span) -> Vec<P<ast::Expr>>,
+        F: Fn(usize, &ast::FieldDef, Span) -> Vec<Box<ast::Expr>>,
     {
         struct_def
             .fields()
@@ -1606,7 +1606,7 @@ fn create_struct_pattern_fields(
     fn create_struct_field_access_fields(
         &self,
         cx: &ExtCtxt<'_>,
-        selflike_args: &[P<Expr>],
+        selflike_args: &[Box<Expr>],
         struct_def: &'a VariantData,
         is_packed: bool,
     ) -> Vec<FieldInfo> {
@@ -1651,7 +1651,7 @@ pub(crate) enum CsFold<'a> {
 
     /// The combination of two field expressions. E.g. for `PartialEq::eq` this
     /// is something like `<field1 equality> && <field2 equality>`.
-    Combine(Span, P<Expr>, P<Expr>),
+    Combine(Span, Box<Expr>, Box<Expr>),
 
     // The fallback case for a struct or enum variant with no fields.
     Fieldless,
@@ -1665,9 +1665,9 @@ pub(crate) fn cs_fold<F>(
     trait_span: Span,
     substructure: &Substructure<'_>,
     mut f: F,
-) -> P<Expr>
+) -> Box<Expr>
 where
-    F: FnMut(&ExtCtxt<'_>, CsFold<'_>) -> P<Expr>,
+    F: FnMut(&ExtCtxt<'_>, CsFold<'_>) -> Box<Expr>,
 {
     match substructure.fields {
         EnumMatching(.., all_fields) | Struct(_, all_fields) => {
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
index f34a6ae..00e70b2 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
@@ -2,7 +2,6 @@
 //! when specifying impls to be derived.
 
 pub(crate) use Ty::*;
-use rustc_ast::ptr::P;
 use rustc_ast::{self as ast, Expr, GenericArg, GenericParamKind, Generics, SelfKind};
 use rustc_expand::base::ExtCtxt;
 use rustc_span::source_map::respan;
@@ -41,7 +40,7 @@ pub(crate) fn to_ty(
         span: Span,
         self_ty: Ident,
         self_generics: &Generics,
-    ) -> P<ast::Ty> {
+    ) -> Box<ast::Ty> {
         cx.ty_path(self.to_path(cx, span, self_ty, self_generics))
     }
     pub(crate) fn to_path(
@@ -90,7 +89,7 @@ pub(crate) fn to_ty(
         span: Span,
         self_ty: Ident,
         self_generics: &Generics,
-    ) -> P<ast::Ty> {
+    ) -> Box<ast::Ty> {
         match self {
             Ref(ty, mutbl) => {
                 let raw_ty = ty.to_ty(cx, span, self_ty, self_generics);
@@ -192,7 +191,7 @@ pub(crate) fn to_generics(
     }
 }
 
-pub(crate) fn get_explicit_self(cx: &ExtCtxt<'_>, span: Span) -> (P<Expr>, ast::ExplicitSelf) {
+pub(crate) fn get_explicit_self(cx: &ExtCtxt<'_>, span: Span) -> (Box<Expr>, ast::ExplicitSelf) {
     // This constructs a fresh `self` path.
     let self_path = cx.expr_self(span);
     let self_ty = respan(span, SelfKind::Region(None, ast::Mutability::Not));
diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs
index e45d09b..1edc296 100644
--- a/compiler/rustc_builtin_macros/src/deriving/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs
@@ -1,7 +1,6 @@
 //! The compiler code necessary to implement the `#[derive]` extensions.
 
 use rustc_ast as ast;
-use rustc_ast::ptr::P;
 use rustc_ast::{GenericArg, MetaItem};
 use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier};
 use rustc_span::{Span, Symbol, sym};
@@ -66,7 +65,7 @@ fn expand(
                         &mut |a| {
                             // Cannot use 'ecx.stmt_item' here, because we need to pass 'ecx'
                             // to the function
-                            items.push(Annotatable::Stmt(P(ast::Stmt {
+                            items.push(Annotatable::Stmt(Box::new(ast::Stmt {
                                 id: ast::DUMMY_NODE_ID,
                                 kind: ast::StmtKind::Item(a.expect_item()),
                                 span,
@@ -91,20 +90,20 @@ fn call_intrinsic(
     cx: &ExtCtxt<'_>,
     span: Span,
     intrinsic: Symbol,
-    args: ThinVec<P<ast::Expr>>,
-) -> P<ast::Expr> {
+    args: ThinVec<Box<ast::Expr>>,
+) -> Box<ast::Expr> {
     let span = cx.with_def_site_ctxt(span);
     let path = cx.std_path(&[sym::intrinsics, intrinsic]);
     cx.expr_call_global(span, path, args)
 }
 
 /// Constructs an expression that calls the `unreachable` intrinsic.
-fn call_unreachable(cx: &ExtCtxt<'_>, span: Span) -> P<ast::Expr> {
+fn call_unreachable(cx: &ExtCtxt<'_>, span: Span) -> Box<ast::Expr> {
     let span = cx.with_def_site_ctxt(span);
     let path = cx.std_path(&[sym::intrinsics, sym::unreachable]);
     let call = cx.expr_call_global(span, path, ThinVec::new());
 
-    cx.expr_block(P(ast::Block {
+    cx.expr_block(Box::new(ast::Block {
         stmts: thin_vec![cx.stmt_expr(call)],
         id: ast::DUMMY_NODE_ID,
         rules: ast::BlockCheckMode::Unsafe(ast::CompilerGenerated),
@@ -116,7 +115,7 @@ fn call_unreachable(cx: &ExtCtxt<'_>, span: Span) -> P<ast::Expr> {
 fn assert_ty_bounds(
     cx: &ExtCtxt<'_>,
     stmts: &mut ThinVec<ast::Stmt>,
-    ty: P<ast::Ty>,
+    ty: Box<ast::Ty>,
     span: Span,
     assert_path: &[Symbol],
 ) {
diff --git a/compiler/rustc_builtin_macros/src/edition_panic.rs b/compiler/rustc_builtin_macros/src/edition_panic.rs
index ccfcc30..08f555b 100644
--- a/compiler/rustc_builtin_macros/src/edition_panic.rs
+++ b/compiler/rustc_builtin_macros/src/edition_panic.rs
@@ -1,4 +1,3 @@
-use rustc_ast::ptr::P;
 use rustc_ast::token::Delimiter;
 use rustc_ast::tokenstream::{DelimSpan, TokenStream};
 use rustc_ast::*;
@@ -48,7 +47,7 @@ fn expand<'cx>(
     ExpandResult::Ready(MacEager::expr(
         cx.expr(
             sp,
-            ExprKind::MacCall(P(MacCall {
+            ExprKind::MacCall(Box::new(MacCall {
                 path: Path {
                     span: sp,
                     segments: cx
@@ -58,7 +57,7 @@ fn expand<'cx>(
                         .collect(),
                     tokens: None,
                 },
-                args: P(DelimArgs {
+                args: Box::new(DelimArgs {
                     dspan: DelimSpan::from_single(sp),
                     delim: Delimiter::Parenthesis,
                     tokens: tts,
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 6785cb6..ec613b7 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -1,7 +1,6 @@
 use std::ops::Range;
 
 use parse::Position::ArgumentNamed;
-use rustc_ast::ptr::P;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::{
     Expr, ExprKind, FormatAlignment, FormatArgPosition, FormatArgPositionKind, FormatArgs,
@@ -45,7 +44,7 @@ enum PositionUsedAs {
 
 #[derive(Debug)]
 struct MacroInput {
-    fmtstr: P<Expr>,
+    fmtstr: Box<Expr>,
     args: FormatArguments,
     /// Whether the first argument was a string literal or a result from eager macro expansion.
     /// If it's not a string literal, we disallow implicit argument capturing.
@@ -1018,7 +1017,7 @@ fn expand_format_args_impl<'cx>(
             };
             match mac {
                 Ok(format_args) => {
-                    MacEager::expr(ecx.expr(sp, ExprKind::FormatArgs(P(format_args))))
+                    MacEager::expr(ecx.expr(sp, ExprKind::FormatArgs(Box::new(format_args))))
                 }
                 Err(guar) => MacEager::expr(DummyResult::raw_expr(sp, Some(guar))),
             }
diff --git a/compiler/rustc_builtin_macros/src/format_foreign.rs b/compiler/rustc_builtin_macros/src/format_foreign.rs
index 13d5b42..3e5a26c 100644
--- a/compiler/rustc_builtin_macros/src/format_foreign.rs
+++ b/compiler/rustc_builtin_macros/src/format_foreign.rs
@@ -346,18 +346,18 @@ fn parse_next_substitution(s: &str) -> Option<(Substitution<'_>, &str)> {
         // ```regex
         // (?x)
         // ^ %
-        // (?: (?P<parameter> \d+) \$ )?
-        // (?P<flags> [-+ 0\#']* )
-        // (?P<width> \d+ | \* (?: (?P<widtha> \d+) \$ )? )?
-        // (?: \. (?P<precision> \d+ | \* (?: (?P<precisiona> \d+) \$ )? ) )?
-        // (?P<length>
+        // (?: (?Box<parameter> \d+) \$ )?
+        // (?Box<flags> [-+ 0\#']* )
+        // (?Box<width> \d+ | \* (?: (?Box<widtha> \d+) \$ )? )?
+        // (?: \. (?Box<precision> \d+ | \* (?: (?Box<precisiona> \d+) \$ )? ) )?
+        // (?Box<length>
         //     # Standard
         //     hh | h | ll | l | L | z | j | t
         //
         //     # Other
         //     | I32 | I64 | I | q
         // )?
-        // (?P<type> . )
+        // (?Box<type> . )
         // ```
 
         // Used to establish the full span at the end.
diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs
index 4b1958b..f14b192 100644
--- a/compiler/rustc_builtin_macros/src/global_allocator.rs
+++ b/compiler/rustc_builtin_macros/src/global_allocator.rs
@@ -1,7 +1,6 @@
 use rustc_ast::expand::allocator::{
     ALLOCATOR_METHODS, AllocatorMethod, AllocatorMethodInput, AllocatorTy, global_fn_name,
 };
-use rustc_ast::ptr::P;
 use rustc_ast::{
     self as ast, AttrVec, Expr, Fn, FnHeader, FnSig, Generics, ItemKind, Mutability, Param, Safety,
     Stmt, StmtKind, Ty, TyKind,
@@ -51,7 +50,7 @@ pub(crate) fn expand(
     let const_body = ecx.expr_block(ecx.block(span, stmts));
     let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body);
     let const_item = if is_stmt {
-        Annotatable::Stmt(P(ecx.stmt_item(span, const_item)))
+        Annotatable::Stmt(Box::new(ecx.stmt_item(span, const_item)))
     } else {
         Annotatable::Item(const_item)
     };
@@ -90,7 +89,7 @@ fn allocator_fn(&self, method: &AllocatorMethod) -> Stmt {
         self.cx.stmt_item(self.ty_span, item)
     }
 
-    fn call_allocator(&self, method: Symbol, mut args: ThinVec<P<Expr>>) -> P<Expr> {
+    fn call_allocator(&self, method: Symbol, mut args: ThinVec<Box<Expr>>) -> Box<Expr> {
         let method = self.cx.std_path(&[sym::alloc, sym::GlobalAlloc, method]);
         let method = self.cx.expr_path(self.cx.path(self.ty_span, method));
         let allocator = self.cx.path_ident(self.ty_span, self.global);
@@ -105,7 +104,7 @@ fn attrs(&self) -> AttrVec {
         thin_vec![self.cx.attr_word(sym::rustc_std_internal_symbol, self.span)]
     }
 
-    fn arg_ty(&self, input: &AllocatorMethodInput, args: &mut ThinVec<Param>) -> P<Expr> {
+    fn arg_ty(&self, input: &AllocatorMethodInput, args: &mut ThinVec<Param>) -> Box<Expr> {
         match input.ty {
             AllocatorTy::Layout => {
                 // If an allocator method is ever introduced having multiple
@@ -148,7 +147,7 @@ fn arg_ty(&self, input: &AllocatorMethodInput, args: &mut ThinVec<Param>) -> P<E
         }
     }
 
-    fn ret_ty(&self, ty: &AllocatorTy) -> P<Ty> {
+    fn ret_ty(&self, ty: &AllocatorTy) -> Box<Ty> {
         match *ty {
             AllocatorTy::ResultPtr => self.ptr_u8(),
 
@@ -160,12 +159,12 @@ fn ret_ty(&self, ty: &AllocatorTy) -> P<Ty> {
         }
     }
 
-    fn usize(&self) -> P<Ty> {
+    fn usize(&self) -> Box<Ty> {
         let usize = self.cx.path_ident(self.span, Ident::new(sym::usize, self.span));
         self.cx.ty_path(usize)
     }
 
-    fn ptr_u8(&self) -> P<Ty> {
+    fn ptr_u8(&self) -> Box<Ty> {
         let u8 = self.cx.path_ident(self.span, Ident::new(sym::u8, self.span));
         let ty_u8 = self.cx.ty_path(u8);
         self.cx.ty_ptr(self.span, ty_u8, Mutability::Mut)
diff --git a/compiler/rustc_builtin_macros/src/iter.rs b/compiler/rustc_builtin_macros/src/iter.rs
index 7ad8390..e9f340e 100644
--- a/compiler/rustc_builtin_macros/src/iter.rs
+++ b/compiler/rustc_builtin_macros/src/iter.rs
@@ -1,4 +1,3 @@
-use rustc_ast::ptr::P;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::{CoroutineKind, DUMMY_NODE_ID, Expr, ast, token};
 use rustc_errors::PResult;
@@ -24,7 +23,7 @@ fn parse_closure<'a>(
     cx: &mut ExtCtxt<'a>,
     span: Span,
     stream: TokenStream,
-) -> PResult<'a, P<Expr>> {
+) -> PResult<'a, Box<Expr>> {
     let mut closure_parser = cx.new_parser_from_tts(stream);
 
     let coroutine_kind = Some(CoroutineKind::Gen {
diff --git a/compiler/rustc_builtin_macros/src/pattern_type.rs b/compiler/rustc_builtin_macros/src/pattern_type.rs
index b61af0b..34faafd 100644
--- a/compiler/rustc_builtin_macros/src/pattern_type.rs
+++ b/compiler/rustc_builtin_macros/src/pattern_type.rs
@@ -1,4 +1,3 @@
-use rustc_ast::ptr::P;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::{AnonConst, DUMMY_NODE_ID, Ty, TyPat, TyPatKind, ast, token};
 use rustc_errors::PResult;
@@ -22,7 +21,10 @@ pub(crate) fn expand<'cx>(
     ExpandResult::Ready(base::MacEager::ty(cx.ty(sp, ast::TyKind::Pat(ty, pat))))
 }
 
-fn parse_pat_ty<'a>(cx: &mut ExtCtxt<'a>, stream: TokenStream) -> PResult<'a, (P<Ty>, P<TyPat>)> {
+fn parse_pat_ty<'a>(
+    cx: &mut ExtCtxt<'a>,
+    stream: TokenStream,
+) -> PResult<'a, (Box<Ty>, Box<TyPat>)> {
     let mut parser = cx.new_parser_from_tts(stream);
 
     let ty = parser.parse_ty()?;
@@ -45,15 +47,15 @@ fn parse_pat_ty<'a>(cx: &mut ExtCtxt<'a>, stream: TokenStream) -> PResult<'a, (P
     Ok((ty, pat))
 }
 
-fn ty_pat(kind: TyPatKind, span: Span) -> P<TyPat> {
-    P(TyPat { id: DUMMY_NODE_ID, kind, span, tokens: None })
+fn ty_pat(kind: TyPatKind, span: Span) -> Box<TyPat> {
+    Box::new(TyPat { id: DUMMY_NODE_ID, kind, span, tokens: None })
 }
 
-fn pat_to_ty_pat(cx: &mut ExtCtxt<'_>, pat: ast::Pat) -> P<TyPat> {
+fn pat_to_ty_pat(cx: &mut ExtCtxt<'_>, pat: ast::Pat) -> Box<TyPat> {
     let kind = match pat.kind {
         ast::PatKind::Range(start, end, include_end) => TyPatKind::Range(
-            start.map(|value| P(AnonConst { id: DUMMY_NODE_ID, value })),
-            end.map(|value| P(AnonConst { id: DUMMY_NODE_ID, value })),
+            start.map(|value| Box::new(AnonConst { id: DUMMY_NODE_ID, value })),
+            end.map(|value| Box::new(AnonConst { id: DUMMY_NODE_ID, value })),
             include_end,
         ),
         ast::PatKind::Or(variants) => {
diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
index df70c93..f440adf 100644
--- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
+++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
@@ -1,6 +1,5 @@
 use std::{mem, slice};
 
-use rustc_ast::ptr::P;
 use rustc_ast::visit::{self, Visitor};
 use rustc_ast::{self as ast, HasNodeId, NodeId, attr};
 use rustc_ast_pretty::pprust;
@@ -286,7 +285,7 @@ fn visit_item(&mut self, item: &'a ast::Item) {
 //              // ...
 //          ];
 //      }
-fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
+fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> Box<ast::Item> {
     let expn_id = cx.resolver.expansion_for_ast_pass(
         DUMMY_SP,
         AstPass::ProcMacroHarness,
diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs
index ecfd46a..37bab5b 100644
--- a/compiler/rustc_builtin_macros/src/source_util.rs
+++ b/compiler/rustc_builtin_macros/src/source_util.rs
@@ -3,7 +3,6 @@
 use std::sync::Arc;
 
 use rustc_ast as ast;
-use rustc_ast::ptr::P;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::{join_path_idents, token};
 use rustc_ast_pretty::pprust;
@@ -144,7 +143,7 @@ struct ExpandInclude<'a> {
         node_id: ast::NodeId,
     }
     impl<'a> MacResult for ExpandInclude<'a> {
-        fn make_expr(mut self: Box<ExpandInclude<'a>>) -> Option<P<ast::Expr>> {
+        fn make_expr(mut self: Box<ExpandInclude<'a>>) -> Option<Box<ast::Expr>> {
             let expr = parse_expr(&mut self.p).ok()?;
             if self.p.token != token::Eof {
                 self.p.psess.buffer_lint(
@@ -157,7 +156,7 @@ fn make_expr(mut self: Box<ExpandInclude<'a>>) -> Option<P<ast::Expr>> {
             Some(expr)
         }
 
-        fn make_items(mut self: Box<ExpandInclude<'a>>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
+        fn make_items(mut self: Box<ExpandInclude<'a>>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
             let mut ret = SmallVec::new();
             loop {
                 match self.p.parse_item(ForceCollect::No) {
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index 7b57c02..7a189ee 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -4,7 +4,6 @@
 use std::assert_matches::assert_matches;
 use std::iter;
 
-use rustc_ast::ptr::P;
 use rustc_ast::{self as ast, GenericParamKind, HasNodeId, attr, join_path_idents};
 use rustc_ast_pretty::pprust;
 use rustc_attr_parsing::AttributeParser;
@@ -78,7 +77,7 @@ pub(crate) fn expand_test_case(
     }
 
     let ret = if is_stmt {
-        Annotatable::Stmt(P(ecx.stmt_item(item.span, item)))
+        Annotatable::Stmt(Box::new(ecx.stmt_item(item.span, item)))
     } else {
         Annotatable::Item(item)
     };
@@ -131,7 +130,7 @@ pub(crate) fn expand_test_or_bench(
     let ast::ItemKind::Fn(fn_) = &item.kind else {
         not_testable_error(cx, attr_sp, Some(&item));
         return if is_stmt {
-            vec![Annotatable::Stmt(P(cx.stmt_item(item.span, item)))]
+            vec![Annotatable::Stmt(Box::new(cx.stmt_item(item.span, item)))]
         } else {
             vec![Annotatable::Item(item)]
         };
@@ -155,7 +154,7 @@ pub(crate) fn expand_test_or_bench(
     };
     if check_result.is_err() {
         return if is_stmt {
-            vec![Annotatable::Stmt(P(cx.stmt_item(item.span, item)))]
+            vec![Annotatable::Stmt(Box::new(cx.stmt_item(item.span, item)))]
         } else {
             vec![Annotatable::Item(item)]
         };
@@ -201,7 +200,7 @@ pub(crate) fn expand_test_or_bench(
     // `-Cinstrument-coverage` builds.
     // This requires `#[allow_internal_unstable(coverage_attribute)]` on the
     // corresponding macro declaration in `core::macros`.
-    let coverage_off = |mut expr: P<ast::Expr>| {
+    let coverage_off = |mut expr: Box<ast::Expr>| {
         assert_matches!(expr.kind, ast::ExprKind::Closure(_));
         expr.attrs.push(cx.attr_nested_word(sym::coverage, sym::off, sp));
         expr
@@ -388,11 +387,11 @@ pub(crate) fn expand_test_or_bench(
     if is_stmt {
         vec![
             // Access to libtest under a hygienic name
-            Annotatable::Stmt(P(cx.stmt_item(sp, test_extern))),
+            Annotatable::Stmt(Box::new(cx.stmt_item(sp, test_extern))),
             // The generated test case
-            Annotatable::Stmt(P(cx.stmt_item(sp, test_const))),
+            Annotatable::Stmt(Box::new(cx.stmt_item(sp, test_const))),
             // The original item
-            Annotatable::Stmt(P(cx.stmt_item(sp, item))),
+            Annotatable::Stmt(Box::new(cx.stmt_item(sp, item))),
         ]
     } else {
         vec![
diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index 111c85d..e803f3b 100644
--- a/compiler/rustc_builtin_macros/src/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
@@ -5,7 +5,6 @@
 use rustc_ast as ast;
 use rustc_ast::entry::EntryPointType;
 use rustc_ast::mut_visit::*;
-use rustc_ast::ptr::P;
 use rustc_ast::visit::Visitor;
 use rustc_ast::{ModKind, attr};
 use rustc_errors::DiagCtxtHandle;
@@ -284,7 +283,7 @@ fn generate_test_harness(
 /// [`TestCtxt::reexport_test_harness_main`] provides a different name for the `main`
 /// function and [`TestCtxt::test_runner`] provides a path that replaces
 /// `test::test_main_static`.
-fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
+fn mk_main(cx: &mut TestCtxt<'_>) -> Box<ast::Item> {
     let sp = cx.def_site;
     let ecx = &cx.ext_cx;
     let test_ident = Ident::new(sym::test, sp);
@@ -348,7 +347,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
         define_opaque: None,
     }));
 
-    let main = P(ast::Item {
+    let main = Box::new(ast::Item {
         attrs: thin_vec![main_attr, coverage_attr, doc_hidden_attr],
         id: ast::DUMMY_NODE_ID,
         kind: main,
@@ -364,7 +363,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
 
 /// Creates a slice containing every test like so:
 /// &[&test1, &test2]
-fn mk_tests_slice(cx: &TestCtxt<'_>, sp: Span) -> P<ast::Expr> {
+fn mk_tests_slice(cx: &TestCtxt<'_>, sp: Span) -> Box<ast::Expr> {
     debug!("building test vector from {} tests", cx.test_cases.len());
     let ecx = &cx.ext_cx;
 
diff --git a/compiler/rustc_builtin_macros/src/util.rs b/compiler/rustc_builtin_macros/src/util.rs
index 38fec2b..f00c170 100644
--- a/compiler/rustc_builtin_macros/src/util.rs
+++ b/compiler/rustc_builtin_macros/src/util.rs
@@ -1,4 +1,3 @@
-use rustc_ast::ptr::P;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::{self as ast, AttrStyle, Attribute, MetaItem, attr, token};
 use rustc_errors::{Applicability, Diag, ErrorGuaranteed};
@@ -83,7 +82,7 @@ pub(crate) struct ExprToSpannedString {
 #[allow(rustc::untranslatable_diagnostic)]
 pub(crate) fn expr_to_spanned_string<'a>(
     cx: &'a mut ExtCtxt<'_>,
-    expr: P<ast::Expr>,
+    expr: Box<ast::Expr>,
     err_msg: &'static str,
 ) -> ExpandResult<ExprToSpannedStringResult<'a>, ()> {
     if !cx.force_mode
@@ -135,7 +134,7 @@ pub(crate) fn expr_to_spanned_string<'a>(
 /// compilation on error, merely emits a non-fatal error and returns `Err`.
 pub(crate) fn expr_to_string(
     cx: &mut ExtCtxt<'_>,
-    expr: P<ast::Expr>,
+    expr: Box<ast::Expr>,
     err_msg: &'static str,
 ) -> ExpandResult<Result<(Symbol, ast::StrStyle), ErrorGuaranteed>, ()> {
     expr_to_spanned_string(cx, expr, err_msg).map(|res| {
@@ -158,7 +157,7 @@ pub(crate) fn check_zero_tts(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream, nam
 }
 
 /// Parse an expression. On error, emit it, advancing to `Eof`, and return `Err`.
-pub(crate) fn parse_expr(p: &mut parser::Parser<'_>) -> Result<P<ast::Expr>, ErrorGuaranteed> {
+pub(crate) fn parse_expr(p: &mut parser::Parser<'_>) -> Result<Box<ast::Expr>, ErrorGuaranteed> {
     let guar = match p.parse_expr() {
         Ok(expr) => return Ok(expr),
         Err(err) => err.emit(),
@@ -209,7 +208,7 @@ pub(crate) fn get_single_expr_from_tts(
     span: Span,
     tts: TokenStream,
     name: &str,
-) -> ExpandResult<Result<P<ast::Expr>, ErrorGuaranteed>, ()> {
+) -> ExpandResult<Result<Box<ast::Expr>, ErrorGuaranteed>, ()> {
     let mut p = cx.new_parser_from_tts(tts);
     if p.token == token::Eof {
         let guar = cx.dcx().emit_err(errors::OnlyOneArgument { span, name });
@@ -232,7 +231,7 @@ pub(crate) fn get_single_expr_from_tts(
 pub(crate) fn get_exprs_from_tts(
     cx: &mut ExtCtxt<'_>,
     tts: TokenStream,
-) -> ExpandResult<Result<Vec<P<ast::Expr>>, ErrorGuaranteed>, ()> {
+) -> ExpandResult<Result<Vec<Box<ast::Expr>>, ErrorGuaranteed>, ()> {
     let mut p = cx.new_parser_from_tts(tts);
     let mut es = Vec::new();
     while p.token != token::Eof {
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 1a9832b..c234aa4 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -7,7 +7,6 @@
 use std::sync::Arc;
 
 use rustc_ast::attr::{AttributeExt, MarkedAttrs};
-use rustc_ast::ptr::P;
 use rustc_ast::token::MetaVarKind;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::visit::{AssocCtxt, Visitor};
@@ -45,11 +44,11 @@
 // to use `assign_id!`
 #[derive(Debug, Clone)]
 pub enum Annotatable {
-    Item(P<ast::Item>),
-    AssocItem(P<ast::AssocItem>, AssocCtxt),
-    ForeignItem(P<ast::ForeignItem>),
-    Stmt(P<ast::Stmt>),
-    Expr(P<ast::Expr>),
+    Item(Box<ast::Item>),
+    AssocItem(Box<ast::AssocItem>, AssocCtxt),
+    ForeignItem(Box<ast::ForeignItem>),
+    Stmt(Box<ast::Stmt>),
+    Expr(Box<ast::Expr>),
     Arm(ast::Arm),
     ExprField(ast::ExprField),
     PatField(ast::PatField),
@@ -141,28 +140,28 @@ pub fn to_tokens(&self) -> TokenStream {
         }
     }
 
-    pub fn expect_item(self) -> P<ast::Item> {
+    pub fn expect_item(self) -> Box<ast::Item> {
         match self {
             Annotatable::Item(i) => i,
             _ => panic!("expected Item"),
         }
     }
 
-    pub fn expect_trait_item(self) -> P<ast::AssocItem> {
+    pub fn expect_trait_item(self) -> Box<ast::AssocItem> {
         match self {
             Annotatable::AssocItem(i, AssocCtxt::Trait) => i,
             _ => panic!("expected Item"),
         }
     }
 
-    pub fn expect_impl_item(self) -> P<ast::AssocItem> {
+    pub fn expect_impl_item(self) -> Box<ast::AssocItem> {
         match self {
             Annotatable::AssocItem(i, AssocCtxt::Impl { .. }) => i,
             _ => panic!("expected Item"),
         }
     }
 
-    pub fn expect_foreign_item(self) -> P<ast::ForeignItem> {
+    pub fn expect_foreign_item(self) -> Box<ast::ForeignItem> {
         match self {
             Annotatable::ForeignItem(i) => i,
             _ => panic!("expected foreign item"),
@@ -176,7 +175,7 @@ pub fn expect_stmt(self) -> ast::Stmt {
         }
     }
 
-    pub fn expect_expr(self) -> P<ast::Expr> {
+    pub fn expect_expr(self) -> Box<ast::Expr> {
         match self {
             Annotatable::Expr(expr) => expr,
             _ => panic!("expected expression"),
@@ -412,37 +411,37 @@ macro_rules! make_stmts_default {
 /// methods are spliced into the AST at the callsite of the macro.
 pub trait MacResult {
     /// Creates an expression.
-    fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> {
+    fn make_expr(self: Box<Self>) -> Option<Box<ast::Expr>> {
         None
     }
 
     /// Creates zero or more items.
-    fn make_items(self: Box<Self>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
+    fn make_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
         None
     }
 
     /// Creates zero or more impl items.
-    fn make_impl_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
+    fn make_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
         None
     }
 
     /// Creates zero or more impl items.
-    fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
+    fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
         None
     }
 
     /// Creates zero or more trait items.
-    fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
+    fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
         None
     }
 
     /// Creates zero or more items in an `extern {}` block
-    fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[P<ast::ForeignItem>; 1]>> {
+    fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::ForeignItem>; 1]>> {
         None
     }
 
     /// Creates a pattern.
-    fn make_pat(self: Box<Self>) -> Option<P<ast::Pat>> {
+    fn make_pat(self: Box<Self>) -> Option<Box<ast::Pat>> {
         None
     }
 
@@ -454,7 +453,7 @@ fn make_pat(self: Box<Self>) -> Option<P<ast::Pat>> {
         make_stmts_default!(self)
     }
 
-    fn make_ty(self: Box<Self>) -> Option<P<ast::Ty>> {
+    fn make_ty(self: Box<Self>) -> Option<Box<ast::Ty>> {
         None
     }
 
@@ -521,38 +520,38 @@ pub fn $fld(v: $t) -> Box<dyn MacResult> {
 }
 
 make_MacEager! {
-    expr: P<ast::Expr>,
-    pat: P<ast::Pat>,
-    items: SmallVec<[P<ast::Item>; 1]>,
-    impl_items: SmallVec<[P<ast::AssocItem>; 1]>,
-    trait_items: SmallVec<[P<ast::AssocItem>; 1]>,
-    foreign_items: SmallVec<[P<ast::ForeignItem>; 1]>,
+    expr: Box<ast::Expr>,
+    pat: Box<ast::Pat>,
+    items: SmallVec<[Box<ast::Item>; 1]>,
+    impl_items: SmallVec<[Box<ast::AssocItem>; 1]>,
+    trait_items: SmallVec<[Box<ast::AssocItem>; 1]>,
+    foreign_items: SmallVec<[Box<ast::ForeignItem>; 1]>,
     stmts: SmallVec<[ast::Stmt; 1]>,
-    ty: P<ast::Ty>,
+    ty: Box<ast::Ty>,
 }
 
 impl MacResult for MacEager {
-    fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> {
+    fn make_expr(self: Box<Self>) -> Option<Box<ast::Expr>> {
         self.expr
     }
 
-    fn make_items(self: Box<Self>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
+    fn make_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
         self.items
     }
 
-    fn make_impl_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
+    fn make_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
         self.impl_items
     }
 
-    fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
+    fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
         self.impl_items
     }
 
-    fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
+    fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
         self.trait_items
     }
 
-    fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[P<ast::ForeignItem>; 1]>> {
+    fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::ForeignItem>; 1]>> {
         self.foreign_items
     }
 
@@ -563,13 +562,13 @@ fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> {
         }
     }
 
-    fn make_pat(self: Box<Self>) -> Option<P<ast::Pat>> {
+    fn make_pat(self: Box<Self>) -> Option<Box<ast::Pat>> {
         if let Some(p) = self.pat {
             return Some(p);
         }
         if let Some(e) = self.expr {
             if matches!(e.kind, ast::ExprKind::Lit(_) | ast::ExprKind::IncludedBytes(_)) {
-                return Some(P(ast::Pat {
+                return Some(Box::new(ast::Pat {
                     id: ast::DUMMY_NODE_ID,
                     span: e.span,
                     kind: PatKind::Expr(e),
@@ -580,7 +579,7 @@ fn make_pat(self: Box<Self>) -> Option<P<ast::Pat>> {
         None
     }
 
-    fn make_ty(self: Box<Self>) -> Option<P<ast::Ty>> {
+    fn make_ty(self: Box<Self>) -> Option<Box<ast::Ty>> {
         self.ty
     }
 }
@@ -608,8 +607,8 @@ pub fn any_valid(span: Span) -> Box<dyn MacResult + 'static> {
     }
 
     /// A plain dummy expression.
-    pub fn raw_expr(sp: Span, guar: Option<ErrorGuaranteed>) -> P<ast::Expr> {
-        P(ast::Expr {
+    pub fn raw_expr(sp: Span, guar: Option<ErrorGuaranteed>) -> Box<ast::Expr> {
+        Box::new(ast::Expr {
             id: ast::DUMMY_NODE_ID,
             kind: if let Some(guar) = guar {
                 ast::ExprKind::Err(guar)
@@ -624,12 +623,12 @@ pub fn raw_expr(sp: Span, guar: Option<ErrorGuaranteed>) -> P<ast::Expr> {
 }
 
 impl MacResult for DummyResult {
-    fn make_expr(self: Box<DummyResult>) -> Option<P<ast::Expr>> {
+    fn make_expr(self: Box<DummyResult>) -> Option<Box<ast::Expr>> {
         Some(DummyResult::raw_expr(self.span, self.guar))
     }
 
-    fn make_pat(self: Box<DummyResult>) -> Option<P<ast::Pat>> {
-        Some(P(ast::Pat {
+    fn make_pat(self: Box<DummyResult>) -> Option<Box<ast::Pat>> {
+        Some(Box::new(ast::Pat {
             id: ast::DUMMY_NODE_ID,
             kind: PatKind::Wild,
             span: self.span,
@@ -637,23 +636,23 @@ fn make_pat(self: Box<DummyResult>) -> Option<P<ast::Pat>> {
         }))
     }
 
-    fn make_items(self: Box<DummyResult>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
+    fn make_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
         Some(SmallVec::new())
     }
 
-    fn make_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
+    fn make_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
         Some(SmallVec::new())
     }
 
-    fn make_trait_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
+    fn make_trait_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
         Some(SmallVec::new())
     }
 
-    fn make_trait_items(self: Box<DummyResult>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
+    fn make_trait_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
         Some(SmallVec::new())
     }
 
-    fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[P<ast::ForeignItem>; 1]>> {
+    fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::ForeignItem>; 1]>> {
         Some(SmallVec::new())
     }
 
@@ -665,11 +664,11 @@ fn make_pat(self: Box<DummyResult>) -> Option<P<ast::Pat>> {
         }])
     }
 
-    fn make_ty(self: Box<DummyResult>) -> Option<P<ast::Ty>> {
+    fn make_ty(self: Box<DummyResult>) -> Option<Box<ast::Ty>> {
         // FIXME(nnethercote): you might expect `ast::TyKind::Dummy` to be used here, but some
         // values produced here end up being lowered to HIR, which `ast::TyKind::Dummy` does not
         // support, so we use an empty tuple instead.
-        Some(P(ast::Ty {
+        Some(Box::new(ast::Ty {
             id: ast::DUMMY_NODE_ID,
             kind: ast::TyKind::Tup(ThinVec::new()),
             span: self.span,
@@ -1162,7 +1161,7 @@ fn pre_expansion_lint(
         registered_tools: &RegisteredTools,
         node_id: NodeId,
         attrs: &[Attribute],
-        items: &[P<Item>],
+        items: &[Box<Item>],
         name: Symbol,
     );
 }
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index 51d6e43..c3e86ec 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -1,4 +1,3 @@
-use rustc_ast::ptr::P;
 use rustc_ast::token::Delimiter;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::util::literal;
@@ -59,10 +58,10 @@ pub fn macro_call(
         path: ast::Path,
         delim: Delimiter,
         tokens: TokenStream,
-    ) -> P<ast::MacCall> {
-        P(ast::MacCall {
+    ) -> Box<ast::MacCall> {
+        Box::new(ast::MacCall {
             path,
-            args: P(ast::DelimArgs {
+            args: Box::new(ast::DelimArgs {
                 dspan: tokenstream::DelimSpan { open: span, close: span },
                 delim,
                 tokens,
@@ -70,32 +69,32 @@ pub fn macro_call(
         })
     }
 
-    pub fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy {
+    pub fn ty_mt(&self, ty: Box<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy {
         ast::MutTy { ty, mutbl }
     }
 
-    pub fn ty(&self, span: Span, kind: ast::TyKind) -> P<ast::Ty> {
-        P(ast::Ty { id: ast::DUMMY_NODE_ID, span, kind, tokens: None })
+    pub fn ty(&self, span: Span, kind: ast::TyKind) -> Box<ast::Ty> {
+        Box::new(ast::Ty { id: ast::DUMMY_NODE_ID, span, kind, tokens: None })
     }
 
-    pub fn ty_infer(&self, span: Span) -> P<ast::Ty> {
+    pub fn ty_infer(&self, span: Span) -> Box<ast::Ty> {
         self.ty(span, ast::TyKind::Infer)
     }
 
-    pub fn ty_path(&self, path: ast::Path) -> P<ast::Ty> {
+    pub fn ty_path(&self, path: ast::Path) -> Box<ast::Ty> {
         self.ty(path.span, ast::TyKind::Path(None, path))
     }
 
     // Might need to take bounds as an argument in the future, if you ever want
     // to generate a bounded existential trait type.
-    pub fn ty_ident(&self, span: Span, ident: Ident) -> P<ast::Ty> {
+    pub fn ty_ident(&self, span: Span, ident: Ident) -> Box<ast::Ty> {
         self.ty_path(self.path_ident(span, ident))
     }
 
     pub fn anon_const(&self, span: Span, kind: ast::ExprKind) -> ast::AnonConst {
         ast::AnonConst {
             id: ast::DUMMY_NODE_ID,
-            value: P(ast::Expr {
+            value: Box::new(ast::Expr {
                 id: ast::DUMMY_NODE_ID,
                 kind,
                 span,
@@ -112,14 +111,14 @@ pub fn const_ident(&self, span: Span, ident: Ident) -> ast::AnonConst {
     pub fn ty_ref(
         &self,
         span: Span,
-        ty: P<ast::Ty>,
+        ty: Box<ast::Ty>,
         lifetime: Option<ast::Lifetime>,
         mutbl: ast::Mutability,
-    ) -> P<ast::Ty> {
+    ) -> Box<ast::Ty> {
         self.ty(span, ast::TyKind::Ref(lifetime, self.ty_mt(ty, mutbl)))
     }
 
-    pub fn ty_ptr(&self, span: Span, ty: P<ast::Ty>, mutbl: ast::Mutability) -> P<ast::Ty> {
+    pub fn ty_ptr(&self, span: Span, ty: Box<ast::Ty>, mutbl: ast::Mutability) -> Box<ast::Ty> {
         self.ty(span, ast::TyKind::Ptr(self.ty_mt(ty, mutbl)))
     }
 
@@ -128,7 +127,7 @@ pub fn typaram(
         span: Span,
         ident: Ident,
         bounds: ast::GenericBounds,
-        default: Option<P<ast::Ty>>,
+        default: Option<Box<ast::Ty>>,
     ) -> ast::GenericParam {
         ast::GenericParam {
             ident: ident.with_span_pos(span),
@@ -163,7 +162,7 @@ pub fn const_param(
         span: Span,
         ident: Ident,
         bounds: ast::GenericBounds,
-        ty: P<ast::Ty>,
+        ty: Box<ast::Ty>,
         default: Option<AnonConst>,
     ) -> ast::GenericParam {
         ast::GenericParam {
@@ -211,11 +210,11 @@ pub fn lifetime_static(&self, span: Span) -> ast::Lifetime {
         self.lifetime(span, Ident::new(kw::StaticLifetime, span))
     }
 
-    pub fn stmt_expr(&self, expr: P<ast::Expr>) -> ast::Stmt {
+    pub fn stmt_expr(&self, expr: Box<ast::Expr>) -> ast::Stmt {
         ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr) }
     }
 
-    pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: Ident, ex: P<ast::Expr>) -> ast::Stmt {
+    pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: Ident, ex: Box<ast::Expr>) -> ast::Stmt {
         self.stmt_let_ty(sp, mutbl, ident, None, ex)
     }
 
@@ -224,15 +223,15 @@ pub fn stmt_let_ty(
         sp: Span,
         mutbl: bool,
         ident: Ident,
-        ty: Option<P<ast::Ty>>,
-        ex: P<ast::Expr>,
+        ty: Option<Box<ast::Ty>>,
+        ex: Box<ast::Expr>,
     ) -> ast::Stmt {
         let pat = if mutbl {
             self.pat_ident_binding_mode(sp, ident, ast::BindingMode::MUT)
         } else {
             self.pat_ident(sp, ident)
         };
-        let local = P(ast::Local {
+        let local = Box::new(ast::Local {
             super_: None,
             pat,
             ty,
@@ -247,8 +246,8 @@ pub fn stmt_let_ty(
     }
 
     /// Generates `let _: Type;`, which is usually used for type assertions.
-    pub fn stmt_let_type_only(&self, span: Span, ty: P<ast::Ty>) -> ast::Stmt {
-        let local = P(ast::Local {
+    pub fn stmt_let_type_only(&self, span: Span, ty: Box<ast::Ty>) -> ast::Stmt {
+        let local = Box::new(ast::Local {
             super_: None,
             pat: self.pat_wild(span),
             ty: Some(ty),
@@ -262,19 +261,19 @@ pub fn stmt_let_type_only(&self, span: Span, ty: P<ast::Ty>) -> ast::Stmt {
         self.stmt_local(local, span)
     }
 
-    pub fn stmt_semi(&self, expr: P<ast::Expr>) -> ast::Stmt {
+    pub fn stmt_semi(&self, expr: Box<ast::Expr>) -> ast::Stmt {
         ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Semi(expr) }
     }
 
-    pub fn stmt_local(&self, local: P<ast::Local>, span: Span) -> ast::Stmt {
+    pub fn stmt_local(&self, local: Box<ast::Local>, span: Span) -> ast::Stmt {
         ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Let(local), span }
     }
 
-    pub fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> ast::Stmt {
+    pub fn stmt_item(&self, sp: Span, item: Box<ast::Item>) -> ast::Stmt {
         ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Item(item), span: sp }
     }
 
-    pub fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> {
+    pub fn block_expr(&self, expr: Box<ast::Expr>) -> Box<ast::Block> {
         self.block(
             expr.span,
             thin_vec![ast::Stmt {
@@ -284,8 +283,8 @@ pub fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> {
             }],
         )
     }
-    pub fn block(&self, span: Span, stmts: ThinVec<ast::Stmt>) -> P<ast::Block> {
-        P(ast::Block {
+    pub fn block(&self, span: Span, stmts: ThinVec<ast::Stmt>) -> Box<ast::Block> {
+        Box::new(ast::Block {
             stmts,
             id: ast::DUMMY_NODE_ID,
             rules: BlockCheckMode::Default,
@@ -294,22 +293,28 @@ pub fn block(&self, span: Span, stmts: ThinVec<ast::Stmt>) -> P<ast::Block> {
         })
     }
 
-    pub fn expr(&self, span: Span, kind: ast::ExprKind) -> P<ast::Expr> {
-        P(ast::Expr { id: ast::DUMMY_NODE_ID, kind, span, attrs: AttrVec::new(), tokens: None })
+    pub fn expr(&self, span: Span, kind: ast::ExprKind) -> Box<ast::Expr> {
+        Box::new(ast::Expr {
+            id: ast::DUMMY_NODE_ID,
+            kind,
+            span,
+            attrs: AttrVec::new(),
+            tokens: None,
+        })
     }
 
-    pub fn expr_path(&self, path: ast::Path) -> P<ast::Expr> {
+    pub fn expr_path(&self, path: ast::Path) -> Box<ast::Expr> {
         self.expr(path.span, ast::ExprKind::Path(None, path))
     }
 
-    pub fn expr_ident(&self, span: Span, id: Ident) -> P<ast::Expr> {
+    pub fn expr_ident(&self, span: Span, id: Ident) -> Box<ast::Expr> {
         self.expr_path(self.path_ident(span, id))
     }
-    pub fn expr_self(&self, span: Span) -> P<ast::Expr> {
+    pub fn expr_self(&self, span: Span) -> Box<ast::Expr> {
         self.expr_ident(span, Ident::with_dummy_span(kw::SelfLower))
     }
 
-    pub fn expr_macro_call(&self, span: Span, call: P<ast::MacCall>) -> P<ast::Expr> {
+    pub fn expr_macro_call(&self, span: Span, call: Box<ast::MacCall>) -> Box<ast::Expr> {
         self.expr(span, ast::ExprKind::MacCall(call))
     }
 
@@ -317,31 +322,31 @@ pub fn expr_binary(
         &self,
         sp: Span,
         op: ast::BinOpKind,
-        lhs: P<ast::Expr>,
-        rhs: P<ast::Expr>,
-    ) -> P<ast::Expr> {
+        lhs: Box<ast::Expr>,
+        rhs: Box<ast::Expr>,
+    ) -> Box<ast::Expr> {
         self.expr(sp, ast::ExprKind::Binary(Spanned { node: op, span: sp }, lhs, rhs))
     }
 
-    pub fn expr_deref(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> {
+    pub fn expr_deref(&self, sp: Span, e: Box<ast::Expr>) -> Box<ast::Expr> {
         self.expr(sp, ast::ExprKind::Unary(UnOp::Deref, e))
     }
 
-    pub fn expr_addr_of(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> {
+    pub fn expr_addr_of(&self, sp: Span, e: Box<ast::Expr>) -> Box<ast::Expr> {
         self.expr(sp, ast::ExprKind::AddrOf(ast::BorrowKind::Ref, ast::Mutability::Not, e))
     }
 
-    pub fn expr_paren(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> {
+    pub fn expr_paren(&self, sp: Span, e: Box<ast::Expr>) -> Box<ast::Expr> {
         self.expr(sp, ast::ExprKind::Paren(e))
     }
 
     pub fn expr_method_call(
         &self,
         span: Span,
-        expr: P<ast::Expr>,
+        expr: Box<ast::Expr>,
         ident: Ident,
-        args: ThinVec<P<ast::Expr>>,
-    ) -> P<ast::Expr> {
+        args: ThinVec<Box<ast::Expr>>,
+    ) -> Box<ast::Expr> {
         let seg = ast::PathSegment::from_ident(ident);
         self.expr(
             span,
@@ -357,38 +362,38 @@ pub fn expr_method_call(
     pub fn expr_call(
         &self,
         span: Span,
-        expr: P<ast::Expr>,
-        args: ThinVec<P<ast::Expr>>,
-    ) -> P<ast::Expr> {
+        expr: Box<ast::Expr>,
+        args: ThinVec<Box<ast::Expr>>,
+    ) -> Box<ast::Expr> {
         self.expr(span, ast::ExprKind::Call(expr, args))
     }
-    pub fn expr_loop(&self, sp: Span, block: P<ast::Block>) -> P<ast::Expr> {
+    pub fn expr_loop(&self, sp: Span, block: Box<ast::Block>) -> Box<ast::Expr> {
         self.expr(sp, ast::ExprKind::Loop(block, None, sp))
     }
-    pub fn expr_asm(&self, sp: Span, expr: P<ast::InlineAsm>) -> P<ast::Expr> {
+    pub fn expr_asm(&self, sp: Span, expr: Box<ast::InlineAsm>) -> Box<ast::Expr> {
         self.expr(sp, ast::ExprKind::InlineAsm(expr))
     }
     pub fn expr_call_ident(
         &self,
         span: Span,
         id: Ident,
-        args: ThinVec<P<ast::Expr>>,
-    ) -> P<ast::Expr> {
+        args: ThinVec<Box<ast::Expr>>,
+    ) -> Box<ast::Expr> {
         self.expr(span, ast::ExprKind::Call(self.expr_ident(span, id), args))
     }
     pub fn expr_call_global(
         &self,
         sp: Span,
         fn_path: Vec<Ident>,
-        args: ThinVec<P<ast::Expr>>,
-    ) -> P<ast::Expr> {
+        args: ThinVec<Box<ast::Expr>>,
+    ) -> Box<ast::Expr> {
         let pathexpr = self.expr_path(self.path_global(sp, fn_path));
         self.expr_call(sp, pathexpr, args)
     }
-    pub fn expr_block(&self, b: P<ast::Block>) -> P<ast::Expr> {
+    pub fn expr_block(&self, b: Box<ast::Block>) -> Box<ast::Expr> {
         self.expr(b.span, ast::ExprKind::Block(b, None))
     }
-    pub fn field_imm(&self, span: Span, ident: Ident, e: P<ast::Expr>) -> ast::ExprField {
+    pub fn field_imm(&self, span: Span, ident: Ident, e: Box<ast::Expr>) -> ast::ExprField {
         ast::ExprField {
             ident: ident.with_span_pos(span),
             expr: e,
@@ -404,10 +409,10 @@ pub fn expr_struct(
         span: Span,
         path: ast::Path,
         fields: ThinVec<ast::ExprField>,
-    ) -> P<ast::Expr> {
+    ) -> Box<ast::Expr> {
         self.expr(
             span,
-            ast::ExprKind::Struct(P(ast::StructExpr {
+            ast::ExprKind::Struct(Box::new(ast::StructExpr {
                 qself: None,
                 path,
                 fields,
@@ -420,61 +425,61 @@ pub fn expr_struct_ident(
         span: Span,
         id: Ident,
         fields: ThinVec<ast::ExprField>,
-    ) -> P<ast::Expr> {
+    ) -> Box<ast::Expr> {
         self.expr_struct(span, self.path_ident(span, id), fields)
     }
 
-    pub fn expr_usize(&self, span: Span, n: usize) -> P<ast::Expr> {
+    pub fn expr_usize(&self, span: Span, n: usize) -> Box<ast::Expr> {
         let suffix = Some(ast::UintTy::Usize.name());
         let lit = token::Lit::new(token::Integer, sym::integer(n), suffix);
         self.expr(span, ast::ExprKind::Lit(lit))
     }
 
-    pub fn expr_u32(&self, span: Span, n: u32) -> P<ast::Expr> {
+    pub fn expr_u32(&self, span: Span, n: u32) -> Box<ast::Expr> {
         let suffix = Some(ast::UintTy::U32.name());
         let lit = token::Lit::new(token::Integer, sym::integer(n), suffix);
         self.expr(span, ast::ExprKind::Lit(lit))
     }
 
-    pub fn expr_bool(&self, span: Span, value: bool) -> P<ast::Expr> {
+    pub fn expr_bool(&self, span: Span, value: bool) -> Box<ast::Expr> {
         let lit = token::Lit::new(token::Bool, if value { kw::True } else { kw::False }, None);
         self.expr(span, ast::ExprKind::Lit(lit))
     }
 
-    pub fn expr_str(&self, span: Span, s: Symbol) -> P<ast::Expr> {
+    pub fn expr_str(&self, span: Span, s: Symbol) -> Box<ast::Expr> {
         let lit = token::Lit::new(token::Str, literal::escape_string_symbol(s), None);
         self.expr(span, ast::ExprKind::Lit(lit))
     }
 
-    pub fn expr_byte_str(&self, span: Span, bytes: Vec<u8>) -> P<ast::Expr> {
+    pub fn expr_byte_str(&self, span: Span, bytes: Vec<u8>) -> Box<ast::Expr> {
         let lit = token::Lit::new(token::ByteStr, literal::escape_byte_str_symbol(&bytes), None);
         self.expr(span, ast::ExprKind::Lit(lit))
     }
 
     /// `[expr1, expr2, ...]`
-    pub fn expr_array(&self, sp: Span, exprs: ThinVec<P<ast::Expr>>) -> P<ast::Expr> {
+    pub fn expr_array(&self, sp: Span, exprs: ThinVec<Box<ast::Expr>>) -> Box<ast::Expr> {
         self.expr(sp, ast::ExprKind::Array(exprs))
     }
 
     /// `&[expr1, expr2, ...]`
-    pub fn expr_array_ref(&self, sp: Span, exprs: ThinVec<P<ast::Expr>>) -> P<ast::Expr> {
+    pub fn expr_array_ref(&self, sp: Span, exprs: ThinVec<Box<ast::Expr>>) -> Box<ast::Expr> {
         self.expr_addr_of(sp, self.expr_array(sp, exprs))
     }
 
-    pub fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
+    pub fn expr_some(&self, sp: Span, expr: Box<ast::Expr>) -> Box<ast::Expr> {
         let some = self.std_path(&[sym::option, sym::Option, sym::Some]);
         self.expr_call_global(sp, some, thin_vec![expr])
     }
 
-    pub fn expr_none(&self, sp: Span) -> P<ast::Expr> {
+    pub fn expr_none(&self, sp: Span) -> Box<ast::Expr> {
         let none = self.std_path(&[sym::option, sym::Option, sym::None]);
         self.expr_path(self.path_global(sp, none))
     }
-    pub fn expr_tuple(&self, sp: Span, exprs: ThinVec<P<ast::Expr>>) -> P<ast::Expr> {
+    pub fn expr_tuple(&self, sp: Span, exprs: ThinVec<Box<ast::Expr>>) -> Box<ast::Expr> {
         self.expr(sp, ast::ExprKind::Tup(exprs))
     }
 
-    pub fn expr_unreachable(&self, span: Span) -> P<ast::Expr> {
+    pub fn expr_unreachable(&self, span: Span) -> Box<ast::Expr> {
         self.expr_macro_call(
             span,
             self.macro_call(
@@ -489,12 +494,12 @@ pub fn expr_unreachable(&self, span: Span) -> P<ast::Expr> {
         )
     }
 
-    pub fn expr_ok(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
+    pub fn expr_ok(&self, sp: Span, expr: Box<ast::Expr>) -> Box<ast::Expr> {
         let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]);
         self.expr_call_global(sp, ok, thin_vec![expr])
     }
 
-    pub fn expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr> {
+    pub fn expr_try(&self, sp: Span, head: Box<ast::Expr>) -> Box<ast::Expr> {
         let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]);
         let ok_path = self.path_global(sp, ok);
         let err = self.std_path(&[sym::result, sym::Result, sym::Err]);
@@ -523,16 +528,16 @@ pub fn expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr> {
         self.expr_match(sp, head, thin_vec![ok_arm, err_arm])
     }
 
-    pub fn pat(&self, span: Span, kind: PatKind) -> P<ast::Pat> {
-        P(ast::Pat { id: ast::DUMMY_NODE_ID, kind, span, tokens: None })
+    pub fn pat(&self, span: Span, kind: PatKind) -> Box<ast::Pat> {
+        Box::new(ast::Pat { id: ast::DUMMY_NODE_ID, kind, span, tokens: None })
     }
-    pub fn pat_wild(&self, span: Span) -> P<ast::Pat> {
+    pub fn pat_wild(&self, span: Span) -> Box<ast::Pat> {
         self.pat(span, PatKind::Wild)
     }
-    pub fn pat_lit(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Pat> {
+    pub fn pat_lit(&self, span: Span, expr: Box<ast::Expr>) -> Box<ast::Pat> {
         self.pat(span, PatKind::Expr(expr))
     }
-    pub fn pat_ident(&self, span: Span, ident: Ident) -> P<ast::Pat> {
+    pub fn pat_ident(&self, span: Span, ident: Ident) -> Box<ast::Pat> {
         self.pat_ident_binding_mode(span, ident, ast::BindingMode::NONE)
     }
 
@@ -541,19 +546,19 @@ pub fn pat_ident_binding_mode(
         span: Span,
         ident: Ident,
         ann: ast::BindingMode,
-    ) -> P<ast::Pat> {
+    ) -> Box<ast::Pat> {
         let pat = PatKind::Ident(ann, ident.with_span_pos(span), None);
         self.pat(span, pat)
     }
-    pub fn pat_path(&self, span: Span, path: ast::Path) -> P<ast::Pat> {
+    pub fn pat_path(&self, span: Span, path: ast::Path) -> Box<ast::Pat> {
         self.pat(span, PatKind::Path(None, path))
     }
     pub fn pat_tuple_struct(
         &self,
         span: Span,
         path: ast::Path,
-        subpats: ThinVec<P<ast::Pat>>,
-    ) -> P<ast::Pat> {
+        subpats: ThinVec<Box<ast::Pat>>,
+    ) -> Box<ast::Pat> {
         self.pat(span, PatKind::TupleStruct(None, path, subpats))
     }
     pub fn pat_struct(
@@ -561,20 +566,20 @@ pub fn pat_struct(
         span: Span,
         path: ast::Path,
         field_pats: ThinVec<ast::PatField>,
-    ) -> P<ast::Pat> {
+    ) -> Box<ast::Pat> {
         self.pat(span, PatKind::Struct(None, path, field_pats, ast::PatFieldsRest::None))
     }
-    pub fn pat_tuple(&self, span: Span, pats: ThinVec<P<ast::Pat>>) -> P<ast::Pat> {
+    pub fn pat_tuple(&self, span: Span, pats: ThinVec<Box<ast::Pat>>) -> Box<ast::Pat> {
         self.pat(span, PatKind::Tuple(pats))
     }
 
-    pub fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
+    pub fn pat_some(&self, span: Span, pat: Box<ast::Pat>) -> Box<ast::Pat> {
         let some = self.std_path(&[sym::option, sym::Option, sym::Some]);
         let path = self.path_global(span, some);
         self.pat_tuple_struct(span, path, thin_vec![pat])
     }
 
-    pub fn arm(&self, span: Span, pat: P<ast::Pat>, expr: P<ast::Expr>) -> ast::Arm {
+    pub fn arm(&self, span: Span, pat: Box<ast::Pat>, expr: Box<ast::Expr>) -> ast::Arm {
         ast::Arm {
             attrs: AttrVec::new(),
             pat,
@@ -590,22 +595,27 @@ pub fn arm_unreachable(&self, span: Span) -> ast::Arm {
         self.arm(span, self.pat_wild(span), self.expr_unreachable(span))
     }
 
-    pub fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: ThinVec<ast::Arm>) -> P<Expr> {
+    pub fn expr_match(
+        &self,
+        span: Span,
+        arg: Box<ast::Expr>,
+        arms: ThinVec<ast::Arm>,
+    ) -> Box<Expr> {
         self.expr(span, ast::ExprKind::Match(arg, arms, MatchKind::Prefix))
     }
 
     pub fn expr_if(
         &self,
         span: Span,
-        cond: P<ast::Expr>,
-        then: P<ast::Expr>,
-        els: Option<P<ast::Expr>>,
-    ) -> P<ast::Expr> {
+        cond: Box<ast::Expr>,
+        then: Box<ast::Expr>,
+        els: Option<Box<ast::Expr>>,
+    ) -> Box<ast::Expr> {
         let els = els.map(|x| self.expr_block(self.block_expr(x)));
         self.expr(span, ast::ExprKind::If(cond, self.block_expr(then), els))
     }
 
-    pub fn lambda(&self, span: Span, ids: Vec<Ident>, body: P<ast::Expr>) -> P<ast::Expr> {
+    pub fn lambda(&self, span: Span, ids: Vec<Ident>, body: Box<ast::Expr>) -> Box<ast::Expr> {
         let fn_decl = self.fn_decl(
             ids.iter().map(|id| self.param(span, *id, self.ty(span, ast::TyKind::Infer))).collect(),
             ast::FnRetTy::Default(span),
@@ -633,11 +643,11 @@ pub fn lambda(&self, span: Span, ids: Vec<Ident>, body: P<ast::Expr>) -> P<ast::
         )
     }
 
-    pub fn lambda0(&self, span: Span, body: P<ast::Expr>) -> P<ast::Expr> {
+    pub fn lambda0(&self, span: Span, body: Box<ast::Expr>) -> Box<ast::Expr> {
         self.lambda(span, Vec::new(), body)
     }
 
-    pub fn lambda1(&self, span: Span, body: P<ast::Expr>, ident: Ident) -> P<ast::Expr> {
+    pub fn lambda1(&self, span: Span, body: Box<ast::Expr>, ident: Ident) -> Box<ast::Expr> {
         self.lambda(span, vec![ident], body)
     }
 
@@ -646,11 +656,11 @@ pub fn lambda_stmts_1(
         span: Span,
         stmts: ThinVec<ast::Stmt>,
         ident: Ident,
-    ) -> P<ast::Expr> {
+    ) -> Box<ast::Expr> {
         self.lambda1(span, self.expr_block(self.block(span, stmts)), ident)
     }
 
-    pub fn param(&self, span: Span, ident: Ident, ty: P<ast::Ty>) -> ast::Param {
+    pub fn param(&self, span: Span, ident: Ident, ty: Box<ast::Ty>) -> ast::Param {
         let arg_pat = self.pat_ident(span, ident);
         ast::Param {
             attrs: AttrVec::default(),
@@ -663,12 +673,12 @@ pub fn param(&self, span: Span, ident: Ident, ty: P<ast::Ty>) -> ast::Param {
     }
 
     // `self` is unused but keep it as method for the convenience use.
-    pub fn fn_decl(&self, inputs: ThinVec<ast::Param>, output: ast::FnRetTy) -> P<ast::FnDecl> {
-        P(ast::FnDecl { inputs, output })
+    pub fn fn_decl(&self, inputs: ThinVec<ast::Param>, output: ast::FnRetTy) -> Box<ast::FnDecl> {
+        Box::new(ast::FnDecl { inputs, output })
     }
 
-    pub fn item(&self, span: Span, attrs: ast::AttrVec, kind: ast::ItemKind) -> P<ast::Item> {
-        P(ast::Item {
+    pub fn item(&self, span: Span, attrs: ast::AttrVec, kind: ast::ItemKind) -> Box<ast::Item> {
+        Box::new(ast::Item {
             attrs,
             id: ast::DUMMY_NODE_ID,
             kind,
@@ -686,10 +696,10 @@ pub fn item_static(
         &self,
         span: Span,
         ident: Ident,
-        ty: P<ast::Ty>,
+        ty: Box<ast::Ty>,
         mutability: ast::Mutability,
-        expr: P<ast::Expr>,
-    ) -> P<ast::Item> {
+        expr: Box<ast::Expr>,
+    ) -> Box<ast::Item> {
         self.item(
             span,
             AttrVec::new(),
@@ -711,9 +721,9 @@ pub fn item_const(
         &self,
         span: Span,
         ident: Ident,
-        ty: P<ast::Ty>,
-        expr: P<ast::Expr>,
-    ) -> P<ast::Item> {
+        ty: Box<ast::Ty>,
+        expr: Box<ast::Expr>,
+    ) -> Box<ast::Item> {
         let defaultness = ast::Defaultness::Final;
         self.item(
             span,
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index f02aa6c..e7ae441 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -4,7 +4,6 @@
 use std::{iter, mem};
 
 use rustc_ast::mut_visit::*;
-use rustc_ast::ptr::P;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::visit::{self, AssocCtxt, Visitor, VisitorResult, try_visit, walk_list};
 use rustc_ast::{
@@ -65,8 +64,8 @@ macro_rules! ast_fragments {
         /// A fragment of AST that can be produced by a single macro expansion.
         /// Can also serve as an input and intermediate result for macro expansion operations.
         pub enum AstFragment {
-            OptExpr(Option<P<ast::Expr>>),
-            MethodReceiverExpr(P<ast::Expr>),
+            OptExpr(Option<Box<ast::Expr>>),
+            MethodReceiverExpr(Box<ast::Expr>),
             $($Kind($AstTy),)*
         }
 
@@ -112,14 +111,14 @@ fn add_placeholders(&mut self, placeholders: &[NodeId]) {
                 }
             }
 
-            pub(crate) fn make_opt_expr(self) -> Option<P<ast::Expr>> {
+            pub(crate) fn make_opt_expr(self) -> Option<Box<ast::Expr>> {
                 match self {
                     AstFragment::OptExpr(expr) => expr,
                     _ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
                 }
             }
 
-            pub(crate) fn make_method_receiver_expr(self) -> P<ast::Expr> {
+            pub(crate) fn make_method_receiver_expr(self) -> Box<ast::Expr> {
                 match self {
                     AstFragment::MethodReceiverExpr(expr) => expr,
                     _ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
@@ -188,17 +187,17 @@ impl<'a> MacResult for crate::mbe::macro_rules::ParserAnyMacro<'a> {
 }
 
 ast_fragments! {
-    Expr(P<ast::Expr>) {
+    Expr(Box<ast::Expr>) {
         "expression";
         one fn visit_expr; fn visit_expr; fn pprust::expr_to_string;
         fn make_expr;
     }
-    Pat(P<ast::Pat>) {
+    Pat(Box<ast::Pat>) {
         "pattern";
         one fn visit_pat; fn visit_pat; fn pprust::pat_to_string;
         fn make_pat;
     }
-    Ty(P<ast::Ty>) {
+    Ty(Box<ast::Ty>) {
         "type";
         one fn visit_ty; fn visit_ty; fn pprust::ty_to_string;
         fn make_ty;
@@ -208,30 +207,30 @@ impl<'a> MacResult for crate::mbe::macro_rules::ParserAnyMacro<'a> {
         many fn flat_map_stmt; fn visit_stmt(); fn pprust::stmt_to_string;
         fn make_stmts;
     }
-    Items(SmallVec<[P<ast::Item>; 1]>) {
+    Items(SmallVec<[Box<ast::Item>; 1]>) {
         "item";
         many fn flat_map_item; fn visit_item(); fn pprust::item_to_string;
         fn make_items;
     }
-    TraitItems(SmallVec<[P<ast::AssocItem>; 1]>) {
+    TraitItems(SmallVec<[Box<ast::AssocItem>; 1]>) {
         "trait item";
         many fn flat_map_assoc_item; fn visit_assoc_item(AssocCtxt::Trait);
             fn pprust::assoc_item_to_string;
         fn make_trait_items;
     }
-    ImplItems(SmallVec<[P<ast::AssocItem>; 1]>) {
+    ImplItems(SmallVec<[Box<ast::AssocItem>; 1]>) {
         "impl item";
         many fn flat_map_assoc_item; fn visit_assoc_item(AssocCtxt::Impl { of_trait: false });
             fn pprust::assoc_item_to_string;
         fn make_impl_items;
     }
-    TraitImplItems(SmallVec<[P<ast::AssocItem>; 1]>) {
+    TraitImplItems(SmallVec<[Box<ast::AssocItem>; 1]>) {
         "impl item";
         many fn flat_map_assoc_item; fn visit_assoc_item(AssocCtxt::Impl { of_trait: true });
             fn pprust::assoc_item_to_string;
         fn make_trait_impl_items;
     }
-    ForeignItems(SmallVec<[P<ast::ForeignItem>; 1]>) {
+    ForeignItems(SmallVec<[Box<ast::ForeignItem>; 1]>) {
         "foreign item";
         many fn flat_map_foreign_item; fn visit_foreign_item(); fn pprust::foreign_item_to_string;
         fn make_foreign_items;
@@ -392,7 +391,7 @@ pub struct Invocation {
 
 pub enum InvocationKind {
     Bang {
-        mac: P<ast::MacCall>,
+        mac: Box<ast::MacCall>,
         span: Span,
     },
     Attr {
@@ -409,7 +408,7 @@ pub enum InvocationKind {
         item: Annotatable,
     },
     GlobDelegation {
-        item: P<ast::AssocItem>,
+        item: Box<ast::AssocItem>,
         /// Whether this is a trait impl or an inherent impl
         of_trait: bool,
     },
@@ -948,15 +947,14 @@ fn expand_invoc(
                     _ => unreachable!(),
                 };
 
-                type Node = AstNodeWrapper<P<ast::AssocItem>, ImplItemTag>;
+                type Node = AstNodeWrapper<Box<ast::AssocItem>, ImplItemTag>;
                 let single_delegations = build_single_delegations::<Node>(
                     self.cx, deleg, &item, &suffixes, item.span, true,
                 );
                 // `-Zmacro-stats` ignores these because they don't seem important.
-                fragment_kind.expect_from_annotatables(
-                    single_delegations
-                        .map(|item| Annotatable::AssocItem(P(item), AssocCtxt::Impl { of_trait })),
-                )
+                fragment_kind.expect_from_annotatables(single_delegations.map(|item| {
+                    Annotatable::AssocItem(Box::new(item), AssocCtxt::Impl { of_trait })
+                }))
             }
         })
     }
@@ -1228,7 +1226,7 @@ fn walk(&mut self, _collector: &mut InvocationCollector<'_, '_>) {
     fn is_mac_call(&self) -> bool {
         false
     }
-    fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
+    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
         unreachable!()
     }
     fn delegation(&self) -> Option<(&ast::DelegationMac, &ast::Item<Self::ItemKind>)> {
@@ -1269,7 +1267,7 @@ fn declared_idents(&self) -> Vec<Ident> {
     }
 }
 
-impl InvocationCollectorNode for P<ast::Item> {
+impl InvocationCollectorNode for Box<ast::Item> {
     const KIND: AstFragmentKind = AstFragmentKind::Items;
     fn to_annotatable(self) -> Annotatable {
         Annotatable::Item(self)
@@ -1283,7 +1281,7 @@ fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::Out
     fn is_mac_call(&self) -> bool {
         matches!(self.kind, ItemKind::MacCall(..))
     }
-    fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
+    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
         match self.kind {
             ItemKind::MacCall(mac) => (mac, self.attrs, AddSemicolon::No),
             _ => unreachable!(),
@@ -1299,7 +1297,7 @@ fn delegation_item_kind(deleg: Box<ast::Delegation>) -> Self::ItemKind {
         ItemKind::Delegation(deleg)
     }
     fn from_item(item: ast::Item<Self::ItemKind>) -> Self {
-        P(item)
+        Box::new(item)
     }
     fn flatten_outputs(items: impl Iterator<Item = Self::OutputTy>) -> Self::OutputTy {
         items.flatten().collect()
@@ -1421,8 +1419,8 @@ fn collect_use_tree_leaves(ut: &ast::UseTree, idents: &mut Vec<Ident>) {
 }
 
 struct TraitItemTag;
-impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitItemTag> {
-    type OutputTy = SmallVec<[P<ast::AssocItem>; 1]>;
+impl InvocationCollectorNode for AstNodeWrapper<Box<ast::AssocItem>, TraitItemTag> {
+    type OutputTy = SmallVec<[Box<ast::AssocItem>; 1]>;
     type ItemKind = AssocItemKind;
     const KIND: AstFragmentKind = AstFragmentKind::TraitItems;
     fn to_annotatable(self) -> Annotatable {
@@ -1437,7 +1435,7 @@ fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::Out
     fn is_mac_call(&self) -> bool {
         matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
     }
-    fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
+    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
         let item = self.wrapped;
         match item.kind {
             AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
@@ -1454,7 +1452,7 @@ fn delegation_item_kind(deleg: Box<ast::Delegation>) -> Self::ItemKind {
         AssocItemKind::Delegation(deleg)
     }
     fn from_item(item: ast::Item<Self::ItemKind>) -> Self {
-        AstNodeWrapper::new(P(item), TraitItemTag)
+        AstNodeWrapper::new(Box::new(item), TraitItemTag)
     }
     fn flatten_outputs(items: impl Iterator<Item = Self::OutputTy>) -> Self::OutputTy {
         items.flatten().collect()
@@ -1462,8 +1460,8 @@ fn flatten_outputs(items: impl Iterator<Item = Self::OutputTy>) -> Self::OutputT
 }
 
 struct ImplItemTag;
-impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag> {
-    type OutputTy = SmallVec<[P<ast::AssocItem>; 1]>;
+impl InvocationCollectorNode for AstNodeWrapper<Box<ast::AssocItem>, ImplItemTag> {
+    type OutputTy = SmallVec<[Box<ast::AssocItem>; 1]>;
     type ItemKind = AssocItemKind;
     const KIND: AstFragmentKind = AstFragmentKind::ImplItems;
     fn to_annotatable(self) -> Annotatable {
@@ -1478,7 +1476,7 @@ fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::Out
     fn is_mac_call(&self) -> bool {
         matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
     }
-    fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
+    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
         let item = self.wrapped;
         match item.kind {
             AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
@@ -1495,7 +1493,7 @@ fn delegation_item_kind(deleg: Box<ast::Delegation>) -> Self::ItemKind {
         AssocItemKind::Delegation(deleg)
     }
     fn from_item(item: ast::Item<Self::ItemKind>) -> Self {
-        AstNodeWrapper::new(P(item), ImplItemTag)
+        AstNodeWrapper::new(Box::new(item), ImplItemTag)
     }
     fn flatten_outputs(items: impl Iterator<Item = Self::OutputTy>) -> Self::OutputTy {
         items.flatten().collect()
@@ -1503,8 +1501,8 @@ fn flatten_outputs(items: impl Iterator<Item = Self::OutputTy>) -> Self::OutputT
 }
 
 struct TraitImplItemTag;
-impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitImplItemTag> {
-    type OutputTy = SmallVec<[P<ast::AssocItem>; 1]>;
+impl InvocationCollectorNode for AstNodeWrapper<Box<ast::AssocItem>, TraitImplItemTag> {
+    type OutputTy = SmallVec<[Box<ast::AssocItem>; 1]>;
     type ItemKind = AssocItemKind;
     const KIND: AstFragmentKind = AstFragmentKind::TraitImplItems;
     fn to_annotatable(self) -> Annotatable {
@@ -1519,7 +1517,7 @@ fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::Out
     fn is_mac_call(&self) -> bool {
         matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
     }
-    fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
+    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
         let item = self.wrapped;
         match item.kind {
             AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
@@ -1536,14 +1534,14 @@ fn delegation_item_kind(deleg: Box<ast::Delegation>) -> Self::ItemKind {
         AssocItemKind::Delegation(deleg)
     }
     fn from_item(item: ast::Item<Self::ItemKind>) -> Self {
-        AstNodeWrapper::new(P(item), TraitImplItemTag)
+        AstNodeWrapper::new(Box::new(item), TraitImplItemTag)
     }
     fn flatten_outputs(items: impl Iterator<Item = Self::OutputTy>) -> Self::OutputTy {
         items.flatten().collect()
     }
 }
 
-impl InvocationCollectorNode for P<ast::ForeignItem> {
+impl InvocationCollectorNode for Box<ast::ForeignItem> {
     const KIND: AstFragmentKind = AstFragmentKind::ForeignItems;
     fn to_annotatable(self) -> Annotatable {
         Annotatable::ForeignItem(self)
@@ -1557,7 +1555,7 @@ fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::Out
     fn is_mac_call(&self) -> bool {
         matches!(self.kind, ForeignItemKind::MacCall(..))
     }
-    fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
+    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
         match self.kind {
             ForeignItemKind::MacCall(mac) => (mac, self.attrs, AddSemicolon::No),
             _ => unreachable!(),
@@ -1672,7 +1670,7 @@ fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::Out
 impl InvocationCollectorNode for ast::Stmt {
     const KIND: AstFragmentKind = AstFragmentKind::Stmts;
     fn to_annotatable(self) -> Annotatable {
-        Annotatable::Stmt(P(self))
+        Annotatable::Stmt(Box::new(self))
     }
     fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
         fragment.make_stmts()
@@ -1689,7 +1687,7 @@ fn is_mac_call(&self) -> bool {
             StmtKind::Let(..) | StmtKind::Empty => false,
         }
     }
-    fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
+    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
         // We pull macro invocations (both attributes and fn-like macro calls) out of their
         // `StmtKind`s and treat them as statement macro invocations, not as items or expressions.
         let (add_semicolon, mac, attrs) = match self.kind {
@@ -1726,7 +1724,7 @@ fn delegation_item_kind(deleg: Box<ast::Delegation>) -> Self::ItemKind {
         ItemKind::Delegation(deleg)
     }
     fn from_item(item: ast::Item<Self::ItemKind>) -> Self {
-        ast::Stmt { id: ast::DUMMY_NODE_ID, span: item.span, kind: StmtKind::Item(P(item)) }
+        ast::Stmt { id: ast::DUMMY_NODE_ID, span: item.span, kind: StmtKind::Item(Box::new(item)) }
     }
     fn flatten_outputs(items: impl Iterator<Item = Self::OutputTy>) -> Self::OutputTy {
         items.flatten().collect()
@@ -1769,7 +1767,7 @@ fn expand_cfg_false(
 }
 
 impl InvocationCollectorNode for ast::Ty {
-    type OutputTy = P<ast::Ty>;
+    type OutputTy = Box<ast::Ty>;
     const KIND: AstFragmentKind = AstFragmentKind::Ty;
     fn to_annotatable(self) -> Annotatable {
         unreachable!()
@@ -1793,7 +1791,7 @@ fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) {
     fn is_mac_call(&self) -> bool {
         matches!(self.kind, ast::TyKind::MacCall(..))
     }
-    fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
+    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
         match self.kind {
             TyKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No),
             _ => unreachable!(),
@@ -1802,7 +1800,7 @@ fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
 }
 
 impl InvocationCollectorNode for ast::Pat {
-    type OutputTy = P<ast::Pat>;
+    type OutputTy = Box<ast::Pat>;
     const KIND: AstFragmentKind = AstFragmentKind::Pat;
     fn to_annotatable(self) -> Annotatable {
         unreachable!()
@@ -1816,7 +1814,7 @@ fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) {
     fn is_mac_call(&self) -> bool {
         matches!(self.kind, PatKind::MacCall(..))
     }
-    fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
+    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
         match self.kind {
             PatKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No),
             _ => unreachable!(),
@@ -1825,10 +1823,10 @@ fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
 }
 
 impl InvocationCollectorNode for ast::Expr {
-    type OutputTy = P<ast::Expr>;
+    type OutputTy = Box<ast::Expr>;
     const KIND: AstFragmentKind = AstFragmentKind::Expr;
     fn to_annotatable(self) -> Annotatable {
-        Annotatable::Expr(P(self))
+        Annotatable::Expr(Box::new(self))
     }
     fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
         fragment.make_expr()
@@ -1842,7 +1840,7 @@ fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) {
     fn is_mac_call(&self) -> bool {
         matches!(self.kind, ExprKind::MacCall(..))
     }
-    fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
+    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
         match self.kind {
             ExprKind::MacCall(mac) => (mac, self.attrs, AddSemicolon::No),
             _ => unreachable!(),
@@ -1851,8 +1849,8 @@ fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
 }
 
 struct OptExprTag;
-impl InvocationCollectorNode for AstNodeWrapper<P<ast::Expr>, OptExprTag> {
-    type OutputTy = Option<P<ast::Expr>>;
+impl InvocationCollectorNode for AstNodeWrapper<Box<ast::Expr>, OptExprTag> {
+    type OutputTy = Option<Box<ast::Expr>>;
     const KIND: AstFragmentKind = AstFragmentKind::OptExpr;
     fn to_annotatable(self) -> Annotatable {
         Annotatable::Expr(self.wrapped)
@@ -1867,7 +1865,7 @@ fn walk_flat_map(mut self, collector: &mut InvocationCollector<'_, '_>) -> Self:
     fn is_mac_call(&self) -> bool {
         matches!(self.wrapped.kind, ast::ExprKind::MacCall(..))
     }
-    fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
+    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
         let node = self.wrapped;
         match node.kind {
             ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
@@ -1884,13 +1882,13 @@ fn pre_flat_map_node_collect_attr(cfg: &StripUnconfigured<'_>, attr: &ast::Attri
 struct MethodReceiverTag;
 
 impl InvocationCollectorNode for AstNodeWrapper<ast::Expr, MethodReceiverTag> {
-    type OutputTy = AstNodeWrapper<P<ast::Expr>, MethodReceiverTag>;
+    type OutputTy = AstNodeWrapper<Box<ast::Expr>, MethodReceiverTag>;
     const KIND: AstFragmentKind = AstFragmentKind::MethodReceiverExpr;
     fn descr() -> &'static str {
         "an expression"
     }
     fn to_annotatable(self) -> Annotatable {
-        Annotatable::Expr(P(self.wrapped))
+        Annotatable::Expr(Box::new(self.wrapped))
     }
     fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
         AstNodeWrapper::new(fragment.make_method_receiver_expr(), MethodReceiverTag)
@@ -1901,7 +1899,7 @@ fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) {
     fn is_mac_call(&self) -> bool {
         matches!(self.wrapped.kind, ast::ExprKind::MacCall(..))
     }
-    fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
+    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
         let node = self.wrapped;
         match node.kind {
             ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
@@ -2038,7 +2036,7 @@ fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> A
         placeholder(fragment_kind, NodeId::placeholder_from_expn_id(expn_id), vis)
     }
 
-    fn collect_bang(&mut self, mac: P<ast::MacCall>, kind: AstFragmentKind) -> AstFragment {
+    fn collect_bang(&mut self, mac: Box<ast::MacCall>, kind: AstFragmentKind) -> AstFragment {
         // cache the macro call span so that it can be
         // easily adjusted for incremental compilation
         let span = mac.span();
@@ -2056,7 +2054,7 @@ fn collect_attr(
 
     fn collect_glob_delegation(
         &mut self,
-        item: P<ast::AssocItem>,
+        item: Box<ast::AssocItem>,
         of_trait: bool,
         kind: AstFragmentKind,
     ) -> AstFragment {
@@ -2328,15 +2326,15 @@ fn visit_node<Node: InvocationCollectorNode<OutputTy: Into<Node>> + DummyAstNode
 }
 
 impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
-    fn flat_map_item(&mut self, node: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
+    fn flat_map_item(&mut self, node: Box<ast::Item>) -> SmallVec<[Box<ast::Item>; 1]> {
         self.flat_map_node(node)
     }
 
     fn flat_map_assoc_item(
         &mut self,
-        node: P<ast::AssocItem>,
+        node: Box<ast::AssocItem>,
         ctxt: AssocCtxt,
-    ) -> SmallVec<[P<ast::AssocItem>; 1]> {
+    ) -> SmallVec<[Box<ast::AssocItem>; 1]> {
         match ctxt {
             AssocCtxt::Trait => self.flat_map_node(AstNodeWrapper::new(node, TraitItemTag)),
             AssocCtxt::Impl { of_trait: false } => {
@@ -2350,8 +2348,8 @@ fn flat_map_assoc_item(
 
     fn flat_map_foreign_item(
         &mut self,
-        node: P<ast::ForeignItem>,
-    ) -> SmallVec<[P<ast::ForeignItem>; 1]> {
+        node: Box<ast::ForeignItem>,
+    ) -> SmallVec<[Box<ast::ForeignItem>; 1]> {
         self.flat_map_node(node)
     }
 
@@ -2446,7 +2444,7 @@ fn visit_method_receiver_expr(&mut self, node: &mut ast::Expr) {
         self.visit_node(AstNodeWrapper::from_mut(node, MethodReceiverTag))
     }
 
-    fn filter_map_expr(&mut self, node: P<ast::Expr>) -> Option<P<ast::Expr>> {
+    fn filter_map_expr(&mut self, node: Box<ast::Expr>) -> Option<Box<ast::Expr>> {
         self.flat_map_node(AstNodeWrapper::new(node, OptExprTag))
     }
 
diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs
index e925052..662c67f 100644
--- a/compiler/rustc_expand/src/module.rs
+++ b/compiler/rustc_expand/src/module.rs
@@ -1,7 +1,6 @@
 use std::iter::once;
 use std::path::{self, Path, PathBuf};
 
-use rustc_ast::ptr::P;
 use rustc_ast::{AttrVec, Attribute, Inline, Item, ModSpans};
 use rustc_errors::{Diag, ErrorGuaranteed};
 use rustc_parse::{exp, new_parser_from_file, unwrap_or_emit_fatal, validate_attr};
@@ -31,7 +30,7 @@ pub struct ModulePathSuccess {
 }
 
 pub(crate) struct ParsedExternalMod {
-    pub items: ThinVec<P<Item>>,
+    pub items: ThinVec<Box<Item>>,
     pub spans: ModSpans,
     pub file_path: PathBuf,
     pub dir_path: PathBuf,
diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs
index 6e1c6df..05f9a5a 100644
--- a/compiler/rustc_expand/src/placeholders.rs
+++ b/compiler/rustc_expand/src/placeholders.rs
@@ -1,5 +1,4 @@
 use rustc_ast::mut_visit::*;
-use rustc_ast::ptr::P;
 use rustc_ast::token::Delimiter;
 use rustc_ast::visit::AssocCtxt;
 use rustc_ast::{self as ast, Safety};
@@ -15,10 +14,10 @@ pub(crate) fn placeholder(
     id: ast::NodeId,
     vis: Option<ast::Visibility>,
 ) -> AstFragment {
-    fn mac_placeholder() -> P<ast::MacCall> {
-        P(ast::MacCall {
+    fn mac_placeholder() -> Box<ast::MacCall> {
+        Box::new(ast::MacCall {
             path: ast::Path { span: DUMMY_SP, segments: ThinVec::new(), tokens: None },
-            args: P(ast::DelimArgs {
+            args: Box::new(ast::DelimArgs {
                 dspan: ast::tokenstream::DelimSpan::dummy(),
                 delim: Delimiter::Parenthesis,
                 tokens: ast::tokenstream::TokenStream::new(Vec::new()),
@@ -35,7 +34,7 @@ fn mac_placeholder() -> P<ast::MacCall> {
     });
     let span = DUMMY_SP;
     let expr_placeholder = || {
-        P(ast::Expr {
+        Box::new(ast::Expr {
             id,
             span,
             attrs: ast::AttrVec::new(),
@@ -43,10 +42,17 @@ fn mac_placeholder() -> P<ast::MacCall> {
             tokens: None,
         })
     };
-    let ty =
-        || P(ast::Ty { id, kind: ast::TyKind::MacCall(mac_placeholder()), span, tokens: None });
-    let pat =
-        || P(ast::Pat { id, kind: ast::PatKind::MacCall(mac_placeholder()), span, tokens: None });
+    let ty = || {
+        Box::new(ast::Ty { id, kind: ast::TyKind::MacCall(mac_placeholder()), span, tokens: None })
+    };
+    let pat = || {
+        Box::new(ast::Pat {
+            id,
+            kind: ast::PatKind::MacCall(mac_placeholder()),
+            span,
+            tokens: None,
+        })
+    };
 
     match kind {
         AstFragmentKind::Crate => AstFragment::Crate(ast::Crate {
@@ -59,7 +65,7 @@ fn mac_placeholder() -> P<ast::MacCall> {
         AstFragmentKind::Expr => AstFragment::Expr(expr_placeholder()),
         AstFragmentKind::OptExpr => AstFragment::OptExpr(Some(expr_placeholder())),
         AstFragmentKind::MethodReceiverExpr => AstFragment::MethodReceiverExpr(expr_placeholder()),
-        AstFragmentKind::Items => AstFragment::Items(smallvec![P(ast::Item {
+        AstFragmentKind::Items => AstFragment::Items(smallvec![Box::new(ast::Item {
             id,
             span,
             vis,
@@ -67,15 +73,17 @@ fn mac_placeholder() -> P<ast::MacCall> {
             kind: ast::ItemKind::MacCall(mac_placeholder()),
             tokens: None,
         })]),
-        AstFragmentKind::TraitItems => AstFragment::TraitItems(smallvec![P(ast::AssocItem {
-            id,
-            span,
-            vis,
-            attrs,
-            kind: ast::AssocItemKind::MacCall(mac_placeholder()),
-            tokens: None,
-        })]),
-        AstFragmentKind::ImplItems => AstFragment::ImplItems(smallvec![P(ast::AssocItem {
+        AstFragmentKind::TraitItems => {
+            AstFragment::TraitItems(smallvec![Box::new(ast::AssocItem {
+                id,
+                span,
+                vis,
+                attrs,
+                kind: ast::AssocItemKind::MacCall(mac_placeholder()),
+                tokens: None,
+            })])
+        }
+        AstFragmentKind::ImplItems => AstFragment::ImplItems(smallvec![Box::new(ast::AssocItem {
             id,
             span,
             vis,
@@ -84,7 +92,7 @@ fn mac_placeholder() -> P<ast::MacCall> {
             tokens: None,
         })]),
         AstFragmentKind::TraitImplItems => {
-            AstFragment::TraitImplItems(smallvec![P(ast::AssocItem {
+            AstFragment::TraitImplItems(smallvec![Box::new(ast::AssocItem {
                 id,
                 span,
                 vis,
@@ -94,7 +102,7 @@ fn mac_placeholder() -> P<ast::MacCall> {
             })])
         }
         AstFragmentKind::ForeignItems => {
-            AstFragment::ForeignItems(smallvec![P(ast::ForeignItem {
+            AstFragment::ForeignItems(smallvec![Box::new(ast::ForeignItem {
                 id,
                 span,
                 vis,
@@ -103,20 +111,20 @@ fn mac_placeholder() -> P<ast::MacCall> {
                 tokens: None,
             })])
         }
-        AstFragmentKind::Pat => AstFragment::Pat(P(ast::Pat {
+        AstFragmentKind::Pat => AstFragment::Pat(Box::new(ast::Pat {
             id,
             span,
             kind: ast::PatKind::MacCall(mac_placeholder()),
             tokens: None,
         })),
-        AstFragmentKind::Ty => AstFragment::Ty(P(ast::Ty {
+        AstFragmentKind::Ty => AstFragment::Ty(Box::new(ast::Ty {
             id,
             span,
             kind: ast::TyKind::MacCall(mac_placeholder()),
             tokens: None,
         })),
         AstFragmentKind::Stmts => AstFragment::Stmts(smallvec![{
-            let mac = P(ast::MacCallStmt {
+            let mac = Box::new(ast::MacCallStmt {
                 mac: mac_placeholder(),
                 style: ast::MacStmtStyle::Braces,
                 attrs: ast::AttrVec::new(),
@@ -297,7 +305,7 @@ fn flat_map_where_predicate(
         }
     }
 
-    fn flat_map_item(&mut self, item: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
+    fn flat_map_item(&mut self, item: Box<ast::Item>) -> SmallVec<[Box<ast::Item>; 1]> {
         match item.kind {
             ast::ItemKind::MacCall(_) => self.remove(item.id).make_items(),
             _ => walk_flat_map_item(self, item),
@@ -306,9 +314,9 @@ fn flat_map_where_predicate(
 
     fn flat_map_assoc_item(
         &mut self,
-        item: P<ast::AssocItem>,
+        item: Box<ast::AssocItem>,
         ctxt: AssocCtxt,
-    ) -> SmallVec<[P<ast::AssocItem>; 1]> {
+    ) -> SmallVec<[Box<ast::AssocItem>; 1]> {
         match item.kind {
             ast::AssocItemKind::MacCall(_) => {
                 let it = self.remove(item.id);
@@ -324,8 +332,8 @@ fn flat_map_assoc_item(
 
     fn flat_map_foreign_item(
         &mut self,
-        item: P<ast::ForeignItem>,
-    ) -> SmallVec<[P<ast::ForeignItem>; 1]> {
+        item: Box<ast::ForeignItem>,
+    ) -> SmallVec<[Box<ast::ForeignItem>; 1]> {
         match item.kind {
             ast::ForeignItemKind::MacCall(_) => self.remove(item.id).make_foreign_items(),
             _ => walk_flat_map_foreign_item(self, item),
@@ -346,7 +354,7 @@ fn visit_method_receiver_expr(&mut self, expr: &mut ast::Expr) {
         }
     }
 
-    fn filter_map_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
+    fn filter_map_expr(&mut self, expr: Box<ast::Expr>) -> Option<Box<ast::Expr>> {
         match expr.kind {
             ast::ExprKind::MacCall(_) => self.remove(expr.id).make_opt_expr(),
             _ => walk_filter_map_expr(self, expr),
diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs
index 84fbbbe..9bfda87 100644
--- a/compiler/rustc_expand/src/proc_macro.rs
+++ b/compiler/rustc_expand/src/proc_macro.rs
@@ -1,4 +1,3 @@
-use rustc_ast::ptr::P;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_errors::ErrorGuaranteed;
 use rustc_parse::parser::{ForceCollect, Parser};
@@ -161,7 +160,7 @@ fn expand(
                 Ok(None) => break,
                 Ok(Some(item)) => {
                     if is_stmt {
-                        items.push(Annotatable::Stmt(P(ecx.stmt_item(span, item))));
+                        items.push(Annotatable::Stmt(Box::new(ecx.stmt_item(span, item))));
                     } else {
                         items.push(Annotatable::Item(item));
                     }
diff --git a/compiler/rustc_expand/src/stats.rs b/compiler/rustc_expand/src/stats.rs
index b4c4eac..3e40632 100644
--- a/compiler/rustc_expand/src/stats.rs
+++ b/compiler/rustc_expand/src/stats.rs
@@ -1,6 +1,5 @@
 use std::iter;
 
-use rustc_ast::ptr::P;
 use rustc_ast::{self as ast, DUMMY_NODE_ID, Expr, ExprKind};
 use rustc_ast_pretty::pprust;
 use rustc_span::hygiene::{ExpnKind, MacroKind};
@@ -41,7 +40,7 @@ pub(crate) fn update_bang_macro_stats(
     ecx: &mut ExtCtxt<'_>,
     fragment_kind: AstFragmentKind,
     span: Span,
-    mac: P<ast::MacCall>,
+    mac: Box<ast::MacCall>,
     fragment: &AstFragment,
 ) {
     // Does this path match any of the include macros, e.g. `include!`?
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index bf4611e..7dc736e 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -1756,7 +1756,7 @@ fn emit_err_pat_wrong_number_of_fields(
         let missing_parentheses = match (expected.kind(), fields, had_err) {
             // #67037: only do this if we could successfully type-check the expected type against
             // the tuple struct pattern. Otherwise the args could get out of range on e.g.,
-            // `let P() = U;` where `P != U` with `struct P<T>(T);`.
+            // `let P() = U;` where `P != U` with `struct Box<T>(T);`.
             (ty::Adt(_, args), [field], Ok(())) => {
                 let field_ty = self.field_ty(pat_span, field, args);
                 match field_ty.kind() {
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 8dec806..dc9eb3c 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -108,7 +108,7 @@ fn pre_expansion_lint(
         registered_tools: &RegisteredTools,
         node_id: ast::NodeId,
         attrs: &[ast::Attribute],
-        items: &[rustc_ast::ptr::P<ast::Item>],
+        items: &[Box<ast::Item>],
         name: Symbol,
     ) {
         pre_expansion_lint(sess, features, self.0, registered_tools, (node_id, attrs, items), name);
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index 48e3bbb..5820508 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -4,7 +4,6 @@
 //! resolution, just before AST lowering. These lints are for purely
 //! syntactical lints.
 
-use rustc_ast::ptr::P;
 use rustc_ast::visit::{self as ast_visit, Visitor, walk_list};
 use rustc_ast::{self as ast, HasAttrs};
 use rustc_data_structures::stack::ensure_sufficient_stack;
@@ -297,7 +296,7 @@ fn check<'ecx, 'tcx, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'ecx,
     }
 }
 
-impl<'a> EarlyCheckNode<'a> for (ast::NodeId, &'a [ast::Attribute], &'a [P<ast::Item>]) {
+impl<'a> EarlyCheckNode<'a> for (ast::NodeId, &'a [ast::Attribute], &'a [Box<ast::Item>]) {
     fn id(self) -> ast::NodeId {
         self.0
     }
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 00c97a2..548c56a 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1530,7 +1530,7 @@ fn get_macro(self, id: DefIndex, sess: &Session) -> ast::MacroDef {
                 let macro_rules = self.root.tables.is_macro_rules.get(self, id);
                 let body =
                     self.root.tables.macro_definition.get(self, id).unwrap().decode((self, sess));
-                ast::MacroDef { macro_rules, body: ast::ptr::P(body) }
+                ast::MacroDef { macro_rules, body: Box::new(body) }
             }
             _ => bug!(),
         }
diff --git a/compiler/rustc_parse/src/parser/asm.rs b/compiler/rustc_parse/src/parser/asm.rs
index d4d0612..41c3b0f 100644
--- a/compiler/rustc_parse/src/parser/asm.rs
+++ b/compiler/rustc_parse/src/parser/asm.rs
@@ -1,4 +1,3 @@
-use rustc_ast::ptr::P;
 use rustc_ast::{self as ast, AsmMacro};
 use rustc_span::{Span, Symbol, kw};
 
@@ -14,7 +13,7 @@ pub struct AsmArg {
 }
 
 pub enum AsmArgKind {
-    Template(P<ast::Expr>),
+    Template(Box<ast::Expr>),
     Operand(Option<Symbol>, ast::InlineAsmOperand),
     Options(Vec<AsmOption>),
     ClobberAbi(Vec<(Symbol, Span)>),
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index e0f810d..a32cd33 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -3,7 +3,6 @@
 
 use ast::token::IdentIsRaw;
 use rustc_ast as ast;
-use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Lit, LitKind, Token, TokenKind};
 use rustc_ast::util::parser::AssocOp;
 use rustc_ast::{
@@ -50,7 +49,7 @@
 
 /// Creates a placeholder argument.
 pub(super) fn dummy_arg(ident: Ident, guar: ErrorGuaranteed) -> Param {
-    let pat = P(Pat {
+    let pat = Box::new(Pat {
         id: ast::DUMMY_NODE_ID,
         kind: PatKind::Ident(BindingMode::NONE, ident, None),
         span: ident.span,
@@ -62,23 +61,23 @@ pub(super) fn dummy_arg(ident: Ident, guar: ErrorGuaranteed) -> Param {
         id: ast::DUMMY_NODE_ID,
         pat,
         span: ident.span,
-        ty: P(ty),
+        ty: Box::new(ty),
         is_placeholder: false,
     }
 }
 
 pub(super) trait RecoverQPath: Sized + 'static {
     const PATH_STYLE: PathStyle = PathStyle::Expr;
-    fn to_ty(&self) -> Option<P<Ty>>;
-    fn recovered(qself: Option<P<QSelf>>, path: ast::Path) -> Self;
+    fn to_ty(&self) -> Option<Box<Ty>>;
+    fn recovered(qself: Option<Box<QSelf>>, path: ast::Path) -> Self;
 }
 
 impl RecoverQPath for Ty {
     const PATH_STYLE: PathStyle = PathStyle::Type;
-    fn to_ty(&self) -> Option<P<Ty>> {
-        Some(P(self.clone()))
+    fn to_ty(&self) -> Option<Box<Ty>> {
+        Some(Box::new(self.clone()))
     }
-    fn recovered(qself: Option<P<QSelf>>, path: ast::Path) -> Self {
+    fn recovered(qself: Option<Box<QSelf>>, path: ast::Path) -> Self {
         Self {
             span: path.span,
             kind: TyKind::Path(qself, path),
@@ -90,10 +89,10 @@ fn recovered(qself: Option<P<QSelf>>, path: ast::Path) -> Self {
 
 impl RecoverQPath for Pat {
     const PATH_STYLE: PathStyle = PathStyle::Pat;
-    fn to_ty(&self) -> Option<P<Ty>> {
+    fn to_ty(&self) -> Option<Box<Ty>> {
         self.to_ty()
     }
-    fn recovered(qself: Option<P<QSelf>>, path: ast::Path) -> Self {
+    fn recovered(qself: Option<Box<QSelf>>, path: ast::Path) -> Self {
         Self {
             span: path.span,
             kind: PatKind::Path(qself, path),
@@ -104,10 +103,10 @@ fn recovered(qself: Option<P<QSelf>>, path: ast::Path) -> Self {
 }
 
 impl RecoverQPath for Expr {
-    fn to_ty(&self) -> Option<P<Ty>> {
+    fn to_ty(&self) -> Option<Box<Ty>> {
         self.to_ty()
     }
-    fn recovered(qself: Option<P<QSelf>>, path: ast::Path) -> Self {
+    fn recovered(qself: Option<Box<QSelf>>, path: ast::Path) -> Self {
         Self {
             span: path.span,
             kind: ExprKind::Path(qself, path),
@@ -977,7 +976,7 @@ pub(super) fn maybe_suggest_struct_literal(
         lo: Span,
         s: BlockCheckMode,
         maybe_struct_name: token::Token,
-    ) -> Option<PResult<'a, P<Block>>> {
+    ) -> Option<PResult<'a, Box<Block>>> {
         if self.token.is_ident() && self.look_ahead(1, |t| t == &token::Colon) {
             // We might be having a struct literal where people forgot to include the path:
             // fn foo() -> Foo {
@@ -1042,7 +1041,7 @@ pub(super) fn recover_closure_body(
         token: token::Token,
         lo: Span,
         decl_hi: Span,
-    ) -> PResult<'a, P<Expr>> {
+    ) -> PResult<'a, Box<Expr>> {
         err.span_label(lo.to(decl_hi), "while parsing the body of this closure");
         let guar = match before.kind {
             token::OpenBrace if token.kind != token::OpenBrace => {
@@ -1260,7 +1259,7 @@ pub(super) fn check_turbofish_missing_angle_brackets(&mut self, segment: &mut Pa
     pub(super) fn check_mistyped_turbofish_with_multiple_type_params(
         &mut self,
         mut e: Diag<'a>,
-        expr: &mut P<Expr>,
+        expr: &mut Box<Expr>,
     ) -> PResult<'a, ErrorGuaranteed> {
         if let ExprKind::Binary(binop, _, _) = &expr.kind
             && let ast::BinOpKind::Lt = binop.node
@@ -1443,7 +1442,7 @@ pub(super) fn check_no_chained_comparison(
         &mut self,
         inner_op: &Expr,
         outer_op: &Spanned<AssocOp>,
-    ) -> PResult<'a, Option<P<Expr>>> {
+    ) -> PResult<'a, Option<Box<Expr>>> {
         debug_assert!(
             outer_op.node.is_comparison(),
             "check_no_chained_comparison: {:?} is not comparison",
@@ -1595,7 +1594,7 @@ pub(super) fn maybe_report_ambiguous_plus(&mut self, impl_dyn_multi: bool, ty: &
     }
 
     /// Swift lets users write `Ty?` to mean `Option<Ty>`. Parse the construct and recover from it.
-    pub(super) fn maybe_recover_from_question_mark(&mut self, ty: P<Ty>) -> P<Ty> {
+    pub(super) fn maybe_recover_from_question_mark(&mut self, ty: Box<Ty>) -> Box<Ty> {
         if self.token == token::Question {
             self.bump();
             let guar = self.dcx().emit_err(QuestionMarkInType {
@@ -1690,10 +1689,10 @@ pub(super) fn maybe_recover_from_bad_type_plus(&mut self, ty: &Ty) -> PResult<'a
 
     pub(super) fn recover_from_prefix_increment(
         &mut self,
-        operand_expr: P<Expr>,
+        operand_expr: Box<Expr>,
         op_span: Span,
         start_stmt: bool,
-    ) -> PResult<'a, P<Expr>> {
+    ) -> PResult<'a, Box<Expr>> {
         let standalone = if start_stmt { IsStandalone::Standalone } else { IsStandalone::Subexpr };
         let kind = IncDecRecovery { standalone, op: IncOrDec::Inc, fixity: UnaryFixity::Pre };
         self.recover_from_inc_dec(operand_expr, kind, op_span)
@@ -1701,10 +1700,10 @@ pub(super) fn recover_from_prefix_increment(
 
     pub(super) fn recover_from_postfix_increment(
         &mut self,
-        operand_expr: P<Expr>,
+        operand_expr: Box<Expr>,
         op_span: Span,
         start_stmt: bool,
-    ) -> PResult<'a, P<Expr>> {
+    ) -> PResult<'a, Box<Expr>> {
         let kind = IncDecRecovery {
             standalone: if start_stmt { IsStandalone::Standalone } else { IsStandalone::Subexpr },
             op: IncOrDec::Inc,
@@ -1715,10 +1714,10 @@ pub(super) fn recover_from_postfix_increment(
 
     pub(super) fn recover_from_postfix_decrement(
         &mut self,
-        operand_expr: P<Expr>,
+        operand_expr: Box<Expr>,
         op_span: Span,
         start_stmt: bool,
-    ) -> PResult<'a, P<Expr>> {
+    ) -> PResult<'a, Box<Expr>> {
         let kind = IncDecRecovery {
             standalone: if start_stmt { IsStandalone::Standalone } else { IsStandalone::Subexpr },
             op: IncOrDec::Dec,
@@ -1729,10 +1728,10 @@ pub(super) fn recover_from_postfix_decrement(
 
     fn recover_from_inc_dec(
         &mut self,
-        base: P<Expr>,
+        base: Box<Expr>,
         kind: IncDecRecovery,
         op_span: Span,
-    ) -> PResult<'a, P<Expr>> {
+    ) -> PResult<'a, Box<Expr>> {
         let mut err = self.dcx().struct_span_err(
             op_span,
             format!("Rust has no {} {} operator", kind.fixity, kind.op.name()),
@@ -1833,8 +1832,8 @@ fn inc_dec_standalone_suggest(
     /// tail, and combines them into a `<Ty>::AssocItem` expression/pattern/type.
     pub(super) fn maybe_recover_from_bad_qpath<T: RecoverQPath>(
         &mut self,
-        base: P<T>,
-    ) -> PResult<'a, P<T>> {
+        base: Box<T>,
+    ) -> PResult<'a, Box<T>> {
         if !self.may_recover() {
             return Ok(base);
         }
@@ -1853,8 +1852,8 @@ pub(super) fn maybe_recover_from_bad_qpath<T: RecoverQPath>(
     pub(super) fn maybe_recover_from_bad_qpath_stage_2<T: RecoverQPath>(
         &mut self,
         ty_span: Span,
-        ty: P<Ty>,
-    ) -> PResult<'a, P<T>> {
+        ty: Box<Ty>,
+    ) -> PResult<'a, Box<T>> {
         self.expect(exp!(PathSep))?;
 
         let mut path = ast::Path { segments: ThinVec::new(), span: DUMMY_SP, tokens: None };
@@ -1867,7 +1866,7 @@ pub(super) fn maybe_recover_from_bad_qpath_stage_2<T: RecoverQPath>(
         });
 
         let path_span = ty_span.shrink_to_hi(); // Use an empty path since `position == 0`.
-        Ok(P(T::recovered(Some(P(QSelf { ty, path_span, position: 0 })), path)))
+        Ok(Box::new(T::recovered(Some(Box::new(QSelf { ty, path_span, position: 0 })), path)))
     }
 
     /// This function gets called in places where a semicolon is NOT expected and if there's a
@@ -1970,7 +1969,7 @@ pub(super) fn recover_colon_as_semi(&mut self) -> bool {
     pub(super) fn recover_incorrect_await_syntax(
         &mut self,
         await_sp: Span,
-    ) -> PResult<'a, P<Expr>> {
+    ) -> PResult<'a, Box<Expr>> {
         let (hi, expr, is_question) = if self.token == token::Bang {
             // Handle `await!(<expr>)`.
             self.recover_await_macro()?
@@ -1982,7 +1981,7 @@ pub(super) fn recover_incorrect_await_syntax(
         self.maybe_recover_from_bad_qpath(expr)
     }
 
-    fn recover_await_macro(&mut self) -> PResult<'a, (Span, P<Expr>, bool)> {
+    fn recover_await_macro(&mut self) -> PResult<'a, (Span, Box<Expr>, bool)> {
         self.expect(exp!(Bang))?;
         self.expect(exp!(OpenParen))?;
         let expr = self.parse_expr()?;
@@ -1990,7 +1989,7 @@ fn recover_await_macro(&mut self) -> PResult<'a, (Span, P<Expr>, bool)> {
         Ok((self.prev_token.span, expr, false))
     }
 
-    fn recover_await_prefix(&mut self, await_sp: Span) -> PResult<'a, (Span, P<Expr>, bool)> {
+    fn recover_await_prefix(&mut self, await_sp: Span) -> PResult<'a, (Span, Box<Expr>, bool)> {
         let is_question = self.eat(exp!(Question)); // Handle `await? <expr>`.
         let expr = if self.token == token::OpenBrace {
             // Handle `await { <expr> }`.
@@ -2052,7 +2051,7 @@ pub(super) fn recover_from_use(&mut self) {
         }
     }
 
-    pub(super) fn try_macro_suggestion(&mut self) -> PResult<'a, P<Expr>> {
+    pub(super) fn try_macro_suggestion(&mut self) -> PResult<'a, Box<Expr>> {
         let is_try = self.token.is_keyword(kw::Try);
         let is_questionmark = self.look_ahead(1, |t| t == &token::Bang); //check for !
         let is_open = self.look_ahead(2, |t| t == &token::OpenParen); //check for (
@@ -2124,7 +2123,7 @@ pub(super) fn recover_seq_parse_error(
         close: ExpTokenPair<'_>,
         lo: Span,
         err: Diag<'a>,
-    ) -> P<Expr> {
+    ) -> Box<Expr> {
         let guar = err.emit();
         // Recover from parse error, callers expect the closing delim to be consumed.
         self.consume_block(open, close, ConsumeClosingDelim::Yes);
@@ -2244,7 +2243,7 @@ pub(super) fn eat_incorrect_doc_comment_for_param_type(&mut self) {
     pub(super) fn parameter_without_type(
         &mut self,
         err: &mut Diag<'_>,
-        pat: P<ast::Pat>,
+        pat: Box<ast::Pat>,
         require_name: bool,
         first_param: bool,
     ) -> Option<Ident> {
@@ -2346,7 +2345,7 @@ pub(super) fn parameter_without_type(
         None
     }
 
-    pub(super) fn recover_arg_parse(&mut self) -> PResult<'a, (P<ast::Pat>, P<ast::Ty>)> {
+    pub(super) fn recover_arg_parse(&mut self) -> PResult<'a, (Box<ast::Pat>, Box<ast::Ty>)> {
         let pat = self.parse_pat_no_top_alt(Some(Expected::ArgumentName), None)?;
         self.expect(exp!(Colon))?;
         let ty = self.parse_ty()?;
@@ -2354,8 +2353,12 @@ pub(super) fn recover_arg_parse(&mut self) -> PResult<'a, (P<ast::Pat>, P<ast::T
         self.dcx().emit_err(PatternMethodParamWithoutBody { span: pat.span });
 
         // Pretend the pattern is `_`, to avoid duplicate errors from AST validation.
-        let pat =
-            P(Pat { kind: PatKind::Wild, span: pat.span, id: ast::DUMMY_NODE_ID, tokens: None });
+        let pat = Box::new(Pat {
+            kind: PatKind::Wild,
+            span: pat.span,
+            id: ast::DUMMY_NODE_ID,
+            tokens: None,
+        });
         Ok((pat, ty))
     }
 
@@ -2506,7 +2509,7 @@ pub(super) fn handle_ambiguous_unbraced_const_arg(
     /// - Single-segment paths (i.e. standalone generic const parameters).
     /// All other expressions that can be parsed will emit an error suggesting the expression be
     /// wrapped in braces.
-    pub(super) fn handle_unambiguous_unbraced_const_arg(&mut self) -> PResult<'a, P<Expr>> {
+    pub(super) fn handle_unambiguous_unbraced_const_arg(&mut self) -> PResult<'a, Box<Expr>> {
         let start = self.token.span;
         let attrs = self.parse_outer_attributes()?;
         let (expr, _) =
@@ -2688,7 +2691,7 @@ pub(super) fn recover_const_arg(
     pub(crate) fn recover_unbraced_const_arg_that_can_begin_ty(
         &mut self,
         mut snapshot: SnapshotParser<'a>,
-    ) -> Option<P<ast::Expr>> {
+    ) -> Option<Box<ast::Expr>> {
         match (|| {
             let attrs = self.parse_outer_attributes()?;
             snapshot.parse_expr_res(Restrictions::CONST_EXPR, attrs)
@@ -2724,9 +2727,9 @@ pub(super) fn dummy_const_arg_needs_braces(&self, mut err: Diag<'a>, span: Span)
     /// `for` loop, `let`, &c. (in contrast to subpatterns within such).
     pub(crate) fn maybe_recover_colon_colon_in_pat_typo(
         &mut self,
-        mut first_pat: P<Pat>,
+        mut first_pat: Box<Pat>,
         expected: Option<Expected>,
-    ) -> P<Pat> {
+    ) -> Box<Pat> {
         if token::Colon != self.token.kind {
             return first_pat;
         }
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 35b987c..0be2619 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -6,7 +6,6 @@
 use ast::mut_visit::{self, MutVisitor};
 use ast::token::IdentIsRaw;
 use ast::{CoroutineKind, ForLoopKind, GenBlockKind, MatchKind, Pat, Path, PathSegment, Recovered};
-use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter, InvisibleOrigin, MetaVarKind, Token, TokenKind};
 use rustc_ast::tokenstream::TokenTree;
 use rustc_ast::util::case::Case;
@@ -56,7 +55,7 @@ pub(super) enum DestructuredFloat {
 impl<'a> Parser<'a> {
     /// Parses an expression.
     #[inline]
-    pub fn parse_expr(&mut self) -> PResult<'a, P<Expr>> {
+    pub fn parse_expr(&mut self) -> PResult<'a, Box<Expr>> {
         self.current_closure.take();
 
         let attrs = self.parse_outer_attributes()?;
@@ -64,7 +63,7 @@ pub fn parse_expr(&mut self) -> PResult<'a, P<Expr>> {
     }
 
     /// Parses an expression, forcing tokens to be collected.
-    pub fn parse_expr_force_collect(&mut self) -> PResult<'a, P<Expr>> {
+    pub fn parse_expr_force_collect(&mut self) -> PResult<'a, Box<Expr>> {
         self.current_closure.take();
 
         // If the expression is associative (e.g. `1 + 2`), then any preceding
@@ -90,7 +89,10 @@ pub fn parse_expr_anon_const(&mut self) -> PResult<'a, AnonConst> {
         self.parse_expr().map(|value| AnonConst { id: DUMMY_NODE_ID, value })
     }
 
-    fn parse_expr_catch_underscore(&mut self, restrictions: Restrictions) -> PResult<'a, P<Expr>> {
+    fn parse_expr_catch_underscore(
+        &mut self,
+        restrictions: Restrictions,
+    ) -> PResult<'a, Box<Expr>> {
         let attrs = self.parse_outer_attributes()?;
         match self.parse_expr_res(restrictions, attrs) {
             Ok((expr, _)) => Ok(expr),
@@ -109,7 +111,7 @@ fn parse_expr_catch_underscore(&mut self, restrictions: Restrictions) -> PResult
     }
 
     /// Parses a sequence of expressions delimited by parentheses.
-    fn parse_expr_paren_seq(&mut self) -> PResult<'a, ThinVec<P<Expr>>> {
+    fn parse_expr_paren_seq(&mut self) -> PResult<'a, ThinVec<Box<Expr>>> {
         self.parse_paren_comma_seq(|p| p.parse_expr_catch_underscore(Restrictions::empty()))
             .map(|(r, _)| r)
     }
@@ -120,7 +122,7 @@ pub(super) fn parse_expr_res(
         &mut self,
         r: Restrictions,
         attrs: AttrWrapper,
-    ) -> PResult<'a, (P<Expr>, bool)> {
+    ) -> PResult<'a, (Box<Expr>, bool)> {
         self.with_res(r, |this| this.parse_expr_assoc_with(Bound::Unbounded, attrs))
     }
 
@@ -131,7 +133,7 @@ pub(super) fn parse_expr_assoc_with(
         &mut self,
         min_prec: Bound<ExprPrecedence>,
         attrs: AttrWrapper,
-    ) -> PResult<'a, (P<Expr>, bool)> {
+    ) -> PResult<'a, (Box<Expr>, bool)> {
         let lhs = if self.token.is_range_separator() {
             return self.parse_expr_prefix_range(attrs).map(|res| (res, false));
         } else {
@@ -147,8 +149,8 @@ pub(super) fn parse_expr_assoc_rest_with(
         &mut self,
         min_prec: Bound<ExprPrecedence>,
         starts_stmt: bool,
-        mut lhs: P<Expr>,
-    ) -> PResult<'a, (P<Expr>, bool)> {
+        mut lhs: Box<Expr>,
+    ) -> PResult<'a, (Box<Expr>, bool)> {
         let mut parsed_something = false;
         if !self.should_continue_as_assoc_expr(&lhs) {
             return Ok((lhs, parsed_something));
@@ -414,10 +416,10 @@ fn expr_is_complete(&self, e: &Expr) -> bool {
     fn parse_expr_range(
         &mut self,
         prec: ExprPrecedence,
-        lhs: P<Expr>,
+        lhs: Box<Expr>,
         limits: RangeLimits,
         cur_op_span: Span,
-    ) -> PResult<'a, P<Expr>> {
+    ) -> PResult<'a, Box<Expr>> {
         let rhs = if self.is_at_start_of_range_notation_rhs() {
             let maybe_lt = self.token;
             let attrs = self.parse_outer_attributes()?;
@@ -448,7 +450,7 @@ fn is_at_start_of_range_notation_rhs(&self) -> bool {
     }
 
     /// Parses prefix-forms of range notation: `..expr`, `..`, `..=expr`.
-    fn parse_expr_prefix_range(&mut self, attrs: AttrWrapper) -> PResult<'a, P<Expr>> {
+    fn parse_expr_prefix_range(&mut self, attrs: AttrWrapper) -> PResult<'a, Box<Expr>> {
         if !attrs.is_empty() {
             let err = errors::DotDotRangeAttribute { span: self.token.span };
             self.dcx().emit_err(err);
@@ -490,7 +492,7 @@ fn parse_expr_prefix_range(&mut self, attrs: AttrWrapper) -> PResult<'a, P<Expr>
     }
 
     /// Parses a prefix-unary-operator expr.
-    fn parse_expr_prefix(&mut self, attrs: AttrWrapper) -> PResult<'a, P<Expr>> {
+    fn parse_expr_prefix(&mut self, attrs: AttrWrapper) -> PResult<'a, Box<Expr>> {
         let lo = self.token.span;
 
         macro_rules! make_it {
@@ -564,7 +566,7 @@ macro_rules! make_it {
         }
     }
 
-    fn parse_expr_prefix_common(&mut self, lo: Span) -> PResult<'a, (Span, P<Expr>)> {
+    fn parse_expr_prefix_common(&mut self, lo: Span) -> PResult<'a, (Span, Box<Expr>)> {
         self.bump();
         let attrs = self.parse_outer_attributes()?;
         let expr = if self.token.is_range_separator() {
@@ -653,12 +655,12 @@ fn interpolated_or_expr_span(&self, expr: &Expr) -> Span {
 
     fn parse_assoc_op_cast(
         &mut self,
-        lhs: P<Expr>,
+        lhs: Box<Expr>,
         lhs_span: Span,
         op_span: Span,
-        expr_kind: fn(P<Expr>, P<Ty>) -> ExprKind,
-    ) -> PResult<'a, P<Expr>> {
-        let mk_expr = |this: &mut Self, lhs: P<Expr>, rhs: P<Ty>| {
+        expr_kind: fn(Box<Expr>, Box<Ty>) -> ExprKind,
+    ) -> PResult<'a, Box<Expr>> {
+        let mk_expr = |this: &mut Self, lhs: Box<Expr>, rhs: Box<Ty>| {
             this.mk_expr(this.mk_expr_sp(&lhs, lhs_span, op_span, rhs.span), expr_kind(lhs, rhs))
         };
 
@@ -873,7 +875,7 @@ fn parse_borrow_modifiers(&mut self) -> (ast::BorrowKind, ast::Mutability) {
     }
 
     /// Parses `a.b` or `a(13)` or `a[4]` or just `a`.
-    fn parse_expr_dot_or_call(&mut self, attrs: AttrWrapper) -> PResult<'a, P<Expr>> {
+    fn parse_expr_dot_or_call(&mut self, attrs: AttrWrapper) -> PResult<'a, Box<Expr>> {
         self.collect_tokens_for_expr(attrs, |this, attrs| {
             let base = this.parse_expr_bottom()?;
             let span = this.interpolated_or_expr_span(&base);
@@ -884,9 +886,9 @@ fn parse_expr_dot_or_call(&mut self, attrs: AttrWrapper) -> PResult<'a, P<Expr>>
     pub(super) fn parse_expr_dot_or_call_with(
         &mut self,
         mut attrs: ast::AttrVec,
-        mut e: P<Expr>,
+        mut e: Box<Expr>,
         lo: Span,
-    ) -> PResult<'a, P<Expr>> {
+    ) -> PResult<'a, Box<Expr>> {
         let mut res = ensure_sufficient_stack(|| {
             loop {
                 let has_question =
@@ -945,8 +947,8 @@ pub(super) fn parse_expr_dot_or_call_with(
     pub(super) fn parse_dot_suffix_expr(
         &mut self,
         lo: Span,
-        base: P<Expr>,
-    ) -> PResult<'a, P<Expr>> {
+        base: Box<Expr>,
+    ) -> PResult<'a, Box<Expr>> {
         // At this point we've consumed something like `expr.` and `self.token` holds the token
         // after the dot.
         match self.token.uninterpolate().kind {
@@ -1232,10 +1234,10 @@ fn mk_expr_tuple_field_access(
         &self,
         lo: Span,
         ident_span: Span,
-        base: P<Expr>,
+        base: Box<Expr>,
         field: Symbol,
         suffix: Option<Symbol>,
-    ) -> P<Expr> {
+    ) -> Box<Expr> {
         if let Some(suffix) = suffix {
             self.expect_no_tuple_index_suffix(ident_span, suffix);
         }
@@ -1243,7 +1245,7 @@ fn mk_expr_tuple_field_access(
     }
 
     /// Parse a function call expression, `expr(...)`.
-    fn parse_expr_fn_call(&mut self, lo: Span, fun: P<Expr>) -> P<Expr> {
+    fn parse_expr_fn_call(&mut self, lo: Span, fun: Box<Expr>) -> Box<Expr> {
         let snapshot = if self.token == token::OpenParen {
             Some((self.create_snapshot_for_diagnostic(), fun.kind.clone()))
         } else {
@@ -1267,9 +1269,9 @@ fn maybe_recover_struct_lit_bad_delims(
         &mut self,
         lo: Span,
         open_paren: Span,
-        seq: PResult<'a, P<Expr>>,
+        seq: PResult<'a, Box<Expr>>,
         snapshot: Option<(SnapshotParser<'a>, ExprKind)>,
-    ) -> PResult<'a, P<Expr>> {
+    ) -> PResult<'a, Box<Expr>> {
         match (self.may_recover(), seq, snapshot) {
             (true, Err(err), Some((mut snapshot, ExprKind::Path(None, path)))) => {
                 snapshot.bump(); // `(`
@@ -1325,7 +1327,7 @@ fn maybe_recover_struct_lit_bad_delims(
     }
 
     /// Parse an indexing expression `expr[...]`.
-    fn parse_expr_index(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> {
+    fn parse_expr_index(&mut self, lo: Span, base: Box<Expr>) -> PResult<'a, Box<Expr>> {
         let prev_span = self.prev_token.span;
         let open_delim_span = self.token.span;
         self.bump(); // `[`
@@ -1339,7 +1341,7 @@ fn parse_expr_index(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>>
     }
 
     /// Assuming we have just parsed `.`, continue parsing into an expression.
-    fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
+    fn parse_dot_suffix(&mut self, self_arg: Box<Expr>, lo: Span) -> PResult<'a, Box<Expr>> {
         if self.token_uninterpolated_span().at_least_rust_2018() && self.eat_keyword(exp!(Await)) {
             return Ok(self.mk_await_expr(self_arg, lo));
         }
@@ -1404,7 +1406,7 @@ fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Exp
     ///
     /// N.B., this does not parse outer attributes, and is private because it only works
     /// correctly if called from `parse_expr_dot_or_call`.
-    fn parse_expr_bottom(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_bottom(&mut self) -> PResult<'a, Box<Expr>> {
         maybe_recover_from_interpolated_ty_qpath!(self, true);
 
         let span = self.token.span;
@@ -1556,7 +1558,7 @@ fn parse_expr_bottom(&mut self) -> PResult<'a, P<Expr>> {
         })
     }
 
-    fn parse_expr_lit(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_lit(&mut self) -> PResult<'a, Box<Expr>> {
         let lo = self.token.span;
         match self.parse_opt_token_lit() {
             Some((token_lit, _)) => {
@@ -1567,7 +1569,7 @@ fn parse_expr_lit(&mut self) -> PResult<'a, P<Expr>> {
         }
     }
 
-    fn parse_expr_tuple_parens(&mut self, restrictions: Restrictions) -> PResult<'a, P<Expr>> {
+    fn parse_expr_tuple_parens(&mut self, restrictions: Restrictions) -> PResult<'a, Box<Expr>> {
         let lo = self.token.span;
         self.expect(exp!(OpenParen))?;
         let (es, trailing_comma) = match self.parse_seq_to_end(
@@ -1596,7 +1598,7 @@ fn parse_expr_tuple_parens(&mut self, restrictions: Restrictions) -> PResult<'a,
         self.maybe_recover_from_bad_qpath(expr)
     }
 
-    fn parse_expr_array_or_repeat(&mut self, close: ExpTokenPair<'_>) -> PResult<'a, P<Expr>> {
+    fn parse_expr_array_or_repeat(&mut self, close: ExpTokenPair<'_>) -> PResult<'a, Box<Expr>> {
         let lo = self.token.span;
         self.bump(); // `[` or other open delim
 
@@ -1627,7 +1629,7 @@ fn parse_expr_array_or_repeat(&mut self, close: ExpTokenPair<'_>) -> PResult<'a,
         self.maybe_recover_from_bad_qpath(expr)
     }
 
-    fn parse_expr_path_start(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_path_start(&mut self) -> PResult<'a, Box<Expr>> {
         let maybe_eq_tok = self.prev_token;
         let (qself, path) = if self.eat_lt() {
             let lt_span = self.prev_token.span;
@@ -1653,7 +1655,7 @@ fn parse_expr_path_start(&mut self) -> PResult<'a, P<Expr>> {
                 self.dcx().emit_err(errors::MacroInvocationWithQualifiedPath(path.span));
             }
             let lo = path.span;
-            let mac = P(MacCall { path, args: self.parse_delim_args()? });
+            let mac = Box::new(MacCall { path, args: self.parse_delim_args()? });
             (lo.to(self.prev_token.span), ExprKind::MacCall(mac))
         } else if self.check(exp!(OpenBrace))
             && let Some(expr) = self.maybe_parse_struct_expr(&qself, &path)
@@ -1675,7 +1677,7 @@ pub(super) fn parse_expr_labeled(
         &mut self,
         label_: Label,
         mut consume_colon: bool,
-    ) -> PResult<'a, P<Expr>> {
+    ) -> PResult<'a, Box<Expr>> {
         let lo = label_.ident.span;
         let label = Some(label_);
         let ate_colon = self.eat(exp!(Colon));
@@ -1810,7 +1812,7 @@ pub(super) fn recover_unclosed_char<L>(
     }
 
     /// Recover on the syntax `do catch { ... }` suggesting `try { ... }` instead.
-    fn recover_do_catch(&mut self) -> PResult<'a, P<Expr>> {
+    fn recover_do_catch(&mut self) -> PResult<'a, Box<Expr>> {
         let lo = self.token.span;
 
         self.bump(); // `do`
@@ -1823,12 +1825,12 @@ fn recover_do_catch(&mut self) -> PResult<'a, P<Expr>> {
     }
 
     /// Parse an expression if the token can begin one.
-    fn parse_expr_opt(&mut self) -> PResult<'a, Option<P<Expr>>> {
+    fn parse_expr_opt(&mut self) -> PResult<'a, Option<Box<Expr>>> {
         Ok(if self.token.can_begin_expr() { Some(self.parse_expr()?) } else { None })
     }
 
     /// Parse `"return" expr?`.
-    fn parse_expr_return(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_return(&mut self) -> PResult<'a, Box<Expr>> {
         let lo = self.prev_token.span;
         let kind = ExprKind::Ret(self.parse_expr_opt()?);
         let expr = self.mk_expr(lo.to(self.prev_token.span), kind);
@@ -1836,7 +1838,7 @@ fn parse_expr_return(&mut self) -> PResult<'a, P<Expr>> {
     }
 
     /// Parse `"do" "yeet" expr?`.
-    fn parse_expr_yeet(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_yeet(&mut self) -> PResult<'a, Box<Expr>> {
         let lo = self.token.span;
 
         self.bump(); // `do`
@@ -1851,7 +1853,7 @@ fn parse_expr_yeet(&mut self) -> PResult<'a, P<Expr>> {
     }
 
     /// Parse `"become" expr`, with `"become"` token already eaten.
-    fn parse_expr_become(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_become(&mut self) -> PResult<'a, Box<Expr>> {
         let lo = self.prev_token.span;
         let kind = ExprKind::Become(self.parse_expr()?);
         let span = lo.to(self.prev_token.span);
@@ -1868,7 +1870,7 @@ fn parse_expr_become(&mut self) -> PResult<'a, P<Expr>> {
     /// `break 'lbl: loop {}`); a labeled break with an unlabeled loop as its value
     /// expression only gets a warning for compatibility reasons; and a labeled break
     /// with a labeled loop does not even get a warning because there is no ambiguity.
-    fn parse_expr_break(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_break(&mut self) -> PResult<'a, Box<Expr>> {
         let lo = self.prev_token.span;
         let mut label = self.eat_label();
         let kind = if self.token == token::Colon
@@ -1930,7 +1932,7 @@ fn parse_expr_break(&mut self) -> PResult<'a, P<Expr>> {
     }
 
     /// Parse `"continue" label?`.
-    fn parse_expr_continue(&mut self, lo: Span) -> PResult<'a, P<Expr>> {
+    fn parse_expr_continue(&mut self, lo: Span) -> PResult<'a, Box<Expr>> {
         let mut label = self.eat_label();
 
         // Recover `continue label` -> `continue 'label`
@@ -1947,7 +1949,7 @@ fn parse_expr_continue(&mut self, lo: Span) -> PResult<'a, P<Expr>> {
     }
 
     /// Parse `"yield" expr?`.
-    fn parse_expr_yield(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_yield(&mut self) -> PResult<'a, Box<Expr>> {
         let lo = self.prev_token.span;
         let kind = ExprKind::Yield(YieldKind::Prefix(self.parse_expr_opt()?));
         let span = lo.to(self.prev_token.span);
@@ -1957,7 +1959,7 @@ fn parse_expr_yield(&mut self) -> PResult<'a, P<Expr>> {
     }
 
     /// Parse `builtin # ident(args,*)`.
-    fn parse_expr_builtin(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_builtin(&mut self) -> PResult<'a, Box<Expr>> {
         self.parse_builtin(|this, lo, ident| {
             Ok(match ident.name {
                 sym::offset_of => Some(this.parse_expr_offset_of(lo)?),
@@ -2005,7 +2007,7 @@ pub(crate) fn parse_builtin<T>(
     }
 
     /// Built-in macro for `offset_of!` expressions.
-    pub(crate) fn parse_expr_offset_of(&mut self, lo: Span) -> PResult<'a, P<Expr>> {
+    pub(crate) fn parse_expr_offset_of(&mut self, lo: Span) -> PResult<'a, Box<Expr>> {
         let container = self.parse_ty()?;
         self.expect(exp!(Comma))?;
 
@@ -2033,7 +2035,7 @@ pub(crate) fn parse_expr_offset_of(&mut self, lo: Span) -> PResult<'a, P<Expr>>
     }
 
     /// Built-in macro for type ascription expressions.
-    pub(crate) fn parse_expr_type_ascribe(&mut self, lo: Span) -> PResult<'a, P<Expr>> {
+    pub(crate) fn parse_expr_type_ascribe(&mut self, lo: Span) -> PResult<'a, Box<Expr>> {
         let expr = self.parse_expr()?;
         self.expect(exp!(Comma))?;
         let ty = self.parse_ty()?;
@@ -2045,7 +2047,7 @@ pub(crate) fn parse_expr_unsafe_binder_cast(
         &mut self,
         lo: Span,
         kind: UnsafeBinderCastKind,
-    ) -> PResult<'a, P<Expr>> {
+    ) -> PResult<'a, Box<Expr>> {
         let expr = self.parse_expr()?;
         let ty = if self.eat(exp!(Comma)) { Some(self.parse_ty()?) } else { None };
         let span = lo.to(self.token.span);
@@ -2155,7 +2157,7 @@ fn recover_after_dot(&mut self) {
     /// Keep this in sync with `Token::can_begin_literal_maybe_minus` and
     /// `Lit::from_token` (excluding unary negation).
     fn eat_token_lit(&mut self) -> Option<token::Lit> {
-        let check_expr = |expr: P<Expr>| {
+        let check_expr = |expr: Box<Expr>| {
             if let ast::ExprKind::Lit(token_lit) = expr.kind {
                 Some(token_lit)
             } else if let ast::ExprKind::Unary(UnOp::Neg, inner) = &expr.kind
@@ -2243,7 +2245,7 @@ pub(super) fn expect_no_tuple_index_suffix(&self, span: Span, suffix: Symbol) {
 
     /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`).
     /// Keep this in sync with `Token::can_begin_literal_maybe_minus`.
-    pub fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
+    pub fn parse_literal_maybe_minus(&mut self) -> PResult<'a, Box<Expr>> {
         if let Some(expr) = self.eat_metavar_seq_with_matcher(
             |mv_kind| matches!(mv_kind, MetaVarKind::Expr { .. }),
             |this| {
@@ -2290,7 +2292,7 @@ fn is_array_like_block(&mut self) -> bool {
     /// Emits a suggestion if it looks like the user meant an array but
     /// accidentally used braces, causing the code to be interpreted as a block
     /// expression.
-    fn maybe_suggest_brackets_instead_of_braces(&mut self, lo: Span) -> Option<P<Expr>> {
+    fn maybe_suggest_brackets_instead_of_braces(&mut self, lo: Span) -> Option<Box<Expr>> {
         let mut snapshot = self.create_snapshot_for_diagnostic();
         match snapshot.parse_expr_array_or_repeat(exp!(CloseBrace)) {
             Ok(arr) => {
@@ -2360,7 +2362,7 @@ pub(super) fn parse_expr_block(
         opt_label: Option<Label>,
         lo: Span,
         blk_mode: BlockCheckMode,
-    ) -> PResult<'a, P<Expr>> {
+    ) -> PResult<'a, Box<Expr>> {
         if self.may_recover() && self.is_array_like_block() {
             if let Some(arr) = self.maybe_suggest_brackets_instead_of_braces(lo) {
                 return Ok(arr);
@@ -2383,13 +2385,13 @@ pub(super) fn parse_expr_block(
     }
 
     /// Parse a block which takes no attributes and has no label
-    fn parse_simple_block(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_simple_block(&mut self) -> PResult<'a, Box<Expr>> {
         let blk = self.parse_block()?;
         Ok(self.mk_expr(blk.span, ExprKind::Block(blk, None)))
     }
 
     /// Parses a closure expression (e.g., `move |args| expr`).
-    fn parse_expr_closure(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_closure(&mut self) -> PResult<'a, Box<Expr>> {
         let lo = self.token.span;
 
         let before = self.prev_token;
@@ -2494,7 +2496,7 @@ fn parse_expr_closure(&mut self) -> PResult<'a, P<Expr>> {
     }
 
     /// If an explicit return type is given, require a block to appear (RFC 968).
-    fn parse_closure_block_body(&mut self, ret_span: Span) -> PResult<'a, P<Expr>> {
+    fn parse_closure_block_body(&mut self, ret_span: Span) -> PResult<'a, Box<Expr>> {
         if self.may_recover()
             && self.token.can_begin_expr()
             && self.token.kind != TokenKind::OpenBrace
@@ -2565,7 +2567,7 @@ fn parse_capture_clause(&mut self) -> PResult<'a, CaptureBy> {
     }
 
     /// Parses the `|arg, arg|` header of a closure.
-    fn parse_fn_block_decl(&mut self) -> PResult<'a, (P<FnDecl>, Span)> {
+    fn parse_fn_block_decl(&mut self) -> PResult<'a, (Box<FnDecl>, Span)> {
         let arg_start = self.token.span.lo();
 
         let inputs = if self.eat(exp!(OrOr)) {
@@ -2587,7 +2589,7 @@ fn parse_fn_block_decl(&mut self) -> PResult<'a, (P<FnDecl>, Span)> {
         let output =
             self.parse_ret_ty(AllowPlus::Yes, RecoverQPath::Yes, RecoverReturnSign::Yes)?;
 
-        Ok((P(FnDecl { inputs, output }), arg_span))
+        Ok((Box::new(FnDecl { inputs, output }), arg_span))
     }
 
     /// Parses a parameter in a closure header (e.g., `|arg, arg|`).
@@ -2618,7 +2620,7 @@ fn parse_fn_block_param(&mut self) -> PResult<'a, Param> {
     }
 
     /// Parses an `if` expression (`if` token already eaten).
-    fn parse_expr_if(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_if(&mut self) -> PResult<'a, Box<Expr>> {
         let lo = self.prev_token.span;
         // Scoping code checks the top level edition of the `if`; let's match it here.
         // The `CondChecker` also checks the edition of the `let` itself, just to make sure.
@@ -2627,7 +2629,7 @@ fn parse_expr_if(&mut self) -> PResult<'a, P<Expr>> {
         self.parse_if_after_cond(lo, cond)
     }
 
-    fn parse_if_after_cond(&mut self, lo: Span, mut cond: P<Expr>) -> PResult<'a, P<Expr>> {
+    fn parse_if_after_cond(&mut self, lo: Span, mut cond: Box<Expr>) -> PResult<'a, Box<Expr>> {
         let cond_span = cond.span;
         // Tries to interpret `cond` as either a missing expression if it's a block,
         // or as an unfinished expression if it's a binop and the RHS is a block.
@@ -2737,7 +2739,10 @@ fn parse_if_after_cond(&mut self, lo: Span, mut cond: P<Expr>) -> PResult<'a, P<
     /// i.e. the same span we use to later decide whether the drop behaviour should be that of
     /// edition `..=2021` or that of `2024..`.
     // Public because it is used in rustfmt forks such as https://github.com/tucant/rustfmt/blob/30c83df9e1db10007bdd16dafce8a86b404329b2/src/parse/macros/html.rs#L57 for custom if expressions.
-    pub fn parse_expr_cond(&mut self, let_chains_policy: LetChainsPolicy) -> PResult<'a, P<Expr>> {
+    pub fn parse_expr_cond(
+        &mut self,
+        let_chains_policy: LetChainsPolicy,
+    ) -> PResult<'a, Box<Expr>> {
         let attrs = self.parse_outer_attributes()?;
         let (mut cond, _) =
             self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL | Restrictions::ALLOW_LET, attrs)?;
@@ -2748,7 +2753,7 @@ pub fn parse_expr_cond(&mut self, let_chains_policy: LetChainsPolicy) -> PResult
     }
 
     /// Parses a `let $pat = $expr` pseudo-expression.
-    fn parse_expr_let(&mut self, restrictions: Restrictions) -> PResult<'a, P<Expr>> {
+    fn parse_expr_let(&mut self, restrictions: Restrictions) -> PResult<'a, Box<Expr>> {
         let recovered = if !restrictions.contains(Restrictions::ALLOW_LET) {
             let err = errors::ExpectedExpressionFoundLet {
                 span: self.token.span,
@@ -2790,7 +2795,7 @@ fn parse_expr_let(&mut self, restrictions: Restrictions) -> PResult<'a, P<Expr>>
     }
 
     /// Parses an `else { ... }` expression (`else` token already eaten).
-    fn parse_expr_else(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_else(&mut self) -> PResult<'a, Box<Expr>> {
         let else_span = self.prev_token.span; // `else`
         let attrs = self.parse_outer_attributes()?; // For recovery.
         let expr = if self.eat_keyword(exp!(If)) {
@@ -2888,7 +2893,7 @@ fn error_on_if_block_attrs(
         }
     }
 
-    fn error_on_extra_if(&mut self, cond: &P<Expr>) -> PResult<'a, ()> {
+    fn error_on_extra_if(&mut self, cond: &Box<Expr>) -> PResult<'a, ()> {
         if let ExprKind::Binary(Spanned { span: binop_span, node: binop }, _, right) = &cond.kind
             && let BinOpKind::And = binop
             && let ExprKind::If(cond, ..) = &right.kind
@@ -2901,7 +2906,7 @@ fn error_on_extra_if(&mut self, cond: &P<Expr>) -> PResult<'a, ()> {
         }
     }
 
-    fn parse_for_head(&mut self) -> PResult<'a, (P<Pat>, P<Expr>)> {
+    fn parse_for_head(&mut self) -> PResult<'a, (Box<Pat>, Box<Expr>)> {
         let begin_paren = if self.token == token::OpenParen {
             // Record whether we are about to parse `for (`.
             // This is used below for recovery in case of `for ( $stuff ) $block`
@@ -2967,7 +2972,7 @@ fn parse_for_head(&mut self) -> PResult<'a, (P<Pat>, P<Expr>)> {
     }
 
     /// Parses `for await? <src_pat> in <src_expr> <src_loop_block>` (`for` token already eaten).
-    fn parse_expr_for(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
+    fn parse_expr_for(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, Box<Expr>> {
         let is_await =
             self.token_uninterpolated_span().at_least_rust_2018() && self.eat_keyword(exp!(Await));
 
@@ -3036,7 +3041,7 @@ fn error_missing_in_for_loop(&mut self) {
     }
 
     /// Parses a `while` or `while let` expression (`while` token already eaten).
-    fn parse_expr_while(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
+    fn parse_expr_while(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, Box<Expr>> {
         let policy = LetChainsPolicy::EditionDependent { current_edition: lo.edition() };
         let cond = self.parse_expr_cond(policy).map_err(|mut err| {
             err.span_label(lo, "while parsing the condition of this `while` expression");
@@ -3064,7 +3069,7 @@ fn parse_expr_while(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a
     }
 
     /// Parses `loop { ... }` (`loop` token already eaten).
-    fn parse_expr_loop(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
+    fn parse_expr_loop(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, Box<Expr>> {
         let loop_span = self.prev_token.span;
         let (attrs, body) = self.parse_inner_attrs_and_block(
             // Only suggest moving erroneous block label to the loop header
@@ -3094,7 +3099,7 @@ pub(crate) fn eat_label(&mut self) -> Option<Label> {
     }
 
     /// Parses a `match ... { ... }` expression (`match` token already eaten).
-    fn parse_expr_match(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_match(&mut self) -> PResult<'a, Box<Expr>> {
         let match_span = self.prev_token.span;
         let attrs = self.parse_outer_attributes()?;
         let (scrutinee, _) = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, attrs)?;
@@ -3108,9 +3113,9 @@ fn parse_match_block(
         &mut self,
         lo: Span,
         match_span: Span,
-        scrutinee: P<Expr>,
+        scrutinee: Box<Expr>,
         match_kind: MatchKind,
-    ) -> PResult<'a, P<Expr>> {
+    ) -> PResult<'a, Box<Expr>> {
         if let Err(mut e) = self.expect(exp!(OpenBrace)) {
             if self.token == token::Semi {
                 e.span_suggestion_short(
@@ -3167,7 +3172,7 @@ fn parse_match_block(
     /// Attempt to recover from match arm body with statements and no surrounding braces.
     fn parse_arm_body_missing_braces(
         &mut self,
-        first_expr: &P<Expr>,
+        first_expr: &Box<Expr>,
         arrow_span: Span,
     ) -> Option<(Span, ErrorGuaranteed)> {
         if self.token != token::Semi {
@@ -3439,7 +3444,7 @@ pub(super) fn parse_arm(&mut self) -> PResult<'a, Arm> {
         })
     }
 
-    fn parse_match_arm_guard(&mut self) -> PResult<'a, Option<P<Expr>>> {
+    fn parse_match_arm_guard(&mut self) -> PResult<'a, Option<Box<Expr>>> {
         // Used to check the `if_let_guard` feature mostly by scanning
         // `&&` tokens.
         fn has_let_expr(expr: &Expr) -> bool {
@@ -3470,7 +3475,7 @@ fn has_let_expr(expr: &Expr) -> bool {
         Ok(Some(cond))
     }
 
-    fn parse_match_arm_pat_and_guard(&mut self) -> PResult<'a, (P<Pat>, Option<P<Expr>>)> {
+    fn parse_match_arm_pat_and_guard(&mut self) -> PResult<'a, (Box<Pat>, Option<Box<Expr>>)> {
         if self.token == token::OpenParen {
             let left = self.token.span;
             let pat = self.parse_pat_no_top_guard(
@@ -3510,7 +3515,7 @@ fn parse_match_arm_pat_and_guard(&mut self) -> PResult<'a, (P<Pat>, Option<P<Exp
         }
     }
 
-    fn parse_match_guard_condition(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_match_guard_condition(&mut self) -> PResult<'a, Box<Expr>> {
         let attrs = self.parse_outer_attributes()?;
         match self.parse_expr_res(Restrictions::ALLOW_LET | Restrictions::IN_IF_GUARD, attrs) {
             Ok((expr, _)) => Ok(expr),
@@ -3544,7 +3549,7 @@ pub(crate) fn is_builtin(&self) -> bool {
     }
 
     /// Parses a `try {...}` expression (`try` token already eaten).
-    fn parse_try_block(&mut self, span_lo: Span) -> PResult<'a, P<Expr>> {
+    fn parse_try_block(&mut self, span_lo: Span) -> PResult<'a, Box<Expr>> {
         let (attrs, body) = self.parse_inner_attrs_and_block(None)?;
         if self.eat_keyword(exp!(Catch)) {
             Err(self.dcx().create_err(errors::CatchAfterTry { span: self.prev_token.span }))
@@ -3573,7 +3578,7 @@ fn is_try_block(&self) -> bool {
     }
 
     /// Parses an `async move? {...}` or `gen move? {...}` expression.
-    fn parse_gen_block(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_gen_block(&mut self) -> PResult<'a, Box<Expr>> {
         let lo = self.token.span;
         let kind = if self.eat_keyword(exp!(Async)) {
             if self.eat_keyword(exp!(Gen)) { GenBlockKind::AsyncGen } else { GenBlockKind::Async }
@@ -3622,9 +3627,9 @@ fn is_certainly_not_a_block(&self) -> bool {
 
     fn maybe_parse_struct_expr(
         &mut self,
-        qself: &Option<P<ast::QSelf>>,
+        qself: &Option<Box<ast::QSelf>>,
         path: &ast::Path,
-    ) -> Option<PResult<'a, P<Expr>>> {
+    ) -> Option<PResult<'a, Box<Expr>>> {
         let struct_allowed = !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL);
         if struct_allowed || self.is_certainly_not_a_block() {
             if let Err(err) = self.expect(exp!(OpenBrace)) {
@@ -3818,10 +3823,10 @@ pub(super) fn parse_struct_fields(
     /// Precondition: already parsed the '{'.
     pub(super) fn parse_expr_struct(
         &mut self,
-        qself: Option<P<ast::QSelf>>,
+        qself: Option<Box<ast::QSelf>>,
         pth: ast::Path,
         recover: bool,
-    ) -> PResult<'a, P<Expr>> {
+    ) -> PResult<'a, Box<Expr>> {
         let lo = pth.span;
         let (fields, base, recovered_async) =
             self.parse_struct_fields(pth.clone(), recover, exp!(CloseBrace))?;
@@ -3830,7 +3835,7 @@ pub(super) fn parse_expr_struct(
         let expr = if let Some(guar) = recovered_async {
             ExprKind::Err(guar)
         } else {
-            ExprKind::Struct(P(ast::StructExpr { qself, path: pth, fields, rest: base }))
+            ExprKind::Struct(Box::new(ast::StructExpr { qself, path: pth, fields, rest: base }))
         };
         Ok(self.mk_expr(span, expr))
     }
@@ -3945,14 +3950,14 @@ fn err_larrow_operator(&self, span: Span) {
         self.dcx().emit_err(errors::LeftArrowOperator { span });
     }
 
-    fn mk_assign_op(&self, assign_op: AssignOp, lhs: P<Expr>, rhs: P<Expr>) -> ExprKind {
+    fn mk_assign_op(&self, assign_op: AssignOp, lhs: Box<Expr>, rhs: Box<Expr>) -> ExprKind {
         ExprKind::AssignOp(assign_op, lhs, rhs)
     }
 
     fn mk_range(
         &mut self,
-        start: Option<P<Expr>>,
-        end: Option<P<Expr>>,
+        start: Option<Box<Expr>>,
+        end: Option<Box<Expr>>,
         limits: RangeLimits,
     ) -> ExprKind {
         if end.is_none() && limits == RangeLimits::Closed {
@@ -3963,51 +3968,56 @@ fn mk_range(
         }
     }
 
-    fn mk_unary(&self, unop: UnOp, expr: P<Expr>) -> ExprKind {
+    fn mk_unary(&self, unop: UnOp, expr: Box<Expr>) -> ExprKind {
         ExprKind::Unary(unop, expr)
     }
 
-    fn mk_binary(&self, binop: BinOp, lhs: P<Expr>, rhs: P<Expr>) -> ExprKind {
+    fn mk_binary(&self, binop: BinOp, lhs: Box<Expr>, rhs: Box<Expr>) -> ExprKind {
         ExprKind::Binary(binop, lhs, rhs)
     }
 
-    fn mk_index(&self, expr: P<Expr>, idx: P<Expr>, brackets_span: Span) -> ExprKind {
+    fn mk_index(&self, expr: Box<Expr>, idx: Box<Expr>, brackets_span: Span) -> ExprKind {
         ExprKind::Index(expr, idx, brackets_span)
     }
 
-    fn mk_call(&self, f: P<Expr>, args: ThinVec<P<Expr>>) -> ExprKind {
+    fn mk_call(&self, f: Box<Expr>, args: ThinVec<Box<Expr>>) -> ExprKind {
         ExprKind::Call(f, args)
     }
 
-    fn mk_await_expr(&mut self, self_arg: P<Expr>, lo: Span) -> P<Expr> {
+    fn mk_await_expr(&mut self, self_arg: Box<Expr>, lo: Span) -> Box<Expr> {
         let span = lo.to(self.prev_token.span);
         let await_expr = self.mk_expr(span, ExprKind::Await(self_arg, self.prev_token.span));
         self.recover_from_await_method_call();
         await_expr
     }
 
-    fn mk_use_expr(&mut self, self_arg: P<Expr>, lo: Span) -> P<Expr> {
+    fn mk_use_expr(&mut self, self_arg: Box<Expr>, lo: Span) -> Box<Expr> {
         let span = lo.to(self.prev_token.span);
         let use_expr = self.mk_expr(span, ExprKind::Use(self_arg, self.prev_token.span));
         self.recover_from_use();
         use_expr
     }
 
-    pub(crate) fn mk_expr_with_attrs(&self, span: Span, kind: ExprKind, attrs: AttrVec) -> P<Expr> {
-        P(Expr { kind, span, attrs, id: DUMMY_NODE_ID, tokens: None })
+    pub(crate) fn mk_expr_with_attrs(
+        &self,
+        span: Span,
+        kind: ExprKind,
+        attrs: AttrVec,
+    ) -> Box<Expr> {
+        Box::new(Expr { kind, span, attrs, id: DUMMY_NODE_ID, tokens: None })
     }
 
-    pub(crate) fn mk_expr(&self, span: Span, kind: ExprKind) -> P<Expr> {
+    pub(crate) fn mk_expr(&self, span: Span, kind: ExprKind) -> Box<Expr> {
         self.mk_expr_with_attrs(span, kind, AttrVec::new())
     }
 
-    pub(super) fn mk_expr_err(&self, span: Span, guar: ErrorGuaranteed) -> P<Expr> {
+    pub(super) fn mk_expr_err(&self, span: Span, guar: ErrorGuaranteed) -> Box<Expr> {
         self.mk_expr(span, ExprKind::Err(guar))
     }
 
     /// Create expression span ensuring the span of the parent node
     /// is larger than the span of lhs and rhs, including the attributes.
-    fn mk_expr_sp(&self, lhs: &P<Expr>, lhs_span: Span, op_span: Span, rhs_span: Span) -> Span {
+    fn mk_expr_sp(&self, lhs: &Box<Expr>, lhs_span: Span, op_span: Span, rhs_span: Span) -> Span {
         lhs.attrs
             .iter()
             .find(|a| a.style == AttrStyle::Outer)
@@ -4019,8 +4029,8 @@ fn mk_expr_sp(&self, lhs: &P<Expr>, lhs_span: Span, op_span: Span, rhs_span: Spa
     fn collect_tokens_for_expr(
         &mut self,
         attrs: AttrWrapper,
-        f: impl FnOnce(&mut Self, ast::AttrVec) -> PResult<'a, P<Expr>>,
-    ) -> PResult<'a, P<Expr>> {
+        f: impl FnOnce(&mut Self, ast::AttrVec) -> PResult<'a, Box<Expr>>,
+    ) -> PResult<'a, Box<Expr>> {
         self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
             let res = f(this, attrs)?;
             let trailing = Trailing::from(
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index 8632634..4a8530a 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -308,9 +308,7 @@ pub(super) fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
 
     /// Parses an experimental fn contract
     /// (`contract_requires(WWW) contract_ensures(ZZZ)`)
-    pub(super) fn parse_contract(
-        &mut self,
-    ) -> PResult<'a, Option<rustc_ast::ptr::P<ast::FnContract>>> {
+    pub(super) fn parse_contract(&mut self) -> PResult<'a, Option<Box<ast::FnContract>>> {
         let requires = if self.eat_keyword_noexpect(exp!(ContractRequires).kw) {
             self.psess.gated_spans.gate(sym::contracts_internals, self.prev_token.span);
             let precond = self.parse_expr()?;
@@ -328,7 +326,7 @@ pub(super) fn parse_contract(
         if requires.is_none() && ensures.is_none() {
             Ok(None)
         } else {
-            Ok(Some(rustc_ast::ptr::P(ast::FnContract { requires, ensures })))
+            Ok(Some(Box::new(ast::FnContract { requires, ensures })))
         }
     }
 
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index cb7c564..14a90e7 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -3,7 +3,6 @@
 
 use ast::token::IdentIsRaw;
 use rustc_ast::ast::*;
-use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter, InvisibleOrigin, MetaVarKind, TokenKind};
 use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
 use rustc_ast::util::case::Case;
@@ -56,12 +55,12 @@ fn parse_item_mod(&mut self, attrs: &mut AttrVec) -> PResult<'a, ItemKind> {
     pub fn parse_mod(
         &mut self,
         term: ExpTokenPair<'_>,
-    ) -> PResult<'a, (AttrVec, ThinVec<P<Item>>, ModSpans)> {
+    ) -> PResult<'a, (AttrVec, ThinVec<Box<Item>>, ModSpans)> {
         let lo = self.token.span;
         let attrs = self.parse_inner_attributes()?;
 
         let post_attr_lo = self.token.span;
-        let mut items: ThinVec<P<_>> = ThinVec::new();
+        let mut items: ThinVec<Box<_>> = ThinVec::new();
 
         // There shouldn't be any stray semicolons before or after items.
         // `parse_item` consumes the appropriate semicolons so any leftover is an error.
@@ -116,9 +115,9 @@ pub fn parse_mod(
 }
 
 impl<'a> Parser<'a> {
-    pub fn parse_item(&mut self, force_collect: ForceCollect) -> PResult<'a, Option<P<Item>>> {
+    pub fn parse_item(&mut self, force_collect: ForceCollect) -> PResult<'a, Option<Box<Item>>> {
         let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true };
-        self.parse_item_(fn_parse_mode, force_collect).map(|i| i.map(P))
+        self.parse_item_(fn_parse_mode, force_collect).map(|i| i.map(Box::new))
     }
 
     fn parse_item_(
@@ -327,7 +326,7 @@ fn parse_item_kind(
                 self.recover_missing_kw_before_item()?;
             }
             // MACRO INVOCATION ITEM
-            ItemKind::MacCall(P(self.parse_item_macro(vis)?))
+            ItemKind::MacCall(Box::new(self.parse_item_macro(vis)?))
         } else {
             return Ok(None);
         };
@@ -951,7 +950,7 @@ fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, Ite
     pub fn parse_impl_item(
         &mut self,
         force_collect: ForceCollect,
-    ) -> PResult<'a, Option<Option<P<AssocItem>>>> {
+    ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
         let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true };
         self.parse_assoc_item(fn_parse_mode, force_collect)
     }
@@ -959,7 +958,7 @@ pub fn parse_impl_item(
     pub fn parse_trait_item(
         &mut self,
         force_collect: ForceCollect,
-    ) -> PResult<'a, Option<Option<P<AssocItem>>>> {
+    ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
         let fn_parse_mode =
             FnParseMode { req_name: |edition| edition >= Edition::Edition2018, req_body: false };
         self.parse_assoc_item(fn_parse_mode, force_collect)
@@ -970,7 +969,7 @@ fn parse_assoc_item(
         &mut self,
         fn_parse_mode: FnParseMode,
         force_collect: ForceCollect,
-    ) -> PResult<'a, Option<Option<P<AssocItem>>>> {
+    ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
         Ok(self.parse_item_(fn_parse_mode, force_collect)?.map(
             |Item { attrs, id, span, vis, kind, tokens }| {
                 let kind = match AssocItemKind::try_from(kind) {
@@ -997,7 +996,7 @@ fn parse_assoc_item(
                         _ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"),
                     },
                 };
-                Some(P(Item { attrs, id, span, vis, kind, tokens }))
+                Some(Box::new(Item { attrs, id, span, vis, kind, tokens }))
             },
         ))
     }
@@ -1237,7 +1236,7 @@ fn parse_item_foreign_mod(
     pub fn parse_foreign_item(
         &mut self,
         force_collect: ForceCollect,
-    ) -> PResult<'a, Option<Option<P<ForeignItem>>>> {
+    ) -> PResult<'a, Option<Option<Box<ForeignItem>>>> {
         let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: false };
         Ok(self.parse_item_(fn_parse_mode, force_collect)?.map(
             |Item { attrs, id, span, vis, kind, tokens }| {
@@ -1263,7 +1262,7 @@ pub fn parse_foreign_item(
                         _ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
                     },
                 };
-                Some(P(Item { attrs, id, span, vis, kind, tokens }))
+                Some(Box::new(Item { attrs, id, span, vis, kind, tokens }))
             },
         ))
     }
@@ -1424,7 +1423,9 @@ fn parse_static_item(
     /// ```ebnf
     /// Const = "const" ($ident | "_") Generics ":" $ty (= $expr)? WhereClause ";" ;
     /// ```
-    fn parse_const_item(&mut self) -> PResult<'a, (Ident, Generics, P<Ty>, Option<P<ast::Expr>>)> {
+    fn parse_const_item(
+        &mut self,
+    ) -> PResult<'a, (Ident, Generics, Box<Ty>, Option<Box<ast::Expr>>)> {
         let ident = self.parse_ident_or_underscore()?;
 
         let mut generics = self.parse_generics()?;
@@ -1517,7 +1518,7 @@ fn recover_missing_global_item_type(
         &mut self,
         colon_present: bool,
         m: Option<Mutability>,
-    ) -> P<Ty> {
+    ) -> Box<Ty> {
         // Construct the error and stash it away with the hope
         // that typeck will later enrich the error with a type.
         let kind = match m {
@@ -1537,7 +1538,7 @@ fn recover_missing_global_item_type(
 
         // The user intended that the type be inferred,
         // so treat this as if the user wrote e.g. `const A: _ = expr;`.
-        P(Ty { kind: TyKind::Infer, span, id: ast::DUMMY_NODE_ID, tokens: None })
+        Box::new(Ty { kind: TyKind::Infer, span, id: ast::DUMMY_NODE_ID, tokens: None })
     }
 
     /// Parses an enum declaration.
@@ -2207,7 +2208,7 @@ fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemKind> {
             let arrow = TokenTree::token_alone(token::FatArrow, pspan.between(bspan)); // `=>`
             let tokens = TokenStream::new(vec![params, arrow, body]);
             let dspan = DelimSpan::from_pair(pspan.shrink_to_lo(), bspan.shrink_to_hi());
-            P(DelimArgs { dspan, delim: Delimiter::Brace, tokens })
+            Box::new(DelimArgs { dspan, delim: Delimiter::Brace, tokens })
         } else {
             self.unexpected_any()?
         };
@@ -2409,7 +2410,7 @@ fn parse_fn(
         sig_lo: Span,
         vis: &Visibility,
         case: Case,
-    ) -> PResult<'a, (Ident, FnSig, Generics, Option<P<FnContract>>, Option<P<Block>>)> {
+    ) -> PResult<'a, (Ident, FnSig, Generics, Option<Box<FnContract>>, Option<Box<Block>>)> {
         let fn_span = self.token.span;
         let header = self.parse_fn_front_matter(vis, case, FrontMatterParsingMode::Function)?; // `const ... fn`
         let ident = self.parse_ident()?; // `foo`
@@ -2539,7 +2540,7 @@ fn parse_fn_body(
         sig_hi: &mut Span,
         req_body: bool,
         fn_params_end: Option<Span>,
-    ) -> PResult<'a, Option<P<Block>>> {
+    ) -> PResult<'a, Option<Box<Block>>> {
         let has_semi = if req_body {
             self.token == TokenKind::Semi
         } else {
@@ -2939,8 +2940,8 @@ pub(super) fn parse_fn_decl(
         req_name: ReqName,
         ret_allow_plus: AllowPlus,
         recover_return_sign: RecoverReturnSign,
-    ) -> PResult<'a, P<FnDecl>> {
-        Ok(P(FnDecl {
+    ) -> PResult<'a, Box<FnDecl>> {
+        Ok(Box::new(FnDecl {
             inputs: self.parse_fn_params(req_name)?,
             output: self.parse_ret_ty(ret_allow_plus, RecoverQPath::Yes, recover_return_sign)?,
         }))
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 90491e5..0a8a020 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -25,7 +25,6 @@
 pub(crate) use item::FnParseMode;
 pub use pat::{CommaRecoveryMode, RecoverColon, RecoverComma};
 use path::PathStyle;
-use rustc_ast::ptr::P;
 use rustc_ast::token::{
     self, IdentIsRaw, InvisibleOrigin, MetaVarKind, NtExprKind, NtPatKind, Token, TokenKind,
 };
@@ -1286,7 +1285,7 @@ fn parse_constness_(&mut self, case: Case, is_closure: bool) -> Const {
     }
 
     /// Parses inline const expressions.
-    fn parse_const_block(&mut self, span: Span, pat: bool) -> PResult<'a, P<Expr>> {
+    fn parse_const_block(&mut self, span: Span, pat: bool) -> PResult<'a, Box<Expr>> {
         self.expect_keyword(exp!(Const))?;
         let (attrs, blk) = self.parse_inner_attrs_and_block(None)?;
         let anon_const = AnonConst {
@@ -1343,9 +1342,9 @@ fn parse_field_name(&mut self) -> PResult<'a, Ident> {
         }
     }
 
-    fn parse_delim_args(&mut self) -> PResult<'a, P<DelimArgs>> {
+    fn parse_delim_args(&mut self) -> PResult<'a, Box<DelimArgs>> {
         if let Some(args) = self.parse_delim_args_inner() {
-            Ok(P(args))
+            Ok(Box::new(args))
         } else {
             self.unexpected_any()
         }
@@ -1470,7 +1469,7 @@ pub fn parse_visibility(&mut self, fbt: FollowedByType) -> PResult<'a, Visibilit
                 let path = self.parse_path(PathStyle::Mod)?; // `path`
                 self.expect(exp!(CloseParen))?; // `)`
                 let vis = VisibilityKind::Restricted {
-                    path: P(path),
+                    path: Box::new(path),
                     id: ast::DUMMY_NODE_ID,
                     shorthand: false,
                 };
@@ -1487,7 +1486,7 @@ pub fn parse_visibility(&mut self, fbt: FollowedByType) -> PResult<'a, Visibilit
                 let path = self.parse_path(PathStyle::Mod)?; // `crate`/`super`/`self`
                 self.expect(exp!(CloseParen))?; // `)`
                 let vis = VisibilityKind::Restricted {
-                    path: P(path),
+                    path: Box::new(path),
                     id: ast::DUMMY_NODE_ID,
                     shorthand: true,
                 };
@@ -1652,14 +1651,14 @@ pub enum ParseNtResult {
     Tt(TokenTree),
     Ident(Ident, IdentIsRaw),
     Lifetime(Ident, IdentIsRaw),
-    Item(P<ast::Item>),
-    Block(P<ast::Block>),
-    Stmt(P<ast::Stmt>),
-    Pat(P<ast::Pat>, NtPatKind),
-    Expr(P<ast::Expr>, NtExprKind),
-    Literal(P<ast::Expr>),
-    Ty(P<ast::Ty>),
-    Meta(P<ast::AttrItem>),
-    Path(P<ast::Path>),
-    Vis(P<ast::Visibility>),
+    Item(Box<ast::Item>),
+    Block(Box<ast::Block>),
+    Stmt(Box<ast::Stmt>),
+    Pat(Box<ast::Pat>, NtPatKind),
+    Expr(Box<ast::Expr>, NtExprKind),
+    Literal(Box<ast::Expr>),
+    Ty(Box<ast::Ty>),
+    Meta(Box<ast::AttrItem>),
+    Path(Box<ast::Path>),
+    Vis(Box<ast::Visibility>),
 }
diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs
index 7c83e96..42eb078 100644
--- a/compiler/rustc_parse/src/parser/nonterminal.rs
+++ b/compiler/rustc_parse/src/parser/nonterminal.rs
@@ -1,4 +1,3 @@
-use rustc_ast::ptr::P;
 use rustc_ast::token::NtExprKind::*;
 use rustc_ast::token::NtPatKind::*;
 use rustc_ast::token::{self, InvisibleOrigin, MetaVarKind, NonterminalKind, Token};
@@ -129,7 +128,7 @@ pub fn parse_nonterminal(&mut self, kind: NonterminalKind) -> PResult<'a, ParseN
                 Ok(ParseNtResult::Block(self.collect_tokens_no_attrs(|this| this.parse_block())?))
             }
             NonterminalKind::Stmt => match self.parse_stmt(ForceCollect::Yes)? {
-                Some(stmt) => Ok(ParseNtResult::Stmt(P(stmt))),
+                Some(stmt) => Ok(ParseNtResult::Stmt(Box::new(stmt))),
                 None => {
                     Err(self.dcx().create_err(UnexpectedNonterminal::Statement(self.token.span)))
                 }
@@ -170,16 +169,15 @@ pub fn parse_nonterminal(&mut self, kind: NonterminalKind) -> PResult<'a, ParseN
                     }))
                 }
             }
-            NonterminalKind::Path => Ok(ParseNtResult::Path(P(
-                self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?
+            NonterminalKind::Path => Ok(ParseNtResult::Path(Box::new(
+                self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?,
             ))),
             NonterminalKind::Meta => {
-                Ok(ParseNtResult::Meta(P(self.parse_attr_item(ForceCollect::Yes)?)))
+                Ok(ParseNtResult::Meta(Box::new(self.parse_attr_item(ForceCollect::Yes)?)))
             }
-            NonterminalKind::Vis => {
-                Ok(ParseNtResult::Vis(P(self
-                    .collect_tokens_no_attrs(|this| this.parse_visibility(FollowedByType::Yes))?)))
-            }
+            NonterminalKind::Vis => Ok(ParseNtResult::Vis(Box::new(
+                self.collect_tokens_no_attrs(|this| this.parse_visibility(FollowedByType::Yes))?,
+            ))),
             NonterminalKind::Lifetime => {
                 // We want to keep `'keyword` parsing, just like `keyword` is still
                 // an ident for nonterminal purposes.
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 64653ee2a..a415849 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -1,7 +1,6 @@
 use std::ops::Bound;
 
 use rustc_ast::mut_visit::{self, MutVisitor};
-use rustc_ast::ptr::P;
 use rustc_ast::token::NtPatKind::*;
 use rustc_ast::token::{self, IdentIsRaw, MetaVarKind, Token};
 use rustc_ast::util::parser::ExprPrecedence;
@@ -108,7 +107,7 @@ pub fn parse_pat_allow_top_guard(
         rc: RecoverComma,
         ra: RecoverColon,
         rt: CommaRecoveryMode,
-    ) -> PResult<'a, P<Pat>> {
+    ) -> PResult<'a, Box<Pat>> {
         let pat = self.parse_pat_no_top_guard(expected, rc, ra, rt)?;
 
         if self.eat_keyword(exp!(If)) {
@@ -131,7 +130,7 @@ pub fn parse_pat_no_top_alt(
         &mut self,
         expected: Option<Expected>,
         syntax_loc: Option<PatternLocation>,
-    ) -> PResult<'a, P<Pat>> {
+    ) -> PResult<'a, Box<Pat>> {
         self.parse_pat_with_range_pat(true, expected, syntax_loc)
     }
 
@@ -150,7 +149,7 @@ pub fn parse_pat_no_top_guard(
         rc: RecoverComma,
         ra: RecoverColon,
         rt: CommaRecoveryMode,
-    ) -> PResult<'a, P<Pat>> {
+    ) -> PResult<'a, Box<Pat>> {
         self.parse_pat_no_top_guard_inner(expected, rc, ra, rt, None).map(|(pat, _)| pat)
     }
 
@@ -163,7 +162,7 @@ fn parse_pat_no_top_guard_inner(
         ra: RecoverColon,
         rt: CommaRecoveryMode,
         syntax_loc: Option<PatternLocation>,
-    ) -> PResult<'a, (P<Pat>, bool)> {
+    ) -> PResult<'a, (Box<Pat>, bool)> {
         // Keep track of whether we recovered from a trailing vert so that we can avoid duplicated
         // suggestions (which bothers rustfix).
         //
@@ -253,7 +252,7 @@ pub(super) fn parse_pat_before_ty(
         expected: Option<Expected>,
         rc: RecoverComma,
         syntax_loc: PatternLocation,
-    ) -> PResult<'a, (P<Pat>, bool)> {
+    ) -> PResult<'a, (Box<Pat>, bool)> {
         // We use `parse_pat_allow_top_alt` regardless of whether we actually want top-level
         // or-patterns so that we can detect when a user tries to use it. This allows us to print a
         // better error message.
@@ -301,7 +300,7 @@ pub(super) fn parse_pat_before_ty(
     ///
     /// The return value represents the parsed pattern and `true` if a `Colon` was parsed (`false`
     /// otherwise).
-    pub(super) fn parse_fn_param_pat_colon(&mut self) -> PResult<'a, (P<Pat>, bool)> {
+    pub(super) fn parse_fn_param_pat_colon(&mut self) -> PResult<'a, (Box<Pat>, bool)> {
         // In order to get good UX, we first recover in the case of a leading vert for an illegal
         // top-level or-pat. Normally, this means recovering both `|` and `||`, but in this case,
         // a leading `||` probably doesn't indicate an or-pattern attempt, so we handle that
@@ -685,7 +684,7 @@ fn visit_pat(&mut self, p: &'a Pat) -> Self::Result {
         PatVisitor { parser: self, stmt, arm: None, field: None }.visit_stmt(stmt);
     }
 
-    fn eat_metavar_pat(&mut self) -> Option<P<Pat>> {
+    fn eat_metavar_pat(&mut self) -> Option<Box<Pat>> {
         // Must try both kinds of pattern nonterminals.
         if let Some(pat) = self.eat_metavar_seq_with_matcher(
             |mv_kind| matches!(mv_kind, MetaVarKind::Pat(PatParam { .. })),
@@ -713,7 +712,7 @@ fn parse_pat_with_range_pat(
         allow_range_pat: bool,
         expected: Option<Expected>,
         syntax_loc: Option<PatternLocation>,
-    ) -> PResult<'a, P<Pat>> {
+    ) -> PResult<'a, Box<Pat>> {
         maybe_recover_from_interpolated_ty_qpath!(self, true);
 
         if let Some(pat) = self.eat_metavar_pat() {
@@ -909,7 +908,7 @@ fn recover_dotdotdot_rest_pat(&mut self, lo: Span) -> PatKind {
     /// e.g. [F#][and] where they are called AND-patterns.
     ///
     /// [and]: https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/pattern-matching
-    fn recover_intersection_pat(&mut self, lhs: P<Pat>) -> PResult<'a, P<Pat>> {
+    fn recover_intersection_pat(&mut self, lhs: Box<Pat>) -> PResult<'a, Box<Pat>> {
         if self.token != token::At {
             // Next token is not `@` so it's not going to be an intersection pattern.
             return Ok(lhs);
@@ -1091,7 +1090,7 @@ fn parse_pat_ident_mut(&mut self) -> PResult<'a, PatKind> {
 
     /// Turn all by-value immutable bindings in a pattern into mutable bindings.
     /// Returns `true` if any change was made.
-    fn make_all_value_bindings_mutable(pat: &mut P<Pat>) -> bool {
+    fn make_all_value_bindings_mutable(pat: &mut Box<Pat>) -> bool {
         struct AddMut(bool);
         impl MutVisitor for AddMut {
             fn visit_pat(&mut self, pat: &mut Pat) {
@@ -1139,7 +1138,7 @@ fn recover_additional_muts(&mut self) {
     fn parse_pat_mac_invoc(&mut self, path: Path) -> PResult<'a, PatKind> {
         self.bump();
         let args = self.parse_delim_args()?;
-        let mac = P(MacCall { path, args });
+        let mac = Box::new(MacCall { path, args });
         Ok(PatKind::MacCall(mac))
     }
 
@@ -1147,7 +1146,7 @@ fn fatal_unexpected_non_pat(
         &mut self,
         err: Diag<'a>,
         expected: Option<Expected>,
-    ) -> PResult<'a, P<Pat>> {
+    ) -> PResult<'a, Box<Pat>> {
         err.cancel();
 
         let expected = Expected::to_string_or_fallback(expected);
@@ -1182,7 +1181,7 @@ fn parse_range_end(&mut self) -> Option<Spanned<RangeEnd>> {
     /// `$begin $form` has already been parsed.
     fn parse_pat_range_begin_with(
         &mut self,
-        begin: P<Expr>,
+        begin: Box<Expr>,
         re: Spanned<RangeEnd>,
     ) -> PResult<'a, PatKind> {
         let end = if self.is_pat_range_end_start(0) {
@@ -1262,7 +1261,7 @@ fn is_pat_range_end_start(&self, dist: usize) -> bool {
     }
 
     /// Parse a range pattern end bound
-    fn parse_pat_range_end(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_pat_range_end(&mut self) -> PResult<'a, Box<Expr>> {
         // recover leading `(`
         let open_paren = (self.may_recover() && self.eat_noexpect(&token::OpenParen))
             .then_some(self.prev_token.span);
@@ -1380,7 +1379,7 @@ fn parse_pat_ident(
     }
 
     /// Parse a struct ("record") pattern (e.g. `Foo { ... }` or `Foo::Bar { ... }`).
-    fn parse_pat_struct(&mut self, qself: Option<P<QSelf>>, path: Path) -> PResult<'a, PatKind> {
+    fn parse_pat_struct(&mut self, qself: Option<Box<QSelf>>, path: Path) -> PResult<'a, PatKind> {
         if qself.is_some() {
             // Feature gate the use of qualified paths in patterns
             self.psess.gated_spans.gate(sym::more_qualified_paths, path.span);
@@ -1400,7 +1399,7 @@ fn parse_pat_struct(&mut self, qself: Option<P<QSelf>>, path: Path) -> PResult<'
     /// Parse tuple struct or tuple variant pattern (e.g. `Foo(...)` or `Foo::Bar(...)`).
     fn parse_pat_tuple_struct(
         &mut self,
-        qself: Option<P<QSelf>>,
+        qself: Option<Box<QSelf>>,
         path: Path,
     ) -> PResult<'a, PatKind> {
         let (fields, _) = self.parse_paren_comma_seq(|p| {
@@ -1749,11 +1748,11 @@ fn parse_pat_field(&mut self, lo: Span, attrs: AttrVec) -> PResult<'a, PatField>
         })
     }
 
-    pub(super) fn mk_pat_ident(&self, span: Span, ann: BindingMode, ident: Ident) -> P<Pat> {
+    pub(super) fn mk_pat_ident(&self, span: Span, ann: BindingMode, ident: Ident) -> Box<Pat> {
         self.mk_pat(span, PatKind::Ident(ann, ident, None))
     }
 
-    pub(super) fn mk_pat(&self, span: Span, kind: PatKind) -> P<Pat> {
-        P(Pat { kind, span, id: ast::DUMMY_NODE_ID, tokens: None })
+    pub(super) fn mk_pat(&self, span: Span, kind: PatKind) -> Box<Pat> {
+        Box::new(Pat { kind, span, id: ast::DUMMY_NODE_ID, tokens: None })
     }
 }
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 8e65ab9..a6ec3ea 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -1,7 +1,6 @@
 use std::mem;
 
 use ast::token::IdentIsRaw;
-use rustc_ast::ptr::P;
 use rustc_ast::token::{self, MetaVarKind, Token, TokenKind};
 use rustc_ast::{
     self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocItemConstraint,
@@ -75,7 +74,7 @@ impl<'a> Parser<'a> {
     /// `<T as U>::a`
     /// `<T as U>::F::a<S>` (without disambiguator)
     /// `<T as U>::F::a::<S>` (with disambiguator)
-    pub(super) fn parse_qpath(&mut self, style: PathStyle) -> PResult<'a, (P<QSelf>, Path)> {
+    pub(super) fn parse_qpath(&mut self, style: PathStyle) -> PResult<'a, (Box<QSelf>, Path)> {
         let lo = self.prev_token.span;
         let ty = self.parse_ty()?;
 
@@ -105,7 +104,7 @@ pub(super) fn parse_qpath(&mut self, style: PathStyle) -> PResult<'a, (P<QSelf>,
             self.expect(exp!(PathSep))?;
         }
 
-        let qself = P(QSelf { ty, path_span, position: path.segments.len() });
+        let qself = Box::new(QSelf { ty, path_span, position: path.segments.len() });
         if !is_import_coupler {
             self.parse_path_segments(&mut path.segments, style, None)?;
         }
@@ -380,7 +379,7 @@ pub(super) fn parse_path_segment(
                             .emit_err(errors::BadReturnTypeNotationOutput { span, suggestion });
                     }
 
-                    P(ast::GenericArgs::ParenthesizedElided(span))
+                    Box::new(ast::GenericArgs::ParenthesizedElided(span))
                 } else {
                     // `(T, U) -> R`
 
@@ -842,7 +841,7 @@ fn parse_assoc_equality_term(
     /// - A literal.
     /// - A numeric literal prefixed by `-`.
     /// - A single-segment path.
-    pub(super) fn expr_is_valid_const_arg(&self, expr: &P<rustc_ast::Expr>) -> bool {
+    pub(super) fn expr_is_valid_const_arg(&self, expr: &Box<rustc_ast::Expr>) -> bool {
         match &expr.kind {
             ast::ExprKind::Block(_, _)
             | ast::ExprKind::Lit(_)
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 2fa6520..7aacb67 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -4,7 +4,6 @@
 
 use ast::Label;
 use rustc_ast as ast;
-use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter, InvisibleOrigin, MetaVarKind, TokenKind};
 use rustc_ast::util::classify::{self, TrailingBrace};
 use rustc_ast::{
@@ -157,7 +156,7 @@ pub fn parse_stmt_without_recovery(
             FnParseMode { req_name: |_| true, req_body: true },
             force_collect,
         )? {
-            self.mk_stmt(lo.to(item.span), StmtKind::Item(P(item)))
+            self.mk_stmt(lo.to(item.span), StmtKind::Item(Box::new(item)))
         } else if self.eat(exp!(Semi)) {
             // Do not attempt to parse an expression if we're done here.
             self.error_outer_attrs(attrs);
@@ -246,7 +245,7 @@ fn parse_stmt_mac(&mut self, lo: Span, attrs: AttrVec, path: ast::Path) -> PResu
             _ => MacStmtStyle::NoBraces,
         };
 
-        let mac = P(MacCall { path, args });
+        let mac = Box::new(MacCall { path, args });
 
         let kind = if (style == MacStmtStyle::Braces
             && !matches!(self.token.kind, token::Dot | token::Question))
@@ -256,7 +255,7 @@ fn parse_stmt_mac(&mut self, lo: Span, attrs: AttrVec, path: ast::Path) -> PResu
                     | token::Eof
                     | token::CloseInvisible(InvisibleOrigin::MetaVar(MetaVarKind::Stmt))
             ) {
-            StmtKind::MacCall(P(MacCallStmt { mac, style, attrs, tokens: None }))
+            StmtKind::MacCall(Box::new(MacCallStmt { mac, style, attrs, tokens: None }))
         } else {
             // Since none of the above applied, this is an expression statement macro.
             let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac));
@@ -307,7 +306,7 @@ fn recover_stmt_local_after_let(
     }
 
     /// Parses a local variable declaration.
-    fn parse_local(&mut self, super_: Option<Span>, attrs: AttrVec) -> PResult<'a, P<Local>> {
+    fn parse_local(&mut self, super_: Option<Span>, attrs: AttrVec) -> PResult<'a, Box<Local>> {
         let lo = super_.unwrap_or(self.prev_token.span);
 
         if self.token.is_keyword(kw::Const) && self.look_ahead(1, |t| t.is_ident()) {
@@ -409,7 +408,7 @@ fn parse_local(&mut self, super_: Option<Span>, attrs: AttrVec) -> PResult<'a, P
             }
         };
         let hi = if self.token == token::Semi { self.token.span } else { self.prev_token.span };
-        Ok(P(ast::Local {
+        Ok(Box::new(ast::Local {
             super_,
             ty,
             pat,
@@ -463,7 +462,7 @@ fn check_let_else_init_trailing_brace(&self, init: &ast::Expr) {
     }
 
     /// Parses the RHS of a local variable declaration (e.g., `= 14;`).
-    fn parse_initializer(&mut self, eq_optional: bool) -> PResult<'a, Option<P<Expr>>> {
+    fn parse_initializer(&mut self, eq_optional: bool) -> PResult<'a, Option<Box<Expr>>> {
         let eq_consumed = match self.token.kind {
             token::PlusEq
             | token::MinusEq
@@ -494,7 +493,7 @@ fn parse_initializer(&mut self, eq_optional: bool) -> PResult<'a, Option<P<Expr>
     }
 
     /// Parses a block. No inner attributes are allowed.
-    pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
+    pub fn parse_block(&mut self) -> PResult<'a, Box<Block>> {
         let (attrs, block) = self.parse_inner_attrs_and_block(None)?;
         if let [.., last] = &*attrs {
             let suggest_to_outer = match &last.kind {
@@ -679,7 +678,7 @@ fn error_block_no_opening_brace<T>(&mut self) -> PResult<'a, T> {
     pub(super) fn parse_inner_attrs_and_block(
         &mut self,
         loop_header: Option<Span>,
-    ) -> PResult<'a, (AttrVec, P<Block>)> {
+    ) -> PResult<'a, (AttrVec, Box<Block>)> {
         self.parse_block_common(self.token.span, BlockCheckMode::Default, loop_header)
     }
 
@@ -692,7 +691,7 @@ pub(super) fn parse_block_common(
         lo: Span,
         blk_mode: BlockCheckMode,
         loop_header: Option<Span>,
-    ) -> PResult<'a, (AttrVec, P<Block>)> {
+    ) -> PResult<'a, (AttrVec, Box<Block>)> {
         if let Some(block) = self.eat_metavar_seq(MetaVarKind::Block, |this| this.parse_block()) {
             return Ok((AttrVec::new(), block));
         }
@@ -718,7 +717,7 @@ pub fn parse_block_tail(
         lo: Span,
         s: BlockCheckMode,
         recover: AttemptLocalParseRecovery,
-    ) -> PResult<'a, P<Block>> {
+    ) -> PResult<'a, Box<Block>> {
         let mut stmts = ThinVec::new();
         let mut snapshot = None;
         while !self.eat(exp!(CloseBrace)) {
@@ -1050,8 +1049,8 @@ pub(super) fn mk_block(
         stmts: ThinVec<Stmt>,
         rules: BlockCheckMode,
         span: Span,
-    ) -> P<Block> {
-        P(Block { stmts, id: DUMMY_NODE_ID, rules, span, tokens: None })
+    ) -> Box<Block> {
+        Box::new(Block { stmts, id: DUMMY_NODE_ID, rules, span, tokens: None })
     }
 
     pub(super) fn mk_stmt(&self, span: Span, kind: StmtKind) -> Stmt {
@@ -1062,7 +1061,7 @@ pub(super) fn mk_stmt_err(&self, span: Span, guar: ErrorGuaranteed) -> Stmt {
         self.mk_stmt(span, StmtKind::Expr(self.mk_expr_err(span, guar)))
     }
 
-    pub(super) fn mk_block_err(&self, span: Span, guar: ErrorGuaranteed) -> P<Block> {
+    pub(super) fn mk_block_err(&self, span: Span, guar: ErrorGuaranteed) -> Box<Block> {
         self.mk_block(thin_vec![self.mk_stmt_err(span, guar)], BlockCheckMode::Default, span)
     }
 }
diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs
index 43a1d77..a6e7266 100644
--- a/compiler/rustc_parse/src/parser/tests.rs
+++ b/compiler/rustc_parse/src/parser/tests.rs
@@ -8,7 +8,6 @@
 use std::{io, str};
 
 use ast::token::IdentIsRaw;
-use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter, Token};
 use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
 use rustc_ast::{self as ast, PatKind, visit};
@@ -2240,7 +2239,7 @@ fn parse_item_from_source_str(
     name: FileName,
     source: String,
     psess: &ParseSess,
-) -> PResult<'_, Option<P<ast::Item>>> {
+) -> PResult<'_, Option<Box<ast::Item>>> {
     unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source))
         .parse_item(ForceCollect::No)
 }
@@ -2251,12 +2250,12 @@ fn sp(a: u32, b: u32) -> Span {
 }
 
 /// Parses a string, return an expression.
-fn string_to_expr(source_str: String) -> P<ast::Expr> {
+fn string_to_expr(source_str: String) -> Box<ast::Expr> {
     with_error_checking_parse(source_str, &psess(), |p| p.parse_expr())
 }
 
 /// Parses a string, returns an item.
-fn string_to_item(source_str: String) -> Option<P<ast::Item>> {
+fn string_to_item(source_str: String) -> Option<Box<ast::Item>> {
     with_error_checking_parse(source_str, &psess(), |p| p.parse_item(ForceCollect::No))
 }
 
@@ -2520,7 +2519,7 @@ fn parse_expr_from_source_str(
         name: FileName,
         source: String,
         psess: &ParseSess,
-    ) -> PResult<'_, P<ast::Expr>> {
+    ) -> PResult<'_, Box<ast::Expr>> {
         unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source)).parse_expr()
     }
 
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 59048e4..0d47973 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -1,4 +1,3 @@
-use rustc_ast::ptr::P;
 use rustc_ast::token::{self, IdentIsRaw, MetaVarKind, Token, TokenKind};
 use rustc_ast::util::case::Case;
 use rustc_ast::{
@@ -105,7 +104,7 @@ fn can_begin_dyn_bound_in_edition_2015(t: &Token) -> bool {
 
 impl<'a> Parser<'a> {
     /// Parses a type.
-    pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
+    pub fn parse_ty(&mut self) -> PResult<'a, Box<Ty>> {
         // Make sure deeply nested types don't overflow the stack.
         ensure_sufficient_stack(|| {
             self.parse_ty_common(
@@ -122,7 +121,7 @@ pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
     pub(super) fn parse_ty_with_generics_recovery(
         &mut self,
         ty_params: &Generics,
-    ) -> PResult<'a, P<Ty>> {
+    ) -> PResult<'a, Box<Ty>> {
         self.parse_ty_common(
             AllowPlus::Yes,
             AllowCVariadic::No,
@@ -136,7 +135,7 @@ pub(super) fn parse_ty_with_generics_recovery(
     /// Parse a type suitable for a function or function pointer parameter.
     /// The difference from `parse_ty` is that this version allows `...`
     /// (`CVarArgs`) at the top level of the type.
-    pub(super) fn parse_ty_for_param(&mut self) -> PResult<'a, P<Ty>> {
+    pub(super) fn parse_ty_for_param(&mut self) -> PResult<'a, Box<Ty>> {
         self.parse_ty_common(
             AllowPlus::Yes,
             AllowCVariadic::Yes,
@@ -153,7 +152,7 @@ pub(super) fn parse_ty_for_param(&mut self) -> PResult<'a, P<Ty>> {
     ///     `+` is prohibited to maintain operator priority (P(+) < P(&)).
     /// Example 2: `value1 as TYPE + value2`
     ///     `+` is prohibited to avoid interactions with expression grammar.
-    pub(super) fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
+    pub(super) fn parse_ty_no_plus(&mut self) -> PResult<'a, Box<Ty>> {
         self.parse_ty_common(
             AllowPlus::No,
             AllowCVariadic::No,
@@ -166,7 +165,7 @@ pub(super) fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
 
     /// Parses a type following an `as` cast. Similar to `parse_ty_no_plus`, but signaling origin
     /// for better diagnostics involving `?`.
-    pub(super) fn parse_as_cast_ty(&mut self) -> PResult<'a, P<Ty>> {
+    pub(super) fn parse_as_cast_ty(&mut self) -> PResult<'a, Box<Ty>> {
         self.parse_ty_common(
             AllowPlus::No,
             AllowCVariadic::No,
@@ -177,7 +176,7 @@ pub(super) fn parse_as_cast_ty(&mut self) -> PResult<'a, P<Ty>> {
         )
     }
 
-    pub(super) fn parse_ty_no_question_mark_recover(&mut self) -> PResult<'a, P<Ty>> {
+    pub(super) fn parse_ty_no_question_mark_recover(&mut self) -> PResult<'a, Box<Ty>> {
         self.parse_ty_common(
             AllowPlus::Yes,
             AllowCVariadic::No,
@@ -190,7 +189,7 @@ pub(super) fn parse_ty_no_question_mark_recover(&mut self) -> PResult<'a, P<Ty>>
 
     /// Parse a type without recovering `:` as `->` to avoid breaking code such
     /// as `where fn() : for<'a>`.
-    pub(super) fn parse_ty_for_where_clause(&mut self) -> PResult<'a, P<Ty>> {
+    pub(super) fn parse_ty_for_where_clause(&mut self) -> PResult<'a, Box<Ty>> {
         self.parse_ty_common(
             AllowPlus::Yes,
             AllowCVariadic::No,
@@ -250,7 +249,7 @@ fn parse_ty_common(
         recover_return_sign: RecoverReturnSign,
         ty_generics: Option<&Generics>,
         recover_question_mark: RecoverQuestionMark,
-    ) -> PResult<'a, P<Ty>> {
+    ) -> PResult<'a, Box<Ty>> {
         let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes;
         maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
         if self.token == token::Pound && self.look_ahead(1, |t| *t == token::OpenBracket) {
@@ -425,7 +424,7 @@ fn parse_unsafe_binder_ty(&mut self) -> PResult<'a, TyKind> {
         let span = lo.to(self.prev_token.span);
         self.psess.gated_spans.gate(sym::unsafe_binders, span);
 
-        Ok(TyKind::UnsafeBinder(P(UnsafeBinderTy { generic_params, inner_ty })))
+        Ok(TyKind::UnsafeBinder(Box::new(UnsafeBinderTy { generic_params, inner_ty })))
     }
 
     /// Parses either:
@@ -610,7 +609,7 @@ fn parse_array_or_slice_ty(&mut self) -> PResult<'a, TyKind> {
     /// - `[u8, 5]` → suggests using `;`, return a Array type
     /// - `[u8 5]` → suggests using `;`, return a Array type
     /// Consider to add more cases in the future.
-    fn maybe_recover_array_ty_without_semi(&mut self, elt_ty: P<Ty>) -> PResult<'a, TyKind> {
+    fn maybe_recover_array_ty_without_semi(&mut self, elt_ty: Box<Ty>) -> PResult<'a, TyKind> {
         let span = self.token.span;
         let token_descr = super::token_descr(&self.token);
         let mut err =
@@ -773,7 +772,13 @@ fn parse_ty_fn_ptr(
         let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?;
 
         let decl_span = span_start.to(self.prev_token.span);
-        Ok(TyKind::FnPtr(P(FnPtrTy { ext, safety, generic_params: params, decl, decl_span })))
+        Ok(TyKind::FnPtr(Box::new(FnPtrTy {
+            ext,
+            safety,
+            generic_params: params,
+            decl,
+            decl_span,
+        })))
     }
 
     /// Recover from function pointer types with a generic parameter list (e.g. `fn<'a>(&'a str)`).
@@ -915,7 +920,7 @@ fn parse_path_start_ty(
         let path = self.parse_path_inner(PathStyle::Type, ty_generics)?;
         if self.eat(exp!(Bang)) {
             // Macro invocation in type position
-            Ok(TyKind::MacCall(P(MacCall { path, args: self.parse_delim_args()? })))
+            Ok(TyKind::MacCall(Box::new(MacCall { path, args: self.parse_delim_args()? })))
         } else if allow_plus == AllowPlus::Yes && self.check_plus() {
             // `Trait1 + Trait2 + 'a`
             self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true, ast::Parens::No)
@@ -1015,7 +1020,7 @@ fn parse_generic_lt_bound(
         let bound = GenericBound::Outlives(lt);
         if let ast::Parens::Yes = parens {
             // FIXME(Centril): Consider not erroring here and accepting `('lt)` instead,
-            // possibly introducing `GenericBound::Paren(P<GenericBound>)`?
+            // possibly introducing `GenericBound::Paren(Box<GenericBound>)`?
             self.recover_paren_lifetime(lo)?;
         }
         Ok(bound)
@@ -1317,12 +1322,14 @@ fn recover_path_from_fn(&mut self) -> Option<ast::Path> {
                     segments: thin_vec![ast::PathSegment {
                         ident: Ident::new(sym::Fn, fn_token_span),
                         id: DUMMY_NODE_ID,
-                        args: Some(P(ast::GenericArgs::Parenthesized(ast::ParenthesizedArgs {
-                            span: args_lo.to(self.prev_token.span),
-                            inputs: decl.inputs.iter().map(|a| a.ty.clone()).collect(),
-                            inputs_span: args_lo.until(decl.output.span()),
-                            output: decl.output.clone(),
-                        }))),
+                        args: Some(Box::new(ast::GenericArgs::Parenthesized(
+                            ast::ParenthesizedArgs {
+                                span: args_lo.to(self.prev_token.span),
+                                inputs: decl.inputs.iter().map(|a| a.ty.clone()).collect(),
+                                inputs_span: args_lo.until(decl.output.span()),
+                                output: decl.output.clone(),
+                            }
+                        ))),
                     }],
                     tokens: None,
                 })
@@ -1464,7 +1471,7 @@ pub(super) fn expect_lifetime(&mut self) -> Lifetime {
         }
     }
 
-    pub(super) fn mk_ty(&self, span: Span, kind: TyKind) -> P<Ty> {
-        P(Ty { kind, span, id: ast::DUMMY_NODE_ID, tokens: None })
+    pub(super) fn mk_ty(&self, span: Span, kind: TyKind) -> Box<Ty> {
+        Box::new(Ty { kind, span, id: ast::DUMMY_NODE_ID, tokens: None })
     }
 }
diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs
index 6ee325d..c83610d 100644
--- a/compiler/rustc_passes/src/input_stats.rs
+++ b/compiler/rustc_passes/src/input_stats.rs
@@ -44,11 +44,11 @@ fn new() -> Node {
 /// For example, `ast::Visitor` has `visit_ident`, but `Ident`s are always
 /// stored inline within other AST nodes, so we don't implement `visit_ident`
 /// here. In contrast, we do implement `visit_expr` because `ast::Expr` is
-/// always stored as `P<ast::Expr>`, and every such expression should be
+/// always stored as `Box<ast::Expr>`, and every such expression should be
 /// measured separately.
 ///
 /// In general, a `visit_foo` method should be implemented here if the
-/// corresponding `Foo` type is always stored on its own, e.g.: `P<Foo>`,
+/// corresponding `Foo` type is always stored on its own, e.g.: `Box<Foo>`,
 /// `Box<Foo>`, `Vec<Foo>`, `Box<[Foo]>`.
 ///
 /// There are some types in the AST and HIR tree that the visitors do not have
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 517e20e..66f7958 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1,4 +1,3 @@
-use rustc_ast::ptr::P;
 use rustc_ast::visit::{self, Visitor};
 use rustc_ast::{
     self as ast, CRATE_NODE_ID, Crate, ItemKind, ModKind, NodeId, Path, join_path_idents,
@@ -3347,7 +3346,7 @@ fn visit_item(&mut self, item: &'tcx ast::Item) {
     }
 }
 
-fn search_for_any_use_in_items(items: &[P<ast::Item>]) -> Option<Span> {
+fn search_for_any_use_in_items(items: &[Box<ast::Item>]) -> Option<Span> {
     for item in items {
         if let ItemKind::Use(..) = item.kind
             && is_span_suitable_for_use_injection(item.span)
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index fb6f572..8f0c08c 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -12,7 +12,6 @@
 use std::collections::hash_map::Entry;
 use std::mem::{replace, swap, take};
 
-use rustc_ast::ptr::P;
 use rustc_ast::visit::{
     AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor, try_visit, visit_opt, walk_list,
 };
@@ -670,7 +669,7 @@ pub(crate) struct UnnecessaryQualification<'ra> {
 #[derive(Default, Debug)]
 struct DiagMetadata<'ast> {
     /// The current trait's associated items' ident, used for diagnostic suggestions.
-    current_trait_assoc_items: Option<&'ast [P<AssocItem>]>,
+    current_trait_assoc_items: Option<&'ast [Box<AssocItem>]>,
 
     /// The current self type if inside an impl (used for better errors).
     current_self_type: Option<Ty>,
@@ -720,7 +719,7 @@ struct DiagMetadata<'ast> {
     current_type_path: Option<&'ast Ty>,
 
     /// The current impl items (used to suggest).
-    current_impl_items: Option<&'ast [P<AssocItem>]>,
+    current_impl_items: Option<&'ast [Box<AssocItem>]>,
 
     /// When processing impl trait
     currently_processing_impl_trait: Option<(TraitRef, Ty)>,
@@ -3038,7 +3037,7 @@ fn with_current_self_item<T>(&mut self, self_item: &Item, f: impl FnOnce(&mut Se
     }
 
     /// When evaluating a `trait` use its associated types' idents for suggestions in E0412.
-    fn resolve_trait_items(&mut self, trait_items: &'ast [P<AssocItem>]) {
+    fn resolve_trait_items(&mut self, trait_items: &'ast [Box<AssocItem>]) {
         let trait_assoc_items =
             replace(&mut self.diag_metadata.current_trait_assoc_items, Some(trait_items));
 
@@ -3179,7 +3178,7 @@ fn resolve_implementation(
         opt_trait_reference: &'ast Option<TraitRef>,
         self_type: &'ast Ty,
         item_id: NodeId,
-        impl_items: &'ast [P<AssocItem>],
+        impl_items: &'ast [Box<AssocItem>],
     ) {
         debug!("resolve_implementation");
         // If applicable, create a rib for the type parameters.
@@ -3671,7 +3670,7 @@ fn is_base_res_local(&self, nid: NodeId) -> bool {
     /// pattern as a whole counts as a never pattern (since it's definitionallly unreachable).
     fn compute_and_check_or_pat_binding_map(
         &mut self,
-        pats: &[P<Pat>],
+        pats: &[Box<Pat>],
     ) -> Result<FxIndexMap<Ident, BindingInfo>, IsNeverPattern> {
         let mut missing_vars = FxIndexMap::default();
         let mut inconsistent_vars = FxIndexMap::default();
@@ -4109,7 +4108,7 @@ fn try_resolve_as_non_binding(
     fn smart_resolve_path(
         &mut self,
         id: NodeId,
-        qself: &Option<P<QSelf>>,
+        qself: &Option<Box<QSelf>>,
         path: &Path,
         source: PathSource<'_, 'ast, '_>,
     ) {
@@ -4126,7 +4125,7 @@ fn smart_resolve_path(
     #[instrument(level = "debug", skip(self))]
     fn smart_resolve_path_fragment(
         &mut self,
-        qself: &Option<P<QSelf>>,
+        qself: &Option<Box<QSelf>>,
         path: &[Segment],
         source: PathSource<'_, 'ast, '_>,
         finalize: Finalize,
@@ -4434,7 +4433,7 @@ fn should_report_errs(&self) -> bool {
     // Resolve in alternative namespaces if resolution in the primary namespace fails.
     fn resolve_qpath_anywhere(
         &mut self,
-        qself: &Option<P<QSelf>>,
+        qself: &Option<Box<QSelf>>,
         path: &[Segment],
         primary_ns: Namespace,
         span: Span,
@@ -4485,7 +4484,7 @@ fn resolve_qpath_anywhere(
     /// Handles paths that may refer to associated items.
     fn resolve_qpath(
         &mut self,
-        qself: &Option<P<QSelf>>,
+        qself: &Option<Box<QSelf>>,
         path: &[Segment],
         ns: Namespace,
         finalize: Finalize,
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 19cd452..0807142 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -4,7 +4,6 @@
 use std::iter;
 use std::ops::Deref;
 
-use rustc_ast::ptr::P;
 use rustc_ast::visit::{FnCtxt, FnKind, LifetimeCtxt, Visitor, walk_ty};
 use rustc_ast::{
     self as ast, AssocItemKind, DUMMY_NODE_ID, Expr, ExprKind, GenericParam, GenericParamKind,
@@ -2150,7 +2149,7 @@ fn suggest_alternative_construction_methods(
         err: &mut Diag<'_>,
         path_span: Span,
         call_span: Span,
-        args: &[P<Expr>],
+        args: &[Box<Expr>],
     ) {
         if def_id.is_local() {
             // Doing analysis on local `DefId`s would cause infinite recursion.
@@ -3788,7 +3787,7 @@ fn mk_where_bound_predicate(
             ident: last.ident,
             gen_args: None,
             kind: ast::AssocItemConstraintKind::Equality {
-                term: ast::Term::Ty(ast::ptr::P(ast::Ty {
+                term: ast::Term::Ty(Box::new(ast::Ty {
                     kind: ast::TyKind::Path(None, poly_trait_ref.trait_ref.path.clone()),
                     id: DUMMY_NODE_ID,
                     span: DUMMY_SP,
@@ -3805,7 +3804,7 @@ fn mk_where_bound_predicate(
             Some(_) => return None,
             None => {
                 second_last.args =
-                    Some(ast::ptr::P(ast::GenericArgs::AngleBracketed(ast::AngleBracketedArgs {
+                    Some(Box::new(ast::GenericArgs::AngleBracketed(ast::AngleBracketedArgs {
                         args: ThinVec::from([added_constraint]),
                         span: DUMMY_SP,
                     })));
@@ -3818,7 +3817,7 @@ fn mk_where_bound_predicate(
 
     let new_where_bound_predicate = ast::WhereBoundPredicate {
         bound_generic_params: ThinVec::new(),
-        bounded_ty: ast::ptr::P(ty.clone()),
+        bounded_ty: Box::new(ty.clone()),
         bounds: vec![ast::GenericBound::Trait(ast::PolyTraitRef {
             bound_generic_params: ThinVec::new(),
             modifiers: ast::TraitBoundModifiers::NONE,
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index 374e1f6..ae72178 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -738,7 +738,7 @@ fn get_closure_name(
                 get_name(err, &local.pat.kind)
             }
             // Different to previous arm because one is `&hir::Local` and the other
-            // is `P<hir::Local>`.
+            // is `Box<hir::Local>`.
             hir::Node::LetStmt(local) => get_name(err, &local.pat.kind),
             _ => None,
         }
diff --git a/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs b/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs
index 38cf7e3..07a8eb5 100644
--- a/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs
+++ b/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs
@@ -1,6 +1,5 @@
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
 use rustc_ast::node_id::{NodeId, NodeMap};
-use rustc_ast::ptr::P;
 use rustc_ast::visit::{Visitor, walk_expr};
 use rustc_ast::{Crate, Expr, ExprKind, Item, ItemKind, MacroDef, ModKind, Ty, TyKind, UseTreeKind};
 use rustc_errors::Applicability;
@@ -124,7 +123,7 @@ fn visit_ty(&mut self, ty: &Ty) {
 }
 
 impl SingleComponentPathImports {
-    fn check_mod(&mut self, items: &[P<Item>]) {
+    fn check_mod(&mut self, items: &[Box<Item>]) {
         // keep track of imports reused with `self` keyword, such as `self::crypto_hash` in the example
         // below. Removing the `use crypto_hash;` would make this a compile error
         // ```
diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
index bd84209..e9ad578 100644
--- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
@@ -7,13 +7,14 @@
 use clippy_utils::over;
 use rustc_ast::PatKind::*;
 use rustc_ast::mut_visit::*;
-use rustc_ast::ptr::P;
 use rustc_ast::{self as ast, DUMMY_NODE_ID, Mutability, Pat, PatKind};
 use rustc_ast_pretty::pprust;
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::DUMMY_SP;
+// import needed to shadow `PatKind::Box` glob-imported above
+use std::boxed::Box;
 use std::cell::Cell;
 use std::mem;
 use thin_vec::{ThinVec, thin_vec};
@@ -97,7 +98,7 @@ fn lint_unnested_or_patterns(cx: &EarlyContext<'_>, pat: &Pat) {
         return;
     }
 
-    let mut pat = P(pat.clone());
+    let mut pat = Box::new(pat.clone());
 
     // Nix all the paren patterns everywhere so that they aren't in our way.
     remove_all_parens(&mut pat);
@@ -119,7 +120,7 @@ fn lint_unnested_or_patterns(cx: &EarlyContext<'_>, pat: &Pat) {
 }
 
 /// Remove all `(p)` patterns in `pat`.
-fn remove_all_parens(pat: &mut P<Pat>) {
+fn remove_all_parens(pat: &mut Box<Pat>) {
     #[derive(Default)]
     struct Visitor {
         /// If is not in the outer most pattern. This is needed to avoid removing the outermost
@@ -142,7 +143,7 @@ fn visit_pat(&mut self, pat: &mut Pat) {
 }
 
 /// Insert parens where necessary according to Rust's precedence rules for patterns.
-fn insert_necessary_parens(pat: &mut P<Pat>) {
+fn insert_necessary_parens(pat: &mut Box<Pat>) {
     struct Visitor;
     impl MutVisitor for Visitor {
         fn visit_pat(&mut self, pat: &mut Pat) {
@@ -154,7 +155,7 @@ fn visit_pat(&mut self, pat: &mut Pat) {
                 Ref(p, Mutability::Not) if matches!(p.kind, Ident(BindingMode::MUT, ..)) => p, // `&(mut x)`
                 _ => return,
             };
-            target.kind = Paren(P(take_pat(target)));
+            target.kind = Paren(Box::new(take_pat(target)));
         }
     }
     Visitor.visit_pat(pat);
@@ -162,7 +163,7 @@ fn visit_pat(&mut self, pat: &mut Pat) {
 
 /// Unnest or-patterns `p0 | ... | p1` in the pattern `pat`.
 /// For example, this would transform `Some(0) | FOO | Some(2)` into `Some(0 | 2) | FOO`.
-fn unnest_or_patterns(pat: &mut P<Pat>) -> bool {
+fn unnest_or_patterns(pat: &mut Box<Pat>) -> bool {
     struct Visitor {
         changed: bool,
     }
@@ -222,7 +223,7 @@ macro_rules! always_pat {
 /// Focus on `focus_idx` in `alternatives`,
 /// attempting to extend it with elements of the same constructor `C`
 /// in `alternatives[focus_idx + 1..]`.
-fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: usize) -> bool {
+fn transform_with_focus_on_idx(alternatives: &mut ThinVec<Box<Pat>>, focus_idx: usize) -> bool {
     // Extract the kind; we'll need to make some changes in it.
     let mut focus_kind = mem::replace(&mut alternatives[focus_idx].kind, Wild);
     // We'll focus on `alternatives[focus_idx]`,
@@ -303,12 +304,12 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: us
 /// So when we fixate on some `ident_k: pat_k`, we try to find `ident_k` in the other pattern
 /// and check that all `fp_i` where `i ∈ ((0...n) \ k)` between two patterns are equal.
 fn extend_with_struct_pat(
-    qself1: Option<&P<ast::QSelf>>,
+    qself1: Option<&Box<ast::QSelf>>,
     path1: &ast::Path,
     fps1: &mut [ast::PatField],
     rest1: ast::PatFieldsRest,
     start: usize,
-    alternatives: &mut ThinVec<P<Pat>>,
+    alternatives: &mut ThinVec<Box<Pat>>,
 ) -> bool {
     (0..fps1.len()).any(|idx| {
         let pos_in_2 = Cell::new(None); // The element `k`.
@@ -346,11 +347,11 @@ fn extend_with_struct_pat(
 /// while also requiring `ps1[..n] ~ ps2[..n]` (pre) and `ps1[n + 1..] ~ ps2[n + 1..]` (post),
 /// where `~` denotes semantic equality.
 fn extend_with_matching_product(
-    targets: &mut [P<Pat>],
+    targets: &mut [Box<Pat>],
     start: usize,
-    alternatives: &mut ThinVec<P<Pat>>,
-    predicate: impl Fn(&PatKind, &[P<Pat>], usize) -> bool,
-    extract: impl Fn(PatKind) -> ThinVec<P<Pat>>,
+    alternatives: &mut ThinVec<Box<Pat>>,
+    predicate: impl Fn(&PatKind, &[Box<Pat>], usize) -> bool,
+    extract: impl Fn(PatKind) -> ThinVec<Box<Pat>>,
 ) -> bool {
     (0..targets.len()).any(|idx| {
         let tail_or = drain_matching(
@@ -377,14 +378,14 @@ fn take_pat(from: &mut Pat) -> Pat {
 
 /// Extend `target` as an or-pattern with the alternatives
 /// in `tail_or` if there are any and return if there were.
-fn extend_with_tail_or(target: &mut Pat, tail_or: ThinVec<P<Pat>>) -> bool {
-    fn extend(target: &mut Pat, mut tail_or: ThinVec<P<Pat>>) {
+fn extend_with_tail_or(target: &mut Pat, tail_or: ThinVec<Box<Pat>>) -> bool {
+    fn extend(target: &mut Pat, mut tail_or: ThinVec<Box<Pat>>) {
         match target {
             // On an existing or-pattern in the target, append to it.
             Pat { kind: Or(ps), .. } => ps.append(&mut tail_or),
             // Otherwise convert the target to an or-pattern.
             target => {
-                let mut init_or = thin_vec![P(take_pat(target))];
+                let mut init_or = thin_vec![Box::new(take_pat(target))];
                 init_or.append(&mut tail_or);
                 target.kind = Or(init_or);
             },
@@ -403,10 +404,10 @@ fn extend(target: &mut Pat, mut tail_or: ThinVec<P<Pat>>) {
 // Only elements beginning with `start` are considered for extraction.
 fn drain_matching(
     start: usize,
-    alternatives: &mut ThinVec<P<Pat>>,
+    alternatives: &mut ThinVec<Box<Pat>>,
     predicate: impl Fn(&PatKind) -> bool,
-    extract: impl Fn(PatKind) -> P<Pat>,
-) -> ThinVec<P<Pat>> {
+    extract: impl Fn(PatKind) -> Box<Pat>,
+) -> ThinVec<Box<Pat>> {
     let mut tail_or = ThinVec::new();
     let mut idx = 0;
 
@@ -438,15 +439,15 @@ fn drain_matching(
 fn extend_with_matching(
     target: &mut Pat,
     start: usize,
-    alternatives: &mut ThinVec<P<Pat>>,
+    alternatives: &mut ThinVec<Box<Pat>>,
     predicate: impl Fn(&PatKind) -> bool,
-    extract: impl Fn(PatKind) -> P<Pat>,
+    extract: impl Fn(PatKind) -> Box<Pat>,
 ) -> bool {
     extend_with_tail_or(target, drain_matching(start, alternatives, predicate, extract))
 }
 
 /// Are the patterns in `ps1` and `ps2` equal save for `ps1[idx]` compared to `ps2[idx]`?
-fn eq_pre_post(ps1: &[P<Pat>], ps2: &[P<Pat>], idx: usize) -> bool {
+fn eq_pre_post(ps1: &[Box<Pat>], ps2: &[Box<Pat>], idx: usize) -> bool {
     ps1.len() == ps2.len()
         && ps1[idx].is_rest() == ps2[idx].is_rest() // Avoid `[x, ..] | [x, 0]` => `[x, .. | 0]`.
         && over(&ps1[..idx], &ps2[..idx], |l, r| eq_pat(l, r))
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
index 96f0273..0312bf56 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
@@ -5,7 +5,6 @@
 #![allow(clippy::wildcard_imports, clippy::enum_glob_use)]
 
 use crate::{both, over};
-use rustc_ast::ptr::P;
 use rustc_ast::{self as ast, *};
 use rustc_span::symbol::Ident;
 use std::mem;
@@ -83,11 +82,11 @@ pub fn eq_field_pat(l: &PatField, r: &PatField) -> bool {
         && over(&l.attrs, &r.attrs, eq_attr)
 }
 
-pub fn eq_qself(l: &P<QSelf>, r: &P<QSelf>) -> bool {
+pub fn eq_qself(l: &Box<QSelf>, r: &Box<QSelf>) -> bool {
     l.position == r.position && eq_ty(&l.ty, &r.ty)
 }
 
-pub fn eq_maybe_qself(l: Option<&P<QSelf>>, r: Option<&P<QSelf>>) -> bool {
+pub fn eq_maybe_qself(l: Option<&Box<QSelf>>, r: Option<&Box<QSelf>>) -> bool {
     match (l, r) {
         (Some(l), Some(r)) => eq_qself(l, r),
         (None, None) => true,
@@ -130,7 +129,7 @@ pub fn eq_generic_arg(l: &GenericArg, r: &GenericArg) -> bool {
     }
 }
 
-pub fn eq_expr_opt(l: Option<&P<Expr>>, r: Option<&P<Expr>>) -> bool {
+pub fn eq_expr_opt(l: Option<&Box<Expr>>, r: Option<&Box<Expr>>) -> bool {
     both(l, r, |l, r| eq_expr(l, r))
 }
 
@@ -727,7 +726,7 @@ pub fn eq_fn_header(l: &FnHeader, r: &FnHeader) -> bool {
 }
 
 #[expect(clippy::ref_option, reason = "This is the type how it is stored in the AST")]
-pub fn eq_opt_fn_contract(l: &Option<P<FnContract>>, r: &Option<P<FnContract>>) -> bool {
+pub fn eq_opt_fn_contract(l: &Option<Box<FnContract>>, r: &Option<Box<FnContract>>) -> bool {
     match (l, r) {
         (Some(l), Some(r)) => {
             eq_expr_opt(l.requires.as_ref(), r.requires.as_ref()) && eq_expr_opt(l.ensures.as_ref(), r.ensures.as_ref())
diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs
index bdff671..4e525be 100644
--- a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs
@@ -127,11 +127,11 @@ pub fn syntax_node_to_token_tree_modified<Ctx, SpanMap>(
 
 // The following items are what `rustc` macro can be parsed into :
 // link: https://github.com/rust-lang/rust/blob/9ebf47851a357faa4cd97f4b1dc7835f6376e639/src/libsyntax/ext/expand.rs#L141
-// * Expr(P<ast::Expr>)                     -> token_tree_to_expr
-// * Pat(P<ast::Pat>)                       -> token_tree_to_pat
-// * Ty(P<ast::Ty>)                         -> token_tree_to_ty
+// * Expr(Box<ast::Expr>)                     -> token_tree_to_expr
+// * Pat(Box<ast::Pat>)                       -> token_tree_to_pat
+// * Ty(Box<ast::Ty>)                         -> token_tree_to_ty
 // * Stmts(SmallVec<[ast::Stmt; 1]>)        -> token_tree_to_stmts
-// * Items(SmallVec<[P<ast::Item>; 1]>)     -> token_tree_to_items
+// * Items(SmallVec<[Box<ast::Item>; 1]>)     -> token_tree_to_items
 //
 // * TraitItems(SmallVec<[ast::TraitItem; 1]>)
 // * AssocItems(SmallVec<[ast::AssocItem; 1]>)
diff --git a/src/tools/rustfmt/src/chains.rs b/src/tools/rustfmt/src/chains.rs
index 034ecde..2f38819 100644
--- a/src/tools/rustfmt/src/chains.rs
+++ b/src/tools/rustfmt/src/chains.rs
@@ -58,7 +58,7 @@
 use std::borrow::Cow;
 use std::cmp::min;
 
-use rustc_ast::{ast, ptr};
+use rustc_ast::ast;
 use rustc_span::{BytePos, Span, symbol};
 use tracing::debug;
 
@@ -187,7 +187,7 @@ enum ChainItemKind {
     MethodCall(
         ast::PathSegment,
         Vec<ast::GenericArg>,
-        ThinVec<ptr::P<ast::Expr>>,
+        ThinVec<Box<ast::Expr>>,
     ),
     StructField(symbol::Ident),
     TupleField(symbol::Ident, bool),
@@ -343,7 +343,7 @@ fn is_comment(&self) -> bool {
     fn rewrite_method_call(
         method_name: symbol::Ident,
         types: &[ast::GenericArg],
-        args: &[ptr::P<ast::Expr>],
+        args: &[Box<ast::Expr>],
         span: Span,
         context: &RewriteContext<'_>,
         shape: Shape,
diff --git a/src/tools/rustfmt/src/closures.rs b/src/tools/rustfmt/src/closures.rs
index 61e148c..bb10a79 100644
--- a/src/tools/rustfmt/src/closures.rs
+++ b/src/tools/rustfmt/src/closures.rs
@@ -1,4 +1,4 @@
-use rustc_ast::{ast, ptr};
+use rustc_ast::ast;
 use rustc_span::Span;
 use thin_vec::thin_vec;
 use tracing::debug;
@@ -165,7 +165,7 @@ fn rewrite_closure_with_block(
     let block = ast::Block {
         stmts: thin_vec![ast::Stmt {
             id: ast::NodeId::root(),
-            kind: ast::StmtKind::Expr(ptr::P(body.clone())),
+            kind: ast::StmtKind::Expr(Box::new(body.clone())),
             span: body.span,
         }],
         id: ast::NodeId::root(),
diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs
index 08aedff..975f9be 100644
--- a/src/tools/rustfmt/src/expr.rs
+++ b/src/tools/rustfmt/src/expr.rs
@@ -3,7 +3,7 @@
 
 use itertools::Itertools;
 use rustc_ast::token::{Delimiter, Lit, LitKind};
-use rustc_ast::{ForLoopKind, MatchKind, ast, ptr, token};
+use rustc_ast::{ForLoopKind, MatchKind, ast, token};
 use rustc_span::{BytePos, Span};
 use tracing::debug;
 
@@ -1368,7 +1368,7 @@ fn choose_separator_tactic(context: &RewriteContext<'_>, span: Span) -> Option<S
 pub(crate) fn rewrite_call(
     context: &RewriteContext<'_>,
     callee: &str,
-    args: &[ptr::P<ast::Expr>],
+    args: &[Box<ast::Expr>],
     span: Span,
     shape: Shape,
 ) -> RewriteResult {
@@ -1634,7 +1634,7 @@ fn struct_lit_can_be_aligned(fields: &[ast::ExprField], has_base: bool) -> bool
 fn rewrite_struct_lit<'a>(
     context: &RewriteContext<'_>,
     path: &ast::Path,
-    qself: &Option<ptr::P<ast::QSelf>>,
+    qself: &Option<Box<ast::QSelf>>,
     fields: &'a [ast::ExprField],
     struct_rest: &ast::StructRest,
     attrs: &[ast::Attribute],
diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs
index 7084639..57d4142 100644
--- a/src/tools/rustfmt/src/items.rs
+++ b/src/tools/rustfmt/src/items.rs
@@ -4,8 +4,8 @@
 use std::cmp::{Ordering, max, min};
 
 use regex::Regex;
+use rustc_ast::ast;
 use rustc_ast::visit;
-use rustc_ast::{ast, ptr};
 use rustc_span::{BytePos, DUMMY_SP, Ident, Span, symbol};
 use tracing::debug;
 
@@ -725,9 +725,9 @@ fn format_variant(
             .ok()
     }
 
-    fn visit_impl_items(&mut self, items: &[ptr::P<ast::AssocItem>]) {
+    fn visit_impl_items(&mut self, items: &[Box<ast::AssocItem>]) {
         if self.get_context().config.reorder_impl_items() {
-            type TyOpt = Option<ptr::P<ast::Ty>>;
+            type TyOpt = Option<Box<ast::Ty>>;
             use crate::ast::AssocItemKind::*;
             let is_type = |ty: &TyOpt| opaque_ty(ty).is_none();
             let is_opaque = |ty: &TyOpt| opaque_ty(ty).is_some();
@@ -934,7 +934,7 @@ pub(crate) fn format_impl(
 
 fn is_impl_single_line(
     context: &RewriteContext<'_>,
-    items: &[ptr::P<ast::AssocItem>],
+    items: &[Box<ast::AssocItem>],
     result: &str,
     where_clause_str: &str,
     item: &ast::Item,
@@ -2024,7 +2024,7 @@ pub(crate) struct StaticParts<'a> {
     generics: Option<&'a ast::Generics>,
     ty: &'a ast::Ty,
     mutability: ast::Mutability,
-    expr_opt: Option<&'a ptr::P<ast::Expr>>,
+    expr_opt: Option<&'a Box<ast::Expr>>,
     defaultness: Option<ast::Defaultness>,
     span: Span,
 }
diff --git a/src/tools/rustfmt/src/macros.rs b/src/tools/rustfmt/src/macros.rs
index 0ff0aad..2e7ac90 100644
--- a/src/tools/rustfmt/src/macros.rs
+++ b/src/tools/rustfmt/src/macros.rs
@@ -12,9 +12,9 @@
 use std::collections::HashMap;
 use std::panic::{AssertUnwindSafe, catch_unwind};
 
+use rustc_ast::ast;
 use rustc_ast::token::{Delimiter, Token, TokenKind};
 use rustc_ast::tokenstream::{TokenStream, TokenStreamIter, TokenTree};
-use rustc_ast::{ast, ptr};
 use rustc_ast_pretty::pprust;
 use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Symbol};
 use tracing::debug;
@@ -53,10 +53,10 @@ pub(crate) enum MacroPosition {
 
 #[derive(Debug)]
 pub(crate) enum MacroArg {
-    Expr(ptr::P<ast::Expr>),
-    Ty(ptr::P<ast::Ty>),
-    Pat(ptr::P<ast::Pat>),
-    Item(ptr::P<ast::Item>),
+    Expr(Box<ast::Expr>),
+    Ty(Box<ast::Ty>),
+    Pat(Box<ast::Pat>),
+    Item(Box<ast::Item>),
     Keyword(Ident, Span),
 }
 
diff --git a/src/tools/rustfmt/src/matches.rs b/src/tools/rustfmt/src/matches.rs
index 8f62648e..209cb2f 100644
--- a/src/tools/rustfmt/src/matches.rs
+++ b/src/tools/rustfmt/src/matches.rs
@@ -2,7 +2,7 @@
 
 use std::iter::repeat;
 
-use rustc_ast::{MatchKind, ast, ptr};
+use rustc_ast::{MatchKind, ast};
 use rustc_span::{BytePos, Span};
 use tracing::debug;
 
@@ -394,7 +394,7 @@ fn flatten_arm_body<'a>(
 
 fn rewrite_match_body(
     context: &RewriteContext<'_>,
-    body: &ptr::P<ast::Expr>,
+    body: &Box<ast::Expr>,
     pats_str: &str,
     shape: Shape,
     has_guard: bool,
@@ -569,7 +569,7 @@ fn rewrite_match_body(
 // The `if ...` guard on a match arm.
 fn rewrite_guard(
     context: &RewriteContext<'_>,
-    guard: &Option<ptr::P<ast::Expr>>,
+    guard: &Option<Box<ast::Expr>>,
     shape: Shape,
     // The amount of space used up on this line for the pattern in
     // the arm (excludes offset).
diff --git a/src/tools/rustfmt/src/modules.rs b/src/tools/rustfmt/src/modules.rs
index 44c8123..3bc656b 100644
--- a/src/tools/rustfmt/src/modules.rs
+++ b/src/tools/rustfmt/src/modules.rs
@@ -26,7 +26,7 @@
 #[derive(Debug, Clone)]
 pub(crate) struct Module<'a> {
     ast_mod_kind: Option<Cow<'a, ast::ModKind>>,
-    pub(crate) items: Cow<'a, ThinVec<rustc_ast::ptr::P<ast::Item>>>,
+    pub(crate) items: Cow<'a, ThinVec<Box<ast::Item>>>,
     inner_attr: ast::AttrVec,
     pub(crate) span: Span,
 }
@@ -35,7 +35,7 @@ impl<'a> Module<'a> {
     pub(crate) fn new(
         mod_span: Span,
         ast_mod_kind: Option<Cow<'a, ast::ModKind>>,
-        mod_items: Cow<'a, ThinVec<rustc_ast::ptr::P<ast::Item>>>,
+        mod_items: Cow<'a, ThinVec<Box<ast::Item>>>,
         mod_attrs: Cow<'a, ast::AttrVec>,
     ) -> Self {
         let inner_attr = mod_attrs
@@ -170,7 +170,7 @@ fn visit_cfg_if(&mut self, item: Cow<'ast, ast::Item>) -> Result<(), ModuleResol
     /// Visit modules defined inside macro calls.
     fn visit_mod_outside_ast(
         &mut self,
-        items: ThinVec<rustc_ast::ptr::P<ast::Item>>,
+        items: ThinVec<Box<ast::Item>>,
     ) -> Result<(), ModuleResolutionError> {
         for item in items {
             if is_cfg_if(&item) {
@@ -197,7 +197,7 @@ fn visit_mod_outside_ast(
     /// Visit modules from AST.
     fn visit_mod_from_ast(
         &mut self,
-        items: &'ast [rustc_ast::ptr::P<ast::Item>],
+        items: &'ast [Box<ast::Item>],
     ) -> Result<(), ModuleResolutionError> {
         for item in items {
             if is_cfg_if(item) {
diff --git a/src/tools/rustfmt/src/overflow.rs b/src/tools/rustfmt/src/overflow.rs
index 728adff..bb1ebc8 100644
--- a/src/tools/rustfmt/src/overflow.rs
+++ b/src/tools/rustfmt/src/overflow.rs
@@ -3,8 +3,8 @@
 use std::cmp::min;
 
 use itertools::Itertools;
+use rustc_ast::ast;
 use rustc_ast::token::Delimiter;
-use rustc_ast::{ast, ptr};
 use rustc_span::Span;
 use tracing::debug;
 
@@ -219,7 +219,7 @@ pub(crate) trait IntoOverflowableItem<'a>: Rewrite + Spanned {
     fn into_overflowable_item(&'a self) -> OverflowableItem<'a>;
 }
 
-impl<'a, T: 'a + IntoOverflowableItem<'a>> IntoOverflowableItem<'a> for ptr::P<T> {
+impl<'a, T: 'a + IntoOverflowableItem<'a>> IntoOverflowableItem<'a> for Box<T> {
     fn into_overflowable_item(&'a self) -> OverflowableItem<'a> {
         (**self).into_overflowable_item()
     }
diff --git a/src/tools/rustfmt/src/parse/macros/lazy_static.rs b/src/tools/rustfmt/src/parse/macros/lazy_static.rs
index cbe8100..8611615 100644
--- a/src/tools/rustfmt/src/parse/macros/lazy_static.rs
+++ b/src/tools/rustfmt/src/parse/macros/lazy_static.rs
@@ -1,5 +1,4 @@
 use rustc_ast::ast;
-use rustc_ast::ptr::P;
 use rustc_ast::token;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_parse::exp;
@@ -10,7 +9,7 @@
 pub(crate) fn parse_lazy_static(
     context: &RewriteContext<'_>,
     ts: TokenStream,
-) -> Option<Vec<(ast::Visibility, symbol::Ident, P<ast::Ty>, P<ast::Expr>)>> {
+) -> Option<Vec<(ast::Visibility, symbol::Ident, Box<ast::Ty>, Box<ast::Expr>)>> {
     let mut result = vec![];
     let mut parser = super::build_parser(context, ts);
     macro_rules! parse_or {
diff --git a/src/tools/rustfmt/src/parse/macros/mod.rs b/src/tools/rustfmt/src/parse/macros/mod.rs
index d796448..724d7a09 100644
--- a/src/tools/rustfmt/src/parse/macros/mod.rs
+++ b/src/tools/rustfmt/src/parse/macros/mod.rs
@@ -1,6 +1,6 @@
+use rustc_ast::ast;
 use rustc_ast::token::{Delimiter, NonterminalKind, NtExprKind::*, NtPatKind::*, TokenKind};
 use rustc_ast::tokenstream::TokenStream;
-use rustc_ast::{ast, ptr};
 use rustc_parse::MACRO_ARGUMENTS;
 use rustc_parse::parser::{ForceCollect, Parser, Recovery};
 use rustc_session::parse::ParseSess;
@@ -49,26 +49,26 @@ macro_rules! parse_macro_arg {
         Expr,
         NonterminalKind::Expr(Expr),
         |parser: &mut Parser<'b>| parser.parse_expr(),
-        |x: ptr::P<ast::Expr>| Some(x)
+        |x: Box<ast::Expr>| Some(x)
     );
     parse_macro_arg!(
         Ty,
         NonterminalKind::Ty,
         |parser: &mut Parser<'b>| parser.parse_ty(),
-        |x: ptr::P<ast::Ty>| Some(x)
+        |x: Box<ast::Ty>| Some(x)
     );
     parse_macro_arg!(
         Pat,
         NonterminalKind::Pat(PatParam { inferred: false }),
         |parser: &mut Parser<'b>| parser.parse_pat_no_top_alt(None, None),
-        |x: ptr::P<ast::Pat>| Some(x)
+        |x: Box<ast::Pat>| Some(x)
     );
-    // `parse_item` returns `Option<ptr::P<ast::Item>>`.
+    // `parse_item` returns `Option<Box<ast::Item>>`.
     parse_macro_arg!(
         Item,
         NonterminalKind::Item,
         |parser: &mut Parser<'b>| parser.parse_item(ForceCollect::No),
-        |x: Option<ptr::P<ast::Item>>| x
+        |x: Option<Box<ast::Item>>| x
     );
 
     None
@@ -164,7 +164,7 @@ pub(crate) fn parse_macro_args(
 pub(crate) fn parse_expr(
     context: &RewriteContext<'_>,
     tokens: TokenStream,
-) -> Option<ptr::P<ast::Expr>> {
+) -> Option<Box<ast::Expr>> {
     let mut parser = build_parser(context, tokens);
     parser.parse_expr().ok()
 }
diff --git a/src/tools/rustfmt/src/parse/parser.rs b/src/tools/rustfmt/src/parse/parser.rs
index f357aed6..2ec8769 100644
--- a/src/tools/rustfmt/src/parse/parser.rs
+++ b/src/tools/rustfmt/src/parse/parser.rs
@@ -1,7 +1,7 @@
 use std::panic::{AssertUnwindSafe, catch_unwind};
 use std::path::{Path, PathBuf};
 
-use rustc_ast::{ast, attr, ptr};
+use rustc_ast::{ast, attr};
 use rustc_errors::Diag;
 use rustc_parse::parser::Parser as RawParser;
 use rustc_parse::{exp, new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
@@ -102,7 +102,7 @@ pub(crate) fn parse_file_as_module(
         psess: &'a ParseSess,
         path: &Path,
         span: Span,
-    ) -> Result<(ast::AttrVec, ThinVec<ptr::P<ast::Item>>, Span), ParserError> {
+    ) -> Result<(ast::AttrVec, ThinVec<Box<ast::Item>>, Span), ParserError> {
         let result = catch_unwind(AssertUnwindSafe(|| {
             let mut parser =
                 unwrap_or_emit_fatal(new_parser_from_file(psess.inner(), path, Some(span)));
diff --git a/src/tools/rustfmt/src/patterns.rs b/src/tools/rustfmt/src/patterns.rs
index cb3879f..d212ecf 100644
--- a/src/tools/rustfmt/src/patterns.rs
+++ b/src/tools/rustfmt/src/patterns.rs
@@ -1,5 +1,4 @@
 use rustc_ast::ast::{self, BindingMode, ByRef, Pat, PatField, PatKind, RangeEnd, RangeSyntax};
-use rustc_ast::ptr;
 use rustc_span::{BytePos, Span};
 
 use crate::comment::{FindUncommented, combine_strs_with_missing_comments};
@@ -77,7 +76,7 @@ fn is_short_pattern_inner(context: &RewriteContext<'_>, pat: &ast::Pat) -> bool
 }
 
 pub(crate) struct RangeOperand<'a, T> {
-    pub operand: &'a Option<ptr::P<T>>,
+    pub operand: &'a Option<Box<T>>,
     pub span: Span,
 }
 
@@ -329,8 +328,8 @@ fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteR
 pub fn rewrite_range_pat<T: Rewrite>(
     context: &RewriteContext<'_>,
     shape: Shape,
-    lhs: &Option<ptr::P<T>>,
-    rhs: &Option<ptr::P<T>>,
+    lhs: &Option<Box<T>>,
+    rhs: &Option<Box<T>>,
     end_kind: &rustc_span::source_map::Spanned<RangeEnd>,
     span: Span,
 ) -> RewriteResult {
@@ -371,7 +370,7 @@ pub fn rewrite_range_pat<T: Rewrite>(
 }
 
 fn rewrite_struct_pat(
-    qself: &Option<ptr::P<ast::QSelf>>,
+    qself: &Option<Box<ast::QSelf>>,
     path: &ast::Path,
     fields: &[ast::PatField],
     ellipsis: bool,
@@ -505,7 +504,7 @@ fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteR
 
 #[derive(Debug)]
 pub(crate) enum TuplePatField<'a> {
-    Pat(&'a ptr::P<ast::Pat>),
+    Pat(&'a Box<ast::Pat>),
     Dotdot(Span),
 }
 
@@ -562,7 +561,7 @@ pub(crate) fn can_be_overflowed_pat(
 }
 
 fn rewrite_tuple_pat(
-    pats: &[ptr::P<ast::Pat>],
+    pats: &[Box<ast::Pat>],
     path_str: Option<String>,
     span: Span,
     context: &RewriteContext<'_>,
diff --git a/src/tools/rustfmt/src/rewrite.rs b/src/tools/rustfmt/src/rewrite.rs
index 8302070..f0accd6 100644
--- a/src/tools/rustfmt/src/rewrite.rs
+++ b/src/tools/rustfmt/src/rewrite.rs
@@ -3,7 +3,6 @@
 use std::cell::{Cell, RefCell};
 use std::rc::Rc;
 
-use rustc_ast::ptr;
 use rustc_span::Span;
 use thiserror::Error;
 
@@ -24,7 +23,7 @@ fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteR
     }
 }
 
-impl<T: Rewrite> Rewrite for ptr::P<T> {
+impl<T: Rewrite> Rewrite for Box<T> {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
         (**self).rewrite(context, shape)
     }
diff --git a/src/tools/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs
index ac13299..020651e 100644
--- a/src/tools/rustfmt/src/spanned.rs
+++ b/src/tools/rustfmt/src/spanned.rs
@@ -1,6 +1,6 @@
 use std::cmp::max;
 
-use rustc_ast::{ast, ptr};
+use rustc_ast::ast;
 use rustc_span::{Span, source_map};
 
 use crate::macros::MacroArg;
@@ -12,7 +12,7 @@ pub(crate) trait Spanned {
     fn span(&self) -> Span;
 }
 
-impl<T: Spanned> Spanned for ptr::P<T> {
+impl<T: Spanned> Spanned for Box<T> {
     fn span(&self) -> Span {
         (**self).span()
     }
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index 9ee10d8..5dce9a0 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -1,7 +1,6 @@
 use std::ops::Deref;
 
 use rustc_ast::ast::{self, FnRetTy, Mutability, Term};
-use rustc_ast::ptr;
 use rustc_span::{BytePos, Pos, Span, symbol::kw};
 use tracing::debug;
 
@@ -39,7 +38,7 @@ pub(crate) enum PathContext {
 pub(crate) fn rewrite_path(
     context: &RewriteContext<'_>,
     path_context: PathContext,
-    qself: &Option<ptr::P<ast::QSelf>>,
+    qself: &Option<Box<ast::QSelf>>,
     path: &ast::Path,
     shape: Shape,
 ) -> RewriteResult {
@@ -1340,7 +1339,7 @@ fn join_bounds_inner(
     }
 }
 
-pub(crate) fn opaque_ty(ty: &Option<ptr::P<ast::Ty>>) -> Option<&ast::GenericBounds> {
+pub(crate) fn opaque_ty(ty: &Option<Box<ast::Ty>>) -> Option<&ast::GenericBounds> {
     ty.as_ref().and_then(|t| match &t.kind {
         ast::TyKind::ImplTrait(_, bounds) => Some(bounds),
         _ => None,
diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs
index fcd475b..b9950e9 100644
--- a/src/tools/rustfmt/src/utils.rs
+++ b/src/tools/rustfmt/src/utils.rs
@@ -1,10 +1,10 @@
 use std::borrow::Cow;
 
+use rustc_ast::YieldKind;
 use rustc_ast::ast::{
     self, Attribute, MetaItem, MetaItemInner, MetaItemKind, NodeId, Path, Visibility,
     VisibilityKind,
 };
-use rustc_ast::{YieldKind, ptr};
 use rustc_ast_pretty::pprust;
 use rustc_span::{BytePos, LocalExpnId, Span, Symbol, SyntaxContext, sym, symbol};
 use unicode_width::UnicodeWidthStr;
@@ -149,8 +149,8 @@ pub(crate) fn format_extern(ext: ast::Extern, explicit_abi: bool) -> Cow<'static
 }
 
 #[inline]
-// Transform `Vec<rustc_ast::ptr::P<T>>` into `Vec<&T>`
-pub(crate) fn ptr_vec_to_ref_vec<T>(vec: &[ptr::P<T>]) -> Vec<&T> {
+// Transform `Vec<Box<T>>` into `Vec<&T>`
+pub(crate) fn ptr_vec_to_ref_vec<T>(vec: &[Box<T>]) -> Vec<&T> {
     vec.iter().map(|x| &**x).collect::<Vec<_>>()
 }
 
diff --git a/src/tools/rustfmt/src/visitor.rs b/src/tools/rustfmt/src/visitor.rs
index f6a9a3f..23d07c9 100644
--- a/src/tools/rustfmt/src/visitor.rs
+++ b/src/tools/rustfmt/src/visitor.rs
@@ -874,7 +874,7 @@ fn is_unknown_rustfmt_attr(&self, segments: &[ast::PathSegment]) -> bool {
         !is_skip_attr(segments)
     }
 
-    fn walk_mod_items(&mut self, items: &[rustc_ast::ptr::P<ast::Item>]) {
+    fn walk_mod_items(&mut self, items: &[Box<ast::Item>]) {
         self.visit_items_with_reordering(&ptr_vec_to_ref_vec(items));
     }
 
diff --git a/tests/ui-fulldeps/auxiliary/parser.rs b/tests/ui-fulldeps/auxiliary/parser.rs
index 8a37051..6726969 100644
--- a/tests/ui-fulldeps/auxiliary/parser.rs
+++ b/tests/ui-fulldeps/auxiliary/parser.rs
@@ -10,7 +10,6 @@
 use rustc_ast::ast::{AttrKind, Attribute, DUMMY_NODE_ID, Expr};
 use rustc_ast::mut_visit::{self, MutVisitor};
 use rustc_ast::node_id::NodeId;
-use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Token};
 use rustc_ast::tokenstream::{AttrTokenStream, AttrTokenTree, LazyAttrTokenStream};
 use rustc_errors::Diag;
@@ -19,7 +18,7 @@
 use rustc_span::{AttrId, DUMMY_SP, FileName, Span};
 use std::sync::Arc;
 
-pub fn parse_expr(psess: &ParseSess, source_code: &str) -> Option<P<Expr>> {
+pub fn parse_expr(psess: &ParseSess, source_code: &str) -> Option<Box<Expr>> {
     let parser = rustc_parse::unwrap_or_emit_fatal(rustc_parse::new_parser_from_source_str(
         psess,
         FileName::anon_source_code(source_code),
diff --git a/tests/ui-fulldeps/pprust-expr-roundtrip.rs b/tests/ui-fulldeps/pprust-expr-roundtrip.rs
index 8bca208..08ded2a 100644
--- a/tests/ui-fulldeps/pprust-expr-roundtrip.rs
+++ b/tests/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -35,7 +35,6 @@
 
 use parser::parse_expr;
 use rustc_ast::mut_visit::MutVisitor;
-use rustc_ast::ptr::P;
 use rustc_ast::*;
 use rustc_ast_pretty::pprust;
 use rustc_session::parse::ParseSess;
@@ -45,11 +44,11 @@
 use thin_vec::{thin_vec, ThinVec};
 
 // Helper functions for building exprs
-fn expr(kind: ExprKind) -> P<Expr> {
-    P(Expr { id: DUMMY_NODE_ID, kind, span: DUMMY_SP, attrs: AttrVec::new(), tokens: None })
+fn expr(kind: ExprKind) -> Box<Expr> {
+    Box::new(Expr { id: DUMMY_NODE_ID, kind, span: DUMMY_SP, attrs: AttrVec::new(), tokens: None })
 }
 
-fn make_x() -> P<Expr> {
+fn make_x() -> Box<Expr> {
     let seg = PathSegment::from_ident(Ident::from_str("x"));
     let path = Path { segments: thin_vec![seg], span: DUMMY_SP, tokens: None };
     expr(ExprKind::Path(None, path))
@@ -58,7 +57,7 @@ fn make_x() -> P<Expr> {
 /// Iterate over exprs of depth up to `depth`. The goal is to explore all "interesting"
 /// combinations of expression nesting. For example, we explore combinations using `if`, but not
 /// `while` or `match`, since those should print and parse in much the same way as `if`.
-fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
+fn iter_exprs(depth: usize, f: &mut dyn FnMut(Box<Expr>)) {
     if depth == 0 {
         f(make_x());
         return;
@@ -108,7 +107,7 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Unary(UnOp::Deref, e)));
             }
             9 => {
-                let block = P(Block {
+                let block = Box::new(Block {
                     stmts: ThinVec::new(),
                     id: DUMMY_NODE_ID,
                     rules: BlockCheckMode::Default,
@@ -118,7 +117,10 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::If(e, block.clone(), None)));
             }
             10 => {
-                let decl = P(FnDecl { inputs: thin_vec![], output: FnRetTy::Default(DUMMY_SP) });
+                let decl = Box::new(FnDecl {
+                    inputs: thin_vec![],
+                    output: FnRetTy::Default(DUMMY_SP),
+                });
                 iter_exprs(depth - 1, &mut |e| {
                     g(ExprKind::Closure(Box::new(Closure {
                         binder: ClosureBinder::NotPresent,
@@ -159,7 +161,7 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
             }
             16 => {
                 let path = Path::from_ident(Ident::from_str("S"));
-                g(ExprKind::Struct(P(StructExpr {
+                g(ExprKind::Struct(Box::new(StructExpr {
                     qself: None,
                     path,
                     fields: thin_vec![],
@@ -170,8 +172,12 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Try(e)));
             }
             18 => {
-                let pat =
-                    P(Pat { id: DUMMY_NODE_ID, kind: PatKind::Wild, span: DUMMY_SP, tokens: None });
+                let pat = Box::new(Pat {
+                    id: DUMMY_NODE_ID,
+                    kind: PatKind::Wild,
+                    span: DUMMY_SP,
+                    tokens: None,
+                });
                 iter_exprs(depth - 1, &mut |e| {
                     g(ExprKind::Let(pat.clone(), e, DUMMY_SP, Recovered::No))
                 })
@@ -204,7 +210,7 @@ fn visit_expr(&mut self, e: &mut Expr) {
         mut_visit::walk_expr(self, e);
         let expr = std::mem::replace(e, Expr::dummy());
 
-        e.kind = ExprKind::Paren(P(expr));
+        e.kind = ExprKind::Paren(Box::new(expr));
     }
 }