diff options
-rw-r--r-- | crates/ra_hir/src/db.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 412 |
3 files changed, 240 insertions, 194 deletions
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index d8832a9de..a9840905c 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -181,6 +181,26 @@ pub trait HirDatabase: DefDatabase + AstDatabase { | |||
181 | #[salsa::volatile] | 181 | #[salsa::volatile] |
182 | fn solver(&self, krate: Crate) -> Arc<Mutex<crate::ty::traits::Solver>>; | 182 | fn solver(&self, krate: Crate) -> Arc<Mutex<crate::ty::traits::Solver>>; |
183 | 183 | ||
184 | #[salsa::invoke(crate::ty::traits::chalk::associated_ty_data_query)] | ||
185 | fn associated_ty_data(&self, id: chalk_ir::TypeId) -> Arc<chalk_rust_ir::AssociatedTyDatum>; | ||
186 | |||
187 | #[salsa::invoke(crate::ty::traits::chalk::trait_datum_query)] | ||
188 | fn trait_datum( | ||
189 | &self, | ||
190 | krate: Crate, | ||
191 | trait_id: chalk_ir::TraitId, | ||
192 | ) -> Arc<chalk_rust_ir::TraitDatum>; | ||
193 | |||
194 | #[salsa::invoke(crate::ty::traits::chalk::struct_datum_query)] | ||
195 | fn struct_datum( | ||
196 | &self, | ||
197 | krate: Crate, | ||
198 | struct_id: chalk_ir::StructId, | ||
199 | ) -> Arc<chalk_rust_ir::StructDatum>; | ||
200 | |||
201 | #[salsa::invoke(crate::ty::traits::chalk::impl_datum_query)] | ||
202 | fn impl_datum(&self, krate: Crate, impl_id: chalk_ir::ImplId) -> Arc<chalk_rust_ir::ImplDatum>; | ||
203 | |||
184 | #[salsa::invoke(crate::ty::traits::implements_query)] | 204 | #[salsa::invoke(crate::ty::traits::implements_query)] |
185 | fn implements( | 205 | fn implements( |
186 | &self, | 206 | &self, |
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 9a6349d4b..69c03a36c 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs | |||
@@ -12,7 +12,7 @@ use super::{TraitRef, Ty, Canonical, ProjectionTy}; | |||
12 | 12 | ||
13 | use self::chalk::{ToChalk, from_chalk}; | 13 | use self::chalk::{ToChalk, from_chalk}; |
14 | 14 | ||
15 | mod chalk; | 15 | pub(crate) mod chalk; |
16 | 16 | ||
17 | pub(crate) type Solver = chalk_solve::Solver; | 17 | pub(crate) type Solver = chalk_solve::Solver; |
18 | 18 | ||
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 5105588ee..4ceb8b70b 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs | |||
@@ -10,7 +10,7 @@ use test_utils::tested_by; | |||
10 | use ra_db::salsa::{InternId, InternKey}; | 10 | use ra_db::salsa::{InternId, InternKey}; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | Trait, HasGenericParams, ImplBlock, | 13 | Trait, HasGenericParams, ImplBlock, Crate, |
14 | db::HirDatabase, | 14 | db::HirDatabase, |
15 | ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate, CallableDef, ProjectionTy}, | 15 | ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate, CallableDef, ProjectionTy}, |
16 | ty::display::HirDisplay, | 16 | ty::display::HirDisplay, |
@@ -256,204 +256,16 @@ where | |||
256 | DB: HirDatabase, | 256 | DB: HirDatabase, |
257 | { | 257 | { |
258 | fn associated_ty_data(&self, id: TypeId) -> Arc<AssociatedTyDatum> { | 258 | fn associated_ty_data(&self, id: TypeId) -> Arc<AssociatedTyDatum> { |
259 | debug!("associated_ty_data {:?}", id); | 259 | self.db.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) | ||
281 | } | 260 | } |
282 | fn trait_datum(&self, trait_id: chalk_ir::TraitId) -> Arc<TraitDatum> { | 261 | fn trait_datum(&self, trait_id: chalk_ir::TraitId) -> Arc<TraitDatum> { |
283 | debug!("trait_datum {:?}", trait_id); | 262 | self.db.trait_datum(self.krate, trait_id) |
284 | if trait_id == UNKNOWN_TRAIT { | ||
285 | let trait_datum_bound = chalk_rust_ir::TraitDatumBound { | ||
286 | trait_ref: chalk_ir::TraitRef { | ||
287 | trait_id: UNKNOWN_TRAIT, | ||
288 | parameters: vec![chalk_ir::Ty::BoundVar(0).cast()], | ||
289 | }, | ||
290 | associated_ty_ids: Vec::new(), | ||
291 | where_clauses: Vec::new(), | ||
292 | flags: chalk_rust_ir::TraitFlags { | ||
293 | auto: false, | ||
294 | marker: false, | ||
295 | upstream: true, | ||
296 | fundamental: false, | ||
297 | }, | ||
298 | }; | ||
299 | return Arc::new(TraitDatum { binders: make_binders(trait_datum_bound, 1) }); | ||
300 | } | ||
301 | let trait_: Trait = from_chalk(self.db, trait_id); | ||
302 | debug!("trait {:?} = {:?}", trait_id, trait_.name(self.db)); | ||
303 | let generic_params = trait_.generic_params(self.db); | ||
304 | let bound_vars = Substs::bound_vars(&generic_params); | ||
305 | let trait_ref = trait_.trait_ref(self.db).subst(&bound_vars).to_chalk(self.db); | ||
306 | let flags = chalk_rust_ir::TraitFlags { | ||
307 | auto: trait_.is_auto(self.db), | ||
308 | upstream: trait_.module(self.db).krate(self.db) != Some(self.krate), | ||
309 | // FIXME set these flags correctly | ||
310 | marker: false, | ||
311 | fundamental: false, | ||
312 | }; | ||
313 | let where_clauses = convert_where_clauses(self.db, trait_.into(), &bound_vars); | ||
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(); | ||
323 | let trait_datum_bound = | ||
324 | chalk_rust_ir::TraitDatumBound { trait_ref, where_clauses, flags, associated_ty_ids }; | ||
325 | let trait_datum = TraitDatum { binders: make_binders(trait_datum_bound, bound_vars.len()) }; | ||
326 | Arc::new(trait_datum) | ||
327 | } | 263 | } |
328 | fn struct_datum(&self, struct_id: chalk_ir::StructId) -> Arc<StructDatum> { | 264 | fn struct_datum(&self, struct_id: chalk_ir::StructId) -> Arc<StructDatum> { |
329 | debug!("struct_datum {:?}", struct_id); | 265 | self.db.struct_datum(self.krate, struct_id) |
330 | let type_ctor = from_chalk(self.db, struct_id); | ||
331 | debug!("struct {:?} = {:?}", struct_id, type_ctor); | ||
332 | // FIXME might be nicer if we can create a fake GenericParams for the TypeCtor | ||
333 | // FIXME extract this to a method on Ty | ||
334 | let (num_params, where_clauses, upstream) = match type_ctor { | ||
335 | TypeCtor::Bool | ||
336 | | TypeCtor::Char | ||
337 | | TypeCtor::Int(_) | ||
338 | | TypeCtor::Float(_) | ||
339 | | TypeCtor::Never | ||
340 | | TypeCtor::Str => (0, vec![], true), | ||
341 | TypeCtor::Slice | TypeCtor::Array | TypeCtor::RawPtr(_) | TypeCtor::Ref(_) => { | ||
342 | (1, vec![], true) | ||
343 | } | ||
344 | TypeCtor::FnPtr { num_args } => (num_args as usize + 1, vec![], true), | ||
345 | TypeCtor::Tuple { cardinality } => (cardinality as usize, vec![], true), | ||
346 | TypeCtor::FnDef(callable) => { | ||
347 | tested_by!(trait_resolution_on_fn_type); | ||
348 | let krate = match callable { | ||
349 | CallableDef::Function(f) => f.module(self.db).krate(self.db), | ||
350 | CallableDef::Struct(s) => s.module(self.db).krate(self.db), | ||
351 | CallableDef::EnumVariant(v) => { | ||
352 | v.parent_enum(self.db).module(self.db).krate(self.db) | ||
353 | } | ||
354 | }; | ||
355 | let generic_def: GenericDef = match callable { | ||
356 | CallableDef::Function(f) => f.into(), | ||
357 | CallableDef::Struct(s) => s.into(), | ||
358 | CallableDef::EnumVariant(v) => v.parent_enum(self.db).into(), | ||
359 | }; | ||
360 | let generic_params = generic_def.generic_params(self.db); | ||
361 | let bound_vars = Substs::bound_vars(&generic_params); | ||
362 | let where_clauses = convert_where_clauses(self.db, generic_def, &bound_vars); | ||
363 | ( | ||
364 | generic_params.count_params_including_parent(), | ||
365 | where_clauses, | ||
366 | krate != Some(self.krate), | ||
367 | ) | ||
368 | } | ||
369 | TypeCtor::Adt(adt) => { | ||
370 | let generic_params = adt.generic_params(self.db); | ||
371 | let bound_vars = Substs::bound_vars(&generic_params); | ||
372 | let where_clauses = convert_where_clauses(self.db, adt.into(), &bound_vars); | ||
373 | ( | ||
374 | generic_params.count_params_including_parent(), | ||
375 | where_clauses, | ||
376 | adt.krate(self.db) != Some(self.krate), | ||
377 | ) | ||
378 | } | ||
379 | }; | ||
380 | let flags = chalk_rust_ir::StructFlags { | ||
381 | upstream, | ||
382 | // FIXME set fundamental flag correctly | ||
383 | fundamental: false, | ||
384 | }; | ||
385 | let self_ty = chalk_ir::ApplicationTy { | ||
386 | name: TypeName::TypeKindId(type_ctor.to_chalk(self.db).into()), | ||
387 | parameters: (0..num_params).map(|i| chalk_ir::Ty::BoundVar(i).cast()).collect(), | ||
388 | }; | ||
389 | let struct_datum_bound = chalk_rust_ir::StructDatumBound { | ||
390 | self_ty, | ||
391 | fields: Vec::new(), // FIXME add fields (only relevant for auto traits) | ||
392 | where_clauses, | ||
393 | flags, | ||
394 | }; | ||
395 | let struct_datum = StructDatum { binders: make_binders(struct_datum_bound, num_params) }; | ||
396 | Arc::new(struct_datum) | ||
397 | } | 266 | } |
398 | fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> { | 267 | fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> { |
399 | debug!("impl_datum {:?}", impl_id); | 268 | self.db.impl_datum(self.krate, impl_id) |
400 | let impl_block: ImplBlock = from_chalk(self.db, impl_id); | ||
401 | let generic_params = impl_block.generic_params(self.db); | ||
402 | let bound_vars = Substs::bound_vars(&generic_params); | ||
403 | let trait_ref = impl_block | ||
404 | .target_trait_ref(self.db) | ||
405 | .expect("FIXME handle unresolved impl block trait ref") | ||
406 | .subst(&bound_vars); | ||
407 | let impl_type = if impl_block.module().krate(self.db) == Some(self.krate) { | ||
408 | chalk_rust_ir::ImplType::Local | ||
409 | } else { | ||
410 | chalk_rust_ir::ImplType::External | ||
411 | }; | ||
412 | let where_clauses = convert_where_clauses(self.db, impl_block.into(), &bound_vars); | ||
413 | let negative = impl_block.is_negative(self.db); | ||
414 | debug!( | ||
415 | "impl {:?}: {}{} where {:?}", | ||
416 | impl_id, | ||
417 | if negative { "!" } else { "" }, | ||
418 | trait_ref.display(self.db), | ||
419 | where_clauses | ||
420 | ); | ||
421 | let trait_ = trait_ref.trait_; | ||
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 | |||
444 | let impl_datum_bound = chalk_rust_ir::ImplDatumBound { | ||
445 | trait_ref: if negative { | ||
446 | chalk_rust_ir::PolarizedTraitRef::Negative(trait_ref) | ||
447 | } else { | ||
448 | chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref) | ||
449 | }, | ||
450 | where_clauses, | ||
451 | associated_ty_values, | ||
452 | impl_type, | ||
453 | }; | ||
454 | debug!("impl_datum: {:?}", impl_datum_bound); | ||
455 | let impl_datum = ImplDatum { binders: make_binders(impl_datum_bound, bound_vars.len()) }; | ||
456 | Arc::new(impl_datum) | ||
457 | } | 269 | } |
458 | fn impls_for_trait(&self, trait_id: chalk_ir::TraitId) -> Vec<ImplId> { | 270 | fn impls_for_trait(&self, trait_id: chalk_ir::TraitId) -> Vec<ImplId> { |
459 | debug!("impls_for_trait {:?}", trait_id); | 271 | debug!("impls_for_trait {:?}", trait_id); |
@@ -503,6 +315,220 @@ where | |||
503 | } | 315 | } |
504 | } | 316 | } |
505 | 317 | ||
318 | pub(crate) fn associated_ty_data_query( | ||
319 | db: &impl HirDatabase, | ||
320 | id: TypeId, | ||
321 | ) -> Arc<AssociatedTyDatum> { | ||
322 | debug!("associated_ty_data {:?}", id); | ||
323 | let type_alias: TypeAlias = from_chalk(db, id); | ||
324 | let trait_ = match type_alias.container(db) { | ||
325 | Some(crate::Container::Trait(t)) => t, | ||
326 | _ => panic!("associated type not in trait"), | ||
327 | }; | ||
328 | let generic_params = type_alias.generic_params(db); | ||
329 | let parameter_kinds = generic_params | ||
330 | .params_including_parent() | ||
331 | .into_iter() | ||
332 | .map(|p| chalk_ir::ParameterKind::Ty(lalrpop_intern::intern(&p.name.to_string()))) | ||
333 | .collect(); | ||
334 | let datum = AssociatedTyDatum { | ||
335 | trait_id: trait_.to_chalk(db), | ||
336 | id, | ||
337 | name: lalrpop_intern::intern(&type_alias.name(db).to_string()), | ||
338 | parameter_kinds, | ||
339 | // FIXME add bounds and where clauses | ||
340 | bounds: vec![], | ||
341 | where_clauses: vec![], | ||
342 | }; | ||
343 | Arc::new(datum) | ||
344 | } | ||
345 | |||
346 | pub(crate) fn trait_datum_query( | ||
347 | db: &impl HirDatabase, | ||
348 | krate: Crate, | ||
349 | trait_id: chalk_ir::TraitId, | ||
350 | ) -> Arc<TraitDatum> { | ||
351 | debug!("trait_datum {:?}", trait_id); | ||
352 | if trait_id == UNKNOWN_TRAIT { | ||
353 | let trait_datum_bound = chalk_rust_ir::TraitDatumBound { | ||
354 | trait_ref: chalk_ir::TraitRef { | ||
355 | trait_id: UNKNOWN_TRAIT, | ||
356 | parameters: vec![chalk_ir::Ty::BoundVar(0).cast()], | ||
357 | }, | ||
358 | associated_ty_ids: Vec::new(), | ||
359 | where_clauses: Vec::new(), | ||
360 | flags: chalk_rust_ir::TraitFlags { | ||
361 | auto: false, | ||
362 | marker: false, | ||
363 | upstream: true, | ||
364 | fundamental: false, | ||
365 | }, | ||
366 | }; | ||
367 | return Arc::new(TraitDatum { binders: make_binders(trait_datum_bound, 1) }); | ||
368 | } | ||
369 | let trait_: Trait = from_chalk(db, trait_id); | ||
370 | debug!("trait {:?} = {:?}", trait_id, trait_.name(db)); | ||
371 | let generic_params = trait_.generic_params(db); | ||
372 | let bound_vars = Substs::bound_vars(&generic_params); | ||
373 | let trait_ref = trait_.trait_ref(db).subst(&bound_vars).to_chalk(db); | ||
374 | let flags = chalk_rust_ir::TraitFlags { | ||
375 | auto: trait_.is_auto(db), | ||
376 | upstream: trait_.module(db).krate(db) != Some(krate), | ||
377 | // FIXME set these flags correctly | ||
378 | marker: false, | ||
379 | fundamental: false, | ||
380 | }; | ||
381 | let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars); | ||
382 | let associated_ty_ids = trait_ | ||
383 | .items(db) | ||
384 | .into_iter() | ||
385 | .filter_map(|trait_item| match trait_item { | ||
386 | crate::traits::TraitItem::TypeAlias(type_alias) => Some(type_alias), | ||
387 | _ => None, | ||
388 | }) | ||
389 | .map(|type_alias| type_alias.to_chalk(db)) | ||
390 | .collect(); | ||
391 | let trait_datum_bound = | ||
392 | chalk_rust_ir::TraitDatumBound { trait_ref, where_clauses, flags, associated_ty_ids }; | ||
393 | let trait_datum = TraitDatum { binders: make_binders(trait_datum_bound, bound_vars.len()) }; | ||
394 | Arc::new(trait_datum) | ||
395 | } | ||
396 | |||
397 | pub(crate) fn struct_datum_query( | ||
398 | db: &impl HirDatabase, | ||
399 | krate: Crate, | ||
400 | struct_id: chalk_ir::StructId, | ||
401 | ) -> Arc<StructDatum> { | ||
402 | debug!("struct_datum {:?}", struct_id); | ||
403 | let type_ctor = from_chalk(db, struct_id); | ||
404 | debug!("struct {:?} = {:?}", struct_id, type_ctor); | ||
405 | // FIXME might be nicer if we can create a fake GenericParams for the TypeCtor | ||
406 | // FIXME extract this to a method on Ty | ||
407 | let (num_params, where_clauses, upstream) = match type_ctor { | ||
408 | TypeCtor::Bool | ||
409 | | TypeCtor::Char | ||
410 | | TypeCtor::Int(_) | ||
411 | | TypeCtor::Float(_) | ||
412 | | TypeCtor::Never | ||
413 | | TypeCtor::Str => (0, vec![], true), | ||
414 | TypeCtor::Slice | TypeCtor::Array | TypeCtor::RawPtr(_) | TypeCtor::Ref(_) => { | ||
415 | (1, vec![], true) | ||
416 | } | ||
417 | TypeCtor::FnPtr { num_args } => (num_args as usize + 1, vec![], true), | ||
418 | TypeCtor::Tuple { cardinality } => (cardinality as usize, vec![], true), | ||
419 | TypeCtor::FnDef(callable) => { | ||
420 | tested_by!(trait_resolution_on_fn_type); | ||
421 | let upstream = match callable { | ||
422 | CallableDef::Function(f) => f.module(db).krate(db), | ||
423 | CallableDef::Struct(s) => s.module(db).krate(db), | ||
424 | CallableDef::EnumVariant(v) => v.parent_enum(db).module(db).krate(db), | ||
425 | } != Some(krate); | ||
426 | let generic_def: GenericDef = match callable { | ||
427 | CallableDef::Function(f) => f.into(), | ||
428 | CallableDef::Struct(s) => s.into(), | ||
429 | CallableDef::EnumVariant(v) => v.parent_enum(db).into(), | ||
430 | }; | ||
431 | let generic_params = generic_def.generic_params(db); | ||
432 | let bound_vars = Substs::bound_vars(&generic_params); | ||
433 | let where_clauses = convert_where_clauses(db, generic_def, &bound_vars); | ||
434 | (generic_params.count_params_including_parent(), where_clauses, upstream) | ||
435 | } | ||
436 | TypeCtor::Adt(adt) => { | ||
437 | let generic_params = adt.generic_params(db); | ||
438 | let bound_vars = Substs::bound_vars(&generic_params); | ||
439 | let where_clauses = convert_where_clauses(db, adt.into(), &bound_vars); | ||
440 | ( | ||
441 | generic_params.count_params_including_parent(), | ||
442 | where_clauses, | ||
443 | adt.krate(db) != Some(krate), | ||
444 | ) | ||
445 | } | ||
446 | }; | ||
447 | let flags = chalk_rust_ir::StructFlags { | ||
448 | upstream, | ||
449 | // FIXME set fundamental flag correctly | ||
450 | fundamental: false, | ||
451 | }; | ||
452 | let self_ty = chalk_ir::ApplicationTy { | ||
453 | name: TypeName::TypeKindId(type_ctor.to_chalk(db).into()), | ||
454 | parameters: (0..num_params).map(|i| chalk_ir::Ty::BoundVar(i).cast()).collect(), | ||
455 | }; | ||
456 | let struct_datum_bound = chalk_rust_ir::StructDatumBound { | ||
457 | self_ty, | ||
458 | fields: Vec::new(), // FIXME add fields (only relevant for auto traits) | ||
459 | where_clauses, | ||
460 | flags, | ||
461 | }; | ||
462 | let struct_datum = StructDatum { binders: make_binders(struct_datum_bound, num_params) }; | ||
463 | Arc::new(struct_datum) | ||
464 | } | ||
465 | |||
466 | pub(crate) fn impl_datum_query( | ||
467 | db: &impl HirDatabase, | ||
468 | krate: Crate, | ||
469 | impl_id: ImplId, | ||
470 | ) -> Arc<ImplDatum> { | ||
471 | let _p = ra_prof::profile("impl_datum"); | ||
472 | debug!("impl_datum {:?}", impl_id); | ||
473 | let impl_block: ImplBlock = from_chalk(db, impl_id); | ||
474 | let generic_params = impl_block.generic_params(db); | ||
475 | let bound_vars = Substs::bound_vars(&generic_params); | ||
476 | let trait_ref = impl_block | ||
477 | .target_trait_ref(db) | ||
478 | .expect("FIXME handle unresolved impl block trait ref") | ||
479 | .subst(&bound_vars); | ||
480 | let impl_type = if impl_block.module().krate(db) == Some(krate) { | ||
481 | chalk_rust_ir::ImplType::Local | ||
482 | } else { | ||
483 | chalk_rust_ir::ImplType::External | ||
484 | }; | ||
485 | let where_clauses = convert_where_clauses(db, impl_block.into(), &bound_vars); | ||
486 | let negative = impl_block.is_negative(db); | ||
487 | debug!( | ||
488 | "impl {:?}: {}{} where {:?}", | ||
489 | impl_id, | ||
490 | if negative { "!" } else { "" }, | ||
491 | trait_ref.display(db), | ||
492 | where_clauses | ||
493 | ); | ||
494 | let trait_ = trait_ref.trait_; | ||
495 | let trait_ref = trait_ref.to_chalk(db); | ||
496 | let associated_ty_values = impl_block | ||
497 | .items(db) | ||
498 | .into_iter() | ||
499 | .filter_map(|item| match item { | ||
500 | ImplItem::TypeAlias(t) => Some(t), | ||
501 | _ => None, | ||
502 | }) | ||
503 | .filter_map(|t| { | ||
504 | let assoc_ty = trait_.associated_type_by_name(db, t.name(db))?; | ||
505 | let ty = db.type_for_def(t.into(), crate::Namespace::Types).subst(&bound_vars); | ||
506 | Some(chalk_rust_ir::AssociatedTyValue { | ||
507 | impl_id, | ||
508 | associated_ty_id: assoc_ty.to_chalk(db), | ||
509 | value: chalk_ir::Binders { | ||
510 | value: chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }, | ||
511 | binders: vec![], // we don't support GATs yet | ||
512 | }, | ||
513 | }) | ||
514 | }) | ||
515 | .collect(); | ||
516 | |||
517 | let impl_datum_bound = chalk_rust_ir::ImplDatumBound { | ||
518 | trait_ref: if negative { | ||
519 | chalk_rust_ir::PolarizedTraitRef::Negative(trait_ref) | ||
520 | } else { | ||
521 | chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref) | ||
522 | }, | ||
523 | where_clauses, | ||
524 | associated_ty_values, | ||
525 | impl_type, | ||
526 | }; | ||
527 | debug!("impl_datum: {:?}", impl_datum_bound); | ||
528 | let impl_datum = ImplDatum { binders: make_binders(impl_datum_bound, bound_vars.len()) }; | ||
529 | Arc::new(impl_datum) | ||
530 | } | ||
531 | |||
506 | fn id_from_chalk<T: InternKey>(chalk_id: chalk_ir::RawId) -> T { | 532 | fn id_from_chalk<T: InternKey>(chalk_id: chalk_ir::RawId) -> T { |
507 | T::from_intern_id(InternId::from(chalk_id.index)) | 533 | T::from_intern_id(InternId::from(chalk_id.index)) |
508 | } | 534 | } |