Skip to content

Commit 5076f50

Browse files
committed
Auto merge of rust-lang#13024 - jonas-schievink:hir-pretty, r=jonas-schievink
internal: Add an HIR pretty-printer This improves the "View HIR" command by pretty-printing the HIR to make it much more readable. Example function: ```rust fn newline(&mut self) { match self.buf.chars().rev().skip_while(|ch| *ch == ' ').next() { Some('\n') | None => {} _ => writeln!(self).unwrap(), } } ``` Previous output: ``` HIR expressions in the body of `newline`: Idx::<Expr>(0): Path(Path { type_anchor: None, mod_path: ModPath { kind: Super(0), segments: [] }, generic_args: [] }) Idx::<Expr>(1): Field { expr: Idx::<Expr>(0), name: Name(Text("buf")) } Idx::<Expr>(2): MethodCall { receiver: Idx::<Expr>(1), method_name: Name(Text("chars")), args: [], generic_args: None } Idx::<Expr>(3): MethodCall { receiver: Idx::<Expr>(2), method_name: Name(Text("rev")), args: [], generic_args: None } Idx::<Expr>(4): Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("ch"))] }, generic_args: [None] }) Idx::<Expr>(5): UnaryOp { expr: Idx::<Expr>(4), op: Deref } Idx::<Expr>(6): Literal(Char(' ')) Idx::<Expr>(7): BinaryOp { lhs: Idx::<Expr>(5), rhs: Idx::<Expr>(6), op: Some(CmpOp(Eq { negated: false })) } Idx::<Expr>(8): Closure { args: [Idx::<Pat>(1)], arg_types: [None], ret_type: None, body: Idx::<Expr>(7) } Idx::<Expr>(9): MethodCall { receiver: Idx::<Expr>(3), method_name: Name(Text("skip_while")), args: [Idx::<Expr>(8)], generic_args: None } Idx::<Expr>(10): MethodCall { receiver: Idx::<Expr>(9), method_name: Name(Text("next")), args: [], generic_args: None } Idx::<Expr>(11): Literal(Char('\n')) Idx::<Expr>(12): Block { id: BlockId(37), statements: [], tail: None, label: None } Idx::<Expr>(13): Path(Path { type_anchor: None, mod_path: ModPath { kind: Super(0), segments: [] }, generic_args: [] }) Idx::<Expr>(14): Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("std")), Name(Text("fmt")), Name(Text("Arguments")), Name(Text("new_v1"))] }, generic_args: [None, None, None, None] }) Idx::<Expr>(15): Array(ElementList { elements: [], is_assignee_expr: false }) Idx::<Expr>(16): Ref { expr: Idx::<Expr>(15), rawness: Ref, mutability: Shared } Idx::<Expr>(17): Array(ElementList { elements: [], is_assignee_expr: false }) Idx::<Expr>(18): Ref { expr: Idx::<Expr>(17), rawness: Ref, mutability: Shared } Idx::<Expr>(19): Call { callee: Idx::<Expr>(14), args: [Idx::<Expr>(16), Idx::<Expr>(18)], is_assignee_expr: false } Idx::<Expr>(20): MethodCall { receiver: Idx::<Expr>(13), method_name: Name(Text("write_fmt")), args: [Idx::<Expr>(19)], generic_args: None } Idx::<Expr>(21): MacroStmts { statements: [], tail: Some(Idx::<Expr>(20)) } Idx::<Expr>(22): MethodCall { receiver: Idx::<Expr>(21), method_name: Name(Text("unwrap")), args: [], generic_args: None } Idx::<Expr>(23): Match { expr: Idx::<Expr>(10), arms: [MatchArm { pat: Idx::<Pat>(5), guard: None, expr: Idx::<Expr>(12) }, MatchArm { pat: Idx::<Pat>(6), guard: None, expr: Idx::<Expr>(22) }] } Idx::<Expr>(24): Block { id: BlockId(36), statements: [], tail: Some(Idx::<Expr>(23)), label: None } ``` Output after this PR: ```rust fn newline(…) { match self.buf.chars().rev().skip_while( |ch| (*ch) == (' '), ).next() { Some('\n') | None => {}, _ => { // macro statements self.write_fmt( std::fmt::Arguments::new_v1( &[], &[], ), ) }.unwrap(), } } ``` It also works for consts and statics now. This should make debugging HIR-lowering related issues like rust-lang/rust-analyzer#12940 much easier.
2 parents b6d59f2 + dcbe892 commit 5076f50

File tree

12 files changed

+914
-203
lines changed

12 files changed

+914
-203
lines changed

crates/hir-def/src/body.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod lower;
44
#[cfg(test)]
55
mod tests;
66
pub mod scope;
7+
mod pretty;
78

89
use std::{ops::Index, sync::Arc};
910

@@ -352,6 +353,10 @@ impl Body {
352353
}
353354
}
354355

356+
pub fn pretty_print(&self, db: &dyn DefDatabase, owner: DefWithBodyId) -> String {
357+
pretty::print_body_hir(db, self, owner)
358+
}
359+
355360
fn new(
356361
db: &dyn DefDatabase,
357362
expander: Expander,

0 commit comments

Comments
 (0)