diff options
author | Florian Diebold <[email protected]> | 2020-07-12 14:26:02 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2020-07-15 21:04:49 +0100 |
commit | a48843a16a2306399f2f6a78c69d9192a6480c88 (patch) | |
tree | 2fbaf1c22c631e9e2278e6a33940ccf6ea98037c /crates | |
parent | b63e23e98e7dfbe57de93ebe256254825512e148 (diff) |
Use Chalk closure support
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir/src/db.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/db.rs | 14 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits.rs | 51 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/builtin.rs | 178 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk.rs | 87 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk/mapping.rs | 97 | ||||
-rw-r--r-- | crates/ra_ide_db/src/change.rs | 2 |
8 files changed, 86 insertions, 355 deletions
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index cb48ca065..3a9973abf 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, InternTypeCtorQuery, InternTypeParamIdQuery, |
21 | InternTypeParamIdQuery, ReturnTypeImplTraitsQuery, StructDatumQuery, TraitDatumQuery, | 21 | ReturnTypeImplTraitsQuery, StructDatumQuery, TraitDatumQuery, TraitImplsInCrateQuery, |
22 | TraitImplsInCrateQuery, TraitImplsInDepsQuery, TraitSolveQuery, TyQuery, ValueTyQuery, | 22 | TraitImplsInDepsQuery, TraitSolveQuery, TyQuery, ValueTyQuery, |
23 | }; | 23 | }; |
24 | 24 | ||
25 | #[test] | 25 | #[test] |
diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs index 84afe0484..d8a798771 100644 --- a/crates/ra_hir_ty/src/db.rs +++ b/crates/ra_hir_ty/src/db.rs | |||
@@ -3,8 +3,8 @@ | |||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::{ | 5 | use 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 | }; |
9 | use ra_arena::map::ArenaMap; | 9 | use ra_arena::map::ArenaMap; |
10 | use ra_db::{impl_intern_key, salsa, CrateId, Upcast}; | 10 | use ra_db::{impl_intern_key, salsa, CrateId, Upcast}; |
@@ -12,7 +12,7 @@ use ra_prof::profile; | |||
12 | 12 | ||
13 | use crate::{ | 13 | use 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, TypeCtor, ValueTyDefId, |
18 | }; | 18 | }; |
@@ -85,9 +85,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> { | |||
85 | #[salsa::interned] | 85 | #[salsa::interned] |
86 | fn intern_impl_trait_id(&self, id: OpaqueTyId) -> InternedOpaqueTyId; | 86 | fn intern_impl_trait_id(&self, id: OpaqueTyId) -> InternedOpaqueTyId; |
87 | #[salsa::interned] | 87 | #[salsa::interned] |
88 | fn intern_chalk_impl(&self, impl_: Impl) -> crate::traits::GlobalImplId; | 88 | 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 | 89 | ||
92 | #[salsa::invoke(chalk::associated_ty_data_query)] | 90 | #[salsa::invoke(chalk::associated_ty_data_query)] |
93 | fn associated_ty_data(&self, id: chalk::AssocTypeId) -> Arc<chalk::AssociatedTyDatum>; | 91 | fn associated_ty_data(&self, id: chalk::AssocTypeId) -> Arc<chalk::AssociatedTyDatum>; |
@@ -151,3 +149,7 @@ impl_intern_key!(GlobalTypeParamId); | |||
151 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 149 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
152 | pub struct InternedOpaqueTyId(salsa::InternId); | 150 | pub struct InternedOpaqueTyId(salsa::InternId); |
153 | impl_intern_key!(InternedOpaqueTyId); | 151 | impl_intern_key!(InternedOpaqueTyId); |
152 | |||
153 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
154 | pub struct ClosureId(salsa::InternId); | ||
155 | impl_intern_key!(ClosureId); | ||
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 | ||
4 | use chalk_ir::cast::Cast; | 4 | use chalk_ir::cast::Cast; |
5 | use chalk_solve::Solver; | 5 | use chalk_solve::Solver; |
6 | use hir_def::{ | 6 | use hir_def::{lang_item::LangItemTarget, TraitId}; |
7 | expr::ExprId, lang_item::LangItemTarget, DefWithBodyId, ImplId, TraitId, TypeAliasId, | 7 | use ra_db::CrateId; |
8 | }; | ||
9 | use ra_db::{impl_intern_key, salsa, CrateId}; | ||
10 | use ra_prof::profile; | 8 | use ra_prof::profile; |
11 | 9 | ||
12 | use crate::{db::HirDatabase, DebruijnIndex, Substs}; | 10 | use crate::{db::HirDatabase, DebruijnIndex, Substs}; |
@@ -16,7 +14,6 @@ use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, | |||
16 | use self::chalk::{from_chalk, Interner, ToChalk}; | 14 | use self::chalk::{from_chalk, Interner, ToChalk}; |
17 | 15 | ||
18 | pub(crate) mod chalk; | 16 | pub(crate) mod chalk; |
19 | mod 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)] | ||
279 | pub struct ClosureFnTraitImplData { | ||
280 | def: DefWithBodyId, | ||
281 | expr: ExprId, | ||
282 | fn_trait: FnTrait, | ||
283 | } | ||
284 | |||
285 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
286 | pub 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)] | ||
294 | pub 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)] | ||
303 | pub struct GlobalImplId(salsa::InternId); | ||
304 | impl_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)] | ||
310 | pub 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)] | ||
319 | pub struct AssocTyValueId(salsa::InternId); | ||
320 | impl_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`. | ||
3 | use hir_def::{expr::Expr, TraitId, TypeAliasId}; | ||
4 | use hir_expand::name::name; | ||
5 | use ra_db::CrateId; | ||
6 | |||
7 | use super::{AssocTyValue, Impl}; | ||
8 | use crate::{ | ||
9 | db::HirDatabase, ApplicationTy, BoundVar, DebruijnIndex, Substs, TraitRef, Ty, TypeCtor, | ||
10 | }; | ||
11 | |||
12 | pub(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 | |||
19 | pub(super) struct BuiltinImplAssocTyValueData { | ||
20 | pub impl_: Impl, | ||
21 | pub assoc_ty_id: TypeAliasId, | ||
22 | pub num_vars: usize, | ||
23 | pub value: Ty, | ||
24 | } | ||
25 | |||
26 | pub(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 | |||
52 | pub(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 | |||
59 | pub(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 | |||
74 | fn 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 | |||
95 | fn 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 | |||
147 | fn 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..7f8ba2f12 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 | }; |
13 | use ra_db::{salsa::InternKey, CrateId}; | 13 | use ra_db::{salsa::InternKey, CrateId}; |
14 | 14 | ||
15 | use super::{builtin, AssocTyValue, ChalkContext, Impl}; | 15 | use super::ChalkContext; |
16 | use crate::{ | 16 | use 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 | }; | ||
23 | use mapping::{ | ||
24 | convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, | ||
22 | }; | 25 | }; |
23 | use mapping::{convert_where_clauses, generic_predicate_to_inline_bound, make_binders}; | ||
24 | 26 | ||
25 | pub use self::interner::*; | 27 | pub 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 | ||
427 | fn impl_def_datum( | 427 | fn 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 | ||
501 | fn type_alias_associated_ty_value( | 496 | fn 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 | }; |
@@ -581,18 +576,6 @@ impl From<crate::CallableDefId> for FnDefId { | |||
581 | } | 576 | } |
582 | } | 577 | } |
583 | 578 | ||
584 | impl From<ImplId> for crate::traits::GlobalImplId { | ||
585 | fn from(impl_id: ImplId) -> Self { | ||
586 | InternKey::from_intern_id(impl_id.0) | ||
587 | } | ||
588 | } | ||
589 | |||
590 | impl 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 | |||
596 | impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId { | 579 | impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId { |
597 | fn from(id: OpaqueTyId) -> Self { | 580 | fn from(id: OpaqueTyId) -> Self { |
598 | InternKey::from_intern_id(id.0) | 581 | InternKey::from_intern_id(id.0) |
@@ -605,14 +588,14 @@ impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId { | |||
605 | } | 588 | } |
606 | } | 589 | } |
607 | 590 | ||
608 | impl From<rust_ir::AssociatedTyValueId<Interner>> for crate::traits::AssocTyValueId { | 591 | impl From<chalk_ir::ClosureId<Interner>> for crate::db::ClosureId { |
609 | fn from(id: rust_ir::AssociatedTyValueId<Interner>) -> Self { | 592 | fn from(id: chalk_ir::ClosureId<Interner>) -> Self { |
610 | Self::from_intern_id(id.0) | 593 | Self::from_intern_id(id.0) |
611 | } | 594 | } |
612 | } | 595 | } |
613 | 596 | ||
614 | impl From<crate::traits::AssocTyValueId> for rust_ir::AssociatedTyValueId<Interner> { | 597 | impl From<crate::db::ClosureId> for chalk_ir::ClosureId<Interner> { |
615 | fn from(assoc_ty_value_id: crate::traits::AssocTyValueId) -> Self { | 598 | fn from(id: crate::db::ClosureId) -> Self { |
616 | rust_ir::AssociatedTyValueId(assoc_ty_value_id.as_intern_id()) | 599 | chalk_ir::ClosureId(id.as_intern_id()) |
617 | } | 600 | } |
618 | } | 601 | } |
diff --git a/crates/ra_hir_ty/src/traits/chalk/mapping.rs b/crates/ra_hir_ty/src/traits/chalk/mapping.rs index 3ebb55f77..796947e69 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; | |||
15 | use crate::{ | 15 | use 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,8 +311,15 @@ 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 | TypeName::Closure(closure_id.into()) | ||
317 | } | ||
318 | |||
319 | TypeCtor::FnPtr { .. } => panic!("Trying to convert FnPtr to TypeName"), | ||
320 | |||
321 | TypeCtor::Adt(_) => { | ||
322 | // FIXME no interning needed anymore | ||
316 | // other TypeCtors get interned and turned into a chalk StructId | 323 | // other TypeCtors get interned and turned into a chalk StructId |
317 | let struct_id = db.intern_type_ctor(self).into(); | 324 | let struct_id = db.intern_type_ctor(self).into(); |
318 | TypeName::Adt(struct_id) | 325 | TypeName::Adt(struct_id) |
@@ -355,13 +362,16 @@ impl ToChalk for TypeCtor { | |||
355 | let callable_def = from_chalk(db, fn_def_id); | 362 | let callable_def = from_chalk(db, fn_def_id); |
356 | TypeCtor::FnDef(callable_def) | 363 | TypeCtor::FnDef(callable_def) |
357 | } | 364 | } |
365 | TypeName::Array => TypeCtor::Array, | ||
358 | 366 | ||
359 | TypeName::Array | TypeName::Error => { | 367 | TypeName::Closure(id) => { |
360 | // this should not be reached, since we don't represent TypeName::Error with TypeCtor | 368 | let id: crate::db::ClosureId = id.into(); |
361 | unreachable!() | 369 | let (def, expr) = db.lookup_intern_closure(id); |
370 | TypeCtor::Closure { def, expr } | ||
362 | } | 371 | } |
363 | TypeName::Closure(_) => { | 372 | |
364 | // FIXME: implement closure support | 373 | TypeName::Error => { |
374 | // this should not be reached, since we don't represent TypeName::Error with TypeCtor | ||
365 | unreachable!() | 375 | unreachable!() |
366 | } | 376 | } |
367 | } | 377 | } |
@@ -433,15 +443,15 @@ impl ToChalk for Mutability { | |||
433 | } | 443 | } |
434 | } | 444 | } |
435 | 445 | ||
436 | impl ToChalk for Impl { | 446 | impl ToChalk for hir_def::ImplId { |
437 | type Chalk = ImplId; | 447 | type Chalk = ImplId; |
438 | 448 | ||
439 | fn to_chalk(self, db: &dyn HirDatabase) -> ImplId { | 449 | fn to_chalk(self, _db: &dyn HirDatabase) -> ImplId { |
440 | db.intern_chalk_impl(self).into() | 450 | chalk_ir::ImplId(self.as_intern_id()) |
441 | } | 451 | } |
442 | 452 | ||
443 | fn from_chalk(db: &dyn HirDatabase, impl_id: ImplId) -> Impl { | 453 | fn from_chalk(_db: &dyn HirDatabase, impl_id: ImplId) -> hir_def::ImplId { |
444 | db.lookup_intern_chalk_impl(impl_id.into()) | 454 | InternKey::from_intern_id(impl_id.0) |
445 | } | 455 | } |
446 | } | 456 | } |
447 | 457 | ||
@@ -469,15 +479,20 @@ impl ToChalk for TypeAliasId { | |||
469 | } | 479 | } |
470 | } | 480 | } |
471 | 481 | ||
472 | impl ToChalk for AssocTyValue { | 482 | pub struct TypeAliasAsValue(pub TypeAliasId); |
483 | |||
484 | impl ToChalk for TypeAliasAsValue { | ||
473 | type Chalk = AssociatedTyValueId; | 485 | type Chalk = AssociatedTyValueId; |
474 | 486 | ||
475 | fn to_chalk(self, db: &dyn HirDatabase) -> AssociatedTyValueId { | 487 | fn to_chalk(self, _db: &dyn HirDatabase) -> AssociatedTyValueId { |
476 | db.intern_assoc_ty_value(self).into() | 488 | rust_ir::AssociatedTyValueId(self.0.as_intern_id()) |
477 | } | 489 | } |
478 | 490 | ||
479 | fn from_chalk(db: &dyn HirDatabase, assoc_ty_value_id: AssociatedTyValueId) -> AssocTyValue { | 491 | fn from_chalk( |
480 | db.lookup_intern_assoc_ty_value(assoc_ty_value_id.into()) | 492 | _db: &dyn HirDatabase, |
493 | assoc_ty_value_id: AssociatedTyValueId, | ||
494 | ) -> TypeAliasAsValue { | ||
495 | TypeAliasAsValue(TypeAliasId::from_intern_id(assoc_ty_value_id.0)) | ||
481 | } | 496 | } |
482 | } | 497 | } |
483 | 498 | ||
@@ -686,52 +701,6 @@ where | |||
686 | } | 701 | } |
687 | } | 702 | } |
688 | 703 | ||
689 | impl 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 | |||
713 | impl 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 | |||
735 | pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> | 704 | pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> |
736 | where | 705 | where |
737 | T: HasInterner<Interner = Interner>, | 706 | T: HasInterner<Interner = Interner>, |
diff --git a/crates/ra_ide_db/src/change.rs b/crates/ra_ide_db/src/change.rs index d1a255dcf..d40cfeb02 100644 --- a/crates/ra_ide_db/src/change.rs +++ b/crates/ra_ide_db/src/change.rs | |||
@@ -281,8 +281,6 @@ impl RootDatabase { | |||
281 | // HirDatabase | 281 | // HirDatabase |
282 | hir::db::InternTypeCtorQuery | 282 | hir::db::InternTypeCtorQuery |
283 | hir::db::InternTypeParamIdQuery | 283 | hir::db::InternTypeParamIdQuery |
284 | hir::db::InternChalkImplQuery | ||
285 | hir::db::InternAssocTyValueQuery | ||
286 | ]; | 284 | ]; |
287 | 285 | ||
288 | acc.sort_by_key(|it| std::cmp::Reverse(it.1)); | 286 | acc.sort_by_key(|it| std::cmp::Reverse(it.1)); |