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.rs217
1 files changed, 175 insertions, 42 deletions
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index 0c4e34db7d..e4a8def442 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -39,8 +39,7 @@ use rustc_apfloat::{
use rustc_ast_ir::FloatTy;
use rustc_hash::FxHashSet;
use rustc_type_ir::{
- AliasTyKind, BoundVarIndexKind, CoroutineArgsParts, CoroutineClosureArgsParts, RegionKind,
- Upcast,
+ AliasTyKind, BoundVarIndexKind, CoroutineArgsParts, RegionKind, Upcast,
inherent::{AdtDef, GenericArgs as _, IntoKind, Term as _, Ty as _, Tys as _},
};
use smallvec::SmallVec;
@@ -48,16 +47,17 @@ use span::Edition;
use stdx::never;
use crate::{
- CallableDefId, FnAbi, ImplTraitId, InferenceResult, MemoryMap, ParamEnvAndCrate, consteval,
- db::{HirDatabase, InternedClosure, InternedCoroutine},
+ CallableDefId, FnAbi, ImplTraitId, MemoryMap, ParamEnvAndCrate, consteval,
+ db::{HirDatabase, InternedClosure},
generics::generics,
layout::Layout,
lower::GenericPredicates,
mir::pad16,
next_solver::{
- AliasTy, Clause, ClauseKind, Const, ConstKind, DbInterner, ExistentialPredicate, FnSig,
- GenericArg, GenericArgKind, GenericArgs, ParamEnv, PolyFnSig, Region, SolverDefId,
- StoredEarlyBinder, StoredTy, Term, TermKind, TraitRef, Ty, TyKind, TypingMode,
+ AliasTy, Allocation, Clause, ClauseKind, Const, ConstKind, DbInterner,
+ ExistentialPredicate, FnSig, GenericArg, GenericArgKind, GenericArgs, ParamEnv, PolyFnSig,
+ Region, SolverDefId, StoredEarlyBinder, StoredTy, Term, TermKind, TraitRef, Ty, TyKind,
+ TypingMode, ValTree,
abi::Safety,
infer::{DbInternerInferExt, traits::ObligationCause},
},
@@ -647,7 +647,7 @@ fn write_projection<'db>(
ClauseKind::TypeOutlives(t) => t.0,
_ => return false,
};
- let TyKind::Alias(AliasTyKind::Projection, a) = ty.kind() else {
+ let TyKind::Alias(a) = ty.kind() else {
return false;
};
a == *alias
@@ -658,7 +658,7 @@ fn write_projection<'db>(
write_bounds_like_dyn_trait_with_prefix(
f,
"impl",
- Either::Left(Ty::new_alias(f.interner, AliasTyKind::Projection, *alias)),
+ Either::Left(Ty::new_alias(f.interner, *alias)),
&bounds,
SizedByDefault::NotSized,
needs_parens_if_multi,
@@ -674,7 +674,7 @@ fn write_projection<'db>(
write!(
f,
">::{}",
- TypeAliasSignature::of(f.db, alias.def_id.expect_type_alias())
+ TypeAliasSignature::of(f.db, alias.kind.def_id().expect_type_alias())
.name
.display(f.db, f.edition())
)?;
@@ -692,6 +692,12 @@ impl<'db> HirDisplay<'db> for GenericArg<'db> {
}
}
+impl<'db> HirDisplay<'db> for Allocation<'db> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
+ render_const_scalar(f, &self.memory, &self.memory_map, self.ty)
+ }
+}
+
impl<'db> HirDisplay<'db> for Const<'db> {
fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
match self.kind() {
@@ -711,12 +717,7 @@ impl<'db> HirDisplay<'db> for Const<'db> {
f.end_location_link();
Ok(())
}
- ConstKind::Value(const_bytes) => render_const_scalar(
- f,
- &const_bytes.value.inner().memory,
- &const_bytes.value.inner().memory_map,
- const_bytes.ty,
- ),
+ ConstKind::Value(value) => render_const_scalar_from_valtree(f, value.ty, value.value),
ConstKind::Unevaluated(unev) => {
let c = unev.def.0;
write!(f, "{}", c.name(f.db))?;
@@ -1006,7 +1007,7 @@ fn render_const_scalar_inner<'db>(
TyKind::Pat(_, _) => f.write_str("<pat>"),
TyKind::Error(..)
| TyKind::Placeholder(_)
- | TyKind::Alias(_, _)
+ | TyKind::Alias(..)
| TyKind::Param(_)
| TyKind::Bound(_, _)
| TyKind::Infer(_) => f.write_str("<placeholder-or-unknown-type>"),
@@ -1015,6 +1016,151 @@ fn render_const_scalar_inner<'db>(
}
}
+fn render_const_scalar_from_valtree<'db>(
+ f: &mut HirFormatter<'_, 'db>,
+ ty: Ty<'db>,
+ valtree: ValTree<'db>,
+) -> Result {
+ let param_env = ParamEnv::empty();
+ let infcx = f.interner.infer_ctxt().build(TypingMode::PostAnalysis);
+ let ty = infcx.at(&ObligationCause::new(), param_env).deeply_normalize(ty).unwrap_or(ty);
+ render_const_scalar_from_valtree_inner(f, ty, valtree, param_env)
+}
+
+fn render_const_scalar_from_valtree_inner<'db>(
+ f: &mut HirFormatter<'_, 'db>,
+ ty: Ty<'db>,
+ valtree: ValTree<'db>,
+ _param_env: ParamEnv<'db>,
+) -> Result {
+ use TyKind;
+ match ty.kind() {
+ TyKind::Bool => write!(f, "{}", valtree.inner().to_leaf().try_to_bool().unwrap()),
+ TyKind::Char => {
+ let it = valtree.inner().to_leaf().to_u32();
+ let Ok(c) = char::try_from(it) else {
+ return f.write_str("<unicode-error>");
+ };
+ write!(f, "{c:?}")
+ }
+ TyKind::Int(_) => {
+ let it = valtree.inner().to_leaf().to_int_unchecked();
+ write!(f, "{it}")
+ }
+ TyKind::Uint(_) => {
+ let it = valtree.inner().to_leaf().to_uint_unchecked();
+ write!(f, "{it}")
+ }
+ TyKind::Float(fl) => match fl {
+ FloatTy::F16 => {
+ // FIXME(#17451): Replace with builtins once they are stabilised.
+ let it = f16::from_bits(valtree.inner().to_leaf().to_u16() as u128);
+ let s = it.to_string();
+ if s.strip_prefix('-').unwrap_or(&s).chars().all(|c| c.is_ascii_digit()) {
+ // Match Rust debug formatting
+ write!(f, "{s}.0")
+ } else {
+ write!(f, "{s}")
+ }
+ }
+ FloatTy::F32 => {
+ let it = f32::from_bits(valtree.inner().to_leaf().to_u32());
+ write!(f, "{it:?}")
+ }
+ FloatTy::F64 => {
+ let it = f64::from_bits(valtree.inner().to_leaf().to_u64());
+ write!(f, "{it:?}")
+ }
+ FloatTy::F128 => {
+ // FIXME(#17451): Replace with builtins once they are stabilised.
+ let it = f128::from_bits(valtree.inner().to_leaf().to_u128());
+ let s = it.to_string();
+ if s.strip_prefix('-').unwrap_or(&s).chars().all(|c| c.is_ascii_digit()) {
+ // Match Rust debug formatting
+ write!(f, "{s}.0")
+ } else {
+ write!(f, "{s}")
+ }
+ }
+ },
+ TyKind::Ref(_, inner_ty, _) => {
+ render_const_scalar_from_valtree_inner(f, inner_ty, valtree, _param_env)
+ }
+ TyKind::Str => {
+ let bytes = valtree
+ .inner()
+ .to_branch()
+ .iter()
+ .map(|konst| match konst.kind() {
+ ConstKind::Value(value) => Some(value.value.inner().to_leaf().to_u8()),
+ _ => None,
+ })
+ .collect::<Option<Vec<_>>>();
+ let Some(bytes) = bytes else { return f.write_str("<invalid-str>") };
+ let s = std::str::from_utf8(&bytes).unwrap_or("<utf8-error>");
+ write!(f, "{s:?}")
+ }
+ TyKind::Slice(inner_ty) | TyKind::Array(inner_ty, _) => {
+ let mut first = true;
+ write!(f, "[")?;
+ for item in valtree.inner().to_branch() {
+ if !first {
+ write!(f, ", ")?;
+ } else {
+ first = false;
+ }
+ let ConstKind::Value(value) = item.kind() else {
+ return f.write_str("<invalid-const>");
+ };
+ render_const_scalar_from_valtree_inner(f, inner_ty, value.value, _param_env)?;
+ }
+ write!(f, "]")
+ }
+ TyKind::Tuple(tys) => {
+ let mut first = true;
+ write!(f, "(")?;
+ for (inner_ty, item) in std::iter::zip(tys, valtree.inner().to_branch()) {
+ if !first {
+ write!(f, ", ")?;
+ } else {
+ first = false;
+ }
+ let ConstKind::Value(value) = item.kind() else {
+ return f.write_str("<invalid-const>");
+ };
+ render_const_scalar_from_valtree_inner(f, inner_ty, value.value, _param_env)?;
+ }
+ write!(f, ")")
+ }
+ TyKind::Adt(..) => {
+ // FIXME: ADTs, requires `adt_const_params`.
+ f.write_str("<adt>")
+ }
+ TyKind::FnDef(..) => ty.hir_fmt(f),
+ TyKind::FnPtr(_, _) | TyKind::RawPtr(_, _) => {
+ let it = valtree.inner().to_leaf().to_uint_unchecked();
+ write!(f, "{it:#X} as ")?;
+ ty.hir_fmt(f)
+ }
+ TyKind::Never => f.write_str("!"),
+ TyKind::Closure(_, _) => f.write_str("<closure>"),
+ TyKind::Coroutine(_, _) => f.write_str("<coroutine>"),
+ TyKind::CoroutineWitness(_, _) => f.write_str("<coroutine-witness>"),
+ TyKind::CoroutineClosure(_, _) => f.write_str("<coroutine-closure>"),
+ TyKind::UnsafeBinder(_) => f.write_str("<unsafe-binder>"),
+ // The below arms are unreachable, since const eval will bail out before here.
+ TyKind::Foreign(_) => f.write_str("<extern-type>"),
+ TyKind::Pat(_, _) => f.write_str("<pat>"),
+ TyKind::Error(..)
+ | TyKind::Placeholder(_)
+ | TyKind::Alias(..)
+ | TyKind::Param(_)
+ | TyKind::Bound(_, _)
+ | TyKind::Infer(_) => f.write_str("<placeholder-or-unknown-type>"),
+ TyKind::Dynamic(_, _) => f.write_str("<dyn-trait>"),
+ }
+}
+
fn render_variant_after_name<'db>(
data: &VariantFields,
f: &mut HirFormatter<'_, 'db>,
@@ -1281,7 +1427,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
hir_fmt_generics(f, parameters.as_slice(), Some(def.def_id().0.into()), None)?;
}
- TyKind::Alias(AliasTyKind::Projection, alias_ty) => {
+ TyKind::Alias(alias_ty @ AliasTy { kind: AliasTyKind::Projection { .. }, .. }) => {
write_projection(f, &alias_ty, trait_bounds_need_parens)?
}
TyKind::Foreign(alias) => {
@@ -1290,8 +1436,8 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
write!(f, "{}", type_alias.name.display(f.db, f.edition()))?;
f.end_location_link();
}
- TyKind::Alias(AliasTyKind::Opaque, alias_ty) => {
- let opaque_ty_id = match alias_ty.def_id {
+ TyKind::Alias(alias_ty @ AliasTy { kind: AliasTyKind::Opaque { def_id }, .. }) => {
+ let opaque_ty_id = match def_id {
SolverDefId::InternedOpaqueTyId(id) => id,
_ => unreachable!(),
};
@@ -1349,9 +1495,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
}
let sig = interner.signature_unclosure(substs.as_closure().sig(), Safety::Safe);
let sig = sig.skip_binder();
- let InternedClosure(owner, _) = db.lookup_intern_closure(id);
- let infer = InferenceResult::of(db, owner);
- let (_, kind) = infer.closure_info(id);
+ let kind = substs.as_closure().kind();
match f.closure_style {
ClosureStyle::ImplFn => write!(f, "impl {kind:?}(")?,
ClosureStyle::RANotation => write!(f, "|")?,
@@ -1403,26 +1547,16 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
}
_ => (),
}
- let CoroutineClosureArgsParts { closure_kind_ty, signature_parts_ty, .. } =
- args.split_coroutine_closure_args();
- let kind = closure_kind_ty.to_opt_closure_kind().unwrap();
+ let kind = args.as_coroutine_closure().kind();
let kind = match kind {
rustc_type_ir::ClosureKind::Fn => "AsyncFn",
rustc_type_ir::ClosureKind::FnMut => "AsyncFnMut",
rustc_type_ir::ClosureKind::FnOnce => "AsyncFnOnce",
};
- let TyKind::FnPtr(coroutine_sig, _) = signature_parts_ty.kind() else {
- unreachable!("invalid coroutine closure signature");
- };
+ let coroutine_sig = args.as_coroutine_closure().coroutine_closure_sig();
let coroutine_sig = coroutine_sig.skip_binder();
- let coroutine_inputs = coroutine_sig.inputs();
- 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 {
- unreachable!("invalid coroutine closure signature");
- };
- let coroutine_output = coroutine_output.as_slice()[1];
+ let coroutine_inputs = coroutine_sig.tupled_inputs_ty.tuple_fields();
+ let coroutine_output = coroutine_sig.return_ty;
match f.closure_style {
ClosureStyle::ImplFn => write!(f, "impl {kind}(")?,
ClosureStyle::RANotation => write!(f, "async |")?,
@@ -1536,17 +1670,16 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
}
TyKind::Infer(..) => write!(f, "_")?,
TyKind::Coroutine(coroutine_id, subst) => {
- let InternedCoroutine(owner, expr_id) = coroutine_id.0.loc(db);
+ let InternedClosure(owner, expr_id) = coroutine_id.0.loc(db);
let CoroutineArgsParts { resume_ty, yield_ty, return_ty, .. } =
subst.split_coroutine_args();
let body = ExpressionStore::of(db, owner);
let expr = &body[expr_id];
match expr {
hir_def::hir::Expr::Closure {
- closure_kind: hir_def::hir::ClosureKind::Async,
+ closure_kind: hir_def::hir::ClosureKind::AsyncBlock { .. },
..
- }
- | hir_def::hir::Expr::Async { .. } => {
+ } => {
let future_trait = f.lang_items().Future;
let output = future_trait.and_then(|t| {
t.trait_items(db)
@@ -1597,7 +1730,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
TyKind::CoroutineWitness(..) => write!(f, "{{coroutine witness}}")?,
TyKind::Pat(_, _) => write!(f, "{{pat}}")?,
TyKind::UnsafeBinder(_) => write!(f, "{{unsafe binder}}")?,
- TyKind::Alias(_, _) => write!(f, "{{alias}}")?,
+ TyKind::Alias(..) => write!(f, "{{alias}}")?,
}
Ok(())
}