aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r--crates/hir_ty/src/lib.rs216
1 files changed, 139 insertions, 77 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 87f10e9d5..113234fa4 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -1,27 +1,29 @@
1//! The type system. We currently use this to infer types for completion, hover 1//! The type system. We currently use this to infer types for completion, hover
2//! information and various assists. 2//! information and various assists.
3
3#[allow(unused)] 4#[allow(unused)]
4macro_rules! eprintln { 5macro_rules! eprintln {
5 ($($tt:tt)*) => { stdx::eprintln!($($tt)*) }; 6 ($($tt:tt)*) => { stdx::eprintln!($($tt)*) };
6} 7}
7 8
8mod autoderef; 9mod autoderef;
9pub mod primitive;
10pub mod traits;
11pub mod method_resolution;
12mod op;
13mod lower;
14pub(crate) mod infer;
15pub(crate) mod utils;
16mod chalk_cast;
17mod chalk_ext;
18mod builder; 10mod builder;
11mod chalk_db;
12mod chalk_ext;
13mod infer;
14mod interner;
15mod lower;
16mod mapping;
17mod op;
18mod tls;
19mod utils;
19mod walk; 20mod walk;
20mod types;
21
22pub mod display;
23pub mod db; 21pub mod db;
24pub mod diagnostics; 22pub mod diagnostics;
23pub mod display;
24pub mod method_resolution;
25pub mod primitive;
26pub mod traits;
25 27
26#[cfg(test)] 28#[cfg(test)]
27mod tests; 29mod tests;
@@ -30,12 +32,12 @@ mod test_db;
30 32
31use std::sync::Arc; 33use std::sync::Arc;
32 34
33use base_db::salsa; 35use chalk_ir::{
34use chalk_ir::UintTy; 36 fold::{Fold, Shift},
35use hir_def::{ 37 interner::HasInterner,
36 expr::ExprId, type_ref::Rawness, ConstParamId, LifetimeParamId, TraitId, TypeAliasId, 38 UintTy,
37 TypeParamId,
38}; 39};
40use hir_def::{expr::ExprId, type_ref::Rawness, TypeParamId};
39 41
40use crate::{db::HirDatabase, display::HirDisplay, utils::generics}; 42use crate::{db::HirDatabase, display::HirDisplay, utils::generics};
41 43
@@ -43,12 +45,17 @@ pub use autoderef::autoderef;
43pub use builder::TyBuilder; 45pub use builder::TyBuilder;
44pub use chalk_ext::*; 46pub use chalk_ext::*;
45pub use infer::{could_unify, InferenceResult}; 47pub use infer::{could_unify, InferenceResult};
48pub use interner::Interner;
46pub use lower::{ 49pub use lower::{
47 associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, 50 associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
48 TyDefId, TyLoweringContext, ValueTyDefId, 51 TyDefId, TyLoweringContext, ValueTyDefId,
49}; 52};
50pub use traits::{chalk::Interner, TraitEnvironment}; 53pub use mapping::{
51pub use types::*; 54 const_from_placeholder_idx, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id,
55 from_placeholder_idx, lt_from_placeholder_idx, to_assoc_type_id, to_chalk_trait_id,
56 to_foreign_def_id, to_placeholder_idx,
57};
58pub use traits::TraitEnvironment;
52pub use walk::TypeWalk; 59pub use walk::TypeWalk;
53 60
54pub use chalk_ir::{ 61pub use chalk_ir::{
@@ -65,6 +72,21 @@ pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
65pub type VariableKind = chalk_ir::VariableKind<Interner>; 72pub type VariableKind = chalk_ir::VariableKind<Interner>;
66pub type VariableKinds = chalk_ir::VariableKinds<Interner>; 73pub type VariableKinds = chalk_ir::VariableKinds<Interner>;
67pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>; 74pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>;
75pub type Binders<T> = chalk_ir::Binders<T>;
76pub type Substitution = chalk_ir::Substitution<Interner>;
77pub type GenericArg = chalk_ir::GenericArg<Interner>;
78pub type GenericArgData = chalk_ir::GenericArgData<Interner>;
79
80pub type Ty = chalk_ir::Ty<Interner>;
81pub type TyKind = chalk_ir::TyKind<Interner>;
82pub type DynTy = chalk_ir::DynTy<Interner>;
83pub type FnPointer = chalk_ir::FnPointer<Interner>;
84// pub type FnSubst = chalk_ir::FnSubst<Interner>;
85pub use chalk_ir::FnSubst;
86pub type ProjectionTy = chalk_ir::ProjectionTy<Interner>;
87pub type AliasTy = chalk_ir::AliasTy<Interner>;
88pub type OpaqueTy = chalk_ir::OpaqueTy<Interner>;
89pub type InferenceVar = chalk_ir::InferenceVar;
68 90
69pub type Lifetime = chalk_ir::Lifetime<Interner>; 91pub type Lifetime = chalk_ir::Lifetime<Interner>;
70pub type LifetimeData = chalk_ir::LifetimeData<Interner>; 92pub type LifetimeData = chalk_ir::LifetimeData<Interner>;
@@ -76,12 +98,27 @@ pub type ConstValue = chalk_ir::ConstValue<Interner>;
76pub type ConcreteConst = chalk_ir::ConcreteConst<Interner>; 98pub type ConcreteConst = chalk_ir::ConcreteConst<Interner>;
77 99
78pub type ChalkTraitId = chalk_ir::TraitId<Interner>; 100pub type ChalkTraitId = chalk_ir::TraitId<Interner>;
101pub type TraitRef = chalk_ir::TraitRef<Interner>;
102pub type QuantifiedWhereClause = Binders<WhereClause>;
103pub type QuantifiedWhereClauses = chalk_ir::QuantifiedWhereClauses<Interner>;
104pub type Canonical<T> = chalk_ir::Canonical<T>;
79 105
80pub type FnSig = chalk_ir::FnSig<Interner>; 106pub type FnSig = chalk_ir::FnSig<Interner>;
81 107
108pub type InEnvironment<T> = chalk_ir::InEnvironment<T>;
109pub type DomainGoal = chalk_ir::DomainGoal<Interner>;
110pub type AliasEq = chalk_ir::AliasEq<Interner>;
111pub type Solution = chalk_solve::Solution<Interner>;
112pub type ConstrainedSubst = chalk_ir::ConstrainedSubst<Interner>;
113pub type Guidance = chalk_solve::Guidance<Interner>;
114pub type WhereClause = chalk_ir::WhereClause<Interner>;
115
82// FIXME: get rid of this 116// FIXME: get rid of this
83pub fn subst_prefix(s: &Substitution, n: usize) -> Substitution { 117pub fn subst_prefix(s: &Substitution, n: usize) -> Substitution {
84 Substitution::intern(s.interned()[..std::cmp::min(s.len(&Interner), n)].into()) 118 Substitution::from_iter(
119 &Interner,
120 s.as_slice(&Interner)[..std::cmp::min(s.len(&Interner), n)].iter().cloned(),
121 )
85} 122}
86 123
87/// Return an index of a parameter in the generic type parameter list by it's id. 124/// Return an index of a parameter in the generic type parameter list by it's id.
@@ -89,14 +126,17 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> {
89 generics(db.upcast(), id.parent).param_idx(id) 126 generics(db.upcast(), id.parent).param_idx(id)
90} 127}
91 128
92pub fn wrap_empty_binders<T>(value: T) -> Binders<T> 129pub(crate) fn wrap_empty_binders<T>(value: T) -> Binders<T>
93where 130where
94 T: TypeWalk, 131 T: Fold<Interner, Result = T> + HasInterner<Interner = Interner>,
95{ 132{
96 Binders::empty(&Interner, value.shifted_in_from(DebruijnIndex::ONE)) 133 Binders::empty(&Interner, value.shifted_in_from(&Interner, DebruijnIndex::ONE))
97} 134}
98 135
99pub fn make_only_type_binders<T>(num_vars: usize, value: T) -> Binders<T> { 136pub(crate) fn make_only_type_binders<T: HasInterner<Interner = Interner>>(
137 num_vars: usize,
138 value: T,
139) -> Binders<T> {
100 Binders::new( 140 Binders::new(
101 VariableKinds::from_iter( 141 VariableKinds::from_iter(
102 &Interner, 142 &Interner,
@@ -108,7 +148,7 @@ pub fn make_only_type_binders<T>(num_vars: usize, value: T) -> Binders<T> {
108} 148}
109 149
110// FIXME: get rid of this 150// FIXME: get rid of this
111pub fn make_canonical<T>( 151pub fn make_canonical<T: HasInterner<Interner = Interner>>(
112 value: T, 152 value: T,
113 kinds: impl IntoIterator<Item = TyVariableKind>, 153 kinds: impl IntoIterator<Item = TyVariableKind>,
114) -> Canonical<T> { 154) -> Canonical<T> {
@@ -129,6 +169,8 @@ pub struct CallableSig {
129 is_varargs: bool, 169 is_varargs: bool,
130} 170}
131 171
172has_interner!(CallableSig);
173
132/// A polymorphic function signature. 174/// A polymorphic function signature.
133pub type PolyFnSig = Binders<CallableSig>; 175pub type PolyFnSig = Binders<CallableSig>;
134 176
@@ -144,10 +186,10 @@ impl CallableSig {
144 params_and_return: fn_ptr 186 params_and_return: fn_ptr
145 .substitution 187 .substitution
146 .clone() 188 .clone()
147 .shifted_out_to(DebruijnIndex::ONE) 189 .shifted_out_to(&Interner, DebruijnIndex::ONE)
148 .expect("unexpected lifetime vars in fn ptr") 190 .expect("unexpected lifetime vars in fn ptr")
149 .0 191 .0
150 .interned() 192 .as_slice(&Interner)
151 .iter() 193 .iter()
152 .map(|arg| arg.assert_ty_ref(&Interner).clone()) 194 .map(|arg| arg.assert_ty_ref(&Interner).clone())
153 .collect(), 195 .collect(),
@@ -164,7 +206,22 @@ impl CallableSig {
164 } 206 }
165} 207}
166 208
167impl Ty {} 209impl Fold<Interner> for CallableSig {
210 type Result = CallableSig;
211
212 fn fold_with<'i>(
213 self,
214 folder: &mut dyn chalk_ir::fold::Folder<'i, Interner>,
215 outer_binder: DebruijnIndex,
216 ) -> chalk_ir::Fallible<Self::Result>
217 where
218 Interner: 'i,
219 {
220 let vec = self.params_and_return.to_vec();
221 let folded = vec.fold_with(folder, outer_binder)?;
222 Ok(CallableSig { params_and_return: folded.into(), is_varargs: self.is_varargs })
223 }
224}
168 225
169#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] 226#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
170pub enum ImplTraitId { 227pub enum ImplTraitId {
@@ -177,70 +234,75 @@ pub struct ReturnTypeImplTraits {
177 pub(crate) impl_traits: Vec<ReturnTypeImplTrait>, 234 pub(crate) impl_traits: Vec<ReturnTypeImplTrait>,
178} 235}
179 236
237has_interner!(ReturnTypeImplTraits);
238
180#[derive(Clone, PartialEq, Eq, Debug, Hash)] 239#[derive(Clone, PartialEq, Eq, Debug, Hash)]
181pub(crate) struct ReturnTypeImplTrait { 240pub(crate) struct ReturnTypeImplTrait {
182 pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>, 241 pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>,
183} 242}
184 243
185pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { 244pub fn static_lifetime() -> Lifetime {
186 chalk_ir::ForeignDefId(salsa::InternKey::as_intern_id(&id)) 245 LifetimeData::Static.intern(&Interner)
187}
188
189pub fn from_foreign_def_id(id: ForeignDefId) -> TypeAliasId {
190 salsa::InternKey::from_intern_id(id.0)
191}
192
193pub fn to_assoc_type_id(id: TypeAliasId) -> AssocTypeId {
194 chalk_ir::AssocTypeId(salsa::InternKey::as_intern_id(&id))
195}
196
197pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId {
198 salsa::InternKey::from_intern_id(id.0)
199}
200
201pub fn from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> TypeParamId {
202 assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT);
203 let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx));
204 db.lookup_intern_type_param_id(interned_id)
205} 246}
206 247
207pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeParamId) -> PlaceholderIndex { 248pub fn dummy_usize_const() -> Const {
208 let interned_id = db.intern_type_param_id(id); 249 let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner);
209 PlaceholderIndex { 250 chalk_ir::ConstData {
210 ui: chalk_ir::UniverseIndex::ROOT, 251 ty: usize_ty,
211 idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(), 252 value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }),
212 } 253 }
254 .intern(&Interner)
213} 255}
214 256
215pub fn lt_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> LifetimeParamId { 257pub(crate) fn fold_free_vars<T: HasInterner<Interner = Interner> + Fold<Interner>>(
216 assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); 258 t: T,
217 let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx)); 259 f: impl FnMut(BoundVar, DebruijnIndex) -> Ty,
218 db.lookup_intern_lifetime_param_id(interned_id) 260) -> T::Result {
219} 261 use chalk_ir::{fold::Folder, Fallible};
262 struct FreeVarFolder<F>(F);
263 impl<'i, F: FnMut(BoundVar, DebruijnIndex) -> Ty + 'i> Folder<'i, Interner> for FreeVarFolder<F> {
264 fn as_dyn(&mut self) -> &mut dyn Folder<'i, Interner> {
265 self
266 }
220 267
221pub fn const_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> ConstParamId { 268 fn interner(&self) -> &'i Interner {
222 assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); 269 &Interner
223 let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx)); 270 }
224 db.lookup_intern_const_param_id(interned_id)
225}
226 271
227pub fn to_chalk_trait_id(id: TraitId) -> ChalkTraitId { 272 fn fold_free_var_ty(
228 chalk_ir::TraitId(salsa::InternKey::as_intern_id(&id)) 273 &mut self,
274 bound_var: BoundVar,
275 outer_binder: DebruijnIndex,
276 ) -> Fallible<Ty> {
277 Ok(self.0(bound_var, outer_binder))
278 }
279 }
280 t.fold_with(&mut FreeVarFolder(f), DebruijnIndex::INNERMOST).expect("fold failed unexpectedly")
229} 281}
230 282
231pub fn from_chalk_trait_id(id: ChalkTraitId) -> TraitId { 283pub(crate) fn fold_tys<T: HasInterner<Interner = Interner> + Fold<Interner>>(
232 salsa::InternKey::from_intern_id(id.0) 284 t: T,
233} 285 f: impl FnMut(Ty, DebruijnIndex) -> Ty,
286 binders: DebruijnIndex,
287) -> T::Result {
288 use chalk_ir::{
289 fold::{Folder, SuperFold},
290 Fallible,
291 };
292 struct TyFolder<F>(F);
293 impl<'i, F: FnMut(Ty, DebruijnIndex) -> Ty + 'i> Folder<'i, Interner> for TyFolder<F> {
294 fn as_dyn(&mut self) -> &mut dyn Folder<'i, Interner> {
295 self
296 }
234 297
235pub fn static_lifetime() -> Lifetime { 298 fn interner(&self) -> &'i Interner {
236 LifetimeData::Static.intern(&Interner) 299 &Interner
237} 300 }
238 301
239pub fn dummy_usize_const() -> Const { 302 fn fold_ty(&mut self, ty: Ty, outer_binder: DebruijnIndex) -> Fallible<Ty> {
240 let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner); 303 let ty = ty.super_fold_with(self.as_dyn(), outer_binder)?;
241 chalk_ir::ConstData { 304 Ok(self.0(ty, outer_binder))
242 ty: usize_ty, 305 }
243 value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }),
244 } 306 }
245 .intern(&Interner) 307 t.fold_with(&mut TyFolder(f), binders).expect("fold failed unexpectedly")
246} 308}