Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/display.rs')
-rw-r--r--crates/hir/src/display.rs429
1 files changed, 255 insertions, 174 deletions
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs
index d61c2eca83..1f9af564c3 100644
--- a/crates/hir/src/display.rs
+++ b/crates/hir/src/display.rs
@@ -2,19 +2,22 @@
use either::Either;
use hir_def::{
- AdtId, GenericDefId,
+ AdtId, BuiltinDeriveImplId, FunctionId, GenericDefId, ImplId, ItemContainerId,
+ builtin_derive::BuiltinDeriveImplMethod,
expr_store::ExpressionStore,
hir::generics::{GenericParams, TypeOrConstParamData, TypeParamProvenance, WherePredicate},
item_tree::FieldsShape,
- lang_item::LangItem,
signatures::{StaticFlags, TraitFlags},
type_ref::{TypeBound, TypeRef, TypeRefId},
};
+use hir_expand::name::Name;
use hir_ty::{
+ GenericPredicates,
db::HirDatabase,
display::{
- HirDisplay, HirDisplayError, HirDisplayWithExpressionStore, HirFormatter, SizedByDefault,
- hir_display_with_store, write_bounds_like_dyn_trait_with_prefix, write_visibility,
+ HirDisplay, HirDisplayWithExpressionStore, HirFormatter, Result, SizedByDefault,
+ hir_display_with_store, write_bounds_like_dyn_trait_with_prefix, write_params_bounds,
+ write_visibility,
},
next_solver::ClauseKind,
};
@@ -22,25 +25,78 @@ use itertools::Itertools;
use rustc_type_ir::inherent::IntoKind;
use crate::{
- Adt, AsAssocItem, AssocItem, AssocItemContainer, Const, ConstParam, Crate, Enum,
+ Adt, AnyFunctionId, AsAssocItem, AssocItem, AssocItemContainer, Const, ConstParam, Crate, Enum,
ExternCrateDecl, Field, Function, GenericParam, HasCrate, HasVisibility, Impl, LifetimeParam,
Macro, Module, SelfParam, Static, Struct, StructKind, Trait, TraitRef, TupleField, Type,
TypeAlias, TypeNs, TypeOrConstParam, TypeParam, Union, Variant,
};
+fn write_builtin_derive_impl_method<'db>(
+ f: &mut HirFormatter<'_, 'db>,
+ impl_: BuiltinDeriveImplId,
+ method: BuiltinDeriveImplMethod,
+) -> Result {
+ let db = f.db;
+ let loc = impl_.loc(db);
+ let (adt_params, _adt_params_store) = db.generic_params_and_store(loc.adt.into());
+
+ if f.show_container_bounds() && !adt_params.is_empty() {
+ f.write_str("impl")?;
+ write_generic_params(loc.adt.into(), f)?;
+ f.write_char(' ')?;
+ let trait_id = loc.trait_.get_id(f.lang_items());
+ if let Some(trait_id) = trait_id {
+ f.start_location_link(trait_id.into());
+ }
+ write!(f, "{}", Name::new_symbol_root(loc.trait_.name()).display(db, f.edition()))?;
+ if trait_id.is_some() {
+ f.end_location_link();
+ }
+ f.write_str(" for ")?;
+ f.start_location_link(loc.adt.into());
+ write!(f, "{}", Adt::from(loc.adt).name(db).display(db, f.edition()))?;
+ f.end_location_link();
+ write_generic_args(loc.adt.into(), f)?;
+ f.write_char('\n')?;
+ }
+
+ let Some(trait_method) = method.trait_method(db, impl_) else {
+ return write!(f, "fn {}(…)", method.name());
+ };
+ let has_written_where = write_function(f, trait_method)?;
+
+ if f.show_container_bounds() && !adt_params.is_empty() {
+ if !has_written_where {
+ f.write_str("\nwhere")?
+ }
+ write!(f, "\n // Bounds from impl:")?;
+
+ let predicates =
+ hir_ty::builtin_derive::predicates(db, impl_).explicit_predicates().skip_binder();
+ write_params_bounds(f, predicates)?;
+ }
+
+ Ok(())
+}
+
impl<'db> HirDisplay<'db> for Function {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
+ let id = match self.id {
+ AnyFunctionId::FunctionId(id) => id,
+ AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ } => {
+ return write_builtin_derive_impl_method(f, impl_, method);
+ }
+ };
+
let db = f.db;
- let data = db.function_signature(self.id);
- let container = self.as_assoc_item(db).map(|it| it.container(db));
- let mut module = self.module(db);
+ let container = id.loc(db).container;
// Write container (trait or impl)
let container_params = match container {
- Some(AssocItemContainer::Trait(trait_)) => {
- let (params, params_store) = f.db.generic_params_and_store(trait_.id.into());
+ ItemContainerId::TraitId(trait_) => {
+ let (params, params_store) = f.db.generic_params_and_store(trait_.into());
if f.show_container_bounds() && !params.is_empty() {
- write_trait_header(&trait_, f)?;
+ write_trait_header(trait_.into(), f)?;
f.write_char('\n')?;
has_disaplayable_predicates(f.db, &params, &params_store)
.then_some((params, params_store))
@@ -48,10 +104,10 @@ impl<'db> HirDisplay<'db> for Function {
None
}
}
- Some(AssocItemContainer::Impl(impl_)) => {
- let (params, params_store) = f.db.generic_params_and_store(impl_.id.into());
+ ItemContainerId::ImplId(impl_) => {
+ let (params, params_store) = f.db.generic_params_and_store(impl_.into());
if f.show_container_bounds() && !params.is_empty() {
- write_impl_header(&impl_, f)?;
+ write_impl_header(impl_, f)?;
f.write_char('\n')?;
has_disaplayable_predicates(f.db, &params, &params_store)
.then_some((params, params_store))
@@ -59,156 +115,180 @@ impl<'db> HirDisplay<'db> for Function {
None
}
}
- None => None,
+ _ => None,
};
// Write signature of the function
- // Block-local impls are "hoisted" to the nearest (non-block) module.
- if let Some(AssocItemContainer::Impl(_)) = container {
- module = module.nearest_non_block_module(db);
+ let has_written_where = write_function(f, id)?;
+ if let Some((container_params, container_params_store)) = container_params {
+ if !has_written_where {
+ f.write_str("\nwhere")?;
+ }
+ let container_name = match container {
+ ItemContainerId::TraitId(_) => "trait",
+ ItemContainerId::ImplId(_) => "impl",
+ _ => unreachable!(),
+ };
+ write!(f, "\n // Bounds from {container_name}:",)?;
+ write_where_predicates(&container_params, &container_params_store, f)?;
}
- let module_id = module.id;
-
- write_visibility(module_id, self.visibility(db), f)?;
+ Ok(())
+ }
+}
- if data.is_default() {
- f.write_str("default ")?;
- }
- if data.is_const() {
- f.write_str("const ")?;
- }
- if data.is_async() {
- f.write_str("async ")?;
- }
- // FIXME: This will show `unsafe` for functions that are `#[target_feature]` but not unsafe
- // (they are conditionally unsafe to call). We probably should show something else.
- if self.is_unsafe_to_call(db, None, f.edition()) {
- f.write_str("unsafe ")?;
- }
- if let Some(abi) = &data.abi {
- write!(f, "extern \"{}\" ", abi.as_str())?;
- }
- write!(f, "fn {}", data.name.display(f.db, f.edition()))?;
+fn write_function<'db>(f: &mut HirFormatter<'_, 'db>, func_id: FunctionId) -> Result<bool> {
+ let db = f.db;
+ let func = Function::from(func_id);
+ let data = db.function_signature(func_id);
- write_generic_params(GenericDefId::FunctionId(self.id), f)?;
+ let mut module = func.module(db);
+ // Block-local impls are "hoisted" to the nearest (non-block) module.
+ if let ItemContainerId::ImplId(_) = func_id.loc(db).container {
+ module = module.nearest_non_block_module(db);
+ }
+ let module_id = module.id;
- f.write_char('(')?;
+ write_visibility(module_id, func.visibility(db), f)?;
- let mut first = true;
- let mut skip_self = 0;
- if let Some(self_param) = self.self_param(db) {
- self_param.hir_fmt(f)?;
- first = false;
- skip_self = 1;
- }
+ if data.is_default() {
+ f.write_str("default ")?;
+ }
+ if data.is_const() {
+ f.write_str("const ")?;
+ }
+ if data.is_async() {
+ f.write_str("async ")?;
+ }
+ // FIXME: This will show `unsafe` for functions that are `#[target_feature]` but not unsafe
+ // (they are conditionally unsafe to call). We probably should show something else.
+ if func.is_unsafe_to_call(db, None, f.edition()) {
+ f.write_str("unsafe ")?;
+ }
+ if let Some(abi) = &data.abi {
+ write!(f, "extern \"{}\" ", abi.as_str())?;
+ }
+ write!(f, "fn {}", data.name.display(f.db, f.edition()))?;
- // FIXME: Use resolved `param.ty` once we no longer discard lifetimes
- let body = db.body(self.id.into());
- for (type_ref, param) in data.params.iter().zip(self.assoc_fn_params(db)).skip(skip_self) {
- if !first {
- f.write_str(", ")?;
- } else {
- first = false;
- }
+ write_generic_params(GenericDefId::FunctionId(func_id), f)?;
- let pat_id = body.params[param.idx - body.self_param.is_some() as usize];
- let pat_str = body.pretty_print_pat(db, self.id.into(), pat_id, true, f.edition());
- f.write_str(&pat_str)?;
+ f.write_char('(')?;
- f.write_str(": ")?;
- type_ref.hir_fmt(f, &data.store)?;
+ let mut first = true;
+ let mut skip_self = 0;
+ if let Some(self_param) = func.self_param(db) {
+ self_param.hir_fmt(f)?;
+ first = false;
+ skip_self = 1;
+ }
+
+ // FIXME: Use resolved `param.ty` once we no longer discard lifetimes
+ let body = db.body(func_id.into());
+ for (type_ref, param) in data.params.iter().zip(func.assoc_fn_params(db)).skip(skip_self) {
+ if !first {
+ f.write_str(", ")?;
+ } else {
+ first = false;
}
- if data.is_varargs() {
- if !first {
- f.write_str(", ")?;
- }
- f.write_str("...")?;
- }
-
- f.write_char(')')?;
-
- // `FunctionData::ret_type` will be `::core::future::Future<Output = ...>` for async fns.
- // Use ugly pattern match to strip the Future trait.
- // Better way?
- let ret_type = if !data.is_async() {
- data.ret_type
- } else if let Some(ret_type) = data.ret_type {
- match &data.store[ret_type] {
- TypeRef::ImplTrait(bounds) => match &bounds[0] {
- &TypeBound::Path(path, _) => Some(
- *data.store[path]
- .segments()
- .iter()
- .last()
- .unwrap()
- .args_and_bindings
- .unwrap()
- .bindings[0]
- .type_ref
- .as_ref()
- .unwrap(),
- ),
- _ => None,
- },
+ let pat_id = body.params[param.idx - body.self_param.is_some() as usize];
+ let pat_str = body.pretty_print_pat(db, func_id.into(), pat_id, true, f.edition());
+ f.write_str(&pat_str)?;
+
+ f.write_str(": ")?;
+ type_ref.hir_fmt(f, &data.store)?;
+ }
+
+ if data.is_varargs() {
+ if !first {
+ f.write_str(", ")?;
+ }
+ f.write_str("...")?;
+ }
+
+ f.write_char(')')?;
+
+ // `FunctionData::ret_type` will be `::core::future::Future<Output = ...>` for async fns.
+ // Use ugly pattern match to strip the Future trait.
+ // Better way?
+ let ret_type = if !data.is_async() {
+ data.ret_type
+ } else if let Some(ret_type) = data.ret_type {
+ match &data.store[ret_type] {
+ TypeRef::ImplTrait(bounds) => match &bounds[0] {
+ &TypeBound::Path(path, _) => Some(
+ *data.store[path]
+ .segments()
+ .iter()
+ .last()
+ .unwrap()
+ .args_and_bindings
+ .unwrap()
+ .bindings[0]
+ .type_ref
+ .as_ref()
+ .unwrap(),
+ ),
_ => None,
- }
- } else {
- None
- };
-
- if let Some(ret_type) = ret_type {
- match &data.store[ret_type] {
- TypeRef::Tuple(tup) if tup.is_empty() => {}
- _ => {
- f.write_str(" -> ")?;
- ret_type.hir_fmt(f, &data.store)?;
- }
- }
+ },
+ _ => None,
}
+ } else {
+ None
+ };
- // Write where clauses
- let has_written_where = write_where_clause(GenericDefId::FunctionId(self.id), f)?;
- if let Some((container_params, container_params_store)) = container_params {
- if !has_written_where {
- f.write_str("\nwhere")?;
+ if let Some(ret_type) = ret_type {
+ match &data.store[ret_type] {
+ TypeRef::Tuple(tup) if tup.is_empty() => {}
+ _ => {
+ f.write_str(" -> ")?;
+ ret_type.hir_fmt(f, &data.store)?;
}
- let container_name = match container.unwrap() {
- AssocItemContainer::Trait(_) => "trait",
- AssocItemContainer::Impl(_) => "impl",
- };
- write!(f, "\n // Bounds from {container_name}:",)?;
- write_where_predicates(&container_params, &container_params_store, f)?;
}
- Ok(())
}
+
+ // Write where clauses
+ let has_written_where = write_where_clause(GenericDefId::FunctionId(func_id), f)?;
+ Ok(has_written_where)
}
-fn write_impl_header<'db>(
- impl_: &Impl,
- f: &mut HirFormatter<'_, 'db>,
-) -> Result<(), HirDisplayError> {
+fn write_impl_header<'db>(impl_: ImplId, f: &mut HirFormatter<'_, 'db>) -> Result {
let db = f.db;
f.write_str("impl")?;
- let def_id = GenericDefId::ImplId(impl_.id);
+ let def_id = GenericDefId::ImplId(impl_);
write_generic_params(def_id, f)?;
- if let Some(trait_) = impl_.trait_(db) {
- let trait_data = db.trait_signature(trait_.id);
- write!(f, " {} for", trait_data.name.display(db, f.edition()))?;
+ let impl_data = db.impl_signature(impl_);
+ if let Some(target_trait) = &impl_data.target_trait {
+ f.write_char(' ')?;
+ hir_display_with_store(&impl_data.store[target_trait.path], &impl_data.store).hir_fmt(f)?;
+ f.write_str(" for")?;
}
f.write_char(' ')?;
- impl_.self_ty(db).hir_fmt(f)?;
+ Impl::from(impl_).self_ty(db).hir_fmt(f)?;
Ok(())
}
impl<'db> HirDisplay<'db> for SelfParam {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
- let data = f.db.function_signature(self.func);
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
+ let func = match self.func.id {
+ AnyFunctionId::FunctionId(id) => id,
+ AnyFunctionId::BuiltinDeriveImplMethod { method, .. } => match method {
+ BuiltinDeriveImplMethod::clone
+ | BuiltinDeriveImplMethod::fmt
+ | BuiltinDeriveImplMethod::hash
+ | BuiltinDeriveImplMethod::cmp
+ | BuiltinDeriveImplMethod::partial_cmp
+ | BuiltinDeriveImplMethod::eq => return f.write_str("&self"),
+ BuiltinDeriveImplMethod::default => {
+ unreachable!("this trait method does not have a self param")
+ }
+ },
+ };
+ let data = f.db.function_signature(func);
let param = *data.params.first().unwrap();
match &data.store[param] {
TypeRef::Path(p) if p.is_self_type() => f.write_str("self"),
@@ -233,7 +313,7 @@ impl<'db> HirDisplay<'db> for SelfParam {
}
impl<'db> HirDisplay<'db> for Adt {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
match self {
Adt::Struct(it) => it.hir_fmt(f),
Adt::Union(it) => it.hir_fmt(f),
@@ -243,7 +323,7 @@ impl<'db> HirDisplay<'db> for Adt {
}
impl<'db> HirDisplay<'db> for Struct {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
let module_id = self.module(f.db).id;
// FIXME: Render repr if its set explicitly?
write_visibility(module_id, self.visibility(f.db), f)?;
@@ -284,7 +364,7 @@ impl<'db> HirDisplay<'db> for Struct {
}
impl<'db> HirDisplay<'db> for Enum {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
f.write_str("enum ")?;
write!(f, "{}", self.name(f.db).display(f.db, f.edition()))?;
@@ -301,7 +381,7 @@ impl<'db> HirDisplay<'db> for Enum {
}
impl<'db> HirDisplay<'db> for Union {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
f.write_str("union ")?;
write!(f, "{}", self.name(f.db).display(f.db, f.edition()))?;
@@ -322,7 +402,7 @@ fn write_fields<'db>(
limit: usize,
in_line: bool,
f: &mut HirFormatter<'_, 'db>,
-) -> Result<(), HirDisplayError> {
+) -> Result {
let count = fields.len().min(limit);
let (indent, separator) = if in_line { ("", ' ') } else { (" ", '\n') };
f.write_char(if !has_where_clause { ' ' } else { separator })?;
@@ -355,7 +435,7 @@ fn write_variants<'db>(
has_where_clause: bool,
limit: usize,
f: &mut HirFormatter<'_, 'db>,
-) -> Result<(), HirDisplayError> {
+) -> Result {
let count = variants.len().min(limit);
f.write_char(if !has_where_clause { ' ' } else { '\n' })?;
if count == 0 {
@@ -391,7 +471,7 @@ fn write_variants<'db>(
}
impl<'db> HirDisplay<'db> for Field {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
write_visibility(self.parent.module(f.db).id, self.visibility(f.db), f)?;
write!(f, "{}: ", self.name(f.db).display(f.db, f.edition()))?;
self.ty(f.db).hir_fmt(f)
@@ -399,14 +479,14 @@ impl<'db> HirDisplay<'db> for Field {
}
impl<'db> HirDisplay<'db> for TupleField {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
write!(f, "pub {}: ", self.name().display(f.db, f.edition()))?;
self.ty(f.db).hir_fmt(f)
}
}
impl<'db> HirDisplay<'db> for Variant {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
write!(f, "{}", self.name(f.db).display(f.db, f.edition()))?;
let data = self.id.fields(f.db);
match data.shape {
@@ -436,19 +516,19 @@ impl<'db> HirDisplay<'db> for Variant {
}
impl<'db> HirDisplay<'db> for Type<'db> {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
self.ty.hir_fmt(f)
}
}
impl<'db> HirDisplay<'db> for TypeNs<'db> {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
self.ty.hir_fmt(f)
}
}
impl<'db> HirDisplay<'db> for ExternCrateDecl {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
f.write_str("extern crate ")?;
write!(f, "{}", self.name(f.db).display(f.db, f.edition()))?;
@@ -460,7 +540,7 @@ impl<'db> HirDisplay<'db> for ExternCrateDecl {
}
impl<'db> HirDisplay<'db> for GenericParam {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
match self {
GenericParam::TypeParam(it) => it.hir_fmt(f),
GenericParam::ConstParam(it) => it.hir_fmt(f),
@@ -470,7 +550,7 @@ impl<'db> HirDisplay<'db> for GenericParam {
}
impl<'db> HirDisplay<'db> for TypeOrConstParam {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
match self.split(f.db) {
either::Either::Left(it) => it.hir_fmt(f),
either::Either::Right(it) => it.hir_fmt(f),
@@ -479,16 +559,14 @@ impl<'db> HirDisplay<'db> for TypeOrConstParam {
}
impl<'db> HirDisplay<'db> for TypeParam {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
let params = f.db.generic_params(self.id.parent());
let param_data = &params[self.id.local_id()];
let krate = self.id.parent().krate(f.db).id;
let ty = self.ty(f.db).ty;
- let predicates = f.db.generic_predicates(self.id.parent());
+ let predicates = GenericPredicates::query_all(f.db, self.id.parent());
let predicates = predicates
- .instantiate_identity()
- .into_iter()
- .flatten()
+ .iter_identity_copied()
.filter(|wc| match wc.kind().skip_binder() {
ClauseKind::Trait(tr) => tr.self_ty() == ty,
ClauseKind::Projection(proj) => proj.self_ty() == ty,
@@ -521,7 +599,7 @@ impl<'db> HirDisplay<'db> for TypeParam {
return Ok(());
}
- let sized_trait = LangItem::Sized.resolve_trait(f.db, krate);
+ let sized_trait = f.lang_items().Sized;
let has_only_sized_bound =
predicates.iter().all(move |pred| match pred.kind().skip_binder() {
ClauseKind::Trait(it) => Some(it.def_id().0) == sized_trait,
@@ -543,22 +621,31 @@ impl<'db> HirDisplay<'db> for TypeParam {
}
impl<'db> HirDisplay<'db> for LifetimeParam {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
write!(f, "{}", self.name(f.db).display(f.db, f.edition()))
}
}
impl<'db> HirDisplay<'db> for ConstParam {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
write!(f, "const {}: ", self.name(f.db).display(f.db, f.edition()))?;
self.ty(f.db).hir_fmt(f)
}
}
-fn write_generic_params<'db>(
+fn write_generic_params<'db>(def: GenericDefId, f: &mut HirFormatter<'_, 'db>) -> Result {
+ write_generic_params_or_args(def, f, true)
+}
+
+fn write_generic_args<'db>(def: GenericDefId, f: &mut HirFormatter<'_, 'db>) -> Result {
+ write_generic_params_or_args(def, f, false)
+}
+
+fn write_generic_params_or_args<'db>(
def: GenericDefId,
f: &mut HirFormatter<'_, 'db>,
-) -> Result<(), HirDisplayError> {
+ include_defaults: bool,
+) -> Result {
let (params, store) = f.db.generic_params_and_store(def);
if params.iter_lt().next().is_none()
&& params.iter_type_or_consts().all(|it| it.1.const_param().is_none())
@@ -593,7 +680,7 @@ fn write_generic_params<'db>(
}
delim(f)?;
write!(f, "{}", name.display(f.db, f.edition()))?;
- if let Some(default) = &ty.default {
+ if include_defaults && let Some(default) = &ty.default {
f.write_str(" = ")?;
default.hir_fmt(f, &store)?;
}
@@ -603,7 +690,7 @@ fn write_generic_params<'db>(
write!(f, "const {}: ", name.display(f.db, f.edition()))?;
c.ty.hir_fmt(f, &store)?;
- if let Some(default) = &c.default {
+ if include_defaults && let Some(default) = &c.default {
f.write_str(" = ")?;
default.hir_fmt(f, &store)?;
}
@@ -616,10 +703,7 @@ fn write_generic_params<'db>(
Ok(())
}
-fn write_where_clause<'db>(
- def: GenericDefId,
- f: &mut HirFormatter<'_, 'db>,
-) -> Result<bool, HirDisplayError> {
+fn write_where_clause<'db>(def: GenericDefId, f: &mut HirFormatter<'_, 'db>) -> Result<bool> {
let (params, store) = f.db.generic_params_and_store(def);
if !has_disaplayable_predicates(f.db, &params, &store) {
return Ok(false);
@@ -651,7 +735,7 @@ fn write_where_predicates<'db>(
params: &GenericParams,
store: &ExpressionStore,
f: &mut HirFormatter<'_, 'db>,
-) -> Result<(), HirDisplayError> {
+) -> Result {
use WherePredicate::*;
// unnamed type targets are displayed inline with the argument itself, e.g. `f: impl Y`.
@@ -712,7 +796,7 @@ fn write_where_predicates<'db>(
}
impl<'db> HirDisplay<'db> for Const {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
let db = f.db;
let container = self.as_assoc_item(db).map(|it| it.container(db));
let mut module = self.module(db);
@@ -733,7 +817,7 @@ impl<'db> HirDisplay<'db> for Const {
}
impl<'db> HirDisplay<'db> for Static {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
let data = f.db.static_signature(self.id);
f.write_str("static ")?;
@@ -747,15 +831,15 @@ impl<'db> HirDisplay<'db> for Static {
}
impl<'db> HirDisplay<'db> for TraitRef<'db> {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
self.trait_ref.hir_fmt(f)
}
}
impl<'db> HirDisplay<'db> for Trait {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
// FIXME(trait-alias) needs special handling to print the equal sign
- write_trait_header(self, f)?;
+ write_trait_header(*self, f)?;
let def_id = GenericDefId::TraitId(self.id);
let has_where_clause = write_where_clause(def_id, f)?;
@@ -792,10 +876,7 @@ impl<'db> HirDisplay<'db> for Trait {
}
}
-fn write_trait_header<'db>(
- trait_: &Trait,
- f: &mut HirFormatter<'_, 'db>,
-) -> Result<(), HirDisplayError> {
+fn write_trait_header<'db>(trait_: Trait, f: &mut HirFormatter<'_, 'db>) -> Result {
write_visibility(trait_.module(f.db).id, trait_.visibility(f.db), f)?;
let data = f.db.trait_signature(trait_.id);
if data.flags.contains(TraitFlags::UNSAFE) {
@@ -810,7 +891,7 @@ fn write_trait_header<'db>(
}
impl<'db> HirDisplay<'db> for TypeAlias {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
let data = f.db.type_alias_signature(self.id);
write!(f, "type {}", data.name.display(f.db, f.edition()))?;
@@ -833,7 +914,7 @@ impl<'db> HirDisplay<'db> for TypeAlias {
}
impl<'db> HirDisplay<'db> for Module {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
match self.parent(f.db) {
Some(m) => write_visibility(m.id, self.visibility(f.db), f)?,
None => {
@@ -851,7 +932,7 @@ impl<'db> HirDisplay<'db> for Module {
}
impl<'db> HirDisplay<'db> for Crate {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
match self.display_name(f.db) {
Some(name) => write!(f, "extern crate {name}"),
None => f.write_str("extern crate {unknown}"),
@@ -860,7 +941,7 @@ impl<'db> HirDisplay<'db> for Crate {
}
impl<'db> HirDisplay<'db> for Macro {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
match self.id {
hir_def::MacroId::Macro2Id(_) => f.write_str("macro"),
hir_def::MacroId::MacroRulesId(_) => f.write_str("macro_rules!"),