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.rs137
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),
}
}