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.rs97
1 files changed, 73 insertions, 24 deletions
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index 241690d008..66b5398b88 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -4,7 +4,7 @@
use std::{
fmt::{self, Debug},
- mem::size_of,
+ mem::{self, size_of},
};
use base_db::CrateId;
@@ -36,12 +36,13 @@ use crate::{
consteval::try_const_usize,
db::{HirDatabase, InternedClosure},
from_assoc_type_id, from_foreign_def_id, from_placeholder_idx,
+ generics::generics,
layout::Layout,
lt_from_placeholder_idx,
mapping::from_chalk,
mir::pad16,
primitive, to_assoc_type_id,
- utils::{self, detect_variant_from_bytes, generics, ClosureSubst},
+ utils::{self, detect_variant_from_bytes, ClosureSubst},
AdtId, AliasEq, AliasTy, Binders, CallableDefId, CallableSig, ConcreteConst, Const,
ConstScalar, ConstValue, DomainGoal, FnAbi, GenericArg, ImplTraitId, Interner, Lifetime,
LifetimeData, LifetimeOutlives, MemoryMap, Mutability, OpaqueTy, ProjectionTy, ProjectionTyExt,
@@ -74,6 +75,8 @@ pub struct HirFormatter<'a> {
/// When rendering something that has a concept of "children" (like fields in a struct), this limits
/// how many should be rendered.
pub entity_limit: Option<usize>,
+ /// When rendering functions, whether to show the constraint from the container
+ show_container_bounds: bool,
omit_verbose_types: bool,
closure_style: ClosureStyle,
display_target: DisplayTarget,
@@ -101,6 +104,7 @@ pub trait HirDisplay {
omit_verbose_types: bool,
display_target: DisplayTarget,
closure_style: ClosureStyle,
+ show_container_bounds: bool,
) -> HirDisplayWrapper<'a, Self>
where
Self: Sized,
@@ -117,6 +121,7 @@ pub trait HirDisplay {
omit_verbose_types,
display_target,
closure_style,
+ show_container_bounds,
}
}
@@ -134,6 +139,7 @@ pub trait HirDisplay {
omit_verbose_types: false,
closure_style: ClosureStyle::ImplFn,
display_target: DisplayTarget::Diagnostics,
+ show_container_bounds: false,
}
}
@@ -155,6 +161,7 @@ pub trait HirDisplay {
omit_verbose_types: true,
closure_style: ClosureStyle::ImplFn,
display_target: DisplayTarget::Diagnostics,
+ show_container_bounds: false,
}
}
@@ -176,6 +183,7 @@ pub trait HirDisplay {
omit_verbose_types: true,
closure_style: ClosureStyle::ImplFn,
display_target: DisplayTarget::Diagnostics,
+ show_container_bounds: false,
}
}
@@ -198,6 +206,7 @@ pub trait HirDisplay {
omit_verbose_types: false,
closure_style: ClosureStyle::ImplFn,
display_target: DisplayTarget::SourceCode { module_id, allow_opaque },
+ show_container_bounds: false,
}) {
Ok(()) => {}
Err(HirDisplayError::FmtError) => panic!("Writing to String can't fail!"),
@@ -219,6 +228,29 @@ pub trait HirDisplay {
omit_verbose_types: false,
closure_style: ClosureStyle::ImplFn,
display_target: DisplayTarget::Test,
+ show_container_bounds: false,
+ }
+ }
+
+ /// Returns a String representation of `self` that shows the constraint from
+ /// the container for functions
+ fn display_with_container_bounds<'a>(
+ &'a self,
+ db: &'a dyn HirDatabase,
+ show_container_bounds: bool,
+ ) -> HirDisplayWrapper<'a, Self>
+ where
+ Self: Sized,
+ {
+ HirDisplayWrapper {
+ db,
+ t: self,
+ max_size: None,
+ limited_size: None,
+ omit_verbose_types: false,
+ closure_style: ClosureStyle::ImplFn,
+ display_target: DisplayTarget::Diagnostics,
+ show_container_bounds,
}
}
}
@@ -277,6 +309,10 @@ impl HirFormatter<'_> {
pub fn omit_verbose_types(&self) -> bool {
self.omit_verbose_types
}
+
+ pub fn show_container_bounds(&self) -> bool {
+ self.show_container_bounds
+ }
}
#[derive(Clone, Copy)]
@@ -336,6 +372,7 @@ pub struct HirDisplayWrapper<'a, T> {
omit_verbose_types: bool,
closure_style: ClosureStyle,
display_target: DisplayTarget,
+ show_container_bounds: bool,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -365,6 +402,7 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
omit_verbose_types: self.omit_verbose_types,
display_target: self.display_target,
closure_style: self.closure_style,
+ show_container_bounds: self.show_container_bounds,
})
}
@@ -423,7 +461,7 @@ impl HirDisplay for ProjectionTy {
let proj_params_count =
self.substitution.len(Interner) - trait_ref.substitution.len(Interner);
let proj_params = &self.substitution.as_slice(Interner)[..proj_params_count];
- hir_fmt_generics(f, proj_params, None)
+ hir_fmt_generics(f, proj_params, None, None)
}
}
@@ -456,7 +494,7 @@ impl HirDisplay for Const {
ConstValue::Placeholder(idx) => {
let id = from_placeholder_idx(f.db, *idx);
let generics = generics(f.db.upcast(), id.parent);
- let param_data = &generics.params[id.local_id];
+ let param_data = &generics[id.local_id];
write!(f, "{}", param_data.name().unwrap().display(f.db.upcast()))?;
Ok(())
}
@@ -468,6 +506,7 @@ impl HirDisplay for Const {
f,
parameters.as_slice(Interner),
c.generic_def(f.db.upcast()),
+ None,
)?;
Ok(())
}
@@ -670,7 +709,7 @@ fn render_const_scalar(
TyKind::FnDef(..) => ty.hir_fmt(f),
TyKind::Function(_) | TyKind::Raw(_, _) => {
let it = u128::from_le_bytes(pad16(b, false));
- write!(f, "{:#X} as ", it)?;
+ write!(f, "{it:#X} as ")?;
ty.hir_fmt(f)
}
TyKind::Array(ty, len) => {
@@ -950,7 +989,7 @@ impl HirDisplay for Ty {
if parameters.len(Interner) > 0 {
let generics = generics(db.upcast(), def.into());
- let (parent_len, self_, type_, const_, impl_, lifetime) =
+ let (parent_len, self_param, type_, const_, impl_, lifetime) =
generics.provenance_split();
let parameters = parameters.as_slice(Interner);
// We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self?
@@ -958,7 +997,7 @@ impl HirDisplay for Ty {
// `parameters` are in the order of fn's params (including impl traits), fn's lifetimes
// parent's params (those from enclosing impl or trait, if any).
let (fn_params, other) =
- parameters.split_at(self_ + type_ + const_ + lifetime);
+ parameters.split_at(self_param as usize + type_ + const_ + lifetime);
let (_impl, parent_params) = other.split_at(impl_);
debug_assert_eq!(parent_params.len(), parent_len);
@@ -967,11 +1006,11 @@ impl HirDisplay for Ty {
let fn_params = generic_args_sans_defaults(f, Some(def.into()), fn_params);
write!(f, "<")?;
- hir_fmt_generic_arguments(f, parent_params)?;
+ hir_fmt_generic_arguments(f, parent_params, None)?;
if !parent_params.is_empty() && !fn_params.is_empty() {
write!(f, ", ")?;
}
- hir_fmt_generic_arguments(f, fn_params)?;
+ hir_fmt_generic_arguments(f, fn_params, None)?;
write!(f, ">")?;
}
}
@@ -1016,7 +1055,7 @@ impl HirDisplay for Ty {
let generic_def = self.as_generic_def(db);
- hir_fmt_generics(f, parameters.as_slice(Interner), generic_def)?;
+ hir_fmt_generics(f, parameters.as_slice(Interner), generic_def, None)?;
}
TyKind::AssociatedType(assoc_type_id, parameters) => {
let type_alias = from_assoc_type_id(*assoc_type_id);
@@ -1039,7 +1078,7 @@ impl HirDisplay for Ty {
f.end_location_link();
// Note that the generic args for the associated type come before those for the
// trait (including the self type).
- hir_fmt_generics(f, parameters.as_slice(Interner), None)
+ hir_fmt_generics(f, parameters.as_slice(Interner), None, None)
} else {
let projection_ty = ProjectionTy {
associated_ty_id: to_assoc_type_id(type_alias),
@@ -1141,7 +1180,7 @@ impl HirDisplay for Ty {
}
ClosureStyle::ClosureWithSubst => {
write!(f, "{{closure#{:?}}}", id.0.as_u32())?;
- return hir_fmt_generics(f, substs.as_slice(Interner), None);
+ return hir_fmt_generics(f, substs.as_slice(Interner), None, None);
}
_ => (),
}
@@ -1177,7 +1216,7 @@ impl HirDisplay for Ty {
TyKind::Placeholder(idx) => {
let id = from_placeholder_idx(db, *idx);
let generics = generics(db.upcast(), id.parent);
- let param_data = &generics.params[id.local_id];
+ let param_data = &generics[id.local_id];
match param_data {
TypeOrConstParamData::TypeParamData(p) => match p.provenance {
TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => {
@@ -1329,6 +1368,7 @@ fn hir_fmt_generics(
f: &mut HirFormatter<'_>,
parameters: &[GenericArg],
generic_def: Option<hir_def::GenericDefId>,
+ self_: Option<&Ty>,
) -> Result<(), HirDisplayError> {
if parameters.is_empty() {
return Ok(());
@@ -1348,7 +1388,7 @@ fn hir_fmt_generics(
});
if !parameters_to_write.is_empty() && !only_err_lifetimes {
write!(f, "<")?;
- hir_fmt_generic_arguments(f, parameters_to_write)?;
+ hir_fmt_generic_arguments(f, parameters_to_write, self_)?;
write!(f, ">")?;
}
@@ -1411,6 +1451,7 @@ fn generic_args_sans_defaults<'ga>(
fn hir_fmt_generic_arguments(
f: &mut HirFormatter<'_>,
parameters: &[GenericArg],
+ self_: Option<&Ty>,
) -> Result<(), HirDisplayError> {
let mut first = true;
let lifetime_offset = parameters.iter().position(|arg| arg.lifetime(Interner).is_some());
@@ -1432,11 +1473,13 @@ fn hir_fmt_generic_arguments(
continue;
}
- if !first {
+ if !mem::take(&mut first) {
write!(f, ", ")?;
}
- first = false;
- generic_arg.hir_fmt(f)?;
+ match self_ {
+ self_ @ Some(_) if generic_arg.ty(Interner) == self_ => write!(f, "Self")?,
+ _ => generic_arg.hir_fmt(f)?,
+ }
}
Ok(())
}
@@ -1559,12 +1602,16 @@ fn write_bounds_like_dyn_trait(
write!(f, "{}", f.db.trait_data(trait_).name.display(f.db.upcast()))?;
f.end_location_link();
if is_fn_trait {
- if let [_self, params @ ..] = trait_ref.substitution.as_slice(Interner) {
+ if let [self_, params @ ..] = trait_ref.substitution.as_slice(Interner) {
if let Some(args) =
params.first().and_then(|it| it.assert_ty_ref(Interner).as_tuple())
{
write!(f, "(")?;
- hir_fmt_generic_arguments(f, args.as_slice(Interner))?;
+ hir_fmt_generic_arguments(
+ f,
+ args.as_slice(Interner),
+ self_.ty(Interner),
+ )?;
write!(f, ")")?;
}
}
@@ -1574,10 +1621,10 @@ fn write_bounds_like_dyn_trait(
Some(trait_.into()),
trait_ref.substitution.as_slice(Interner),
);
- if let [_self, params @ ..] = params {
+ if let [self_, params @ ..] = params {
if !params.is_empty() {
write!(f, "<")?;
- hir_fmt_generic_arguments(f, params)?;
+ hir_fmt_generic_arguments(f, params, self_.ty(Interner))?;
// there might be assoc type bindings, so we leave the angle brackets open
angle_open = true;
}
@@ -1635,6 +1682,7 @@ fn write_bounds_like_dyn_trait(
hir_fmt_generic_arguments(
f,
&proj.substitution.as_slice(Interner)[..proj_arg_count],
+ None,
)?;
write!(f, ">")?;
}
@@ -1691,7 +1739,8 @@ fn fmt_trait_ref(
f.start_location_link(trait_.into());
write!(f, "{}", f.db.trait_data(trait_).name.display(f.db.upcast()))?;
f.end_location_link();
- hir_fmt_generics(f, &tr.substitution.as_slice(Interner)[1..], None)
+ let substs = tr.substitution.as_slice(Interner);
+ hir_fmt_generics(f, &substs[1..], None, substs[0].ty(Interner))
}
impl HirDisplay for TraitRef {
@@ -1749,7 +1798,7 @@ impl HirDisplay for LifetimeData {
LifetimeData::Placeholder(idx) => {
let id = lt_from_placeholder_idx(f.db, *idx);
let generics = generics(f.db.upcast(), id.parent);
- let param_data = &generics.params[id.local_id];
+ let param_data = &generics[id.local_id];
write!(f, "{}", param_data.name.display(f.db.upcast()))?;
Ok(())
}
@@ -1943,7 +1992,7 @@ impl HirDisplay for Path {
(_, PathKind::Plain) => {}
(_, PathKind::Abs) => {}
(_, PathKind::Crate) => write!(f, "crate")?,
- (_, PathKind::Super(0)) => write!(f, "self")?,
+ (_, &PathKind::SELF) => write!(f, "self")?,
(_, PathKind::Super(n)) => {
for i in 0..*n {
if i > 0 {