Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/builder.rs')
-rw-r--r--crates/hir-ty/src/builder.rs222
1 files changed, 26 insertions, 196 deletions
diff --git a/crates/hir-ty/src/builder.rs b/crates/hir-ty/src/builder.rs
index 706bbe856c..5c4eb8475b 100644
--- a/crates/hir-ty/src/builder.rs
+++ b/crates/hir-ty/src/builder.rs
@@ -1,15 +1,14 @@
//! `TyBuilder`, a helper for building instances of `Ty` and related types.
use chalk_ir::{
- AdtId, DebruijnIndex, Scalar,
- cast::{Cast, CastTo, Caster},
+ DebruijnIndex, Scalar,
+ cast::{Cast, Caster},
};
-use hir_def::{GenericDefId, GenericParamId, TraitId, TypeAliasId, builtin_type::BuiltinType};
+use hir_def::{GenericDefId, GenericParamId, TraitId, builtin_type::BuiltinType};
use smallvec::SmallVec;
use crate::{
- BoundVar, CallableSig, GenericArg, GenericArgData, Interner, ProjectionTy, Substitution,
- TraitRef, Ty, TyDefId, TyExt, TyKind,
+ BoundVar, GenericArg, GenericArgData, Interner, Substitution, TraitRef, Ty, TyKind,
consteval::unknown_const_as_generic,
db::HirDatabase,
error_lifetime,
@@ -19,18 +18,18 @@ use crate::{
DbInterner, EarlyBinder,
mapping::{ChalkToNextSolver, NextSolverToChalk},
},
- primitive, to_assoc_type_id, to_chalk_trait_id,
+ primitive, to_chalk_trait_id,
};
#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum ParamKind {
+pub(crate) enum ParamKind {
Type,
Lifetime,
Const(Ty),
}
/// This is a builder for `Ty` or anything that needs a `Substitution`.
-pub struct TyBuilder<D> {
+pub(crate) struct TyBuilder<D> {
/// The `data` field is used to keep track of what we're building (e.g. an
/// ADT, a `TraitRef`, ...).
data: D,
@@ -60,10 +59,6 @@ impl<D> TyBuilder<D> {
Self { data, vec: SmallVec::with_capacity(param_kinds.len()), param_kinds, parent_subst }
}
- fn new_empty(data: D) -> Self {
- TyBuilder::new(data, SmallVec::new(), None)
- }
-
fn build_internal(self) -> (D, Substitution) {
assert_eq!(
self.vec.len(),
@@ -83,35 +78,15 @@ impl<D> TyBuilder<D> {
(self.data, subst)
}
- pub fn build_into_subst(self) -> Substitution {
- self.build_internal().1
- }
-
- pub fn push(mut self, arg: impl CastTo<GenericArg>) -> Self {
- assert!(self.remaining() > 0);
- let arg = arg.cast(Interner);
- let expected_kind = &self.param_kinds[self.vec.len()];
-
- let arg_kind = match arg.data(Interner) {
- GenericArgData::Ty(_) => ParamKind::Type,
- GenericArgData::Lifetime(_) => panic!("Got lifetime in TyBuilder::push"),
- GenericArgData::Const(c) => {
- let c = c.data(Interner);
- ParamKind::Const(c.ty.clone())
- }
- };
- assert_eq!(*expected_kind, arg_kind);
-
- self.vec.push(arg);
-
- self
- }
-
- pub fn remaining(&self) -> usize {
+ pub(crate) fn remaining(&self) -> usize {
self.param_kinds.len() - self.vec.len()
}
- pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self {
+ pub(crate) fn fill_with_bound_vars(
+ self,
+ debruijn: DebruijnIndex,
+ starting_from: usize,
+ ) -> Self {
// self.fill is inlined to make borrow checker happy
let mut this = self;
let other = &this.param_kinds[this.vec.len()..];
@@ -129,22 +104,6 @@ impl<D> TyBuilder<D> {
this
}
- pub fn fill_with_unknown(self) -> Self {
- let interner = DbInterner::conjure();
- // self.fill is inlined to make borrow checker happy
- let mut this = self;
- let filler = this.param_kinds[this.vec.len()..].iter().map(|x| match x {
- ParamKind::Type => TyKind::Error.intern(Interner).cast(Interner),
- ParamKind::Const(ty) => {
- unknown_const_as_generic(ty.to_nextsolver(interner)).to_chalk(interner)
- }
- ParamKind::Lifetime => error_lifetime().cast(Interner),
- });
- this.vec.extend(filler.casted(Interner));
- assert_eq!(this.remaining(), 0);
- this
- }
-
#[tracing::instrument(skip_all)]
pub(crate) fn fill_with_inference_vars(self, table: &mut InferenceTable<'_>) -> Self {
self.fill(|x| {
@@ -157,7 +116,7 @@ impl<D> TyBuilder<D> {
})
}
- pub fn fill(mut self, filler: impl FnMut(&ParamKind) -> GenericArg) -> Self {
+ pub(crate) fn fill(mut self, filler: impl FnMut(&ParamKind) -> GenericArg) -> Self {
self.vec.extend(self.param_kinds[self.vec.len()..].iter().map(filler));
assert_eq!(self.remaining(), 0);
self
@@ -174,28 +133,11 @@ impl<D> TyBuilder<D> {
}
impl TyBuilder<()> {
- pub fn unit() -> Ty {
- TyKind::Tuple(0, Substitution::empty(Interner)).intern(Interner)
- }
-
- // FIXME: rustc's ty is dependent on the adt type, maybe we need to do that as well
- pub fn discr_ty() -> Ty {
- TyKind::Scalar(chalk_ir::Scalar::Int(chalk_ir::IntTy::I128)).intern(Interner)
- }
-
- pub fn bool() -> Ty {
- TyKind::Scalar(chalk_ir::Scalar::Bool).intern(Interner)
- }
-
- pub fn usize() -> Ty {
+ pub(crate) fn usize() -> Ty {
TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::Usize)).intern(Interner)
}
- pub fn fn_ptr(sig: CallableSig) -> Ty {
- TyKind::Function(sig.to_fn_ptr()).intern(Interner)
- }
-
- pub fn builtin(builtin: BuiltinType) -> Ty {
+ pub(crate) fn builtin(builtin: BuiltinType) -> Ty {
match builtin {
BuiltinType::Char => TyKind::Scalar(Scalar::Char).intern(Interner),
BuiltinType::Bool => TyKind::Scalar(Scalar::Bool).intern(Interner),
@@ -212,16 +154,10 @@ impl TyBuilder<()> {
}
}
- pub fn slice(argument: Ty) -> Ty {
- TyKind::Slice(argument).intern(Interner)
- }
-
- pub fn placeholder_subst(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substitution {
- let params = generics(db, def.into());
- params.placeholder_subst(db)
- }
-
- pub fn unknown_subst(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substitution {
+ pub(crate) fn unknown_subst(
+ db: &dyn HirDatabase,
+ def: impl Into<GenericDefId>,
+ ) -> Substitution {
let interner = DbInterner::conjure();
let params = generics(db, def.into());
Substitution::from_iter(
@@ -239,7 +175,7 @@ impl TyBuilder<()> {
}
#[tracing::instrument(skip_all)]
- pub fn subst_for_def(
+ pub(crate) fn subst_for_def(
db: &dyn HirDatabase,
def: impl Into<GenericDefId>,
parent_subst: Option<Substitution>,
@@ -257,114 +193,25 @@ impl TyBuilder<()> {
TyBuilder::new((), params, parent_subst)
}
- pub fn build(self) -> Substitution {
+ pub(crate) fn build(self) -> Substitution {
let ((), subst) = self.build_internal();
subst
}
}
-impl TyBuilder<hir_def::AdtId> {
- pub fn adt(db: &dyn HirDatabase, def: hir_def::AdtId) -> TyBuilder<hir_def::AdtId> {
- TyBuilder::subst_for_def(db, def, None).with_data(def)
- }
-
- pub fn fill_with_defaults(
- mut self,
- db: &dyn HirDatabase,
- mut fallback: impl FnMut() -> Ty,
- ) -> Self {
- let interner = DbInterner::conjure();
- // Note that we're building ADT, so we never have parent generic parameters.
- let defaults = db.generic_defaults(self.data.into());
-
- if let Some(defaults) = defaults.get(self.vec.len()..) {
- for default_ty in defaults {
- // NOTE(skip_binders): we only check if the arg type is error type.
- if let Some(x) = default_ty.skip_binders().ty(Interner)
- && x.is_unknown()
- {
- self.vec.push(fallback().cast(Interner));
- continue;
- }
- // Each default can only depend on the previous parameters.
- self.vec.push(default_ty.clone().substitute(Interner, &*self.vec).cast(Interner));
- }
- }
-
- // The defaults may be missing if no param has default, so fill that.
- let filler = self.param_kinds[self.vec.len()..].iter().map(|x| match x {
- ParamKind::Type => fallback().cast(Interner),
- ParamKind::Const(ty) => {
- unknown_const_as_generic(ty.to_nextsolver(interner)).to_chalk(interner)
- }
- ParamKind::Lifetime => error_lifetime().cast(Interner),
- });
- self.vec.extend(filler.casted(Interner));
-
- self
- }
-
- pub fn build(self) -> Ty {
- let (adt, subst) = self.build_internal();
- TyKind::Adt(AdtId(adt), subst).intern(Interner)
- }
-}
-
-pub struct Tuple(usize);
-impl TyBuilder<Tuple> {
- pub fn tuple(size: usize) -> TyBuilder<Tuple> {
- TyBuilder::new(Tuple(size), std::iter::repeat_n(ParamKind::Type, size).collect(), None)
- }
-
- pub fn build(self) -> Ty {
- let (Tuple(size), subst) = self.build_internal();
- TyKind::Tuple(size, subst).intern(Interner)
- }
-
- pub fn tuple_with<I>(elements: I) -> Ty
- where
- I: IntoIterator<Item = Ty>,
- <I as IntoIterator>::IntoIter: ExactSizeIterator,
- {
- let elements = elements.into_iter();
- let len = elements.len();
- let mut b =
- TyBuilder::new(Tuple(len), std::iter::repeat_n(ParamKind::Type, len).collect(), None);
- for e in elements {
- b = b.push(e);
- }
- b.build()
- }
-}
-
impl TyBuilder<TraitId> {
- pub fn trait_ref(db: &dyn HirDatabase, def: TraitId) -> TyBuilder<TraitId> {
+ pub(crate) fn trait_ref(db: &dyn HirDatabase, def: TraitId) -> TyBuilder<TraitId> {
TyBuilder::subst_for_def(db, def, None).with_data(def)
}
- pub fn build(self) -> TraitRef {
+ pub(crate) fn build(self) -> TraitRef {
let (trait_id, substitution) = self.build_internal();
TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution }
}
}
-impl TyBuilder<TypeAliasId> {
- pub fn assoc_type_projection(
- db: &dyn HirDatabase,
- def: TypeAliasId,
- parent_subst: Option<Substitution>,
- ) -> TyBuilder<TypeAliasId> {
- TyBuilder::subst_for_def(db, def, parent_subst).with_data(def)
- }
-
- pub fn build(self) -> ProjectionTy {
- let (type_alias, substitution) = self.build_internal();
- ProjectionTy { associated_ty_id: to_assoc_type_id(type_alias), substitution }
- }
-}
-
impl<'db, T: rustc_type_ir::TypeFoldable<DbInterner<'db>>> TyBuilder<EarlyBinder<'db, T>> {
- pub fn build(self, interner: DbInterner<'db>) -> T {
+ pub(crate) fn build(self, interner: DbInterner<'db>) -> T {
let (b, subst) = self.build_internal();
let args: crate::next_solver::GenericArgs<'db> = subst.to_nextsolver(interner);
b.instantiate(interner, args)
@@ -372,24 +219,7 @@ impl<'db, T: rustc_type_ir::TypeFoldable<DbInterner<'db>>> TyBuilder<EarlyBinder
}
impl<'db> TyBuilder<EarlyBinder<'db, crate::next_solver::Ty<'db>>> {
- pub fn def_ty(
- db: &'db dyn HirDatabase,
- def: TyDefId,
- parent_subst: Option<Substitution>,
- ) -> TyBuilder<EarlyBinder<'db, crate::next_solver::Ty<'db>>> {
- let poly_ty = db.ty(def);
- let id: GenericDefId = match def {
- TyDefId::BuiltinType(_) => {
- assert!(parent_subst.is_none());
- return TyBuilder::new_empty(poly_ty);
- }
- TyDefId::AdtId(id) => id.into(),
- TyDefId::TypeAliasId(id) => id.into(),
- };
- TyBuilder::subst_for_def(db, id, parent_subst).with_data(poly_ty)
- }
-
- pub fn impl_self_ty(
+ pub(crate) fn impl_self_ty(
db: &'db dyn HirDatabase,
def: hir_def::ImplId,
) -> TyBuilder<EarlyBinder<'db, crate::next_solver::Ty<'db>>> {