Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/display.rs')
-rw-r--r--crates/hir-ty/src/display.rs439
1 files changed, 200 insertions, 239 deletions
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index 0a3796687f..44bbd84003 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -7,19 +7,17 @@ use std::{
mem,
};
-use base_db::Crate;
+use base_db::{Crate, FxIndexMap};
use either::Either;
use hir_def::{
- FindPathConfig, GeneralConstId, GenericDefId, HasModule, LocalFieldId, Lookup, ModuleDefId,
- ModuleId, TraitId,
+ FindPathConfig, GenericDefId, HasModule, LocalFieldId, Lookup, ModuleDefId, ModuleId, TraitId,
db::DefDatabase,
expr_store::{ExpressionStore, path::Path},
find_path::{self, PrefixKind},
hir::generics::{TypeOrConstParamData, TypeParamProvenance, WherePredicate},
item_scope::ItemInNs,
item_tree::FieldsShape,
- lang_item::LangItem,
- nameres::DefMap,
+ lang_item::LangItems,
signatures::VariantFields,
type_ref::{
ConstRef, LifetimeRef, LifetimeRefId, TraitBoundModifier, TypeBound, TypeRef, TypeRefId,
@@ -40,30 +38,32 @@ use rustc_hash::FxHashSet;
use rustc_type_ir::{
AliasTyKind, BoundVarIndexKind, CoroutineArgsParts, CoroutineClosureArgsParts, RegionKind,
Upcast,
- inherent::{AdtDef, GenericArgs as _, IntoKind, SliceLike, Term as _, Ty as _, Tys as _},
+ inherent::{AdtDef, GenericArgs as _, IntoKind, Term as _, Ty as _, Tys as _},
};
use smallvec::SmallVec;
use span::Edition;
use stdx::never;
-use triomphe::Arc;
use crate::{
- CallableDefId, FnAbi, ImplTraitId, MemoryMap, TraitEnvironment, consteval,
+ CallableDefId, FnAbi, ImplTraitId, InferenceResult, MemoryMap, ParamEnvAndCrate, consteval,
db::{HirDatabase, InternedClosure, InternedCoroutine},
generics::generics,
layout::Layout,
+ lower::GenericPredicates,
mir::pad16,
next_solver::{
- AliasTy, Clause, ClauseKind, Const, ConstKind, DbInterner, EarlyBinder,
- ExistentialPredicate, FnSig, GenericArg, GenericArgs, PolyFnSig, Region, SolverDefId, Term,
- TraitRef, Ty, TyKind, TypingMode,
+ AliasTy, Clause, ClauseKind, Const, ConstKind, DbInterner, ExistentialPredicate, FnSig,
+ GenericArg, GenericArgKind, GenericArgs, ParamEnv, PolyFnSig, Region, SolverDefId,
+ StoredEarlyBinder, StoredTy, Term, TermKind, TraitRef, Ty, TyKind, TypingMode,
abi::Safety,
infer::{DbInternerInferExt, traits::ObligationCause},
},
primitive,
- utils::{self, detect_variant_from_bytes},
+ utils::{detect_variant_from_bytes, fn_traits},
};
+pub type Result<T = (), E = HirDisplayError> = std::result::Result<T, E>;
+
pub trait HirWrite: fmt::Write {
fn start_location_link(&mut self, _location: ModuleDefId) {}
fn end_location_link(&mut self) {}
@@ -143,11 +143,11 @@ impl<'db> BoundsFormattingCtx<'db> {
}
impl<'db> HirFormatter<'_, 'db> {
- fn start_location_link(&mut self, location: ModuleDefId) {
+ pub fn start_location_link(&mut self, location: ModuleDefId) {
self.fmt.start_location_link(location);
}
- fn end_location_link(&mut self) {
+ pub fn end_location_link(&mut self) {
self.fmt.end_location_link();
}
@@ -191,7 +191,7 @@ impl<'db> HirFormatter<'_, 'db> {
}
pub trait HirDisplay<'db> {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError>;
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result;
/// Returns a `Display`able type that is human-readable.
fn into_displayable<'a>(
@@ -309,8 +309,7 @@ pub trait HirDisplay<'db> {
allow_opaque: bool,
) -> Result<String, DisplaySourceCodeError> {
let mut result = String::new();
- let interner =
- DbInterner::new_with(db, Some(module_id.krate()), module_id.containing_block());
+ let interner = DbInterner::new_with(db, module_id.krate(db));
match self.hir_fmt(&mut HirFormatter {
db,
interner,
@@ -321,7 +320,7 @@ pub trait HirDisplay<'db> {
entity_limit: None,
omit_verbose_types: false,
closure_style: ClosureStyle::ImplFn,
- display_target: DisplayTarget::from_crate(db, module_id.krate()),
+ display_target: DisplayTarget::from_crate(db, module_id.krate(db)),
display_kind: DisplayKind::SourceCode { target_module_id: module_id, allow_opaque },
show_container_bounds: false,
display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
@@ -392,11 +391,16 @@ impl<'db> HirFormatter<'_, 'db> {
self.display_target.edition
}
+ #[inline]
+ pub fn lang_items(&self) -> &'db LangItems {
+ self.interner.lang_items()
+ }
+
pub fn write_joined<T: HirDisplay<'db>>(
&mut self,
iter: impl IntoIterator<Item = T>,
sep: &str,
- ) -> Result<(), HirDisplayError> {
+ ) -> Result {
let mut first = true;
for e in iter {
if !first {
@@ -415,7 +419,7 @@ impl<'db> HirFormatter<'_, 'db> {
}
/// This allows using the `write!` macro directly with a `HirFormatter`.
- pub fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> Result<(), HirDisplayError> {
+ pub fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> Result {
// We write to a buffer first to track output size
self.buf.clear();
fmt::write(&mut self.buf, args)?;
@@ -425,12 +429,12 @@ impl<'db> HirFormatter<'_, 'db> {
self.fmt.write_str(&self.buf).map_err(HirDisplayError::from)
}
- pub fn write_str(&mut self, s: &str) -> Result<(), HirDisplayError> {
+ pub fn write_str(&mut self, s: &str) -> Result {
self.fmt.write_str(s)?;
Ok(())
}
- pub fn write_char(&mut self, c: char) -> Result<(), HirDisplayError> {
+ pub fn write_char(&mut self, c: char) -> Result {
self.fmt.write_char(c)?;
Ok(())
}
@@ -538,13 +542,9 @@ pub enum ClosureStyle {
}
impl<'db, T: HirDisplay<'db>> HirDisplayWrapper<'_, 'db, T> {
- pub fn write_to<F: HirWrite>(&self, f: &mut F) -> Result<(), HirDisplayError> {
+ pub fn write_to<F: HirWrite>(&self, f: &mut F) -> Result {
let krate = self.display_target.krate;
- let block = match self.display_kind {
- DisplayKind::SourceCode { target_module_id, .. } => target_module_id.containing_block(),
- DisplayKind::Diagnostics | DisplayKind::Test => None,
- };
- let interner = DbInterner::new_with(self.db, Some(krate), block);
+ let interner = DbInterner::new_with(self.db, krate);
self.t.hir_fmt(&mut HirFormatter {
db: self.db,
interner,
@@ -595,21 +595,18 @@ where
const TYPE_HINT_TRUNCATION: &str = "…";
impl<'db, T: HirDisplay<'db>> HirDisplay<'db> for &T {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
HirDisplay::hir_fmt(*self, f)
}
}
impl<'db, T: HirDisplay<'db> + Internable> HirDisplay<'db> for Interned<T> {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
- HirDisplay::hir_fmt(self.as_ref(), f)
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
+ HirDisplay::hir_fmt(&**self, f)
}
}
-fn write_projection<'db>(
- f: &mut HirFormatter<'_, 'db>,
- alias: &AliasTy<'db>,
-) -> Result<(), HirDisplayError> {
+fn write_projection<'db>(f: &mut HirFormatter<'_, 'db>, alias: &AliasTy<'db>) -> Result {
if f.should_truncate() {
return write!(f, "{TYPE_HINT_TRUNCATION}");
}
@@ -625,23 +622,20 @@ fn write_projection<'db>(
{
// FIXME: We shouldn't use `param.id`, it should be removed. We should know the
// `GenericDefId` from the formatted type (store it inside the `HirFormatter`).
- let bounds =
- f.db.generic_predicates(param.id.parent())
- .instantiate_identity()
- .into_iter()
- .flatten()
- .filter(|wc| {
- let ty = match wc.kind().skip_binder() {
- ClauseKind::Trait(tr) => tr.self_ty(),
- ClauseKind::TypeOutlives(t) => t.0,
- _ => return false,
- };
- let TyKind::Alias(AliasTyKind::Projection, a) = ty.kind() else {
- return false;
- };
- a == *alias
- })
- .collect::<Vec<_>>();
+ let bounds = GenericPredicates::query_all(f.db, param.id.parent())
+ .iter_identity_copied()
+ .filter(|wc| {
+ let ty = match wc.kind().skip_binder() {
+ ClauseKind::Trait(tr) => tr.self_ty(),
+ ClauseKind::TypeOutlives(t) => t.0,
+ _ => return false,
+ };
+ let TyKind::Alias(AliasTyKind::Projection, a) = ty.kind() else {
+ return false;
+ };
+ a == *alias
+ })
+ .collect::<Vec<_>>();
if !bounds.is_empty() {
return f.format_bounds_with(*alias, |f| {
write_bounds_like_dyn_trait_with_prefix(
@@ -669,17 +663,17 @@ fn write_projection<'db>(
}
impl<'db> HirDisplay<'db> for GenericArg<'db> {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
- match self {
- GenericArg::Ty(ty) => ty.hir_fmt(f),
- GenericArg::Lifetime(lt) => lt.hir_fmt(f),
- GenericArg::Const(c) => c.hir_fmt(f),
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
+ match self.kind() {
+ GenericArgKind::Type(ty) => ty.hir_fmt(f),
+ GenericArgKind::Lifetime(lt) => lt.hir_fmt(f),
+ GenericArgKind::Const(c) => c.hir_fmt(f),
}
}
}
impl<'db> HirDisplay<'db> for Const<'db> {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
match self.kind() {
ConstKind::Placeholder(_) => write!(f, "<placeholder>"),
ConstKind::Bound(BoundVarIndexKind::Bound(db), bound_const) => {
@@ -702,11 +696,7 @@ impl<'db> HirDisplay<'db> for Const<'db> {
const_bytes.ty,
),
ConstKind::Unevaluated(unev) => {
- let c = match unev.def {
- SolverDefId::ConstId(id) => GeneralConstId::ConstId(id),
- SolverDefId::StaticId(id) => GeneralConstId::StaticId(id),
- _ => unreachable!(),
- };
+ let c = unev.def.0;
write!(f, "{}", c.name(f.db))?;
hir_fmt_generics(f, unev.args.as_slice(), c.generic_def(f.db), None)?;
Ok(())
@@ -722,11 +712,11 @@ fn render_const_scalar<'db>(
b: &[u8],
memory_map: &MemoryMap<'db>,
ty: Ty<'db>,
-) -> Result<(), HirDisplayError> {
- let trait_env = TraitEnvironment::empty(f.krate());
+) -> Result {
+ let param_env = ParamEnv::empty();
let infcx = f.interner.infer_ctxt().build(TypingMode::PostAnalysis);
- let ty = infcx.at(&ObligationCause::new(), trait_env.env).deeply_normalize(ty).unwrap_or(ty);
- render_const_scalar_inner(f, b, memory_map, ty, trait_env)
+ let ty = infcx.at(&ObligationCause::new(), param_env).deeply_normalize(ty).unwrap_or(ty);
+ render_const_scalar_inner(f, b, memory_map, ty, param_env)
}
fn render_const_scalar_inner<'db>(
@@ -734,9 +724,10 @@ fn render_const_scalar_inner<'db>(
b: &[u8],
memory_map: &MemoryMap<'db>,
ty: Ty<'db>,
- trait_env: Arc<TraitEnvironment<'db>>,
-) -> Result<(), HirDisplayError> {
+ param_env: ParamEnv<'db>,
+) -> Result {
use TyKind;
+ let param_env = ParamEnvAndCrate { param_env, krate: f.krate() };
match ty.kind() {
TyKind::Bool => write!(f, "{}", b[0] != 0),
TyKind::Char => {
@@ -799,7 +790,7 @@ fn render_const_scalar_inner<'db>(
TyKind::Slice(ty) => {
let addr = usize::from_le_bytes(b[0..b.len() / 2].try_into().unwrap());
let count = usize::from_le_bytes(b[b.len() / 2..].try_into().unwrap());
- let Ok(layout) = f.db.layout_of_ty(ty, trait_env) else {
+ let Ok(layout) = f.db.layout_of_ty(ty.store(), param_env.store()) else {
return f.write_str("<layout-error>");
};
let size_one = layout.size.bytes_usize();
@@ -833,7 +824,7 @@ fn render_const_scalar_inner<'db>(
let Ok(t) = memory_map.vtable_ty(ty_id) else {
return f.write_str("<ty-missing-in-vtable-map>");
};
- let Ok(layout) = f.db.layout_of_ty(t, trait_env) else {
+ let Ok(layout) = f.db.layout_of_ty(t.store(), param_env.store()) else {
return f.write_str("<layout-error>");
};
let size = layout.size.bytes_usize();
@@ -863,7 +854,7 @@ fn render_const_scalar_inner<'db>(
return f.write_str("<layout-error>");
}
});
- let Ok(layout) = f.db.layout_of_ty(t, trait_env) else {
+ let Ok(layout) = f.db.layout_of_ty(t.store(), param_env.store()) else {
return f.write_str("<layout-error>");
};
let size = layout.size.bytes_usize();
@@ -875,7 +866,7 @@ fn render_const_scalar_inner<'db>(
}
},
TyKind::Tuple(tys) => {
- let Ok(layout) = f.db.layout_of_ty(ty, trait_env.clone()) else {
+ let Ok(layout) = f.db.layout_of_ty(ty.store(), param_env.store()) else {
return f.write_str("<layout-error>");
};
f.write_str("(")?;
@@ -887,7 +878,7 @@ fn render_const_scalar_inner<'db>(
f.write_str(", ")?;
}
let offset = layout.fields.offset(id).bytes_usize();
- let Ok(layout) = f.db.layout_of_ty(ty, trait_env.clone()) else {
+ let Ok(layout) = f.db.layout_of_ty(ty.store(), param_env.store()) else {
f.write_str("<layout-error>")?;
continue;
};
@@ -898,7 +889,7 @@ fn render_const_scalar_inner<'db>(
}
TyKind::Adt(def, args) => {
let def = def.def_id().0;
- let Ok(layout) = f.db.layout_of_adt(def, args, trait_env.clone()) else {
+ let Ok(layout) = f.db.layout_of_adt(def, args.store(), param_env.store()) else {
return f.write_str("<layout-error>");
};
match def {
@@ -909,7 +900,7 @@ fn render_const_scalar_inner<'db>(
render_variant_after_name(
s.fields(f.db),
f,
- &field_types,
+ field_types,
f.db.trait_environment(def.into()),
&layout,
args,
@@ -921,7 +912,7 @@ fn render_const_scalar_inner<'db>(
write!(f, "{}", f.db.union_signature(u).name.display(f.db, f.edition()))
}
hir_def::AdtId::EnumId(e) => {
- let Ok(target_data_layout) = f.db.target_data_layout(trait_env.krate) else {
+ let Ok(target_data_layout) = f.db.target_data_layout(f.krate()) else {
return f.write_str("<target-layout-not-available>");
};
let Some((var_id, var_layout)) =
@@ -941,7 +932,7 @@ fn render_const_scalar_inner<'db>(
render_variant_after_name(
var_id.fields(f.db),
f,
- &field_types,
+ field_types,
f.db.trait_environment(def.into()),
var_layout,
args,
@@ -961,7 +952,7 @@ fn render_const_scalar_inner<'db>(
let Some(len) = consteval::try_const_usize(f.db, len) else {
return f.write_str("<unknown-array-len>");
};
- let Ok(layout) = f.db.layout_of_ty(ty, trait_env) else {
+ let Ok(layout) = f.db.layout_of_ty(ty.store(), param_env.store()) else {
return f.write_str("<layout-error>");
};
let size_one = layout.size.bytes_usize();
@@ -1001,19 +992,20 @@ fn render_const_scalar_inner<'db>(
fn render_variant_after_name<'db>(
data: &VariantFields,
f: &mut HirFormatter<'_, 'db>,
- field_types: &ArenaMap<LocalFieldId, EarlyBinder<'db, Ty<'db>>>,
- trait_env: Arc<TraitEnvironment<'db>>,
+ field_types: &'db ArenaMap<LocalFieldId, StoredEarlyBinder<StoredTy>>,
+ param_env: ParamEnv<'db>,
layout: &Layout,
args: GenericArgs<'db>,
b: &[u8],
memory_map: &MemoryMap<'db>,
-) -> Result<(), HirDisplayError> {
+) -> Result {
+ let param_env = ParamEnvAndCrate { param_env, krate: f.krate() };
match data.shape {
FieldsShape::Record | FieldsShape::Tuple => {
let render_field = |f: &mut HirFormatter<'_, 'db>, id: LocalFieldId| {
let offset = layout.fields.offset(u32::from(id.into_raw()) as usize).bytes_usize();
- let ty = field_types[id].instantiate(f.interner, args);
- let Ok(layout) = f.db.layout_of_ty(ty, trait_env.clone()) else {
+ let ty = field_types[id].get().instantiate(f.interner, args);
+ let Ok(layout) = f.db.layout_of_ty(ty.store(), param_env.store()) else {
return f.write_str("<layout-error>");
};
let size = layout.size.bytes_usize();
@@ -1050,10 +1042,7 @@ fn render_variant_after_name<'db>(
}
impl<'db> HirDisplay<'db> for Ty<'db> {
- fn hir_fmt(
- &self,
- f @ &mut HirFormatter { db, .. }: &mut HirFormatter<'_, 'db>,
- ) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f @ &mut HirFormatter { db, .. }: &mut HirFormatter<'_, 'db>) -> Result {
let interner = f.interner;
if f.should_truncate() {
return write!(f, "{TYPE_HINT_TRUNCATION}");
@@ -1109,7 +1098,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
bounds.iter().any(|bound| match bound.skip_binder() {
ExistentialPredicate::Trait(trait_ref) => {
let trait_ = trait_ref.def_id.0;
- fn_traits(db, trait_).any(|it| it == trait_)
+ fn_traits(f.lang_items()).any(|it| it == trait_)
}
_ => false,
});
@@ -1122,13 +1111,8 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
_ => unreachable!(),
};
let impl_trait_id = db.lookup_intern_impl_trait_id(opaque_ty_id);
- if let ImplTraitId::ReturnTypeImplTrait(func, idx) = impl_trait_id {
- let datas = db
- .return_type_impl_traits(func)
- .expect("impl trait id without data");
- let data = (*datas)
- .as_ref()
- .map_bound(|rpit| &rpit.impl_traits[idx].predicates);
+ if let ImplTraitId::ReturnTypeImplTrait(func, _) = impl_trait_id {
+ let data = impl_trait_id.predicates(db);
let bounds =
|| data.iter_instantiated_copied(f.interner, ty.args.as_slice());
let mut len = bounds().count();
@@ -1158,7 +1142,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
let contains_impl_fn = bounds().any(|bound| {
if let ClauseKind::Trait(trait_ref) = bound.kind().skip_binder() {
let trait_ = trait_ref.def_id().0;
- fn_traits(db, trait_).any(|it| it == trait_)
+ fn_traits(f.lang_items()).any(|it| it == trait_)
} else {
false
}
@@ -1239,7 +1223,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
};
f.end_location_link();
- if args.len() > 0 {
+ if !args.is_empty() {
let generic_def_id = GenericDefId::from_callable(db, def);
let generics = generics(db, generic_def_id);
let (parent_len, self_param, type_, const_, impl_, lifetime) =
@@ -1354,43 +1338,24 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
));
}
let impl_trait_id = db.lookup_intern_impl_trait_id(opaque_ty_id);
- match impl_trait_id {
- ImplTraitId::ReturnTypeImplTrait(func, idx) => {
- let datas =
- db.return_type_impl_traits(func).expect("impl trait id without data");
- let data =
- (*datas).as_ref().map_bound(|rpit| &rpit.impl_traits[idx].predicates);
- let bounds = data
- .iter_instantiated_copied(interner, alias_ty.args.as_slice())
- .collect::<Vec<_>>();
- let krate = func.krate(db);
- write_bounds_like_dyn_trait_with_prefix(
- f,
- "impl",
- Either::Left(*self),
- &bounds,
- SizedByDefault::Sized { anchor: krate },
- )?;
+ let data = impl_trait_id.predicates(db);
+ let bounds = data
+ .iter_instantiated_copied(interner, alias_ty.args.as_slice())
+ .collect::<Vec<_>>();
+ let krate = match impl_trait_id {
+ ImplTraitId::ReturnTypeImplTrait(func, _) => {
+ func.krate(db)
// FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
}
- ImplTraitId::TypeAliasImplTrait(alias, idx) => {
- let datas =
- db.type_alias_impl_traits(alias).expect("impl trait id without data");
- let data =
- (*datas).as_ref().map_bound(|rpit| &rpit.impl_traits[idx].predicates);
- let bounds = data
- .iter_instantiated_copied(interner, alias_ty.args.as_slice())
- .collect::<Vec<_>>();
- let krate = alias.krate(db);
- write_bounds_like_dyn_trait_with_prefix(
- f,
- "impl",
- Either::Left(*self),
- &bounds,
- SizedByDefault::Sized { anchor: krate },
- )?;
- }
- }
+ ImplTraitId::TypeAliasImplTrait(alias, _) => alias.krate(db),
+ };
+ write_bounds_like_dyn_trait_with_prefix(
+ f,
+ "impl",
+ Either::Left(*self),
+ &bounds,
+ SizedByDefault::Sized { anchor: krate },
+ )?;
}
TyKind::Closure(id, substs) => {
let id = id.0;
@@ -1418,37 +1383,30 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
}
_ => (),
}
- let sig = substs
- .split_closure_args_untupled()
- .closure_sig_as_fn_ptr_ty
- .callable_sig(interner);
- if let Some(sig) = sig {
- let sig = sig.skip_binder();
- let InternedClosure(def, _) = db.lookup_intern_closure(id);
- let infer = db.infer(def);
- let (_, kind) = infer.closure_info(id);
- match f.closure_style {
- ClosureStyle::ImplFn => write!(f, "impl {kind:?}(")?,
- ClosureStyle::RANotation => write!(f, "|")?,
- _ => unreachable!(),
- }
- if sig.inputs().is_empty() {
- } else if f.should_truncate() {
- write!(f, "{TYPE_HINT_TRUNCATION}")?;
- } else {
- f.write_joined(sig.inputs(), ", ")?;
- };
- match f.closure_style {
- ClosureStyle::ImplFn => write!(f, ")")?,
- ClosureStyle::RANotation => write!(f, "|")?,
- _ => unreachable!(),
- }
- if f.closure_style == ClosureStyle::RANotation || !sig.output().is_unit() {
- write!(f, " -> ")?;
- sig.output().hir_fmt(f)?;
- }
+ let sig = interner.signature_unclosure(substs.as_closure().sig(), Safety::Safe);
+ let sig = sig.skip_binder();
+ let InternedClosure(def, _) = db.lookup_intern_closure(id);
+ let infer = InferenceResult::for_body(db, def);
+ let (_, kind) = infer.closure_info(id);
+ match f.closure_style {
+ ClosureStyle::ImplFn => write!(f, "impl {kind:?}(")?,
+ ClosureStyle::RANotation => write!(f, "|")?,
+ _ => unreachable!(),
+ }
+ if sig.inputs().is_empty() {
+ } else if f.should_truncate() {
+ write!(f, "{TYPE_HINT_TRUNCATION}")?;
} else {
- write!(f, "{{closure}}")?;
+ f.write_joined(sig.inputs(), ", ")?;
+ };
+ match f.closure_style {
+ ClosureStyle::ImplFn => write!(f, ")")?,
+ ClosureStyle::RANotation => write!(f, "|")?,
+ _ => unreachable!(),
+ }
+ if f.closure_style == ClosureStyle::RANotation || !sig.output().is_unit() {
+ write!(f, " -> ")?;
+ sig.output().hir_fmt(f)?;
}
}
TyKind::CoroutineClosure(id, args) => {
@@ -1494,7 +1452,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
};
let coroutine_sig = coroutine_sig.skip_binder();
let coroutine_inputs = coroutine_sig.inputs();
- let TyKind::Tuple(coroutine_inputs) = coroutine_inputs.as_slice()[1].kind() else {
+ let TyKind::Tuple(coroutine_inputs) = coroutine_inputs[1].kind() else {
unreachable!("invalid coroutine closure signature");
};
let TyKind::Tuple(coroutine_output) = coroutine_sig.output().kind() else {
@@ -1541,11 +1499,8 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
)?
}
TypeParamProvenance::ArgumentImplTrait => {
- let bounds = db
- .generic_predicates(param.id.parent())
- .instantiate_identity()
- .into_iter()
- .flatten()
+ let bounds = GenericPredicates::query_all(f.db, param.id.parent())
+ .iter_identity_copied()
.filter(|wc| match wc.kind().skip_binder() {
ClauseKind::Trait(tr) => tr.self_ty() == *self,
ClauseKind::Projection(proj) => proj.self_ty() == *self,
@@ -1553,7 +1508,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
_ => false,
})
.collect::<Vec<_>>();
- let krate = param.id.parent().module(db).krate();
+ let krate = param.id.parent().module(db).krate(db);
write_bounds_like_dyn_trait_with_prefix(
f,
"impl",
@@ -1622,8 +1577,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
..
}
| hir_def::hir::Expr::Async { .. } => {
- let future_trait =
- LangItem::Future.resolve_trait(db, owner.module(db).krate());
+ let future_trait = f.lang_items().Future;
let output = future_trait.and_then(|t| {
t.trait_items(db)
.associated_type_by_name(&Name::new_symbol_root(sym::Output))
@@ -1684,7 +1638,7 @@ fn hir_fmt_generics<'db>(
parameters: &[GenericArg<'db>],
generic_def: Option<hir_def::GenericDefId>,
self_: Option<Ty<'db>>,
-) -> Result<(), HirDisplayError> {
+) -> Result {
if parameters.is_empty() {
return Ok(());
}
@@ -1734,7 +1688,7 @@ fn hir_fmt_generic_args<'db>(
parameters: &[GenericArg<'db>],
generic_def: Option<hir_def::GenericDefId>,
self_: Option<Ty<'db>>,
-) -> Result<(), HirDisplayError> {
+) -> Result {
if parameters.is_empty() {
return Ok(());
}
@@ -1754,7 +1708,7 @@ fn hir_fmt_generic_arguments<'db>(
f: &mut HirFormatter<'_, 'db>,
parameters: &[GenericArg<'db>],
self_: Option<Ty<'db>>,
-) -> Result<(), HirDisplayError> {
+) -> Result {
let mut first = true;
let lifetime_offset = parameters.iter().position(|arg| arg.region().is_some());
@@ -1778,7 +1732,7 @@ fn hir_fmt_tys<'db>(
f: &mut HirFormatter<'_, 'db>,
tys: &[Ty<'db>],
self_: Option<Ty<'db>>,
-) -> Result<(), HirDisplayError> {
+) -> Result {
let mut first = true;
for ty in tys {
@@ -1794,7 +1748,7 @@ fn hir_fmt_tys<'db>(
}
impl<'db> HirDisplay<'db> for PolyFnSig<'db> {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
let FnSig { inputs_and_output, c_variadic, safety, abi: _ } = self.skip_binder();
if let Safety::Unsafe = safety {
write!(f, "unsafe ")?;
@@ -1825,19 +1779,14 @@ impl<'db> HirDisplay<'db> for PolyFnSig<'db> {
}
impl<'db> HirDisplay<'db> for Term<'db> {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
- match self {
- Term::Ty(it) => it.hir_fmt(f),
- Term::Const(it) => it.hir_fmt(f),
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
+ match self.kind() {
+ TermKind::Ty(it) => it.hir_fmt(f),
+ TermKind::Const(it) => it.hir_fmt(f),
}
}
}
-fn fn_traits(db: &dyn DefDatabase, trait_: TraitId) -> impl Iterator<Item = TraitId> + '_ {
- let krate = trait_.lookup(db).container.krate();
- utils::fn_traits(db, krate)
-}
-
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum SizedByDefault {
NotSized,
@@ -1849,7 +1798,7 @@ impl SizedByDefault {
match self {
Self::NotSized => false,
Self::Sized { anchor } => {
- let sized_trait = LangItem::Sized.resolve_trait(db, anchor);
+ let sized_trait = hir_def::lang_item::lang_items(db, anchor).Sized;
Some(trait_) == sized_trait
}
}
@@ -1862,7 +1811,7 @@ pub fn write_bounds_like_dyn_trait_with_prefix<'db>(
this: Either<Ty<'db>, Region<'db>>,
predicates: &[Clause<'db>],
default_sized: SizedByDefault,
-) -> Result<(), HirDisplayError> {
+) -> Result {
write!(f, "{prefix}")?;
if !predicates.is_empty()
|| predicates.is_empty() && matches!(default_sized, SizedByDefault::Sized { .. })
@@ -1879,7 +1828,7 @@ fn write_bounds_like_dyn_trait<'db>(
this: Either<Ty<'db>, Region<'db>>,
predicates: &[Clause<'db>],
default_sized: SizedByDefault,
-) -> Result<(), HirDisplayError> {
+) -> Result {
// Note: This code is written to produce nice results (i.e.
// corresponding to surface Rust) for types that can occur in
// actual Rust. It will have weird results if the predicates
@@ -1902,7 +1851,7 @@ fn write_bounds_like_dyn_trait<'db>(
}
}
if !is_fn_trait {
- is_fn_trait = fn_traits(f.db, trait_).any(|it| it == trait_);
+ is_fn_trait = fn_traits(f.lang_items()).any(|it| it == trait_);
}
if !is_fn_trait && angle_open {
write!(f, ">")?;
@@ -1986,7 +1935,7 @@ fn write_bounds_like_dyn_trait<'db>(
let own_args = projection.projection_term.own_args(f.interner);
if !own_args.is_empty() {
write!(f, "<")?;
- hir_fmt_generic_arguments(f, own_args.as_slice(), None)?;
+ hir_fmt_generic_arguments(f, own_args, None)?;
write!(f, ">")?;
}
write!(f, " = ")?;
@@ -2000,7 +1949,7 @@ fn write_bounds_like_dyn_trait<'db>(
write!(f, ">")?;
}
if let SizedByDefault::Sized { anchor } = default_sized {
- let sized_trait = LangItem::Sized.resolve_trait(f.db, anchor);
+ let sized_trait = hir_def::lang_item::lang_items(f.db, anchor).Sized;
if !is_sized {
if !first {
write!(f, " + ")?;
@@ -2022,8 +1971,51 @@ fn write_bounds_like_dyn_trait<'db>(
Ok(())
}
+pub fn write_params_bounds<'db>(
+ f: &mut HirFormatter<'_, 'db>,
+ predicates: &[Clause<'db>],
+) -> Result {
+ // Use an FxIndexMap to keep user's order, as far as possible.
+ let mut per_type = FxIndexMap::<_, Vec<_>>::default();
+ for &predicate in predicates {
+ let base_ty = match predicate.kind().skip_binder() {
+ ClauseKind::Trait(clause) => Either::Left(clause.self_ty()),
+ ClauseKind::RegionOutlives(clause) => Either::Right(clause.0),
+ ClauseKind::TypeOutlives(clause) => Either::Left(clause.0),
+ ClauseKind::Projection(clause) => Either::Left(clause.self_ty()),
+ ClauseKind::ConstArgHasType(..)
+ | ClauseKind::WellFormed(_)
+ | ClauseKind::ConstEvaluatable(_)
+ | ClauseKind::HostEffect(..)
+ | ClauseKind::UnstableFeature(_) => continue,
+ };
+ per_type.entry(base_ty).or_default().push(predicate);
+ }
+
+ for (base_ty, clauses) in per_type {
+ f.write_str(" ")?;
+ match base_ty {
+ Either::Left(it) => it.hir_fmt(f)?,
+ Either::Right(it) => it.hir_fmt(f)?,
+ }
+ f.write_str(": ")?;
+ // Rudimentary approximation: type params are `Sized` by default, everything else not.
+ // FIXME: This is not correct, really. But I'm not sure how we can from the ty representation
+ // to extract the default sizedness, and if it's possible at all.
+ let default_sized = match base_ty {
+ Either::Left(ty) if matches!(ty.kind(), TyKind::Param(_)) => {
+ SizedByDefault::Sized { anchor: f.krate() }
+ }
+ _ => SizedByDefault::NotSized,
+ };
+ write_bounds_like_dyn_trait(f, base_ty, &clauses, default_sized)?;
+ f.write_str(",\n")?;
+ }
+ Ok(())
+}
+
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 {
let trait_ = self.def_id.0;
f.start_location_link(trait_.into());
write!(f, "{}", f.db.trait_signature(trait_).name.display(f.db, f.edition()))?;
@@ -2034,7 +2026,7 @@ impl<'db> HirDisplay<'db> for TraitRef<'db> {
}
impl<'db> HirDisplay<'db> for Region<'db> {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
match self.kind() {
RegionKind::ReEarlyParam(param) => {
let generics = generics(f.db, param.id.parent);
@@ -2068,19 +2060,20 @@ pub fn write_visibility<'db>(
module_id: ModuleId,
vis: Visibility,
f: &mut HirFormatter<'_, 'db>,
-) -> Result<(), HirDisplayError> {
+) -> Result {
match vis {
Visibility::Public => write!(f, "pub "),
Visibility::PubCrate(_) => write!(f, "pub(crate) "),
Visibility::Module(vis_id, _) => {
let def_map = module_id.def_map(f.db);
- let root_module_id = def_map.module_id(DefMap::ROOT);
+ let root_module_id = def_map.root_module_id();
if vis_id == module_id {
// pub(self) or omitted
Ok(())
- } else if root_module_id == vis_id && !root_module_id.is_within_block() {
+ } else if root_module_id == vis_id && root_module_id.block(f.db).is_none() {
write!(f, "pub(crate) ")
- } else if module_id.containing_module(f.db) == Some(vis_id) && !vis_id.is_block_module()
+ } else if module_id.containing_module(f.db) == Some(vis_id)
+ && !vis_id.is_block_module(f.db)
{
write!(f, "pub(super) ")
} else {
@@ -2091,21 +2084,13 @@ pub fn write_visibility<'db>(
}
pub trait HirDisplayWithExpressionStore<'db> {
- fn hir_fmt(
- &self,
- f: &mut HirFormatter<'_, 'db>,
- store: &ExpressionStore,
- ) -> Result<(), HirDisplayError>;
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>, store: &ExpressionStore) -> Result;
}
impl<'db, T: ?Sized + HirDisplayWithExpressionStore<'db>> HirDisplayWithExpressionStore<'db>
for &'_ T
{
- fn hir_fmt(
- &self,
- f: &mut HirFormatter<'_, 'db>,
- store: &ExpressionStore,
- ) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>, store: &ExpressionStore) -> Result {
T::hir_fmt(&**self, f, store)
}
}
@@ -2126,16 +2111,12 @@ impl<'a, T> ExpressionStoreAdapter<'a, T> {
}
impl<'db, T: HirDisplayWithExpressionStore<'db>> HirDisplay<'db> for ExpressionStoreAdapter<'_, T> {
- fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
T::hir_fmt(&self.0, f, self.1)
}
}
impl<'db> HirDisplayWithExpressionStore<'db> for LifetimeRefId {
- fn hir_fmt(
- &self,
- f: &mut HirFormatter<'_, 'db>,
- store: &ExpressionStore,
- ) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>, store: &ExpressionStore) -> Result {
match &store[*self] {
LifetimeRef::Named(name) => write!(f, "{}", name.display(f.db, f.edition())),
LifetimeRef::Static => write!(f, "'static"),
@@ -2154,11 +2135,7 @@ impl<'db> HirDisplayWithExpressionStore<'db> for LifetimeRefId {
}
impl<'db> HirDisplayWithExpressionStore<'db> for TypeRefId {
- fn hir_fmt(
- &self,
- f: &mut HirFormatter<'_, 'db>,
- store: &ExpressionStore,
- ) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>, store: &ExpressionStore) -> Result {
match &store[*self] {
TypeRef::Never => write!(f, "!")?,
TypeRef::TypeParam(param) => {
@@ -2283,11 +2260,7 @@ impl<'db> HirDisplayWithExpressionStore<'db> for TypeRefId {
}
impl<'db> HirDisplayWithExpressionStore<'db> for ConstRef {
- fn hir_fmt(
- &self,
- f: &mut HirFormatter<'_, 'db>,
- _store: &ExpressionStore,
- ) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>, _store: &ExpressionStore) -> Result {
// FIXME
write!(f, "{{const}}")?;
@@ -2296,11 +2269,7 @@ impl<'db> HirDisplayWithExpressionStore<'db> for ConstRef {
}
impl<'db> HirDisplayWithExpressionStore<'db> for TypeBound {
- fn hir_fmt(
- &self,
- f: &mut HirFormatter<'_, 'db>,
- store: &ExpressionStore,
- ) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>, store: &ExpressionStore) -> Result {
match self {
&TypeBound::Path(path, modifier) => {
match modifier {
@@ -2340,11 +2309,7 @@ impl<'db> HirDisplayWithExpressionStore<'db> for TypeBound {
}
impl<'db> HirDisplayWithExpressionStore<'db> for Path {
- fn hir_fmt(
- &self,
- f: &mut HirFormatter<'_, 'db>,
- store: &ExpressionStore,
- ) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>, store: &ExpressionStore) -> Result {
match (self.type_anchor(), self.kind()) {
(Some(anchor), _) => {
write!(f, "<")?;
@@ -2492,11 +2457,7 @@ impl<'db> HirDisplayWithExpressionStore<'db> for Path {
}
impl<'db> HirDisplayWithExpressionStore<'db> for hir_def::expr_store::path::GenericArg {
- fn hir_fmt(
- &self,
- f: &mut HirFormatter<'_, 'db>,
- store: &ExpressionStore,
- ) -> Result<(), HirDisplayError> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>, store: &ExpressionStore) -> Result {
match self {
hir_def::expr_store::path::GenericArg::Type(ty) => ty.hir_fmt(f, store),
hir_def::expr_store::path::GenericArg::Const(_c) => {