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.rs | 97 |
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 { |