aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/db.rs6
-rw-r--r--crates/ra_hir_def/src/lib.rs8
-rw-r--r--crates/ra_hir_ty/src/db.rs18
-rw-r--r--crates/ra_hir_ty/src/lib.rs8
-rw-r--r--crates/ra_hir_ty/src/tests.rs6
-rw-r--r--crates/ra_hir_ty/src/traits.rs51
-rw-r--r--crates/ra_hir_ty/src/traits/builtin.rs178
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs99
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/interner.rs14
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/mapping.rs104
-rw-r--r--crates/ra_ide_db/src/change.rs3
11 files changed, 108 insertions, 387 deletions
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index cb48ca065..1ad92a1f8 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -17,9 +17,9 @@ pub use hir_ty::db::{
17 AssociatedTyDataQuery, AssociatedTyValueQuery, CallableItemSignatureQuery, FieldTypesQuery, 17 AssociatedTyDataQuery, AssociatedTyValueQuery, CallableItemSignatureQuery, FieldTypesQuery,
18 GenericDefaultsQuery, GenericPredicatesForParamQuery, GenericPredicatesQuery, HirDatabase, 18 GenericDefaultsQuery, GenericPredicatesForParamQuery, GenericPredicatesQuery, HirDatabase,
19 HirDatabaseStorage, ImplDatumQuery, ImplSelfTyQuery, ImplTraitQuery, InferQueryQuery, 19 HirDatabaseStorage, ImplDatumQuery, ImplSelfTyQuery, ImplTraitQuery, InferQueryQuery,
20 InherentImplsInCrateQuery, InternAssocTyValueQuery, InternChalkImplQuery, InternTypeCtorQuery, 20 InherentImplsInCrateQuery, InternTypeParamIdQuery, ReturnTypeImplTraitsQuery, StructDatumQuery,
21 InternTypeParamIdQuery, ReturnTypeImplTraitsQuery, StructDatumQuery, TraitDatumQuery, 21 TraitDatumQuery, TraitImplsInCrateQuery, TraitImplsInDepsQuery, TraitSolveQuery, TyQuery,
22 TraitImplsInCrateQuery, TraitImplsInDepsQuery, TraitSolveQuery, TyQuery, ValueTyQuery, 22 ValueTyQuery,
23}; 23};
24 24
25#[test] 25#[test]
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index b71d626c3..87000fe98 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -159,17 +159,17 @@ pub struct FunctionId(salsa::InternId);
159type FunctionLoc = AssocItemLoc<Function>; 159type FunctionLoc = AssocItemLoc<Function>;
160impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function); 160impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function);
161 161
162#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 162#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
163pub struct StructId(salsa::InternId); 163pub struct StructId(salsa::InternId);
164type StructLoc = ItemLoc<Struct>; 164type StructLoc = ItemLoc<Struct>;
165impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct); 165impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct);
166 166
167#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 167#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
168pub struct UnionId(salsa::InternId); 168pub struct UnionId(salsa::InternId);
169pub type UnionLoc = ItemLoc<Union>; 169pub type UnionLoc = ItemLoc<Union>;
170impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union); 170impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union);
171 171
172#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 172#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
173pub struct EnumId(salsa::InternId); 173pub struct EnumId(salsa::InternId);
174pub type EnumLoc = ItemLoc<Enum>; 174pub type EnumLoc = ItemLoc<Enum>;
175impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum); 175impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum);
@@ -239,7 +239,7 @@ pub enum AssocContainerId {
239impl_from!(ContainerId for AssocContainerId); 239impl_from!(ContainerId for AssocContainerId);
240 240
241/// A Data Type 241/// A Data Type
242#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 242#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
243pub enum AdtId { 243pub enum AdtId {
244 StructId(StructId), 244 StructId(StructId),
245 UnionId(UnionId), 245 UnionId(UnionId),
diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs
index 84afe0484..608bab1b1 100644
--- a/crates/ra_hir_ty/src/db.rs
+++ b/crates/ra_hir_ty/src/db.rs
@@ -3,8 +3,8 @@
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_def::{ 5use hir_def::{
6 db::DefDatabase, DefWithBodyId, FunctionId, GenericDefId, ImplId, LocalFieldId, TypeParamId, 6 db::DefDatabase, expr::ExprId, DefWithBodyId, FunctionId, GenericDefId, ImplId, LocalFieldId,
7 VariantId, 7 TypeParamId, VariantId,
8}; 8};
9use ra_arena::map::ArenaMap; 9use ra_arena::map::ArenaMap;
10use ra_db::{impl_intern_key, salsa, CrateId, Upcast}; 10use ra_db::{impl_intern_key, salsa, CrateId, Upcast};
@@ -12,9 +12,9 @@ use ra_prof::profile;
12 12
13use crate::{ 13use crate::{
14 method_resolution::{InherentImpls, TraitImpls}, 14 method_resolution::{InherentImpls, TraitImpls},
15 traits::{chalk, AssocTyValue, Impl}, 15 traits::chalk,
16 Binders, CallableDef, GenericPredicate, InferenceResult, OpaqueTyId, PolyFnSig, 16 Binders, CallableDef, GenericPredicate, InferenceResult, OpaqueTyId, PolyFnSig,
17 ReturnTypeImplTraits, TraitRef, Ty, TyDefId, TypeCtor, ValueTyDefId, 17 ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId,
18}; 18};
19use hir_expand::name::Name; 19use hir_expand::name::Name;
20 20
@@ -77,17 +77,13 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
77 77
78 // Interned IDs for Chalk integration 78 // Interned IDs for Chalk integration
79 #[salsa::interned] 79 #[salsa::interned]
80 fn intern_type_ctor(&self, type_ctor: TypeCtor) -> crate::TypeCtorId;
81 #[salsa::interned]
82 fn intern_callable_def(&self, callable_def: CallableDef) -> crate::CallableDefId; 80 fn intern_callable_def(&self, callable_def: CallableDef) -> crate::CallableDefId;
83 #[salsa::interned] 81 #[salsa::interned]
84 fn intern_type_param_id(&self, param_id: TypeParamId) -> GlobalTypeParamId; 82 fn intern_type_param_id(&self, param_id: TypeParamId) -> GlobalTypeParamId;
85 #[salsa::interned] 83 #[salsa::interned]
86 fn intern_impl_trait_id(&self, id: OpaqueTyId) -> InternedOpaqueTyId; 84 fn intern_impl_trait_id(&self, id: OpaqueTyId) -> InternedOpaqueTyId;
87 #[salsa::interned] 85 #[salsa::interned]
88 fn intern_chalk_impl(&self, impl_: Impl) -> crate::traits::GlobalImplId; 86 fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> ClosureId;
89 #[salsa::interned]
90 fn intern_assoc_ty_value(&self, assoc_ty_value: AssocTyValue) -> crate::traits::AssocTyValueId;
91 87
92 #[salsa::invoke(chalk::associated_ty_data_query)] 88 #[salsa::invoke(chalk::associated_ty_data_query)]
93 fn associated_ty_data(&self, id: chalk::AssocTypeId) -> Arc<chalk::AssociatedTyDatum>; 89 fn associated_ty_data(&self, id: chalk::AssocTypeId) -> Arc<chalk::AssociatedTyDatum>;
@@ -151,3 +147,7 @@ impl_intern_key!(GlobalTypeParamId);
151#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 147#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
152pub struct InternedOpaqueTyId(salsa::InternId); 148pub struct InternedOpaqueTyId(salsa::InternId);
153impl_intern_key!(InternedOpaqueTyId); 149impl_intern_key!(InternedOpaqueTyId);
150
151#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
152pub struct ClosureId(salsa::InternId);
153impl_intern_key!(ClosureId);
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index c4c24a83b..9f034eca5 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -112,6 +112,7 @@ pub enum TypeCtor {
112 /// fn foo() -> i32 { 1 } 112 /// fn foo() -> i32 { 1 }
113 /// let bar: fn() -> i32 = foo; 113 /// let bar: fn() -> i32 = foo;
114 /// ``` 114 /// ```
115 // FIXME make this a Ty variant like in Chalk
115 FnPtr { num_args: u16, is_varargs: bool }, 116 FnPtr { num_args: u16, is_varargs: bool },
116 117
117 /// The never type `!`. 118 /// The never type `!`.
@@ -139,13 +140,6 @@ pub enum TypeCtor {
139 Closure { def: DefWithBodyId, expr: ExprId }, 140 Closure { def: DefWithBodyId, expr: ExprId },
140} 141}
141 142
142/// This exists just for Chalk, because Chalk just has a single `StructId` where
143/// we have different kinds of ADTs, primitive types and special type
144/// constructors like tuples and function pointers.
145#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
146pub struct TypeCtorId(salsa::InternId);
147impl_intern_key!(TypeCtorId);
148
149/// This exists just for Chalk, because Chalk just has a single `FnDefId` where 143/// This exists just for Chalk, because Chalk just has a single `FnDefId` where
150/// we have different IDs for struct and enum variant constructors. 144/// we have different IDs for struct and enum variant constructors.
151#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] 145#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs
index d57b3f288..c972bf845 100644
--- a/crates/ra_hir_ty/src/tests.rs
+++ b/crates/ra_hir_ty/src/tests.rs
@@ -40,7 +40,11 @@ fn setup_tracing() -> tracing::subscriber::DefaultGuard {
40 use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry}; 40 use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry};
41 use tracing_tree::HierarchicalLayer; 41 use tracing_tree::HierarchicalLayer;
42 let filter = EnvFilter::from_env("CHALK_DEBUG"); 42 let filter = EnvFilter::from_env("CHALK_DEBUG");
43 let layer = HierarchicalLayer::default().with_indent_amount(2).with_writer(std::io::stderr); 43 let layer = HierarchicalLayer::default()
44 .with_indent_lines(true)
45 .with_ansi(false)
46 .with_indent_amount(2)
47 .with_writer(std::io::stderr);
44 let subscriber = Registry::default().with(filter).with(layer); 48 let subscriber = Registry::default().with(filter).with(layer);
45 tracing::subscriber::set_default(subscriber) 49 tracing::subscriber::set_default(subscriber)
46} 50}
diff --git a/crates/ra_hir_ty/src/traits.rs b/crates/ra_hir_ty/src/traits.rs
index f7edb4c8b..3f6d2cf35 100644
--- a/crates/ra_hir_ty/src/traits.rs
+++ b/crates/ra_hir_ty/src/traits.rs
@@ -3,10 +3,8 @@ use std::sync::Arc;
3 3
4use chalk_ir::cast::Cast; 4use chalk_ir::cast::Cast;
5use chalk_solve::Solver; 5use chalk_solve::Solver;
6use hir_def::{ 6use hir_def::{lang_item::LangItemTarget, TraitId};
7 expr::ExprId, lang_item::LangItemTarget, DefWithBodyId, ImplId, TraitId, TypeAliasId, 7use ra_db::CrateId;
8};
9use ra_db::{impl_intern_key, salsa, CrateId};
10use ra_prof::profile; 8use ra_prof::profile;
11 9
12use crate::{db::HirDatabase, DebruijnIndex, Substs}; 10use crate::{db::HirDatabase, DebruijnIndex, Substs};
@@ -16,7 +14,6 @@ use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty,
16use self::chalk::{from_chalk, Interner, ToChalk}; 14use self::chalk::{from_chalk, Interner, ToChalk};
17 15
18pub(crate) mod chalk; 16pub(crate) mod chalk;
19mod builtin;
20 17
21// This controls the maximum size of types Chalk considers. If we set this too 18// This controls the maximum size of types Chalk considers. If we set this too
22// high, we can run into slow edge cases; if we set it too low, Chalk won't 19// high, we can run into slow edge cases; if we set it too low, Chalk won't
@@ -274,47 +271,3 @@ impl FnTrait {
274 } 271 }
275 } 272 }
276} 273}
277
278#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
279pub struct ClosureFnTraitImplData {
280 def: DefWithBodyId,
281 expr: ExprId,
282 fn_trait: FnTrait,
283}
284
285#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
286pub struct UnsizeToSuperTraitObjectData {
287 trait_: TraitId,
288 super_trait: TraitId,
289}
290
291/// An impl. Usually this comes from an impl block, but some built-in types get
292/// synthetic impls.
293#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
294pub enum Impl {
295 /// A normal impl from an impl block.
296 ImplDef(ImplId),
297 /// Closure types implement the Fn traits synthetically.
298 // FIXME: implement closure support from Chalk, remove this
299 ClosureFnTraitImpl(ClosureFnTraitImplData),
300}
301/// This exists just for Chalk, because our ImplIds are only unique per module.
302#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
303pub struct GlobalImplId(salsa::InternId);
304impl_intern_key!(GlobalImplId);
305
306/// An associated type value. Usually this comes from a `type` declaration
307/// inside an impl block, but for built-in impls we have to synthesize it.
308/// (We only need this because Chalk wants a unique ID for each of these.)
309#[derive(Debug, Clone, PartialEq, Eq, Hash)]
310pub enum AssocTyValue {
311 /// A normal assoc type value from an impl block.
312 TypeAlias(TypeAliasId),
313 /// The output type of the Fn trait implementation.
314 ClosureFnTraitImplOutput(ClosureFnTraitImplData),
315}
316/// This exists just for Chalk, because it needs a unique ID for each associated
317/// type value in an impl (even synthetic ones).
318#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
319pub struct AssocTyValueId(salsa::InternId);
320impl_intern_key!(AssocTyValueId);
diff --git a/crates/ra_hir_ty/src/traits/builtin.rs b/crates/ra_hir_ty/src/traits/builtin.rs
deleted file mode 100644
index 60cc9a9f5..000000000
--- a/crates/ra_hir_ty/src/traits/builtin.rs
+++ /dev/null
@@ -1,178 +0,0 @@
1//! This module provides the built-in trait implementations, e.g. to make
2//! closures implement `Fn`.
3use hir_def::{expr::Expr, TraitId, TypeAliasId};
4use hir_expand::name::name;
5use ra_db::CrateId;
6
7use super::{AssocTyValue, Impl};
8use crate::{
9 db::HirDatabase, ApplicationTy, BoundVar, DebruijnIndex, Substs, TraitRef, Ty, TypeCtor,
10};
11
12pub(super) struct BuiltinImplData {
13 pub num_vars: usize,
14 pub trait_ref: TraitRef,
15 pub where_clauses: Vec<super::GenericPredicate>,
16 pub assoc_ty_values: Vec<AssocTyValue>,
17}
18
19pub(super) struct BuiltinImplAssocTyValueData {
20 pub impl_: Impl,
21 pub assoc_ty_id: TypeAliasId,
22 pub num_vars: usize,
23 pub value: Ty,
24}
25
26pub(super) fn get_builtin_impls(
27 db: &dyn HirDatabase,
28 krate: CrateId,
29 ty: &Ty,
30 // The first argument for the trait, if present
31 _arg: &Option<Ty>,
32 trait_: TraitId,
33 mut callback: impl FnMut(Impl),
34) {
35 // Note: since impl_datum needs to be infallible, we need to make sure here
36 // that we have all prerequisites to build the respective impls.
37 if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { def, expr }, .. }) = ty {
38 for &fn_trait in [super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter()
39 {
40 if let Some(actual_trait) = fn_trait.get_id(db, krate) {
41 if trait_ == actual_trait {
42 let impl_ = super::ClosureFnTraitImplData { def: *def, expr: *expr, fn_trait };
43 if check_closure_fn_trait_impl_prerequisites(db, krate, impl_) {
44 callback(Impl::ClosureFnTraitImpl(impl_));
45 }
46 }
47 }
48 }
49 }
50}
51
52pub(super) fn impl_datum(db: &dyn HirDatabase, krate: CrateId, impl_: Impl) -> BuiltinImplData {
53 match impl_ {
54 Impl::ImplDef(_) => unreachable!(),
55 Impl::ClosureFnTraitImpl(data) => closure_fn_trait_impl_datum(db, krate, data),
56 }
57}
58
59pub(super) fn associated_ty_value(
60 db: &dyn HirDatabase,
61 krate: CrateId,
62 data: AssocTyValue,
63) -> BuiltinImplAssocTyValueData {
64 match data {
65 AssocTyValue::TypeAlias(_) => unreachable!(),
66 AssocTyValue::ClosureFnTraitImplOutput(data) => {
67 closure_fn_trait_output_assoc_ty_value(db, krate, data)
68 }
69 }
70}
71
72// Closure Fn trait impls
73
74fn check_closure_fn_trait_impl_prerequisites(
75 db: &dyn HirDatabase,
76 krate: CrateId,
77 data: super::ClosureFnTraitImplData,
78) -> bool {
79 // the respective Fn/FnOnce/FnMut trait needs to exist
80 if data.fn_trait.get_id(db, krate).is_none() {
81 return false;
82 }
83
84 // FIXME: there are more assumptions that we should probably check here:
85 // the traits having no type params, FnOnce being a supertrait
86
87 // the FnOnce trait needs to exist and have an assoc type named Output
88 let fn_once_trait = match (super::FnTrait::FnOnce).get_id(db, krate) {
89 Some(t) => t,
90 None => return false,
91 };
92 db.trait_data(fn_once_trait).associated_type_by_name(&name![Output]).is_some()
93}
94
95fn closure_fn_trait_impl_datum(
96 db: &dyn HirDatabase,
97 krate: CrateId,
98 data: super::ClosureFnTraitImplData,
99) -> BuiltinImplData {
100 // for some closure |X, Y| -> Z:
101 // impl<T, U, V> Fn<(T, U)> for closure<fn(T, U) -> V> { Output = V }
102
103 let trait_ = data
104 .fn_trait
105 .get_id(db, krate) // get corresponding fn trait
106 // the existence of the Fn trait has been checked before
107 .expect("fn trait for closure impl missing");
108
109 let num_args: u16 = match &db.body(data.def)[data.expr] {
110 Expr::Lambda { args, .. } => args.len() as u16,
111 _ => {
112 log::warn!("closure for closure type {:?} not found", data);
113 0
114 }
115 };
116
117 let arg_ty = Ty::apply(
118 TypeCtor::Tuple { cardinality: num_args },
119 Substs::builder(num_args as usize)
120 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
121 .build(),
122 );
123 let sig_ty = Ty::apply(
124 TypeCtor::FnPtr { num_args, is_varargs: false },
125 Substs::builder(num_args as usize + 1)
126 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
127 .build(),
128 );
129
130 let self_ty = Ty::apply_one(TypeCtor::Closure { def: data.def, expr: data.expr }, sig_ty);
131
132 let trait_ref = TraitRef {
133 trait_,
134 substs: Substs::build_for_def(db, trait_).push(self_ty).push(arg_ty).build(),
135 };
136
137 let output_ty_id = AssocTyValue::ClosureFnTraitImplOutput(data);
138
139 BuiltinImplData {
140 num_vars: num_args as usize + 1,
141 trait_ref,
142 where_clauses: Vec::new(),
143 assoc_ty_values: vec![output_ty_id],
144 }
145}
146
147fn closure_fn_trait_output_assoc_ty_value(
148 db: &dyn HirDatabase,
149 krate: CrateId,
150 data: super::ClosureFnTraitImplData,
151) -> BuiltinImplAssocTyValueData {
152 let impl_ = Impl::ClosureFnTraitImpl(data);
153
154 let num_args: u16 = match &db.body(data.def)[data.expr] {
155 Expr::Lambda { args, .. } => args.len() as u16,
156 _ => {
157 log::warn!("closure for closure type {:?} not found", data);
158 0
159 }
160 };
161
162 let output_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, num_args.into()));
163
164 let fn_once_trait =
165 (super::FnTrait::FnOnce).get_id(db, krate).expect("assoc ty value should not exist");
166
167 let output_ty_id = db
168 .trait_data(fn_once_trait)
169 .associated_type_by_name(&name![Output])
170 .expect("assoc ty value should not exist");
171
172 BuiltinImplAssocTyValueData {
173 impl_,
174 assoc_ty_id: output_ty_id,
175 num_vars: num_args as usize + 1,
176 value: output_ty,
177 }
178}
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index c448aea65..1ef5baa05 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -12,15 +12,17 @@ use hir_def::{
12}; 12};
13use ra_db::{salsa::InternKey, CrateId}; 13use ra_db::{salsa::InternKey, CrateId};
14 14
15use super::{builtin, AssocTyValue, ChalkContext, Impl}; 15use super::ChalkContext;
16use crate::{ 16use crate::{
17 db::HirDatabase, 17 db::HirDatabase,
18 display::HirDisplay, 18 display::HirDisplay,
19 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, 19 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
20 utils::generics, 20 utils::generics,
21 CallableDef, DebruijnIndex, GenericPredicate, Substs, Ty, TypeCtor, 21 CallableDef, DebruijnIndex, FnSig, GenericPredicate, Substs, Ty, TypeCtor,
22};
23use mapping::{
24 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
22}; 25};
23use mapping::{convert_where_clauses, generic_predicate_to_inline_bound, make_binders};
24 26
25pub use self::interner::*; 27pub use self::interner::*;
26 28
@@ -102,9 +104,9 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
102 let in_self = self.db.trait_impls_in_crate(self.krate); 104 let in_self = self.db.trait_impls_in_crate(self.krate);
103 let impl_maps = [in_deps, in_self]; 105 let impl_maps = [in_deps, in_self];
104 106
105 let id_to_chalk = |id: hir_def::ImplId| Impl::ImplDef(id).to_chalk(self.db); 107 let id_to_chalk = |id: hir_def::ImplId| id.to_chalk(self.db);
106 108
107 let mut result: Vec<_> = if fps.is_empty() { 109 let result: Vec<_> = if fps.is_empty() {
108 debug!("Unrestricted search for {:?} impls...", trait_); 110 debug!("Unrestricted search for {:?} impls...", trait_);
109 impl_maps 111 impl_maps
110 .iter() 112 .iter()
@@ -121,13 +123,6 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
121 .collect() 123 .collect()
122 }; 124 };
123 125
124 let arg: Option<Ty> =
125 parameters.get(1).map(|p| from_chalk(self.db, p.assert_ty_ref(&Interner).clone()));
126
127 builtin::get_builtin_impls(self.db, self.krate, &ty, &arg, trait_, |i| {
128 result.push(i.to_chalk(self.db))
129 });
130
131 debug!("impls_for_trait returned {} impls", result.len()); 126 debug!("impls_for_trait returned {} impls", result.len());
132 result 127 result
133 } 128 }
@@ -217,32 +212,40 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
217 _closure_id: chalk_ir::ClosureId<Interner>, 212 _closure_id: chalk_ir::ClosureId<Interner>,
218 _substs: &chalk_ir::Substitution<Interner>, 213 _substs: &chalk_ir::Substitution<Interner>,
219 ) -> rust_ir::ClosureKind { 214 ) -> rust_ir::ClosureKind {
220 // FIXME: implement closure support 215 // Fn is the closure kind that implements all three traits
221 unimplemented!() 216 rust_ir::ClosureKind::Fn
222 } 217 }
223 fn closure_inputs_and_output( 218 fn closure_inputs_and_output(
224 &self, 219 &self,
225 _closure_id: chalk_ir::ClosureId<Interner>, 220 _closure_id: chalk_ir::ClosureId<Interner>,
226 _substs: &chalk_ir::Substitution<Interner>, 221 substs: &chalk_ir::Substitution<Interner>,
227 ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> { 222 ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> {
228 // FIXME: implement closure support 223 let sig_ty: Ty =
229 unimplemented!() 224 from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone());
225 let sig = FnSig::from_fn_ptr_substs(
226 &sig_ty.substs().expect("first closure param should be fn ptr"),
227 false,
228 );
229 let io = rust_ir::FnDefInputsAndOutputDatum {
230 argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(),
231 return_type: sig.ret().clone().to_chalk(self.db),
232 };
233 make_binders(io.shifted_in(&Interner), 0)
230 } 234 }
231 fn closure_upvars( 235 fn closure_upvars(
232 &self, 236 &self,
233 _closure_id: chalk_ir::ClosureId<Interner>, 237 _closure_id: chalk_ir::ClosureId<Interner>,
234 _substs: &chalk_ir::Substitution<Interner>, 238 _substs: &chalk_ir::Substitution<Interner>,
235 ) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> { 239 ) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> {
236 // FIXME: implement closure support 240 let ty = Ty::unit().to_chalk(self.db);
237 unimplemented!() 241 make_binders(ty, 0)
238 } 242 }
239 fn closure_fn_substitution( 243 fn closure_fn_substitution(
240 &self, 244 &self,
241 _closure_id: chalk_ir::ClosureId<Interner>, 245 _closure_id: chalk_ir::ClosureId<Interner>,
242 _substs: &chalk_ir::Substitution<Interner>, 246 _substs: &chalk_ir::Substitution<Interner>,
243 ) -> chalk_ir::Substitution<Interner> { 247 ) -> chalk_ir::Substitution<Interner> {
244 // FIXME: implement closure support 248 Substs::empty().to_chalk(self.db)
245 unimplemented!()
246 } 249 }
247 250
248 fn trait_name(&self, _trait_id: chalk_ir::TraitId<Interner>) -> String { 251 fn trait_name(&self, _trait_id: chalk_ir::TraitId<Interner>) -> String {
@@ -417,11 +420,8 @@ pub(crate) fn impl_datum_query(
417) -> Arc<ImplDatum> { 420) -> Arc<ImplDatum> {
418 let _p = ra_prof::profile("impl_datum"); 421 let _p = ra_prof::profile("impl_datum");
419 debug!("impl_datum {:?}", impl_id); 422 debug!("impl_datum {:?}", impl_id);
420 let impl_: Impl = from_chalk(db, impl_id); 423 let impl_: hir_def::ImplId = from_chalk(db, impl_id);
421 match impl_ { 424 impl_def_datum(db, krate, impl_id, impl_)
422 Impl::ImplDef(impl_def) => impl_def_datum(db, krate, impl_id, impl_def),
423 _ => Arc::new(builtin::impl_datum(db, krate, impl_).to_chalk(db)),
424 }
425} 425}
426 426
427fn impl_def_datum( 427fn impl_def_datum(
@@ -472,7 +472,7 @@ fn impl_def_datum(
472 let name = &db.type_alias_data(type_alias).name; 472 let name = &db.type_alias_data(type_alias).name;
473 trait_data.associated_type_by_name(name).is_some() 473 trait_data.associated_type_by_name(name).is_some()
474 }) 474 })
475 .map(|type_alias| AssocTyValue::TypeAlias(type_alias).to_chalk(db)) 475 .map(|type_alias| TypeAliasAsValue(type_alias).to_chalk(db))
476 .collect(); 476 .collect();
477 debug!("impl_datum: {:?}", impl_datum_bound); 477 debug!("impl_datum: {:?}", impl_datum_bound);
478 let impl_datum = ImplDatum { 478 let impl_datum = ImplDatum {
@@ -489,13 +489,8 @@ pub(crate) fn associated_ty_value_query(
489 krate: CrateId, 489 krate: CrateId,
490 id: AssociatedTyValueId, 490 id: AssociatedTyValueId,
491) -> Arc<AssociatedTyValue> { 491) -> Arc<AssociatedTyValue> {
492 let data: AssocTyValue = from_chalk(db, id); 492 let type_alias: TypeAliasAsValue = from_chalk(db, id);
493 match data { 493 type_alias_associated_ty_value(db, krate, type_alias.0)
494 AssocTyValue::TypeAlias(type_alias) => {
495 type_alias_associated_ty_value(db, krate, type_alias)
496 }
497 _ => Arc::new(builtin::associated_ty_value(db, krate, data).to_chalk(db)),
498 }
499} 494}
500 495
501fn type_alias_associated_ty_value( 496fn type_alias_associated_ty_value(
@@ -518,7 +513,7 @@ fn type_alias_associated_ty_value(
518 let ty = db.ty(type_alias.into()); 513 let ty = db.ty(type_alias.into());
519 let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) }; 514 let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) };
520 let value = rust_ir::AssociatedTyValue { 515 let value = rust_ir::AssociatedTyValue {
521 impl_id: Impl::ImplDef(impl_id).to_chalk(db), 516 impl_id: impl_id.to_chalk(db),
522 associated_ty_id: assoc_ty.to_chalk(db), 517 associated_ty_id: assoc_ty.to_chalk(db),
523 value: make_binders(value_bound, ty.num_binders), 518 value: make_binders(value_bound, ty.num_binders),
524 }; 519 };
@@ -557,18 +552,6 @@ pub(crate) fn fn_def_datum_query(
557 Arc::new(datum) 552 Arc::new(datum)
558} 553}
559 554
560impl From<AdtId> for crate::TypeCtorId {
561 fn from(struct_id: AdtId) -> Self {
562 struct_id.0
563 }
564}
565
566impl From<crate::TypeCtorId> for AdtId {
567 fn from(type_ctor_id: crate::TypeCtorId) -> Self {
568 chalk_ir::AdtId(type_ctor_id)
569 }
570}
571
572impl From<FnDefId> for crate::CallableDefId { 555impl From<FnDefId> for crate::CallableDefId {
573 fn from(fn_def_id: FnDefId) -> Self { 556 fn from(fn_def_id: FnDefId) -> Self {
574 InternKey::from_intern_id(fn_def_id.0) 557 InternKey::from_intern_id(fn_def_id.0)
@@ -581,18 +564,6 @@ impl From<crate::CallableDefId> for FnDefId {
581 } 564 }
582} 565}
583 566
584impl From<ImplId> for crate::traits::GlobalImplId {
585 fn from(impl_id: ImplId) -> Self {
586 InternKey::from_intern_id(impl_id.0)
587 }
588}
589
590impl From<crate::traits::GlobalImplId> for ImplId {
591 fn from(impl_id: crate::traits::GlobalImplId) -> Self {
592 chalk_ir::ImplId(impl_id.as_intern_id())
593 }
594}
595
596impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId { 567impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId {
597 fn from(id: OpaqueTyId) -> Self { 568 fn from(id: OpaqueTyId) -> Self {
598 InternKey::from_intern_id(id.0) 569 InternKey::from_intern_id(id.0)
@@ -605,14 +576,14 @@ impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId {
605 } 576 }
606} 577}
607 578
608impl From<rust_ir::AssociatedTyValueId<Interner>> for crate::traits::AssocTyValueId { 579impl From<chalk_ir::ClosureId<Interner>> for crate::db::ClosureId {
609 fn from(id: rust_ir::AssociatedTyValueId<Interner>) -> Self { 580 fn from(id: chalk_ir::ClosureId<Interner>) -> Self {
610 Self::from_intern_id(id.0) 581 Self::from_intern_id(id.0)
611 } 582 }
612} 583}
613 584
614impl From<crate::traits::AssocTyValueId> for rust_ir::AssociatedTyValueId<Interner> { 585impl From<crate::db::ClosureId> for chalk_ir::ClosureId<Interner> {
615 fn from(assoc_ty_value_id: crate::traits::AssocTyValueId) -> Self { 586 fn from(id: crate::db::ClosureId) -> Self {
616 rust_ir::AssociatedTyValueId(assoc_ty_value_id.as_intern_id()) 587 chalk_ir::ClosureId(id.as_intern_id())
617 } 588 }
618} 589}
diff --git a/crates/ra_hir_ty/src/traits/chalk/interner.rs b/crates/ra_hir_ty/src/traits/chalk/interner.rs
index 156b691b4..8d4c51a8f 100644
--- a/crates/ra_hir_ty/src/traits/chalk/interner.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/interner.rs
@@ -41,7 +41,7 @@ impl chalk_ir::interner::Interner for Interner {
41 type InternedCanonicalVarKinds = Vec<chalk_ir::CanonicalVarKind<Self>>; 41 type InternedCanonicalVarKinds = Vec<chalk_ir::CanonicalVarKind<Self>>;
42 type InternedConstraints = Vec<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>>; 42 type InternedConstraints = Vec<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>>;
43 type DefId = InternId; 43 type DefId = InternId;
44 type InternedAdtId = crate::TypeCtorId; 44 type InternedAdtId = hir_def::AdtId;
45 type Identifier = TypeAliasId; 45 type Identifier = TypeAliasId;
46 type FnAbi = (); 46 type FnAbi = ();
47 47
@@ -364,6 +364,18 @@ impl chalk_ir::interner::Interner for Interner {
364 ) -> &'a [chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>] { 364 ) -> &'a [chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>] {
365 constraints 365 constraints
366 } 366 }
367 fn debug_closure_id(
368 _fn_def_id: chalk_ir::ClosureId<Self>,
369 _fmt: &mut fmt::Formatter<'_>,
370 ) -> Option<fmt::Result> {
371 None
372 }
373 fn debug_constraints(
374 _clauses: &chalk_ir::Constraints<Self>,
375 _fmt: &mut fmt::Formatter<'_>,
376 ) -> Option<fmt::Result> {
377 None
378 }
367} 379}
368 380
369impl chalk_ir::interner::HasInterner for Interner { 381impl chalk_ir::interner::HasInterner for Interner {
diff --git a/crates/ra_hir_ty/src/traits/chalk/mapping.rs b/crates/ra_hir_ty/src/traits/chalk/mapping.rs
index 3ebb55f77..a852ce2ac 100644
--- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/mapping.rs
@@ -15,7 +15,7 @@ use ra_db::salsa::InternKey;
15use crate::{ 15use crate::{
16 db::HirDatabase, 16 db::HirDatabase,
17 primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness}, 17 primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness},
18 traits::{builtin, AssocTyValue, Canonical, Impl, Obligation}, 18 traits::{Canonical, Obligation},
19 ApplicationTy, CallableDef, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, 19 ApplicationTy, CallableDef, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId,
20 ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeCtor, 20 ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeCtor,
21}; 21};
@@ -311,18 +311,24 @@ impl ToChalk for TypeCtor {
311 } 311 }
312 TypeCtor::Never => TypeName::Never, 312 TypeCtor::Never => TypeName::Never,
313 313
314 // FIXME convert these 314 TypeCtor::Closure { def, expr } => {
315 TypeCtor::Adt(_) | TypeCtor::FnPtr { .. } | TypeCtor::Closure { .. } => { 315 let closure_id = db.intern_closure((def, expr));
316 // other TypeCtors get interned and turned into a chalk StructId 316 TypeName::Closure(closure_id.into())
317 let struct_id = db.intern_type_ctor(self).into(); 317 }
318 TypeName::Adt(struct_id) 318
319 TypeCtor::Adt(adt_id) => TypeName::Adt(chalk_ir::AdtId(adt_id)),
320
321 TypeCtor::FnPtr { .. } => {
322 // This should not be reached, since Chalk doesn't represent
323 // function pointers with TypeName
324 unreachable!()
319 } 325 }
320 } 326 }
321 } 327 }
322 328
323 fn from_chalk(db: &dyn HirDatabase, type_name: TypeName<Interner>) -> TypeCtor { 329 fn from_chalk(db: &dyn HirDatabase, type_name: TypeName<Interner>) -> TypeCtor {
324 match type_name { 330 match type_name {
325 TypeName::Adt(struct_id) => db.lookup_intern_type_ctor(struct_id.into()), 331 TypeName::Adt(struct_id) => TypeCtor::Adt(struct_id.0),
326 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)), 332 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)),
327 TypeName::OpaqueType(opaque_type_id) => { 333 TypeName::OpaqueType(opaque_type_id) => {
328 TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)) 334 TypeCtor::OpaqueType(from_chalk(db, opaque_type_id))
@@ -355,13 +361,16 @@ impl ToChalk for TypeCtor {
355 let callable_def = from_chalk(db, fn_def_id); 361 let callable_def = from_chalk(db, fn_def_id);
356 TypeCtor::FnDef(callable_def) 362 TypeCtor::FnDef(callable_def)
357 } 363 }
364 TypeName::Array => TypeCtor::Array,
358 365
359 TypeName::Array | TypeName::Error => { 366 TypeName::Closure(id) => {
360 // this should not be reached, since we don't represent TypeName::Error with TypeCtor 367 let id: crate::db::ClosureId = id.into();
361 unreachable!() 368 let (def, expr) = db.lookup_intern_closure(id);
369 TypeCtor::Closure { def, expr }
362 } 370 }
363 TypeName::Closure(_) => { 371
364 // FIXME: implement closure support 372 TypeName::Error => {
373 // this should not be reached, since we don't represent TypeName::Error with TypeCtor
365 unreachable!() 374 unreachable!()
366 } 375 }
367 } 376 }
@@ -433,15 +442,15 @@ impl ToChalk for Mutability {
433 } 442 }
434} 443}
435 444
436impl ToChalk for Impl { 445impl ToChalk for hir_def::ImplId {
437 type Chalk = ImplId; 446 type Chalk = ImplId;
438 447
439 fn to_chalk(self, db: &dyn HirDatabase) -> ImplId { 448 fn to_chalk(self, _db: &dyn HirDatabase) -> ImplId {
440 db.intern_chalk_impl(self).into() 449 chalk_ir::ImplId(self.as_intern_id())
441 } 450 }
442 451
443 fn from_chalk(db: &dyn HirDatabase, impl_id: ImplId) -> Impl { 452 fn from_chalk(_db: &dyn HirDatabase, impl_id: ImplId) -> hir_def::ImplId {
444 db.lookup_intern_chalk_impl(impl_id.into()) 453 InternKey::from_intern_id(impl_id.0)
445 } 454 }
446} 455}
447 456
@@ -469,15 +478,20 @@ impl ToChalk for TypeAliasId {
469 } 478 }
470} 479}
471 480
472impl ToChalk for AssocTyValue { 481pub struct TypeAliasAsValue(pub TypeAliasId);
482
483impl ToChalk for TypeAliasAsValue {
473 type Chalk = AssociatedTyValueId; 484 type Chalk = AssociatedTyValueId;
474 485
475 fn to_chalk(self, db: &dyn HirDatabase) -> AssociatedTyValueId { 486 fn to_chalk(self, _db: &dyn HirDatabase) -> AssociatedTyValueId {
476 db.intern_assoc_ty_value(self).into() 487 rust_ir::AssociatedTyValueId(self.0.as_intern_id())
477 } 488 }
478 489
479 fn from_chalk(db: &dyn HirDatabase, assoc_ty_value_id: AssociatedTyValueId) -> AssocTyValue { 490 fn from_chalk(
480 db.lookup_intern_assoc_ty_value(assoc_ty_value_id.into()) 491 _db: &dyn HirDatabase,
492 assoc_ty_value_id: AssociatedTyValueId,
493 ) -> TypeAliasAsValue {
494 TypeAliasAsValue(TypeAliasId::from_intern_id(assoc_ty_value_id.0))
481 } 495 }
482} 496}
483 497
@@ -686,52 +700,6 @@ where
686 } 700 }
687} 701}
688 702
689impl ToChalk for builtin::BuiltinImplData {
690 type Chalk = ImplDatum;
691
692 fn to_chalk(self, db: &dyn HirDatabase) -> ImplDatum {
693 let impl_type = rust_ir::ImplType::External;
694 let where_clauses = self.where_clauses.into_iter().map(|w| w.to_chalk(db)).collect();
695
696 let impl_datum_bound =
697 rust_ir::ImplDatumBound { trait_ref: self.trait_ref.to_chalk(db), where_clauses };
698 let associated_ty_value_ids =
699 self.assoc_ty_values.into_iter().map(|v| v.to_chalk(db)).collect();
700 rust_ir::ImplDatum {
701 binders: make_binders(impl_datum_bound, self.num_vars),
702 impl_type,
703 polarity: rust_ir::Polarity::Positive,
704 associated_ty_value_ids,
705 }
706 }
707
708 fn from_chalk(_db: &dyn HirDatabase, _data: ImplDatum) -> Self {
709 unimplemented!()
710 }
711}
712
713impl ToChalk for builtin::BuiltinImplAssocTyValueData {
714 type Chalk = AssociatedTyValue;
715
716 fn to_chalk(self, db: &dyn HirDatabase) -> AssociatedTyValue {
717 let ty = self.value.to_chalk(db);
718 let value_bound = rust_ir::AssociatedTyValueBound { ty };
719
720 rust_ir::AssociatedTyValue {
721 associated_ty_id: self.assoc_ty_id.to_chalk(db),
722 impl_id: self.impl_.to_chalk(db),
723 value: make_binders(value_bound, self.num_vars),
724 }
725 }
726
727 fn from_chalk(
728 _db: &dyn HirDatabase,
729 _data: AssociatedTyValue,
730 ) -> builtin::BuiltinImplAssocTyValueData {
731 unimplemented!()
732 }
733}
734
735pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> 703pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T>
736where 704where
737 T: HasInterner<Interner = Interner>, 705 T: HasInterner<Interner = Interner>,
diff --git a/crates/ra_ide_db/src/change.rs b/crates/ra_ide_db/src/change.rs
index d1a255dcf..a1bb3043b 100644
--- a/crates/ra_ide_db/src/change.rs
+++ b/crates/ra_ide_db/src/change.rs
@@ -279,10 +279,7 @@ impl RootDatabase {
279 hir::db::InternImplQuery 279 hir::db::InternImplQuery
280 280
281 // HirDatabase 281 // HirDatabase
282 hir::db::InternTypeCtorQuery
283 hir::db::InternTypeParamIdQuery 282 hir::db::InternTypeParamIdQuery
284 hir::db::InternChalkImplQuery
285 hir::db::InternAssocTyValueQuery
286 ]; 283 ];
287 284
288 acc.sort_by_key(|it| std::cmp::Reverse(it.1)); 285 acc.sort_by_key(|it| std::cmp::Reverse(it.1));