about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2025-04-29 15:24:54 +1000
committerNicholas Nethercote <n.nethercote@gmail.com>2025-05-02 12:41:02 +1000
commit3f842e51a6e97dad23f9717ae27db2960dde1c34 (patch)
treeb4d5c72d7f627a9058954cd1fa54af51787dc19d
parent251cda5e1f0057eb04fd9fc1653f2f1e010e8f97 (diff)
downloadrust-3f842e51a6e97dad23f9717ae27db2960dde1c34.tar.gz
rust-3f842e51a6e97dad23f9717ae27db2960dde1c34.zip
Improve coverage of HIR pretty printing.
By taking the existing `expanded-exhaustive.rs` test and running it with
both `Zunpretty=expanded` *and* `Zunpretty=hir`.

Also rename some files, and split the asm parts out so they only run on
x86-64.
-rw-r--r--tests/ui/unpretty/exhaustive-asm.expanded.stdout33
-rw-r--r--tests/ui/unpretty/exhaustive-asm.hir.stdout31
-rw-r--r--tests/ui/unpretty/exhaustive-asm.rs31
-rw-r--r--tests/ui/unpretty/exhaustive.expanded.stdout (renamed from tests/ui/unpretty/expanded-exhaustive.stdout)87
-rw-r--r--tests/ui/unpretty/exhaustive.hir.stderr172
-rw-r--r--tests/ui/unpretty/exhaustive.hir.stdout700
-rw-r--r--tests/ui/unpretty/exhaustive.rs (renamed from tests/ui/unpretty/expanded-exhaustive.rs)64
-rw-r--r--tests/ui/unpretty/interpolation-expanded.rs (renamed from tests/ui/unpretty/expanded-interpolation.rs)0
-rw-r--r--tests/ui/unpretty/interpolation-expanded.stdout (renamed from tests/ui/unpretty/expanded-interpolation.stdout)0
9 files changed, 1014 insertions, 104 deletions
diff --git a/tests/ui/unpretty/exhaustive-asm.expanded.stdout b/tests/ui/unpretty/exhaustive-asm.expanded.stdout
new file mode 100644
index 00000000000..92829b0ab15
--- /dev/null
+++ b/tests/ui/unpretty/exhaustive-asm.expanded.stdout
@@ -0,0 +1,33 @@
+#![feature(prelude_import)]
+#[prelude_import]
+use std::prelude::rust_2024::*;
+#[macro_use]
+extern crate std;
+//@ revisions: expanded hir
+//@[expanded]compile-flags: -Zunpretty=expanded
+//@[expanded]check-pass
+//@[hir]compile-flags: -Zunpretty=hir
+//@[hir]check-pass
+//@ edition:2024
+//@ only-x86_64
+//
+// asm parts of exhaustive.rs. Separate because we only run this on x86_64.
+
+mod expressions {
+    /// ExprKind::InlineAsm
+    fn expr_inline_asm() {
+        let x;
+        asm!("mov {1}, {0}\nshl {1}, 1\nshl {0}, 2\nadd {0}, {1}",
+            inout(reg)
+            x,
+            out(reg)
+            _);
+    }
+}
+
+mod items {
+    /// ItemKind::GlobalAsm
+    mod item_global_asm {
+        global_asm! (".globl my_asm_func");
+    }
+}
diff --git a/tests/ui/unpretty/exhaustive-asm.hir.stdout b/tests/ui/unpretty/exhaustive-asm.hir.stdout
new file mode 100644
index 00000000000..5a642dff6f2
--- /dev/null
+++ b/tests/ui/unpretty/exhaustive-asm.hir.stdout
@@ -0,0 +1,31 @@
+#[prelude_import]
+use std::prelude::rust_2024::*;
+#[macro_use]
+extern crate std;
+//@ revisions: expanded hir
+//@[expanded]compile-flags: -Zunpretty=expanded
+//@[expanded]check-pass
+//@[hir]compile-flags: -Zunpretty=hir
+//@[hir]check-pass
+//@ edition:2024
+//@ only-x86_64
+//
+// asm parts of exhaustive.rs. Separate because we only run this on x86_64.
+
+mod expressions {
+    /// ExprKind::InlineAsm
+    fn expr_inline_asm() {
+        let x;
+        asm!("mov {1}, {0}\nshl {1}, 1\nshl {0}, 2\nadd {0}, {1}",
+            inout(reg)
+            x,
+            out(reg)
+            _);
+    }
+}
+
+mod items {
+    /// ItemKind::GlobalAsm
+    mod item_global_asm {/// ItemKind::GlobalAsm
+        global_asm! (".globl my_asm_func") }
+    }
diff --git a/tests/ui/unpretty/exhaustive-asm.rs b/tests/ui/unpretty/exhaustive-asm.rs
new file mode 100644
index 00000000000..74a45447a20
--- /dev/null
+++ b/tests/ui/unpretty/exhaustive-asm.rs
@@ -0,0 +1,31 @@
+//@ revisions: expanded hir
+//@[expanded]compile-flags: -Zunpretty=expanded
+//@[expanded]check-pass
+//@[hir]compile-flags: -Zunpretty=hir
+//@[hir]check-pass
+//@ edition:2024
+//@ only-x86_64
+//
+// asm parts of exhaustive.rs. Separate because we only run this on x86_64.
+
+mod expressions {
+    /// ExprKind::InlineAsm
+    fn expr_inline_asm() {
+        let x;
+        core::arch::asm!(
+            "mov {tmp}, {x}",
+            "shl {tmp}, 1",
+            "shl {x}, 2",
+            "add {x}, {tmp}",
+            x = inout(reg) x,
+            tmp = out(reg) _,
+        );
+    }
+}
+
+mod items {
+    /// ItemKind::GlobalAsm
+    mod item_global_asm {
+        core::arch::global_asm!(".globl my_asm_func");
+    }
+}
diff --git a/tests/ui/unpretty/expanded-exhaustive.stdout b/tests/ui/unpretty/exhaustive.expanded.stdout
index c6ffbb0d316..9712ba58e62 100644
--- a/tests/ui/unpretty/expanded-exhaustive.stdout
+++ b/tests/ui/unpretty/exhaustive.expanded.stdout
@@ -1,7 +1,13 @@
 #![feature(prelude_import)]
