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 | 102 |
1 files changed, 58 insertions, 44 deletions
diff --git a/crates/hir-def/src/expr_store/pretty.rs b/crates/hir-def/src/expr_store/pretty.rs index 5b9da3c5e6..4ba70938d0 100644 --- a/crates/hir-def/src/expr_store/pretty.rs +++ b/crates/hir-def/src/expr_store/pretty.rs @@ -9,7 +9,7 @@ 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, @@ -510,7 +510,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 +559,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 +569,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 +582,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 +631,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 +659,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 +685,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 +705,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 +718,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 +830,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 +865,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 +937,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 +966,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 +1008,7 @@ impl Printer<'_> { self.print_expr(*c); } Pat::Expr(expr) => { - self.print_expr(*expr); + self.print_expr_in(prec, *expr); } } } @@ -1181,7 +1193,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), } } |