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 | 238 |
1 files changed, 218 insertions, 20 deletions
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index cdf6085b65..ae0113fcbd 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -11,8 +11,8 @@ use base_db::Crate; use chalk_ir::{BoundVar, Safety, TyKind}; use either::Either; use hir_def::{ - GenericDefId, HasModule, ImportPathConfig, LocalFieldId, Lookup, ModuleDefId, ModuleId, - TraitId, + GeneralConstId, GenericDefId, HasModule, ImportPathConfig, LocalFieldId, Lookup, ModuleDefId, + ModuleId, TraitId, db::DefDatabase, expr_store::{ExpressionStore, path::Path}, find_path::{self, PrefixKind}, @@ -38,7 +38,7 @@ use rustc_apfloat::{ }; use rustc_hash::FxHashSet; use rustc_type_ir::{ - AliasTyKind, + AliasTyKind, RegionKind, inherent::{AdtDef, IntoKind, SliceLike}, }; use smallvec::SmallVec; @@ -61,8 +61,9 @@ use crate::{ next_solver::{ BoundExistentialPredicate, Ctor, DbInterner, GenericArgs, SolverDefId, mapping::{ - ChalkToNextSolver, convert_args_for_result, convert_const_for_result, - convert_region_for_result, convert_ty_for_result, + ChalkToNextSolver, bound_var_to_lifetime_idx, bound_var_to_type_or_const_param_idx, + convert_args_for_result, convert_const_for_result, convert_region_for_result, + convert_ty_for_result, }, }, primitive, to_assoc_type_id, @@ -715,28 +716,56 @@ impl HirDisplay for GenericArg { } } +impl<'db> HirDisplay for crate::next_solver::GenericArg<'db> { + fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { + match self.kind() { + rustc_type_ir::GenericArgKind::Type(ty) => ty.hir_fmt(f), + rustc_type_ir::GenericArgKind::Lifetime(lt) => lt.hir_fmt(f), + rustc_type_ir::GenericArgKind::Const(c) => c.hir_fmt(f), + } + } +} + impl HirDisplay for Const { fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { - let data = self.interned(); - match &data.value { - ConstValue::BoundVar(idx) => idx.hir_fmt(f), - ConstValue::InferenceVar(..) => write!(f, "#c#"), - ConstValue::Placeholder(idx) => { - let id = from_placeholder_idx(f.db, *idx); + let c = self.to_nextsolver(DbInterner::new_with(f.db, None, None)); + c.hir_fmt(f) + } +} + +impl<'db> HirDisplay for crate::next_solver::Const<'db> { + fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { + match self.kind() { + rustc_type_ir::ConstKind::Bound(db, bound_const) => { + write!(f, "?{}.{}", db.as_u32(), bound_const.as_u32()) + } + rustc_type_ir::ConstKind::Infer(..) => write!(f, "#c#"), + rustc_type_ir::ConstKind::Placeholder(idx) => { + let id = bound_var_to_type_or_const_param_idx(f.db, idx.bound); let generics = generics(f.db, id.parent); let param_data = &generics[id.local_id]; write!(f, "{}", param_data.name().unwrap().display(f.db, f.edition()))?; Ok(()) } - ConstValue::Concrete(c) => match &c.interned { - ConstScalar::Bytes(b, m) => render_const_scalar(f, b, m, &data.ty), - ConstScalar::UnevaluatedConst(c, parameters) => { - write!(f, "{}", c.name(f.db))?; - hir_fmt_generics(f, parameters.as_slice(Interner), c.generic_def(f.db), None)?; - Ok(()) - } - ConstScalar::Unknown => f.write_char('_'), - }, + rustc_type_ir::ConstKind::Value(const_bytes) => render_const_scalar_ns( + f, + &const_bytes.value.inner().0, + &const_bytes.value.inner().1, + const_bytes.ty, + ), + rustc_type_ir::ConstKind::Unevaluated(unev) => { + let c = match unev.def { + SolverDefId::ConstId(id) => GeneralConstId::ConstId(id), + SolverDefId::StaticId(id) => GeneralConstId::StaticId(id), + _ => unreachable!(), + }; + write!(f, "{}", c.name(f.db))?; + hir_fmt_generics_ns(f, unev.args.as_slice(), c.generic_def(f.db), None)?; + Ok(()) + } + rustc_type_ir::ConstKind::Error(..) => f.write_char('_'), + rustc_type_ir::ConstKind::Expr(..) => write!(f, "<const-expr>"), + rustc_type_ir::ConstKind::Param(_) => write!(f, "<param>"), } } } @@ -1748,6 +1777,27 @@ fn hir_fmt_generics( Ok(()) } +fn hir_fmt_generics_ns<'db>( + f: &mut HirFormatter<'_>, + parameters: &[crate::next_solver::GenericArg<'db>], + generic_def: Option<hir_def::GenericDefId>, + self_: Option<crate::next_solver::Ty<'db>>, +) -> Result<(), HirDisplayError> { + if parameters.is_empty() { + return Ok(()); + } + + let parameters_to_write = generic_args_sans_defaults_ns(f, generic_def, parameters); + + if !parameters_to_write.is_empty() { + write!(f, "<")?; + hir_fmt_generic_arguments_ns(f, parameters_to_write, self_)?; + write!(f, ">")?; + } + + Ok(()) +} + fn generic_args_sans_defaults<'ga>( f: &mut HirFormatter<'_>, generic_def: Option<hir_def::GenericDefId>, @@ -1803,6 +1853,87 @@ fn generic_args_sans_defaults<'ga>( } } +fn hir_fmt_generic_args<'db>( + f: &mut HirFormatter<'_>, + parameters: &[crate::next_solver::GenericArg<'db>], + generic_def: Option<hir_def::GenericDefId>, + self_: Option<crate::next_solver::Ty<'db>>, +) -> Result<(), HirDisplayError> { + if parameters.is_empty() { + return Ok(()); + } + + let parameters_to_write = generic_args_sans_defaults_ns(f, generic_def, parameters); + + if !parameters_to_write.is_empty() { + write!(f, "<")?; + hir_fmt_generic_arguments_ns(f, parameters_to_write, self_)?; + write!(f, ">")?; + } + + Ok(()) +} + +fn generic_args_sans_defaults_ns<'ga, 'db>( + f: &mut HirFormatter<'_>, + generic_def: Option<hir_def::GenericDefId>, + parameters: &'ga [crate::next_solver::GenericArg<'db>], +) -> &'ga [crate::next_solver::GenericArg<'db>] { + let interner = DbInterner::new_with(f.db, Some(f.krate()), None); + if f.display_kind.is_source_code() || f.omit_verbose_types() { + match generic_def + .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) + .filter(|it| !it.is_empty()) + { + None => parameters, + Some(default_parameters) => { + let should_show = |arg: &crate::next_solver::GenericArg<'db>, i: usize| { + let is_err = |arg: &crate::next_solver::GenericArg<'db>| match arg.kind() { + rustc_type_ir::GenericArgKind::Lifetime(it) => { + matches!(it.kind(), RegionKind::ReError(..)) + } + rustc_type_ir::GenericArgKind::Type(it) => { + matches!(it.kind(), rustc_type_ir::TyKind::Error(..)) + } + rustc_type_ir::GenericArgKind::Const(it) => { + matches!(it.kind(), rustc_type_ir::ConstKind::Error(..),) + } + }; + // if the arg is error like, render it to inform the user + if is_err(arg) { + return true; + } + // otherwise, if the arg is equal to the param default, hide it (unless the + // default is an error which can happen for the trait Self type) + match default_parameters.get(i) { + None => true, + Some(default_parameter) => { + // !is_err(default_parameter.skip_binders()) + // && + arg != &default_parameter + .clone() + .substitute( + Interner, + &convert_args_for_result(interner, ¶meters[..i]), + ) + .to_nextsolver(interner) + } + } + }; + let mut default_from = 0; + for (i, parameter) in parameters.iter().enumerate() { + if should_show(parameter, i) { + default_from = i + 1; + } + } + ¶meters[0..default_from] + } + } + } else { + parameters + } +} + fn hir_fmt_generic_arguments( f: &mut HirFormatter<'_>, parameters: &[GenericArg], @@ -1827,6 +1958,30 @@ fn hir_fmt_generic_arguments( Ok(()) } +fn hir_fmt_generic_arguments_ns<'db>( + f: &mut HirFormatter<'_>, + parameters: &[crate::next_solver::GenericArg<'db>], + self_: Option<crate::next_solver::Ty<'db>>, +) -> Result<(), HirDisplayError> { + let mut first = true; + let lifetime_offset = parameters.iter().position(|arg| arg.region().is_some()); + + let (ty_or_const, lifetimes) = match lifetime_offset { + Some(offset) => parameters.split_at(offset), + None => (parameters, &[][..]), + }; + for generic_arg in lifetimes.iter().chain(ty_or_const) { + if !mem::take(&mut first) { + write!(f, ", ")?; + } + match self_ { + self_ @ Some(_) if generic_arg.ty() == self_ => write!(f, "Self")?, + _ => generic_arg.hir_fmt(f)?, + } + } + Ok(()) +} + impl HirDisplay for CallableSig { fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { let CallableSig { params_and_return: _, is_varargs, safety, abi: _ } = *self; @@ -2067,6 +2222,20 @@ impl HirDisplay for TraitRef { } } +impl<'db> HirDisplay for crate::next_solver::TraitRef<'db> { + fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { + let trait_ = match self.def_id { + SolverDefId::TraitId(id) => id, + _ => unreachable!(), + }; + f.start_location_link(trait_.into()); + write!(f, "{}", f.db.trait_signature(trait_).name.display(f.db, f.edition()))?; + f.end_location_link(); + let substs = self.args.as_slice(); + hir_fmt_generic_args(f, &substs[1..], None, substs[0].ty()) + } +} + impl HirDisplay for WhereClause { fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { if f.should_truncate() { @@ -2147,6 +2316,35 @@ impl HirDisplay for LifetimeData { } } +impl<'db> HirDisplay for crate::next_solver::Region<'db> { + fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { + match self.kind() { + rustc_type_ir::RegionKind::RePlaceholder(idx) => { + let id = bound_var_to_lifetime_idx(f.db, idx.bound.var); + let generics = generics(f.db, id.parent); + let param_data = &generics[id.local_id]; + write!(f, "{}", param_data.name.display(f.db, f.edition()))?; + Ok(()) + } + rustc_type_ir::RegionKind::ReBound(db, idx) => { + write!(f, "?{}.{}", db.as_u32(), idx.var.as_u32()) + } + rustc_type_ir::RegionKind::ReVar(_) => write!(f, "_"), + rustc_type_ir::RegionKind::ReStatic => write!(f, "'static"), + rustc_type_ir::RegionKind::ReError(..) => { + if cfg!(test) { + write!(f, "'?") + } else { + write!(f, "'_") + } + } + rustc_type_ir::RegionKind::ReErased => write!(f, "'<erased>"), + rustc_type_ir::RegionKind::ReEarlyParam(_) => write!(f, "<param>"), + rustc_type_ir::RegionKind::ReLateParam(_) => write!(f, "<late-param>"), + } + } +} + impl HirDisplay for DomainGoal { fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { match self { |