-//@ compile-flags: -Zunpretty=expanded
+//@ revisions: expanded hir
+//@[expanded]compile-flags: -Zunpretty=expanded
+//@[expanded]check-pass
+//@[hir]compile-flags: -Zunpretty=hir
+//@[hir]check-fail
 //@ edition:2024
-//@ check-pass
+
+// Note: the HIR revision includes a `.stderr` file because there are some
+// errors that only occur once we get past the AST.
 
 #![feature(auto_traits)]
 #![feature(box_patterns)]
@@ -211,7 +217,10 @@ mod expressions {
     }
 
     /// ExprKind::Await
-    fn expr_await() { let fut; fut.await; }
+    fn expr_await() {
+        let fut;
+        fut.await;
+    }
 
     /// ExprKind::TryBlock
     fn expr_try_block() { try {} try { return; } }
@@ -242,7 +251,9 @@ mod expressions {
     }
 
     /// ExprKind::Underscore
-    fn expr_underscore() { _; }
+    fn expr_underscore() {
+        _;
+    }
 
     /// ExprKind::Path
     fn expr_path() {
@@ -275,16 +286,8 @@ mod expressions {
     /// ExprKind::Ret
     fn expr_ret() { return; return true; }
 
-    /// ExprKind::InlineAsm
-    fn expr_inline_asm() {
-        let x;
-        asm!("mov {1}, {0}\nshl {1}, 1\nshl {0}, 2\nadd {0}, {1}",
-            inout(reg)
-            x,
-            out(reg)
-            _);
-    }
 
+    /// ExprKind::InlineAsm: see exhaustive-asm.rs
     /// ExprKind::OffsetOf
     fn expr_offset_of() {
 
@@ -300,65 +303,12 @@ mod expressions {
 
 
 
-
-
-
-
-
-
         // ...
 
 
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
         // concat_idents is deprecated
 
 
@@ -450,10 +400,7 @@ mod items {
         unsafe extern "C++" {}
         unsafe extern "C" {}
     }
-    /// ItemKind::GlobalAsm
-    mod item_global_asm {
-        global_asm! (".globl my_asm_func");
-    }
+    /// ItemKind::GlobalAsm: see exhaustive-asm.rs
     /// ItemKind::TyAlias
     mod item_ty_alias {
         pub type Type<'a> where T: 'a = T;
diff --git a/tests/ui/unpretty/exhaustive.hir.stderr b/tests/ui/unpretty/exhaustive.hir.stderr
new file mode 100644
index 00000000000..58f7ff0f598
--- /dev/null
+++ b/tests/ui/unpretty/exhaustive.hir.stderr
@@ -0,0 +1,172 @@
+error[E0697]: closures cannot be static
+  --> $DIR/exhaustive.rs:211:9
+   |
+LL |         static || value;
+   |         ^^^^^^^^^
+
+error[E0697]: closures cannot be static
+  --> $DIR/exhaustive.rs:212:9
+   |
+LL |         static move || value;
+   |         ^^^^^^^^^^^^^^
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/exhaustive.rs:241:13
+   |
+LL |     fn expr_await() {
+   |     --------------- this is not `async`
+LL |         let fut;
+LL |         fut.await;
+   |             ^^^^^ only allowed inside `async` functions and blocks
+
+error: in expressions, `_` can only be used on the left-hand side of an assignment
+  --> $DIR/exhaustive.rs:290:9
+   |
+LL |         _;
+   |         ^ `_` not allowed here
+
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/exhaustive.rs:300:9
+   |
+LL |         x::();
+   |         ^^^^^ only `Fn` traits may use parentheses
+
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/exhaustive.rs:301:9
+   |
+LL |         x::(T, T) -> T;
+   |         ^^^^^^^^^^^^^^ only `Fn` traits may use parentheses
+   |
+help: use angle brackets instead
+   |
+LL -         x::(T, T) -> T;
+LL +         x::<T, T> -> T;
+   |
+
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/exhaustive.rs:302:9
+   |
+LL |         crate::() -> ()::expressions::() -> ()::expr_path;
+   |         ^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses
+
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/exhaustive.rs:302:26
+   |
+LL |         crate::() -> ()::expressions::() -> ()::expr_path;
+   |                          ^^^^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses
+
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/exhaustive.rs:305:9
+   |
+LL |         core::()::marker::()::PhantomData;
+   |         ^^^^^^^^ only `Fn` traits may use parentheses
+
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/exhaustive.rs:305:19
+   |
+LL |         core::()::marker::()::PhantomData;
+   |                   ^^^^^^^^^^ only `Fn` traits may use parentheses
+
+error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
+  --> $DIR/exhaustive.rs:392:9
+   |
+LL |         yield;
+   |         ^^^^^
+   |
+help: use `#[coroutine]` to make this closure a coroutine
+   |
+LL |     #[coroutine] fn expr_yield() {
+   |     ++++++++++++
+
+error[E0703]: invalid ABI: found `C++`
+  --> $DIR/exhaustive.rs:472:23
+   |
+LL |         unsafe extern "C++" {}
+   |                       ^^^^^ invalid ABI
+   |
+   = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
+
+error: `..` patterns are not allowed here
+  --> $DIR/exhaustive.rs:679:13
+   |
+LL |         let ..;
+   |             ^^
+   |
+   = note: only allowed in tuple, tuple struct, and slice patterns
+
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/exhaustive.rs:794:16
+   |
+LL |         let _: T() -> !;
+   |                ^^^^^^^^ only `Fn` traits may use parentheses
+
+error[E0562]: `impl Trait` is not allowed in the type of variable bindings
+  --> $DIR/exhaustive.rs:809:16
+   |
+LL |         let _: impl Send;
+   |                ^^^^^^^^^
+   |
+   = note: `impl Trait` is only allowed in arguments and return types of functions and methods
+   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0562]: `impl Trait` is not allowed in the type of variable bindings
+  --> $DIR/exhaustive.rs:810:16
+   |
+LL |         let _: impl Send + 'static;
+   |                ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `impl Trait` is only allowed in arguments and return types of functions and methods
+   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0562]: `impl Trait` is not allowed in the type of variable bindings
+  --> $DIR/exhaustive.rs:811:16
+   |
+LL |         let _: impl 'static + Send;
+   |                ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `impl Trait` is only allowed in arguments and return types of functions and methods
+   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0562]: `impl Trait` is not allowed in the type of variable bindings
+  --> $DIR/exhaustive.rs:812:16
+   |
+LL |         let _: impl ?Sized;
+   |                ^^^^^^^^^^^
+   |
+   = note: `impl Trait` is only allowed in arguments and return types of functions and methods
+   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0562]: `impl Trait` is not allowed in the type of variable bindings
+  --> $DIR/exhaustive.rs:813:16
+   |
+LL |         let _: impl ~const Clone;
+   |                ^^^^^^^^^^^^^^^^^
+   |
+   = note: `impl Trait` is only allowed in arguments and return types of functions and methods
+   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0562]: `impl Trait` is not allowed in the type of variable bindings
+  --> $DIR/exhaustive.rs:814:16
+   |
+LL |         let _: impl for<'a> Send;
+   |                ^^^^^^^^^^^^^^^^^
+   |
+   = note: `impl Trait` is only allowed in arguments and return types of functions and methods
+   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 20 previous errors
+
+Some errors have detailed explanations: E0214, E0562, E0697, E0703, E0728.
+For more information about an error, try `rustc --explain E0214`.
diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout
new file mode 100644
index 00000000000..d2c379d4366
--- /dev/null
+++ b/tests/ui/unpretty/exhaustive.hir.stdout
@@ -0,0 +1,700 @@
+//@ revisions: expanded hir
+//@[expanded]compile-flags: -Zunpretty=expanded
+//@[expanded]check-pass
+//@[hir]compile-flags: -Zunpretty=hir
+//@[hir]check-fail
+//@ edition:2024
+
+// Note: the HIR revision includes a `.stderr` file because there are some
+// errors that only occur once we get past the AST.
+
+#![feature(auto_traits)]#![feature(box_patterns)]#![feature(builtin_syntax)]#![feature(concat_idents)]#![feature(const_trait_impl)]#![feature(decl_macro)]#![feature(deref_patterns)]#![feature(dyn_star)]#![feature(explicit_tail_calls)]#![feature(gen_blocks)]#![feature(more_qualified_paths)]#![feature(never_patterns)]#![feature(never_type)]#![feature(pattern_types)]#![feature(pattern_type_macro)]#![feature(prelude_import)]#![feature(specialization)]#![feature(trace_macros)]#![feature(trait_alias)]#![feature(try_blocks)]#![feature(yeet_expr)]#![allow(incomplete_features)]
+#[prelude_import]
+use std::prelude::rust_2024::*;
+#[macro_use]
+extern crate std;
+
+#[prelude_import]
+use self::prelude::*;
+
+mod prelude {
+    use std::prelude::rust_2024::*;
+
+    type T = _;
+
+    trait Trait {
+        const
+        CONST:
+        ();
+    }
+}
+
+//! inner single-line doc comment
+/*!
+     * inner multi-line doc comment
+     */
+#[doc = "inner doc attribute"]#[allow(dead_code, unused_variables)]#[no_std]
+mod attributes {//! inner single-line doc comment
+    /*!
+     * inner multi-line doc comment
+     */
+    #![doc =
+    "inner doc attribute"]#![allow(dead_code, unused_variables)]#![no_std]
+
+    /// outer single-line doc comment
+    /**
+     * outer multi-line doc comment
+     */
+    #[doc =
+    "outer doc attribute"]#[doc = "macro"]#[allow()]#[attr = Repr([ReprC])]
+    struct Struct;
+}
+
+mod expressions {
+    /// ExprKind::Array
+    fn expr_array() {
+        [];
+        [true];
+        [true];
+        [true, true];
+        ["long........................................................................"];
+        ["long............................................................",
+                true];
+    }
+
+    /// ExprKind::ConstBlock
+    fn expr_const_block() {
+        const { };
+        const { 1 };
+        const
+                {
+                    struct S;
+                };
+    }
+
+    /// ExprKind::Call
+    fn expr_call() {
+        let f;
+        f();
+        f::<u8>();
+        f::<1>();
+        f::<'static, u8, 1>();
+        f(true);
+        f(true);
+        ()();
+    }
+
+    /// ExprKind::MethodCall
+    fn expr_method_call() {
+        let x;
+        x.f();
+        x.f::<u8>();
+        x.collect::<Vec<_>>();
+    }
+
+    /// ExprKind::Tup
+    fn expr_tup() { (); (true,); (true, false); (true, false); }
+
+    /// ExprKind::Binary
+    fn expr_binary() {
+        let (a, b, c, d, x, y);
+        true || false;
+        true || false && false;
+        a < 1 && 2 < b && c > 3 && 4 > d;
+        a & b & !c;
+        a + b * c - d + -1 * -2 - -3;
+        x = !y;
+    }
+
+    /// ExprKind::Unary
+    fn expr_unary() { let expr; *expr; !expr; -expr; }
+
+    /// ExprKind::Lit
+    fn expr_lit() { 'x'; 1000i8; 1.00000000000000000000001; }
+
+    /// ExprKind::Cast
+    fn expr_cast() { let expr; expr as T; expr as T<u8>; }
+
+    /// ExprKind::Type
+    fn expr_type() { let expr; type_ascribe!(expr, T); }
+
+    /// ExprKind::Let
+    fn expr_let() {
+        let b;
+        if let Some(a) = b { }
+        if let _ = true && false { }
+        if let _ = (true && false) { }
+    }
+
+    /// ExprKind::If
+    fn expr_if() {
+        if true { }
+        if !true { }
+        if let true = true { } else { }
+        if true { } else if false { }
+        if true { } else if false { } else { }
+        if true { return; } else if false { 0 } else { 0 }
+    }
+
+    /// ExprKind::While
+    fn expr_while() {
+        loop { if false { } else { break; } }
+        'a: loop { if false { } else { break; } }
+        loop { if let true = true { } else { break; } }
+    }
+
+    /// ExprKind::ForLoop
+    fn expr_for_loop() {
+        let x;
+        {
+                let _t =
+                    match #[lang = "into_iter"](x) {
+                            mut iter =>
+                                loop {
+                                        match #[lang = "next"](&mut iter) {
+                                                #[lang = "None"] {} => break,
+                                                #[lang = "Some"] {  0: _ } => { }
+                                            }
+                                    },
+                        };
+                _t
+            };
+        {
+                let _t =
+                    match #[lang = "into_iter"](x) {
+                            mut iter =>
+                                'a:
+                                    loop {
+                                        match #[lang = "next"](&mut iter) {
+                                                #[lang = "None"] {} => break,
+                                                #[lang = "Some"] {  0: _ } => { }
+                                            }
+                                    },
+                        };
+                _t
+            }
+    }
+
+    /// ExprKind::Loop
+    fn expr_loop() { loop { } 'a: loop { } }
+
+    /// ExprKind::Match
+    fn expr_match() {
+        let value;
+        match value { }
+        match value { ok => 1, }
+        match value { ok => 1, err => 0, }
+    }
+
+    /// ExprKind::Closure
+    fn expr_closure() {
+        let value;
+        || { };
+        |x| { };
+        |x: u8| { };
+        || ();
+        move || value;
+        || |mut _task_context: ResumeTy| { { let _t = value; _t } };
+        move || |mut _task_context: ResumeTy| { { let _t = value; _t } };
+        || value;
+        move || value;
+        || |mut _task_context: ResumeTy| { { let _t = value; _t } };
+        move || |mut _task_context: ResumeTy| { { let _t = value; _t } };
+        || -> u8 { value };
+        1 + (|| { });
+    }
+
+    /// ExprKind::Block
+    fn expr_block() {
+        { }
+        unsafe { }
+        'a: { }
+        #[allow()]
+        { }
+        #[allow()]
+        { }
+    }
+
+    /// ExprKind::Gen
+    fn expr_gen() {
+        |mut _task_context: ResumeTy| { };
+        move |mut _task_context: ResumeTy| { };
+        || { };
+        move || { };
+        |mut _task_context: ResumeTy| { };
+        move |mut _task_context: ResumeTy| { };
+    }
+
+    /// ExprKind::Await
+    fn expr_await() {
+        let fut;
+        {
+            fut;
+            (/*ERROR*/)
+        };
+    }
+
+    /// ExprKind::TryBlock
+    fn expr_try_block() {
+        { #[lang = "from_output"](()) }
+        { return; #[lang = "from_output"](()) }
+    }
+
+    /// ExprKind::Assign
+    fn expr_assign() { let expr; expr = true; }
+
+    /// ExprKind::AssignOp
+    fn expr_assign_op() { let expr; expr += true; }
+
+    /// ExprKind::Field
+    fn expr_field() { let expr; expr.field; expr.0; }
+
+    /// ExprKind::Index
+    fn expr_index() { let expr; expr[true]; }
+
+    /// ExprKind::Range
+    fn expr_range() {
+        let (lo, hi);
+        #[lang = "RangeFull"] {  };
+        #[lang = "RangeTo"] { end: hi };
+        #[lang = "RangeFrom"] { start: lo };
+        #[lang = "Range"] { start: lo, end: hi };
+        #[lang = "Range"] { start: lo, end: hi };
+        #[lang = "RangeToInclusive"] { end: hi };
+        #[lang = "range_inclusive_new"](lo, hi);
+        #[lang = "range_inclusive_new"](-2, -1);
+    }
+
+    /// ExprKind::Underscore
+    fn expr_underscore() {
+        (/*ERROR*/);
+    }
+
+    /// ExprKind::Path
+    fn expr_path() {
+        let x;
+        crate::expressions::expr_path;
+        crate::expressions::expr_path::<'static>;
+        <T as Default>::default;
+        <T as ::core::default::Default>::default;
+        x;
+        x::<T, T>;
+        crate::expressions::expr_path;
+        core::marker::PhantomData;
+    }
+
+    /// ExprKind::AddrOf
+    fn expr_addr_of() {
+        let expr;
+        &expr;
+        &mut expr;
+        &raw const expr;
+        &raw mut expr;
+    }
+
+    /// ExprKind::Break
+    fn expr_break() { 'a: { break; break 'a; break true; break 'a true; } }
+
+    /// ExprKind::Continue
+    fn expr_continue() { 'a: { continue; continue 'a; } }
+
+    /// ExprKind::Ret
+    fn expr_ret() { return; return true; }
+
+
+    /// ExprKind::InlineAsm: see exhaustive-asm.rs
+    /// ExprKind::OffsetOf
+    fn expr_offset_of() {
+
+
+
+
+
+
+
+
+
+
+
+
+
+        // ...
+
+
+
+
+
+        // concat_idents is deprecated
+
+
+
+
+        { offset_of!(T, field) };
+    }
+    /// ExprKind::MacCall
+    fn expr_mac_call() { "..."; "..."; "..."; }
+    /// ExprKind::Struct
+    fn expr_struct() {
+        struct Struct {
+        }
+        let (x, base);
+        Struct {  };
+        <Struct as ToOwned>::Owned {  };
+        Struct { .. };
+        Struct { ..base };
+        Struct { x };
+        Struct { x, ..base };
+        Struct { x: true };
+        Struct { x: true, .. };
+        Struct { x: true, ..base };
+        Struct { 0: true, ..base };
+    }
+    /// ExprKind::Repeat
+    fn expr_repeat() { [(); 0]; }
+    /// ExprKind::Paren
+    fn expr_paren() { let expr; expr; }
+    /// ExprKind::Try
+    fn expr_try() {
+        let expr;
+        match #[lang = "branch"](expr) {
+                #[lang = "Break"] {  0: residual } =>
+                    #[allow(unreachable_code)]
+                    return #[lang = "from_residual"](residual),
+                #[lang = "Continue"] {  0: val } => #[allow(unreachable_code)]
+                    val,
+            };
+    }
+    /// ExprKind::Yield
+    fn expr_yield() { yield (); yield true; }
+    /// ExprKind::Yeet
+    fn expr_yeet() {
+        return #[lang = "from_yeet"](());
+        return #[lang = "from_yeet"](0);
+    }
+    /// ExprKind::Become
+    fn expr_become() { become true; }
+    /// ExprKind::IncludedBytes
+    fn expr_include_bytes() {
+        b"data for include_bytes in ../expanded-exhaustive.rs\n";
+    }
+    /// ExprKind::FormatArgs
+    fn expr_format_args() {
+        let expr;
+        format_arguments::new_const(&[]);
+        format_arguments::new_v1(&[""],
+            &[format_argument::new_display(&expr)]);
+    }
+}
+mod items {
+    /// ItemKind::ExternCrate
+    mod item_extern_crate {/// ItemKind::ExternCrate
+        extern crate core;
+        extern crate self as unpretty;
+        extern crate core as _;
+    }
+    /// ItemKind::Use
+    mod item_use {/// ItemKind::Use
+        use ::{};
+        use crate::expressions;
+        use crate::items::item_use;
+        use core::*;
+    }
+    /// ItemKind::Static
+    mod item_static {/// ItemKind::Static
+        static A: () = { };
+        static mut B: () = { };
+    }
+    /// ItemKind::Const
+    mod item_const {/// ItemKind::Const
+        const A: () = { };
+        trait TraitItems {
+            const
+            B:
+            ();
+            const
+            C:
+            ()
+            =
+            { };
+        }
+    }
+    /// ItemKind::Fn
+    mod item_fn {/// ItemKind::Fn
+        const unsafe extern "C" fn f() { }
+        async unsafe extern "C" fn g()
+            ->
+                /*impl Trait*/ |mut _task_context: ResumeTy|
+            { { let _t = { }; _t } }
+        fn h<'a, T>() where T: 'a { }
+        trait TraitItems {
+            unsafe extern "C" fn f();
+        }
+        impl TraitItems for _ {
+            unsafe extern "C" fn f() { }
+        }
+    }
+    /// ItemKind::Mod
+    mod item_mod {/// ItemKind::Mod
+    }
+    /// ItemKind::ForeignMod
+    mod item_foreign_mod {/// ItemKind::ForeignMod
+        extern "Rust" { }
+        extern "C" { }
+    }
+    /// ItemKind::GlobalAsm: see exhaustive-asm.rs
+    /// ItemKind::TyAlias
+    mod item_ty_alias {/// ItemKind::GlobalAsm: see exhaustive-asm.rs
+        /// ItemKind::TyAlias
+        type Type<'a> where T: 'a = T;
+    }
+    /// ItemKind::Enum
+    mod item_enum {/// ItemKind::Enum
+        enum Void { }
+        enum Empty {
+            Unit,
+            Tuple(),
+            Struct {
+                },
+        }
+        enum Generic<'a, T> where T: 'a {
+            Tuple(T),
+            Struct {
+                    t: T,
+                },
+        }
+    }
+    /// ItemKind::Struct
+    mod item_struct {/// ItemKind::Struct
+        struct Unit;
+        struct Tuple();
+        struct Newtype(Unit);
+        struct Struct {
+        }
+        struct Generic<'a, T> where T: 'a {
+            t: T,
+        }
+    }
+    /// ItemKind::Union
+    mod item_union {/// ItemKind::Union
+        union Generic<'a, T> where T: 'a {
+            t: T,
+        }
+    }
+    /// ItemKind::Trait
+    mod item_trait {/// ItemKind::Trait
+        auto unsafe trait Send { }
+        trait Trait<'a>: Sized where Self: 'a { }
+    }
+    /// ItemKind::TraitAlias
+    mod item_trait_alias {/// ItemKind::TraitAlias
+        trait Trait<T> = Sized where for<'a> T: 'a;
+    }
+    /// ItemKind::Impl
+    mod item_impl {/// ItemKind::Impl
+        impl () { }
+        impl <T> () { }
+        impl Default for () { }
+        impl const <T> Default for () { }
+    }
+    /// ItemKind::MacCall
+    mod item_mac_call {/// ItemKind::MacCall
+    }
+    /// ItemKind::MacroDef
+    mod item_macro_def {/// ItemKind::MacroDef
+        macro_rules! mac { () => {...}; }
+        macro stringify { () => {} }
+    }
+    /// ItemKind::Delegation
+    /*! FIXME: todo */
+    mod item_delegation {/// ItemKind::Delegation
+        /*! FIXME: todo */
+    }
+    /// ItemKind::DelegationMac
+    /*! FIXME: todo */
+    mod item_delegation_mac {/// ItemKind::DelegationMac
+        /*! FIXME: todo */
+    }
+}
+mod patterns {
+    /// PatKind::Missing
+    fn pat_missing() { let _: for fn(u32, T, &'_ str); }
+    /// PatKind::Wild
+    fn pat_wild() { let _; }
+    /// PatKind::Ident
+    fn pat_ident() {
+        let x;
+        let ref x;
+        let mut x;
+        let ref mut x;
+        let ref mut x@_;
+    }
+    /// PatKind::Struct
+    fn pat_struct() {
+        let T {};
+        let T::<T> {};
+        let T::<'static> {};
+        let T {  x };
+        let T {  x: _x };
+        let T { .. };
+        let T {  x, .. };
+        let T {  x: _x, .. };
+        let T {  0: _x, .. };
+        let <T as ToOwned>::Owned {};
+    }
+    /// PatKind::TupleStruct
+    fn pat_tuple_struct() {
+        struct Tuple();
+        let Tuple();
+        let Tuple::<T>();
+        let Tuple::<'static>();
+        let Tuple(x);
+        let Tuple(..);
+        let Tuple(x, ..);
+    }
+    /// PatKind::Or
+    fn pat_or() { let true | false; let true; let true | false; }
+    /// PatKind::Path
+    fn pat_path() {
+        let core::marker::PhantomData;
+        let core::marker::PhantomData::<T>;
+        let core::marker::PhantomData::<'static>;
+        let <T as Trait>::CONST;
+    }
+    /// PatKind::Tuple
+    fn pat_tuple() { let (); let (true,); let (true, false); }
+    /// PatKind::Box
+    fn pat_box() { let box pat; }
+    /// PatKind::Deref
+    fn pat_deref() { let deref!(pat); }
+    /// PatKind::Ref
+    fn pat_ref() { let &pat; let &mut pat; }
+    /// PatKind::Expr
+    fn pat_expr() { let 1000i8; let -""; }
+    /// PatKind::Range
+    fn pat_range() { let ..1; let 0...; let 0..1; let 0...1; let -2...-1; }
+    /// PatKind::Slice
+    fn pat_slice() { let []; let [true]; let [true]; let [true, false]; }
+    /// PatKind::Rest
+    fn pat_rest() { let _; }
+    /// PatKind::Never
+    fn pat_never() { let !; let Some(!); }
+    /// PatKind::Paren
+    fn pat_paren() { let pat; }
+    /// PatKind::MacCall
+    fn pat_mac_call() { let ""; let ""; let ""; }
+}
+mod statements {
+    /// StmtKind::Let
+    fn stmt_let() {
+        let _;
+        let _ = true;
+        let _: T = true;
+        let _ = true else { return; };
+    }
+    /// StmtKind::Item
+    fn stmt_item() {
+        struct Struct {
+        }
+        struct Unit;
+    }
+    /// StmtKind::Expr
+    fn stmt_expr() { () }
+    /// StmtKind::Semi
+    fn stmt_semi() { 1 + 1; }
+    /// StmtKind::Empty
+    fn stmt_empty() { }
+    /// StmtKind::MacCall
+    fn stmt_mac_call() { "..."; "..."; "..."; }
+}
+mod types {
+    /// TyKind::Slice
+    fn ty_slice() { let _: [T]; }
+    /// TyKind::Array
+    fn ty_array() { let _: [T; 0]; }
+    /// TyKind::Ptr
+    fn ty_ptr() { let _: *const T; let _: *mut T; }
+    /// TyKind::Ref
+    fn ty_ref() {
+        let _: &T;
+        let _: &mut T;
+        let _: &'static T;
+        let _: &'static mut [T];
+        let _: &T<T<T<T<T>>>>;
+        let _: &T<T<T<T<T>>>>;
+    }
+    /// TyKind::BareFn
+    fn ty_bare_fn() {
+        let _: fn();
+        let _: fn() -> ();
+        let _: fn(T);
+        let _: fn(t: T);
+        let _: fn();
+        let _: for<'a> fn();
+    }
+    /// TyKind::Never
+    fn ty_never() { let _: !; }
+    /// TyKind::Tup
+    fn ty_tup() { let _: (); let _: (T,); let _: (T, T); }
+    /// TyKind::Path
+    fn ty_path() {
+        let _: T;
+        let _: T<'static>;
+        let _: T<T>;
+        let _: T<T>;
+        let _: T;
+        let _: <T as ToOwned>::Owned;
+    }
+    /// TyKind::TraitObject
+    fn ty_trait_object() {
+        let _: dyn Send;
+        let _: dyn Send + 'static;
+        let _: dyn Send + 'static;
+        let _: dyn for<'a> Send;
+        let _: dyn* Send;
+    }
+    /// TyKind::ImplTrait
+    const fn ty_impl_trait() {
+        let _: (/*ERROR*/);
+        let _: (/*ERROR*/);
+        let _: (/*ERROR*/);
+        let _: (/*ERROR*/);
+        let _: (/*ERROR*/);
+        let _: (/*ERROR*/);
+    }
+    /// TyKind::Paren
+    fn ty_paren() { let _: T; }
+    /// TyKind::Typeof
+    /*! unused for now */
+    fn ty_typeof() { }
+    /// TyKind::Infer
+    fn ty_infer() { let _: _; }
+    /// TyKind::ImplicitSelf
+    /*! there is no syntax for this */
+    fn ty_implicit_self() { }
+    /// TyKind::MacCall
+    #[expect(deprecated)]
+    fn ty_mac_call() { let _: T; let _: T; let _: T; }
+    /// TyKind::CVarArgs
+    /*! FIXME: todo */
+    fn ty_c_var_args() { }
+    /// TyKind::Pat
+    fn ty_pat() { let _: u32 is 1..=RangeMax; }
+}
+mod visibilities {
+    /// VisibilityKind::Public
+    mod visibility_public {/// VisibilityKind::Public
+        struct Pub;
+    }
+    /// VisibilityKind::Restricted
+    mod visibility_restricted {/// VisibilityKind::Restricted
+        struct PubCrate;
+        struct PubSelf;
+        struct PubSuper;
+        struct PubInCrate;
+        struct PubInSelf;
+        struct PubInSuper;
+        struct PubInCrateVisibilities;
+        struct PubInSelfSuper;
+        struct PubInSuperMod;
+    }
+}
diff --git a/tests/ui/unpretty/expanded-exhaustive.rs b/tests/ui/unpretty/exhaustive.rs
index 5697f615b97..60ad3564689 100644
--- a/tests/ui/unpretty/expanded-exhaustive.rs
+++ b/tests/ui/unpretty/exhaustive.rs
@@ -1,6 +1,12 @@
-//@ compile-flags: -Zunpretty=expanded
+//@ revisions: expanded hir
+//@[expanded]compile-flags: -Zunpretty=expanded
+//@[expanded]check-pass
+//@[hir]compile-flags: -Zunpretty=hir
+//@[hir]check-fail
 //@ edition:2024
-//@ check-pass
+
+// Note: the HIR revision includes a `.stderr` file because there are some
+// errors that only occur once we get past the AST.
 
 #![feature(auto_traits)]
 #![feature(box_patterns)]
@@ -202,8 +208,8 @@ mod expressions {
         move || value;
         async || value;
         async move || value;
-        static || value;
-        static move || value;
+        static || value;            //[hir]~ ERROR closures cannot be static
+        static move || value;       //[hir]~ ERROR closures cannot be static
         (static async || value);
         (static async move || value);
         || -> u8 { value };
@@ -232,7 +238,7 @@ mod expressions {
     /// ExprKind::Await
     fn expr_await() {
         let fut;
-        fut.await;
+        fut.await;  //[hir]~ ERROR `await` is only allowed
     }
 
     /// ExprKind::TryBlock
@@ -281,7 +287,7 @@ mod expressions {
 
     /// ExprKind::Underscore
     fn expr_underscore() {
-        _;
+        _;      //[hir]~ ERROR in expressions, `_` can only
     }
 
     /// ExprKind::Path
@@ -291,10 +297,14 @@ mod expressions {
         crate::expressions::expr_path::<'static>;
         <T as Default>::default;
         <T as ::core::default::Default>::default::<>;
-        x::();
-        x::(T, T) -> T;
+        x::();            //[hir]~ ERROR parenthesized type parameters
+        x::(T, T) -> T;   //[hir]~ ERROR parenthesized type parameters
         crate::() -> ()::expressions::() -> ()::expr_path;
+        //[hir]~^ ERROR parenthesized type parameters
+        //[hir]~| ERROR parenthesized type parameters
         core::()::marker::()::PhantomData;
+        //[hir]~^ ERROR parenthesized type parameters
+        //[hir]~| ERROR parenthesized type parameters
     }
 
     /// ExprKind::AddrOf
@@ -330,18 +340,7 @@ mod expressions {
         return true;
     }
 
-    /// ExprKind::InlineAsm
-    fn expr_inline_asm() {
-        let x;
-        core::arch::asm!(
-            "mov {tmp}, {x}",
-            "shl {tmp}, 1",
-            "shl {x}, 2",
-            "add {x}, {tmp}",
-            x = inout(reg) x,
-            tmp = out(reg) _,
-        );
-    }
+    /// ExprKind::InlineAsm: see exhaustive-asm.rs
 
     /// ExprKind::OffsetOf
     fn expr_offset_of() {
@@ -390,7 +389,7 @@ mod expressions {
 
     /// ExprKind::Yield
     fn expr_yield() {
-        yield;
+        yield;          //[hir]~ ERROR `yield` can only be used
         yield true;
     }
 
@@ -470,14 +469,11 @@ mod items {
 
     /// ItemKind::ForeignMod
     mod item_foreign_mod {
-        unsafe extern "C++" {}
+        unsafe extern "C++" {}  //[hir]~ ERROR invalid ABI
         unsafe extern "C" {}
     }
 
-    /// ItemKind::GlobalAsm
-    mod item_global_asm {
-        core::arch::global_asm!(".globl my_asm_func");
-    }
+    /// ItemKind::GlobalAsm: see exhaustive-asm.rs
 
     /// ItemKind::TyAlias
     mod item_ty_alias {
@@ -680,7 +676,7 @@ mod patterns {
 
     /// PatKind::Rest
     fn pat_rest() {
-        let ..;
+        let ..;     //[hir]~ ERROR `..` patterns are not allowed here
     }
 
     /// PatKind::Never
@@ -795,7 +791,7 @@ mod types {
         let _: T<'static>;
         let _: T<T>;
         let _: T::<T>;
-        let _: T() -> !;
+        let _: T() -> !;    //[hir]~ ERROR parenthesized type parameters
         let _: <T as ToOwned>::Owned;
     }
 
@@ -810,12 +806,12 @@ mod types {
 
     /// TyKind::ImplTrait
     const fn ty_impl_trait() {
-        let _: impl Send;
-        let _: impl Send + 'static;
-        let _: impl 'static + Send;
-        let _: impl ?Sized;
-        let _: impl ~const Clone;
-        let _: impl for<'a> Send;
+        let _: impl Send;               //[hir]~ ERROR `impl Trait` is not allowed
+        let _: impl Send + 'static;     //[hir]~ ERROR `impl Trait` is not allowed
+        let _: impl 'static + Send;     //[hir]~ ERROR `impl Trait` is not allowed
+        let _: impl ?Sized;             //[hir]~ ERROR `impl Trait` is not allowed
+        let _: impl ~const Clone;       //[hir]~ ERROR `impl Trait` is not allowed
+        let _: impl for<'a> Send;       //[hir]~ ERROR `impl Trait` is not allowed
     }
 
     /// TyKind::Paren
diff --git a/tests/ui/unpretty/expanded-interpolation.rs b/tests/ui/unpretty/interpolation-expanded.rs
index 95280f97dac..95280f97dac 100644
--- a/tests/ui/unpretty/expanded-interpolation.rs
+++ b/tests/ui/unpretty/interpolation-expanded.rs
diff --git a/tests/ui/unpretty/expanded-interpolation.stdout b/tests/ui/unpretty/interpolation-expanded.stdout
index d46b46b67f4..d46b46b67f4 100644
--- a/tests/ui/unpretty/expanded-interpolation.stdout
+++ b/tests/ui/unpretty/interpolation-expanded.stdout