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