Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/lib.rs')
| -rw-r--r-- | crates/hir-ty/src/lib.rs | 95 |
1 files changed, 81 insertions, 14 deletions
diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs index ec97bdc2c4..ba64f5c8d7 100644 --- a/crates/hir-ty/src/lib.rs +++ b/crates/hir-ty/src/lib.rs @@ -15,7 +15,8 @@ extern crate rustc_abi; #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_abi as rustc_abi; -// No need to use the in-tree one. +// Use the crates.io version unconditionally until the API settles enough that we can switch to +// using the in-tree one. extern crate ra_ap_rustc_pattern_analysis as rustc_pattern_analysis; mod builder; @@ -89,8 +90,8 @@ pub use lower::{ }; pub use mapping::{ from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, from_placeholder_idx, - lt_from_placeholder_idx, to_assoc_type_id, to_chalk_trait_id, to_foreign_def_id, - to_placeholder_idx, + lt_from_placeholder_idx, lt_to_placeholder_idx, to_assoc_type_id, to_chalk_trait_id, + to_foreign_def_id, to_placeholder_idx, }; pub use method_resolution::check_orphan_rules; pub use traits::TraitEnvironment; @@ -334,11 +335,23 @@ pub(crate) fn make_binders_with_count<T: HasInterner<Interner = Interner>>( generics: &Generics, value: T, ) -> Binders<T> { - let it = generics.iter_id().take(count).map(|id| match id { - Either::Left(_) => None, - Either::Right(id) => Some(db.const_param_ty(id)), - }); - crate::make_type_and_const_binders(it, value) + let it = generics.iter_id().take(count); + + Binders::new( + VariableKinds::from_iter( + Interner, + it.map(|x| match x { + hir_def::GenericParamId::ConstParamId(id) => { + chalk_ir::VariableKind::Const(db.const_param_ty(id)) + } + hir_def::GenericParamId::TypeParamId(_) => { + chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General) + } + hir_def::GenericParamId::LifetimeParamId(_) => chalk_ir::VariableKind::Lifetime, + }), + ), + value, + ) } pub(crate) fn make_binders<T: HasInterner<Interner = Interner>>( @@ -584,29 +597,34 @@ impl TypeFoldable<Interner> for CallableSig { #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] pub enum ImplTraitId { - ReturnTypeImplTrait(hir_def::FunctionId, RpitId), + ReturnTypeImplTrait(hir_def::FunctionId, ImplTraitIdx), + AssociatedTypeImplTrait(hir_def::TypeAliasId, ImplTraitIdx), AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId), } impl_intern_value_trivial!(ImplTraitId); #[derive(Clone, PartialEq, Eq, Debug, Hash)] -pub struct ReturnTypeImplTraits { - pub(crate) impl_traits: Arena<ReturnTypeImplTrait>, +pub struct ImplTraits { + pub(crate) impl_traits: Arena<ImplTrait>, } -has_interner!(ReturnTypeImplTraits); +has_interner!(ImplTraits); #[derive(Clone, PartialEq, Eq, Debug, Hash)] -pub struct ReturnTypeImplTrait { +pub struct ImplTrait { pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>, } -pub type RpitId = Idx<ReturnTypeImplTrait>; +pub type ImplTraitIdx = Idx<ImplTrait>; pub fn static_lifetime() -> Lifetime { LifetimeData::Static.intern(Interner) } +pub fn error_lifetime() -> Lifetime { + static_lifetime() +} + pub(crate) fn fold_free_vars<T: HasInterner<Interner = Interner> + TypeFoldable<Interner>>( t: T, for_ty: impl FnMut(BoundVar, DebruijnIndex) -> Ty, @@ -696,6 +714,55 @@ pub(crate) fn fold_tys_and_consts<T: HasInterner<Interner = Interner> + TypeFold t.fold_with(&mut TyFolder(f), binders) } +pub(crate) fn fold_generic_args<T: HasInterner<Interner = Interner> + TypeFoldable<Interner>>( + t: T, + f: impl FnMut(GenericArgData, DebruijnIndex) -> GenericArgData, + binders: DebruijnIndex, +) -> T { + use chalk_ir::fold::{TypeFolder, TypeSuperFoldable}; + #[derive(chalk_derive::FallibleTypeFolder)] + #[has_interner(Interner)] + struct TyFolder<F: FnMut(GenericArgData, DebruijnIndex) -> GenericArgData>(F); + impl<F: FnMut(GenericArgData, DebruijnIndex) -> GenericArgData> TypeFolder<Interner> + for TyFolder<F> + { + fn as_dyn(&mut self) -> &mut dyn TypeFolder<Interner> { + self + } + + fn interner(&self) -> Interner { + Interner + } + + fn fold_ty(&mut self, ty: Ty, outer_binder: DebruijnIndex) -> Ty { + let ty = ty.super_fold_with(self.as_dyn(), outer_binder); + self.0(GenericArgData::Ty(ty), outer_binder) + .intern(Interner) + .ty(Interner) + .unwrap() + .clone() + } + + fn fold_const(&mut self, c: Const, outer_binder: DebruijnIndex) -> Const { + self.0(GenericArgData::Const(c), outer_binder) + .intern(Interner) + .constant(Interner) + .unwrap() + .clone() + } + + fn fold_lifetime(&mut self, lt: Lifetime, outer_binder: DebruijnIndex) -> Lifetime { + let lt = lt.super_fold_with(self.as_dyn(), outer_binder); + self.0(GenericArgData::Lifetime(lt), outer_binder) + .intern(Interner) + .lifetime(Interner) + .unwrap() + .clone() + } + } + t.fold_with(&mut TyFolder(f), binders) +} + /// 'Canonicalizes' the `t` by replacing any errors with new variables. Also /// ensures there are no unbound variables or inference variables anywhere in /// the `t`. |