Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/expr_store/pretty.rs')
| -rw-r--r-- | crates/hir-def/src/expr_store/pretty.rs | 137 |
1 files changed, 77 insertions, 60 deletions
diff --git a/crates/hir-def/src/expr_store/pretty.rs b/crates/hir-def/src/expr_store/pretty.rs index 5b9da3c5e6..f5ef8e1a35 100644 --- a/crates/hir-def/src/expr_store/pretty.rs +++ b/crates/hir-def/src/expr_store/pretty.rs @@ -9,10 +9,11 @@ use std::{ use hir_expand::{Lookup, mod_path::PathKind}; use itertools::Itertools; use span::Edition; -use syntax::ast::HasName; +use syntax::ast::{HasName, RangeOp}; use crate::{ - AdtId, DefWithBodyId, GenericDefId, TypeParamId, VariantId, + AdtId, DefWithBodyId, FunctionId, GenericDefId, StructId, TypeParamId, VariantId, + attrs::AttrFlags, expr_store::path::{GenericArg, GenericArgs}, hir::{ Array, BindingAnnotation, CaptureBy, ClosureKind, Literal, Movability, Statement, @@ -167,7 +168,7 @@ pub fn print_signature(db: &dyn DefDatabase, owner: GenericDefId, edition: Editi GenericDefId::AdtId(id) => match id { AdtId::StructId(id) => { let signature = db.struct_signature(id); - print_struct(db, &signature, edition) + print_struct(db, id, &signature, edition) } AdtId::UnionId(id) => { format!("unimplemented {id:?}") @@ -179,7 +180,7 @@ pub fn print_signature(db: &dyn DefDatabase, owner: GenericDefId, edition: Editi GenericDefId::ConstId(id) => format!("unimplemented {id:?}"), GenericDefId::FunctionId(id) => { let signature = db.function_signature(id); - print_function(db, &signature, edition) + print_function(db, id, &signature, edition) } GenericDefId::ImplId(id) => format!("unimplemented {id:?}"), GenericDefId::StaticId(id) => format!("unimplemented {id:?}"), @@ -208,7 +209,8 @@ pub fn print_path( pub fn print_struct( db: &dyn DefDatabase, - StructSignature { name, generic_params, store, flags, shape, repr }: &StructSignature, + id: StructId, + StructSignature { name, generic_params, store, flags, shape }: &StructSignature, edition: Edition, ) -> String { let mut p = Printer { @@ -219,7 +221,7 @@ pub fn print_struct( line_format: LineFormat::Newline, edition, }; - if let Some(repr) = repr { + if let Some(repr) = AttrFlags::repr(db, id.into()) { if repr.c() { wln!(p, "#[repr(C)]"); } @@ -255,7 +257,8 @@ pub fn print_struct( pub fn print_function( db: &dyn DefDatabase, - FunctionSignature { + id: FunctionId, + signature @ FunctionSignature { name, generic_params, store, @@ -263,10 +266,10 @@ pub fn print_function( ret_type, abi, flags, - legacy_const_generics_indices, }: &FunctionSignature, edition: Edition, ) -> String { + let legacy_const_generics_indices = signature.legacy_const_generics_indices(db, id); let mut p = Printer { db, store, @@ -298,7 +301,7 @@ pub fn print_function( if i != 0 { w!(p, ", "); } - if legacy_const_generics_indices.as_ref().is_some_and(|idx| idx.contains(&(i as u32))) { + if legacy_const_generics_indices.is_some_and(|idx| idx.contains(&(i as u32))) { w!(p, "const: "); } p.print_type_ref(*param); @@ -510,7 +513,22 @@ impl Printer<'_> { } fn print_expr(&mut self, expr: ExprId) { + self.print_expr_in(None, expr); + } + + fn print_expr_in(&mut self, prec: Option<ast::prec::ExprPrecedence>, expr: ExprId) { let expr = &self.store[expr]; + let needs_parens = match (prec, expr.precedence()) { + (Some(ast::prec::ExprPrecedence::LOr), ast::prec::ExprPrecedence::LOr) => false, + (Some(ast::prec::ExprPrecedence::LAnd), ast::prec::ExprPrecedence::LAnd) => false, + (Some(parent), prec) => prec.needs_parentheses_in(parent), + (None, _) => false, + }; + let prec = Some(expr.precedence()); + + if needs_parens { + w!(self, "("); + } match expr { Expr::Missing => w!(self, "�"), @@ -544,7 +562,7 @@ impl Printer<'_> { w!(self, "let "); self.print_pat(*pat); w!(self, " = "); - self.print_expr(*expr); + self.print_expr_in(prec, *expr); } Expr::Loop { body, label } => { if let Some(lbl) = label { @@ -554,7 +572,7 @@ impl Printer<'_> { self.print_expr(*body); } Expr::Call { callee, args } => { - self.print_expr(*callee); + self.print_expr_in(prec, *callee); w!(self, "("); if !args.is_empty() { self.indented(|p| { @@ -567,7 +585,7 @@ impl Printer<'_> { w!(self, ")"); } Expr::MethodCall { receiver, method_name, args, generic_args } => { - self.print_expr(*receiver); + self.print_expr_in(prec, *receiver); w!(self, ".{}", method_name.display(self.db, self.edition)); if let Some(args) = generic_args { w!(self, "::<"); @@ -616,26 +634,26 @@ impl Printer<'_> { } if let Some(expr) = expr { self.whitespace(); - self.print_expr(*expr); + self.print_expr_in(prec, *expr); } } Expr::Return { expr } => { w!(self, "return"); if let Some(expr) = expr { self.whitespace(); - self.print_expr(*expr); + self.print_expr_in(prec, *expr); } } Expr::Become { expr } => { w!(self, "become"); self.whitespace(); - self.print_expr(*expr); + self.print_expr_in(prec, *expr); } Expr::Yield { expr } => { w!(self, "yield"); if let Some(expr) = expr { self.whitespace(); - self.print_expr(*expr); + self.print_expr_in(prec, *expr); } } Expr::Yeet { expr } => { @@ -644,7 +662,7 @@ impl Printer<'_> { w!(self, "yeet"); if let Some(expr) = expr { self.whitespace(); - self.print_expr(*expr); + self.print_expr_in(prec, *expr); } } Expr::RecordLit { path, fields, spread } => { @@ -670,15 +688,15 @@ impl Printer<'_> { w!(self, "}}"); } Expr::Field { expr, name } => { - self.print_expr(*expr); + self.print_expr_in(prec, *expr); w!(self, ".{}", name.display(self.db, self.edition)); } Expr::Await { expr } => { - self.print_expr(*expr); + self.print_expr_in(prec, *expr); w!(self, ".await"); } Expr::Cast { expr, type_ref } => { - self.print_expr(*expr); + self.print_expr_in(prec, *expr); w!(self, " as "); self.print_type_ref(*type_ref); } @@ -690,11 +708,11 @@ impl Printer<'_> { if mutability.is_mut() { w!(self, "mut "); } - self.print_expr(*expr); + self.print_expr_in(prec, *expr); } Expr::Box { expr } => { w!(self, "box "); - self.print_expr(*expr); + self.print_expr_in(prec, *expr); } Expr::UnaryOp { expr, op } => { let op = match op { @@ -703,43 +721,32 @@ impl Printer<'_> { ast::UnaryOp::Neg => "-", }; w!(self, "{}", op); - self.print_expr(*expr); + self.print_expr_in(prec, *expr); } Expr::BinaryOp { lhs, rhs, op } => { - let (bra, ket) = match op { - None | Some(ast::BinaryOp::Assignment { .. }) => ("", ""), - _ => ("(", ")"), - }; - w!(self, "{}", bra); - self.print_expr(*lhs); - w!(self, "{} ", ket); + self.print_expr_in(prec, *lhs); + self.whitespace(); match op { Some(op) => w!(self, "{}", op), None => w!(self, "�"), // :) } - w!(self, " {}", bra); - self.print_expr(*rhs); - w!(self, "{}", ket); + self.whitespace(); + self.print_expr_in(prec, *rhs); } Expr::Range { lhs, rhs, range_type } => { if let Some(lhs) = lhs { - w!(self, "("); - self.print_expr(*lhs); - w!(self, ") "); + self.print_expr_in(prec, *lhs); } - let range = match range_type { - ast::RangeOp::Exclusive => "..", - ast::RangeOp::Inclusive => "..=", + match range_type { + RangeOp::Exclusive => w!(self, ".."), + RangeOp::Inclusive => w!(self, "..="), }; - w!(self, "{}", range); if let Some(rhs) = rhs { - w!(self, "("); - self.print_expr(*rhs); - w!(self, ") "); + self.print_expr_in(prec, *rhs); } } Expr::Index { base, index } => { - self.print_expr(*base); + self.print_expr_in(prec, *base); w!(self, "["); self.print_expr(*index); w!(self, "]"); @@ -826,9 +833,13 @@ impl Printer<'_> { &Expr::Assignment { target, value } => { self.print_pat(target); w!(self, " = "); - self.print_expr(value); + self.print_expr_in(prec, value); } } + + if needs_parens { + w!(self, ")"); + } } fn print_block( @@ -857,6 +868,7 @@ impl Printer<'_> { } fn print_pat(&mut self, pat: PatId) { + let prec = Some(ast::prec::ExprPrecedence::Shift); let pat = &self.store[pat]; match pat { @@ -928,13 +940,16 @@ impl Printer<'_> { }); w!(self, "}}"); } - Pat::Range { start, end } => { + Pat::Range { start, end, range_type } => { if let Some(start) = start { - self.print_expr(*start); + self.print_expr_in(prec, *start); + } + match range_type { + RangeOp::Inclusive => w!(self, "..="), + RangeOp::Exclusive => w!(self, ".."), } - w!(self, "..="); if let Some(end) = end { - self.print_expr(*end); + self.print_expr_in(prec, *end); } } Pat::Slice { prefix, slice, suffix } => { @@ -954,7 +969,7 @@ impl Printer<'_> { w!(self, "]"); } Pat::Path(path) => self.print_path(path), - Pat::Lit(expr) => self.print_expr(*expr), + Pat::Lit(expr) => self.print_expr_in(prec, *expr), Pat::Bind { id, subpat } => { self.print_binding(*id); if let Some(pat) = subpat { @@ -996,7 +1011,7 @@ impl Printer<'_> { self.print_expr(*c); } Pat::Expr(expr) => { - self.print_expr(*expr); + self.print_expr_in(prec, *expr); } } } @@ -1079,15 +1094,15 @@ impl Printer<'_> { }}; } match *it { - LangItemTarget::ImplDef(it) => w!(self, "{it:?}"), + LangItemTarget::ImplId(it) => w!(self, "{it:?}"), LangItemTarget::EnumId(it) => write_name!(it), - LangItemTarget::Function(it) => write_name!(it), - LangItemTarget::Static(it) => write_name!(it), - LangItemTarget::Struct(it) => write_name!(it), - LangItemTarget::Union(it) => write_name!(it), - LangItemTarget::TypeAlias(it) => write_name!(it), - LangItemTarget::Trait(it) => write_name!(it), - LangItemTarget::EnumVariant(it) => write_name!(it), + LangItemTarget::FunctionId(it) => write_name!(it), + LangItemTarget::StaticId(it) => write_name!(it), + LangItemTarget::StructId(it) => write_name!(it), + LangItemTarget::UnionId(it) => write_name!(it), + LangItemTarget::TypeAliasId(it) => write_name!(it), + LangItemTarget::TraitId(it) => write_name!(it), + LangItemTarget::EnumVariantId(it) => write_name!(it), } if let Some(s) = s { @@ -1181,7 +1196,9 @@ impl Printer<'_> { pub(crate) fn print_generic_arg(&mut self, arg: &GenericArg) { match arg { GenericArg::Type(ty) => self.print_type_ref(*ty), - GenericArg::Const(ConstRef { expr }) => self.print_expr(*expr), + GenericArg::Const(ConstRef { expr }) => { + self.print_expr_in(Some(ast::prec::ExprPrecedence::Unambiguous), *expr) + } GenericArg::Lifetime(lt) => self.print_lifetime_ref(*lt), } } |