aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/traits/chalk.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-06-16 13:00:41 +0100
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-06-16 13:00:41 +0100
commitb81caed43f1886024ededad41a1baa8a03f1d2f4 (patch)
tree0a0289899ec59b425eae6369929a01e97065ce43 /crates/ra_hir/src/ty/traits/chalk.rs
parente6fbff3246cdd3278ff1c376d5abfc1d579f86c2 (diff)
parentad3673d8d86a9b8f1a8dba858abd7cabaa1d5776 (diff)
Merge #1408
1408: Associated type basics & Deref support r=matklad a=flodiebold This adds the necessary Chalk integration to handle associated types and uses it to implement support for `Deref` in the `*` operator and autoderef; so e.g. dot completions through an `Arc` work now. It doesn't yet implement resolution of associated types in paths, though. Also, there's a big FIXME about handling variables in the solution we get from Chalk correctly. Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/ty/traits/chalk.rs')
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs110
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..5105588ee 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
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{TypeId, ImplId, TypeKindId, ProjectionTy, Parameter, Identifier, cast::Cast, PlaceholderIndex, UniverseIndex, TypeName}; 6use chalk_ir::{TypeId, ImplId, TypeKindId, Parameter, Identifier, cast::Cast, PlaceholderIndex, UniverseIndex, TypeName};
7use chalk_rust_ir::{AssociatedTyDatum, TraitDatum, StructDatum, ImplDatum}; 7use chalk_rust_ir::{AssociatedTyDatum, TraitDatum, StructDatum, ImplDatum};
8 8
9use test_utils::tested_by; 9use test_utils::tested_by;
@@ -12,9 +12,9 @@ use ra_db::salsa::{InternId, InternKey};
12use crate::{ 12use 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};
19use super::ChalkContext; 19use super::ChalkContext;
20 20
@@ -156,6 +156,18 @@ impl ToChalk for ImplBlock {
156 } 156 }
157} 157}
158 158
159impl 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
159impl ToChalk for GenericPredicate { 171impl 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
198impl 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
186fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> { 216fn 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,29 @@ impl<'a, DB> chalk_solve::RustIrDatabase for ChalkContext<'a, DB>
225where 255where
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 // FIXME add bounds and where clauses
277 bounds: vec![],
278 where_clauses: vec![],
279 };
280 Arc::new(datum)
230 } 281 }
231 fn trait_datum(&self, trait_id: chalk_ir::TraitId) -> Arc<TraitDatum> { 282 fn trait_datum(&self, trait_id: chalk_ir::TraitId) -> Arc<TraitDatum> {
232 debug!("trait_datum {:?}", trait_id); 283 debug!("trait_datum {:?}", trait_id);
@@ -260,7 +311,15 @@ where
260 fundamental: false, 311 fundamental: false,
261 }; 312 };
262 let where_clauses = convert_where_clauses(self.db, trait_.into(), &bound_vars); 313 let where_clauses = convert_where_clauses(self.db, trait_.into(), &bound_vars);
263 let associated_ty_ids = Vec::new(); // FIXME add associated tys 314 let associated_ty_ids = trait_
315 .items(self.db)
316 .into_iter()
317 .filter_map(|trait_item| match trait_item {
318 crate::traits::TraitItem::TypeAlias(type_alias) => Some(type_alias),
319 _ => None,
320 })
321 .map(|type_alias| type_alias.to_chalk(self.db))
322 .collect();
264 let trait_datum_bound = 323 let trait_datum_bound =
265 chalk_rust_ir::TraitDatumBound { trait_ref, where_clauses, flags, associated_ty_ids }; 324 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()) }; 325 let trait_datum = TraitDatum { binders: make_binders(trait_datum_bound, bound_vars.len()) };
@@ -359,7 +418,29 @@ where
359 trait_ref.display(self.db), 418 trait_ref.display(self.db),
360 where_clauses 419 where_clauses
361 ); 420 );
421 let trait_ = trait_ref.trait_;
362 let trait_ref = trait_ref.to_chalk(self.db); 422 let trait_ref = trait_ref.to_chalk(self.db);
423 let associated_ty_values = impl_block
424 .items(self.db)
425 .into_iter()
426 .filter_map(|item| match item {
427 ImplItem::TypeAlias(t) => Some(t),
428 _ => None,
429 })
430 .filter_map(|t| {
431 let assoc_ty = trait_.associated_type_by_name(self.db, t.name(self.db))?;
432 let ty = self.db.type_for_def(t.into(), crate::Namespace::Types).subst(&bound_vars);
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![], // we don't support GATs yet
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
525impl 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
531impl 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
443impl From<chalk_ir::StructId> for crate::ids::TypeCtorId { 537impl 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)