diff options
author | Florian Diebold <[email protected]> | 2019-05-12 16:53:44 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-06-15 17:21:23 +0100 |
commit | 49489dc20cc9f340d43acb467677b9bc59495ed2 (patch) | |
tree | e8e76acb07e646957a20c8ce5262d893ea7b7b03 /crates/ra_hir/src/ty/traits | |
parent | 6f946f96563bac1f214f86f463287d94968e3688 (diff) |
Add basic infrastructure for assoc type projection
Diffstat (limited to 'crates/ra_hir/src/ty/traits')
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 110 |
1 files changed, 102 insertions, 8 deletions
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 1e4806db0..1e1b6f406 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/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::{TypeId, ImplId, TypeKindId, ProjectionTy, Parameter, Identifier, cast::Cast, PlaceholderIndex, UniverseIndex, TypeName}; | 6 | use chalk_ir::{TypeId, ImplId, TypeKindId, Parameter, Identifier, cast::Cast, PlaceholderIndex, UniverseIndex, TypeName}; |
7 | use chalk_rust_ir::{AssociatedTyDatum, TraitDatum, StructDatum, ImplDatum}; | 7 | use chalk_rust_ir::{AssociatedTyDatum, TraitDatum, StructDatum, ImplDatum}; |
8 | 8 | ||
9 | use test_utils::tested_by; | 9 | use test_utils::tested_by; |
@@ -12,9 +12,9 @@ use ra_db::salsa::{InternId, InternKey}; | |||
12 | use crate::{ | 12 | use crate::{ |
13 | Trait, HasGenericParams, ImplBlock, | 13 | Trait, HasGenericParams, ImplBlock, |
14 | db::HirDatabase, | 14 | db::HirDatabase, |
15 | ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate, CallableDef}, | 15 | ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate, CallableDef, ProjectionTy}, |
16 | ty::display::HirDisplay, | 16 | ty::display::HirDisplay, |
17 | generics::GenericDef, | 17 | generics::GenericDef, TypeAlias, ImplItem, |
18 | }; | 18 | }; |
19 | use super::ChalkContext; | 19 | use super::ChalkContext; |
20 | 20 | ||
@@ -156,6 +156,18 @@ impl ToChalk for ImplBlock { | |||
156 | } | 156 | } |
157 | } | 157 | } |
158 | 158 | ||
159 | impl ToChalk for TypeAlias { | ||
160 | type Chalk = chalk_ir::TypeId; | ||
161 | |||
162 | fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TypeId { | ||
163 | self.id.into() | ||
164 | } | ||
165 | |||
166 | fn from_chalk(_db: &impl HirDatabase, impl_id: chalk_ir::TypeId) -> TypeAlias { | ||
167 | TypeAlias { id: impl_id.into() } | ||
168 | } | ||
169 | } | ||
170 | |||
159 | impl ToChalk for GenericPredicate { | 171 | impl ToChalk for GenericPredicate { |
160 | type Chalk = chalk_ir::QuantifiedWhereClause; | 172 | type Chalk = chalk_ir::QuantifiedWhereClause; |
161 | 173 | ||
@@ -183,6 +195,24 @@ impl ToChalk for GenericPredicate { | |||
183 | } | 195 | } |
184 | } | 196 | } |
185 | 197 | ||
198 | impl ToChalk for ProjectionTy { | ||
199 | type Chalk = chalk_ir::ProjectionTy; | ||
200 | |||
201 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ProjectionTy { | ||
202 | chalk_ir::ProjectionTy { | ||
203 | associated_ty_id: self.associated_ty.to_chalk(db), | ||
204 | parameters: self.parameters.to_chalk(db), | ||
205 | } | ||
206 | } | ||
207 | |||
208 | fn from_chalk(db: &impl HirDatabase, projection_ty: chalk_ir::ProjectionTy) -> ProjectionTy { | ||
209 | ProjectionTy { | ||
210 | associated_ty: from_chalk(db, projection_ty.associated_ty_id), | ||
211 | parameters: from_chalk(db, projection_ty.parameters), | ||
212 | } | ||
213 | } | ||
214 | } | ||
215 | |||
186 | fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> { | 216 | fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> { |
187 | chalk_ir::Binders { | 217 | chalk_ir::Binders { |
188 | value, | 218 | value, |
@@ -225,8 +255,28 @@ impl<'a, DB> chalk_solve::RustIrDatabase for ChalkContext<'a, DB> | |||
225 | where | 255 | where |
226 | DB: HirDatabase, | 256 | DB: HirDatabase, |
227 | { | 257 | { |
228 | fn associated_ty_data(&self, _ty: TypeId) -> Arc<AssociatedTyDatum> { | 258 | fn associated_ty_data(&self, id: TypeId) -> Arc<AssociatedTyDatum> { |
229 | unimplemented!() | 259 | debug!("associated_ty_data {:?}", id); |
260 | let type_alias: TypeAlias = from_chalk(self.db, id); | ||
261 | let trait_ = match type_alias.container(self.db) { | ||
262 | Some(crate::Container::Trait(t)) => t, | ||
263 | _ => panic!("associated type not in trait"), | ||
264 | }; | ||
265 | let generic_params = type_alias.generic_params(self.db); | ||
266 | let parameter_kinds = generic_params | ||
267 | .params_including_parent() | ||
268 | .into_iter() | ||
269 | .map(|p| chalk_ir::ParameterKind::Ty(lalrpop_intern::intern(&p.name.to_string()))) | ||
270 | .collect(); | ||
271 | let datum = AssociatedTyDatum { | ||
272 | trait_id: trait_.to_chalk(self.db), | ||
273 | id, | ||
274 | name: lalrpop_intern::intern(&type_alias.name(self.db).to_string()), | ||
275 | parameter_kinds, | ||
276 | bounds: vec![], // FIXME | ||
277 | where_clauses: vec![], // FIXME | ||
278 | }; | ||
279 | Arc::new(datum) | ||
230 | } | 280 | } |
231 | fn trait_datum(&self, trait_id: chalk_ir::TraitId) -> Arc<TraitDatum> { | 281 | fn trait_datum(&self, trait_id: chalk_ir::TraitId) -> Arc<TraitDatum> { |
232 | debug!("trait_datum {:?}", trait_id); | 282 | debug!("trait_datum {:?}", trait_id); |
@@ -260,7 +310,15 @@ where | |||
260 | fundamental: false, | 310 | fundamental: false, |
261 | }; | 311 | }; |
262 | let where_clauses = convert_where_clauses(self.db, trait_.into(), &bound_vars); | 312 | let where_clauses = convert_where_clauses(self.db, trait_.into(), &bound_vars); |
263 | let associated_ty_ids = Vec::new(); // FIXME add associated tys | 313 | let associated_ty_ids = trait_ |
314 | .items(self.db) | ||
315 | .into_iter() | ||
316 | .filter_map(|trait_item| match trait_item { | ||
317 | crate::traits::TraitItem::TypeAlias(type_alias) => Some(type_alias), | ||
318 | _ => None, | ||
319 | }) | ||
320 | .map(|type_alias| type_alias.to_chalk(self.db)) | ||
321 | .collect(); | ||
264 | let trait_datum_bound = | 322 | let trait_datum_bound = |
265 | chalk_rust_ir::TraitDatumBound { trait_ref, where_clauses, flags, associated_ty_ids }; | 323 | chalk_rust_ir::TraitDatumBound { trait_ref, where_clauses, flags, associated_ty_ids }; |
266 | let trait_datum = TraitDatum { binders: make_binders(trait_datum_bound, bound_vars.len()) }; | 324 | let trait_datum = TraitDatum { binders: make_binders(trait_datum_bound, bound_vars.len()) }; |
@@ -359,7 +417,30 @@ where | |||
359 | trait_ref.display(self.db), | 417 | trait_ref.display(self.db), |
360 | where_clauses | 418 | where_clauses |
361 | ); | 419 | ); |
420 | let trait_ = trait_ref.trait_; | ||
362 | let trait_ref = trait_ref.to_chalk(self.db); | 421 | let trait_ref = trait_ref.to_chalk(self.db); |
422 | let associated_ty_values = impl_block | ||
423 | .items(self.db) | ||
424 | .into_iter() | ||
425 | .filter_map(|item| match item { | ||
426 | ImplItem::TypeAlias(t) => Some(t), | ||
427 | _ => None, | ||
428 | }) | ||
429 | .filter_map(|t| { | ||
430 | let assoc_ty = trait_.associated_type_by_name(self.db, t.name(self.db))?; | ||
431 | let ty = self.db.type_for_def(t.into(), crate::Namespace::Types).subst(&bound_vars); | ||
432 | debug!("ty = {}", ty.display(self.db)); | ||
433 | Some(chalk_rust_ir::AssociatedTyValue { | ||
434 | impl_id, | ||
435 | associated_ty_id: assoc_ty.to_chalk(self.db), | ||
436 | value: chalk_ir::Binders { | ||
437 | value: chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(self.db) }, | ||
438 | binders: vec![], // FIXME add generic params (generic associated types) | ||
439 | }, | ||
440 | }) | ||
441 | }) | ||
442 | .collect(); | ||
443 | |||
363 | let impl_datum_bound = chalk_rust_ir::ImplDatumBound { | 444 | let impl_datum_bound = chalk_rust_ir::ImplDatumBound { |
364 | trait_ref: if negative { | 445 | trait_ref: if negative { |
365 | chalk_rust_ir::PolarizedTraitRef::Negative(trait_ref) | 446 | chalk_rust_ir::PolarizedTraitRef::Negative(trait_ref) |
@@ -367,9 +448,10 @@ where | |||
367 | chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref) | 448 | chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref) |
368 | }, | 449 | }, |
369 | where_clauses, | 450 | where_clauses, |
370 | associated_ty_values: Vec::new(), // FIXME add associated type values | 451 | associated_ty_values, |
371 | impl_type, | 452 | impl_type, |
372 | }; | 453 | }; |
454 | debug!("impl_datum: {:?}", impl_datum_bound); | ||
373 | let impl_datum = ImplDatum { binders: make_binders(impl_datum_bound, bound_vars.len()) }; | 455 | let impl_datum = ImplDatum { binders: make_binders(impl_datum_bound, bound_vars.len()) }; |
374 | Arc::new(impl_datum) | 456 | Arc::new(impl_datum) |
375 | } | 457 | } |
@@ -405,7 +487,7 @@ where | |||
405 | } | 487 | } |
406 | fn split_projection<'p>( | 488 | fn split_projection<'p>( |
407 | &self, | 489 | &self, |
408 | projection: &'p ProjectionTy, | 490 | projection: &'p chalk_ir::ProjectionTy, |
409 | ) -> (Arc<AssociatedTyDatum>, &'p [Parameter], &'p [Parameter]) { | 491 | ) -> (Arc<AssociatedTyDatum>, &'p [Parameter], &'p [Parameter]) { |
410 | debug!("split_projection {:?}", projection); | 492 | debug!("split_projection {:?}", projection); |
411 | unimplemented!() | 493 | unimplemented!() |
@@ -440,6 +522,18 @@ impl From<crate::ids::TraitId> for chalk_ir::TraitId { | |||
440 | } | 522 | } |
441 | } | 523 | } |
442 | 524 | ||
525 | impl From<chalk_ir::TypeId> for crate::ids::TypeAliasId { | ||
526 | fn from(type_id: chalk_ir::TypeId) -> Self { | ||
527 | id_from_chalk(type_id.0) | ||
528 | } | ||
529 | } | ||
530 | |||
531 | impl From<crate::ids::TypeAliasId> for chalk_ir::TypeId { | ||
532 | fn from(type_id: crate::ids::TypeAliasId) -> Self { | ||
533 | chalk_ir::TypeId(id_to_chalk(type_id)) | ||
534 | } | ||
535 | } | ||
536 | |||
443 | impl From<chalk_ir::StructId> for crate::ids::TypeCtorId { | 537 | impl From<chalk_ir::StructId> for crate::ids::TypeCtorId { |
444 | fn from(struct_id: chalk_ir::StructId) -> Self { | 538 | fn from(struct_id: chalk_ir::StructId) -> Self { |
445 | id_from_chalk(struct_id.0) | 539 | id_from_chalk(struct_id.0) |