diff options
Diffstat (limited to 'crates/ra_hir_ty/src/traits/chalk.rs')
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk.rs | 77 |
1 files changed, 62 insertions, 15 deletions
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs index c97b81d57..c448aea65 100644 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs | |||
@@ -3,7 +3,7 @@ use std::sync::Arc; | |||
3 | 3 | ||
4 | use log::debug; | 4 | use log::debug; |
5 | 5 | ||
6 | use chalk_ir::{fold::shift::Shift, GenericArg, TypeName}; | 6 | use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg, TypeName}; |
7 | use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; | 7 | use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; |
8 | 8 | ||
9 | use hir_def::{ | 9 | use hir_def::{ |
@@ -14,7 +14,10 @@ use ra_db::{salsa::InternKey, CrateId}; | |||
14 | 14 | ||
15 | use super::{builtin, AssocTyValue, ChalkContext, Impl}; | 15 | use super::{builtin, AssocTyValue, ChalkContext, Impl}; |
16 | use crate::{ | 16 | use crate::{ |
17 | db::HirDatabase, display::HirDisplay, method_resolution::TyFingerprint, utils::generics, | 17 | db::HirDatabase, |
18 | display::HirDisplay, | ||
19 | method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, | ||
20 | utils::generics, | ||
18 | CallableDef, DebruijnIndex, GenericPredicate, Substs, Ty, TypeCtor, | 21 | CallableDef, DebruijnIndex, GenericPredicate, Substs, Ty, TypeCtor, |
19 | }; | 22 | }; |
20 | use mapping::{convert_where_clauses, generic_predicate_to_inline_bound, make_binders}; | 23 | use mapping::{convert_where_clauses, generic_predicate_to_inline_bound, make_binders}; |
@@ -66,13 +69,31 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
66 | &self, | 69 | &self, |
67 | trait_id: TraitId, | 70 | trait_id: TraitId, |
68 | parameters: &[GenericArg<Interner>], | 71 | parameters: &[GenericArg<Interner>], |
72 | binders: &CanonicalVarKinds<Interner>, | ||
69 | ) -> Vec<ImplId> { | 73 | ) -> Vec<ImplId> { |
70 | debug!("impls_for_trait {:?}", trait_id); | 74 | debug!("impls_for_trait {:?}", trait_id); |
71 | let trait_: hir_def::TraitId = from_chalk(self.db, trait_id); | 75 | let trait_: hir_def::TraitId = from_chalk(self.db, trait_id); |
72 | 76 | ||
73 | let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone()); | 77 | let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone()); |
74 | 78 | ||
79 | fn binder_kind(ty: &Ty, binders: &CanonicalVarKinds<Interner>) -> Option<chalk_ir::TyKind> { | ||
80 | if let Ty::Bound(bv) = ty { | ||
81 | let binders = binders.as_slice(&Interner); | ||
82 | if bv.debruijn == DebruijnIndex::INNERMOST { | ||
83 | if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind { | ||
84 | return Some(tk); | ||
85 | } | ||
86 | } | ||
87 | } | ||
88 | None | ||
89 | } | ||
90 | |||
75 | let self_ty_fp = TyFingerprint::for_impl(&ty); | 91 | let self_ty_fp = TyFingerprint::for_impl(&ty); |
92 | let fps: &[TyFingerprint] = match binder_kind(&ty, binders) { | ||
93 | Some(chalk_ir::TyKind::Integer) => &ALL_INT_FPS, | ||
94 | Some(chalk_ir::TyKind::Float) => &ALL_FLOAT_FPS, | ||
95 | _ => self_ty_fp.as_ref().map(std::slice::from_ref).unwrap_or(&[]), | ||
96 | }; | ||
76 | 97 | ||
77 | // Note: Since we're using impls_for_trait, only impls where the trait | 98 | // Note: Since we're using impls_for_trait, only impls where the trait |
78 | // can be resolved should ever reach Chalk. `impl_datum` relies on that | 99 | // can be resolved should ever reach Chalk. `impl_datum` relies on that |
@@ -83,17 +104,21 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
83 | 104 | ||
84 | let id_to_chalk = |id: hir_def::ImplId| Impl::ImplDef(id).to_chalk(self.db); | 105 | let id_to_chalk = |id: hir_def::ImplId| Impl::ImplDef(id).to_chalk(self.db); |
85 | 106 | ||
86 | let mut result: Vec<_> = match self_ty_fp { | 107 | let mut result: Vec<_> = if fps.is_empty() { |
87 | Some(fp) => impl_maps | 108 | debug!("Unrestricted search for {:?} impls...", trait_); |
109 | impl_maps | ||
110 | .iter() | ||
111 | .flat_map(|crate_impl_defs| crate_impl_defs.for_trait(trait_).map(id_to_chalk)) | ||
112 | .collect() | ||
113 | } else { | ||
114 | impl_maps | ||
88 | .iter() | 115 | .iter() |
89 | .flat_map(|crate_impl_defs| { | 116 | .flat_map(|crate_impl_defs| { |
90 | crate_impl_defs.for_trait_and_self_ty(trait_, fp).map(id_to_chalk) | 117 | fps.iter().flat_map(move |fp| { |
118 | crate_impl_defs.for_trait_and_self_ty(trait_, *fp).map(id_to_chalk) | ||
119 | }) | ||
91 | }) | 120 | }) |
92 | .collect(), | 121 | .collect() |
93 | None => impl_maps | ||
94 | .iter() | ||
95 | .flat_map(|crate_impl_defs| crate_impl_defs.for_trait(trait_).map(id_to_chalk)) | ||
96 | .collect(), | ||
97 | }; | 122 | }; |
98 | 123 | ||
99 | let arg: Option<Ty> = | 124 | let arg: Option<Ty> = |
@@ -219,6 +244,22 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
219 | // FIXME: implement closure support | 244 | // FIXME: implement closure support |
220 | unimplemented!() | 245 | unimplemented!() |
221 | } | 246 | } |
247 | |||
248 | fn trait_name(&self, _trait_id: chalk_ir::TraitId<Interner>) -> String { | ||
249 | unimplemented!() | ||
250 | } | ||
251 | fn adt_name(&self, _struct_id: chalk_ir::AdtId<Interner>) -> String { | ||
252 | unimplemented!() | ||
253 | } | ||
254 | fn assoc_type_name(&self, _assoc_ty_id: chalk_ir::AssocTypeId<Interner>) -> String { | ||
255 | unimplemented!() | ||
256 | } | ||
257 | fn opaque_type_name(&self, _opaque_ty_id: chalk_ir::OpaqueTyId<Interner>) -> String { | ||
258 | unimplemented!() | ||
259 | } | ||
260 | fn fn_def_name(&self, _fn_def_id: chalk_ir::FnDefId<Interner>) -> String { | ||
261 | unimplemented!() | ||
262 | } | ||
222 | } | 263 | } |
223 | 264 | ||
224 | pub(crate) fn program_clauses_for_chalk_env_query( | 265 | pub(crate) fn program_clauses_for_chalk_env_query( |
@@ -354,12 +395,18 @@ pub(crate) fn struct_datum_query( | |||
354 | fundamental: false, | 395 | fundamental: false, |
355 | phantom_data: false, | 396 | phantom_data: false, |
356 | }; | 397 | }; |
357 | let struct_datum_bound = rust_ir::AdtDatumBound { | 398 | // FIXME provide enum variants properly (for auto traits) |
358 | fields: Vec::new(), // FIXME add fields (only relevant for auto traits) | 399 | let variant = rust_ir::AdtVariantDatum { |
359 | where_clauses, | 400 | fields: Vec::new(), // FIXME add fields (only relevant for auto traits), |
401 | }; | ||
402 | let struct_datum_bound = rust_ir::AdtDatumBound { variants: vec![variant], where_clauses }; | ||
403 | let struct_datum = StructDatum { | ||
404 | // FIXME set ADT kind | ||
405 | kind: rust_ir::AdtKind::Struct, | ||
406 | id: struct_id, | ||
407 | binders: make_binders(struct_datum_bound, num_params), | ||
408 | flags, | ||
360 | }; | 409 | }; |
361 | let struct_datum = | ||
362 | StructDatum { id: struct_id, binders: make_binders(struct_datum_bound, num_params), flags }; | ||
363 | Arc::new(struct_datum) | 410 | Arc::new(struct_datum) |
364 | } | 411 | } |
365 | 412 | ||