aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/traits/chalk.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/traits/chalk.rs')
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs182
1 files changed, 100 insertions, 82 deletions
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index c97b81d57..5298dbecf 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
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{fold::shift::Shift, GenericArg, TypeName}; 6use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg, TypeName};
7use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; 7use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
8 8
9use hir_def::{ 9use hir_def::{
@@ -12,12 +12,17 @@ use hir_def::{
12}; 12};
13use ra_db::{salsa::InternKey, CrateId}; 13use ra_db::{salsa::InternKey, CrateId};
14 14
15use super::{builtin, AssocTyValue, ChalkContext, Impl}; 15use super::ChalkContext;
16use crate::{ 16use crate::{
17 db::HirDatabase, display::HirDisplay, method_resolution::TyFingerprint, utils::generics, 17 db::HirDatabase,
18 CallableDef, DebruijnIndex, GenericPredicate, Substs, Ty, TypeCtor, 18 display::HirDisplay,
19 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
20 utils::generics,
21 CallableDefId, DebruijnIndex, FnSig, GenericPredicate, Substs, Ty, TypeCtor,
22};
23use mapping::{
24 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
19}; 25};
20use mapping::{convert_where_clauses, generic_predicate_to_inline_bound, make_binders};
21 26
22pub use self::interner::*; 27pub use self::interner::*;
23 28
@@ -49,7 +54,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
49 self.db.struct_datum(self.krate, struct_id) 54 self.db.struct_datum(self.krate, struct_id)
50 } 55 }
51 fn adt_repr(&self, _struct_id: AdtId) -> rust_ir::AdtRepr { 56 fn adt_repr(&self, _struct_id: AdtId) -> rust_ir::AdtRepr {
52 unreachable!() 57 rust_ir::AdtRepr { repr_c: false, repr_packed: false }
53 } 58 }
54 fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> { 59 fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> {
55 self.db.impl_datum(self.krate, impl_id) 60 self.db.impl_datum(self.krate, impl_id)
@@ -66,13 +71,31 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
66 &self, 71 &self,
67 trait_id: TraitId, 72 trait_id: TraitId,
68 parameters: &[GenericArg<Interner>], 73 parameters: &[GenericArg<Interner>],
74 binders: &CanonicalVarKinds<Interner>,
69 ) -> Vec<ImplId> { 75 ) -> Vec<ImplId> {
70 debug!("impls_for_trait {:?}", trait_id); 76 debug!("impls_for_trait {:?}", trait_id);
71 let trait_: hir_def::TraitId = from_chalk(self.db, trait_id); 77 let trait_: hir_def::TraitId = from_chalk(self.db, trait_id);
72 78
73 let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone()); 79 let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone());
74 80
81 fn binder_kind(ty: &Ty, binders: &CanonicalVarKinds<Interner>) -> Option<chalk_ir::TyKind> {
82 if let Ty::Bound(bv) = ty {
83 let binders = binders.as_slice(&Interner);
84 if bv.debruijn == DebruijnIndex::INNERMOST {
85 if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind {
86 return Some(tk);
87 }
88 }
89 }
90 None
91 }
92
75 let self_ty_fp = TyFingerprint::for_impl(&ty); 93 let self_ty_fp = TyFingerprint::for_impl(&ty);
94 let fps: &[TyFingerprint] = match binder_kind(&ty, binders) {
95 Some(chalk_ir::TyKind::Integer) => &ALL_INT_FPS,
96 Some(chalk_ir::TyKind::Float) => &ALL_FLOAT_FPS,
97 _ => self_ty_fp.as_ref().map(std::slice::from_ref).unwrap_or(&[]),
98 };
76 99
77 // Note: Since we're using impls_for_trait, only impls where the trait 100 // 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 101 // can be resolved should ever reach Chalk. `impl_datum` relies on that
@@ -81,28 +104,25 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
81 let in_self = self.db.trait_impls_in_crate(self.krate); 104 let in_self = self.db.trait_impls_in_crate(self.krate);
82 let impl_maps = [in_deps, in_self]; 105 let impl_maps = [in_deps, in_self];
83 106
84 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);
85 108
86 let mut result: Vec<_> = match self_ty_fp { 109 let result: Vec<_> = if fps.is_empty() {
87 Some(fp) => impl_maps 110 debug!("Unrestricted search for {:?} impls...", trait_);
111 impl_maps
112 .iter()
113 .flat_map(|crate_impl_defs| crate_impl_defs.for_trait(trait_).map(id_to_chalk))
114 .collect()
115 } else {
116 impl_maps
88 .iter() 117 .iter()
89 .flat_map(|crate_impl_defs| { 118 .flat_map(|crate_impl_defs| {
90 crate_impl_defs.for_trait_and_self_ty(trait_, fp).map(id_to_chalk) 119 fps.iter().flat_map(move |fp| {
120 crate_impl_defs.for_trait_and_self_ty(trait_, *fp).map(id_to_chalk)
121 })
91 }) 122 })
92 .collect(), 123 .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 }; 124 };
98 125
99 let arg: Option<Ty> =
100 parameters.get(1).map(|p| from_chalk(self.db, p.assert_ty_ref(&Interner).clone()));
101
102 builtin::get_builtin_impls(self.db, self.krate, &ty, &arg, trait_, |i| {
103 result.push(i.to_chalk(self.db))
104 });
105
106 debug!("impls_for_trait returned {} impls", result.len()); 126 debug!("impls_for_trait returned {} impls", result.len());
107 result 127 result
108 } 128 }
@@ -192,31 +212,55 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
192 _closure_id: chalk_ir::ClosureId<Interner>, 212 _closure_id: chalk_ir::ClosureId<Interner>,
193 _substs: &chalk_ir::Substitution<Interner>, 213 _substs: &chalk_ir::Substitution<Interner>,
194 ) -> rust_ir::ClosureKind { 214 ) -> rust_ir::ClosureKind {
195 // FIXME: implement closure support 215 // Fn is the closure kind that implements all three traits
196 unimplemented!() 216 rust_ir::ClosureKind::Fn
197 } 217 }
198 fn closure_inputs_and_output( 218 fn closure_inputs_and_output(
199 &self, 219 &self,
200 _closure_id: chalk_ir::ClosureId<Interner>, 220 _closure_id: chalk_ir::ClosureId<Interner>,
201 _substs: &chalk_ir::Substitution<Interner>, 221 substs: &chalk_ir::Substitution<Interner>,
202 ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> { 222 ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> {
203 // FIXME: implement closure support 223 let sig_ty: Ty =
204 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)
205 } 234 }
206 fn closure_upvars( 235 fn closure_upvars(
207 &self, 236 &self,
208 _closure_id: chalk_ir::ClosureId<Interner>, 237 _closure_id: chalk_ir::ClosureId<Interner>,
209 _substs: &chalk_ir::Substitution<Interner>, 238 _substs: &chalk_ir::Substitution<Interner>,
210 ) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> { 239 ) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> {
211 // FIXME: implement closure support 240 let ty = Ty::unit().to_chalk(self.db);
212 unimplemented!() 241 make_binders(ty, 0)
213 } 242 }
214 fn closure_fn_substitution( 243 fn closure_fn_substitution(
215 &self, 244 &self,
216 _closure_id: chalk_ir::ClosureId<Interner>, 245 _closure_id: chalk_ir::ClosureId<Interner>,
217 _substs: &chalk_ir::Substitution<Interner>, 246 _substs: &chalk_ir::Substitution<Interner>,
218 ) -> chalk_ir::Substitution<Interner> { 247 ) -> chalk_ir::Substitution<Interner> {
219 // FIXME: implement closure support 248 Substs::empty().to_chalk(self.db)
249 }
250
251 fn trait_name(&self, _trait_id: chalk_ir::TraitId<Interner>) -> String {
252 unimplemented!()
253 }
254 fn adt_name(&self, _struct_id: chalk_ir::AdtId<Interner>) -> String {
255 unimplemented!()
256 }
257 fn assoc_type_name(&self, _assoc_ty_id: chalk_ir::AssocTypeId<Interner>) -> String {
258 unimplemented!()
259 }
260 fn opaque_type_name(&self, _opaque_ty_id: chalk_ir::OpaqueTyId<Interner>) -> String {
261 unimplemented!()
262 }
263 fn fn_def_name(&self, _fn_def_id: chalk_ir::FnDefId<Interner>) -> String {
220 unimplemented!() 264 unimplemented!()
221 } 265 }
222} 266}
@@ -354,12 +398,18 @@ pub(crate) fn struct_datum_query(
354 fundamental: false, 398 fundamental: false,
355 phantom_data: false, 399 phantom_data: false,
356 }; 400 };
357 let struct_datum_bound = rust_ir::AdtDatumBound { 401 // FIXME provide enum variants properly (for auto traits)
358 fields: Vec::new(), // FIXME add fields (only relevant for auto traits) 402 let variant = rust_ir::AdtVariantDatum {
359 where_clauses, 403 fields: Vec::new(), // FIXME add fields (only relevant for auto traits),
404 };
405 let struct_datum_bound = rust_ir::AdtDatumBound { variants: vec![variant], where_clauses };
406 let struct_datum = StructDatum {
407 // FIXME set ADT kind
408 kind: rust_ir::AdtKind::Struct,
409 id: struct_id,
410 binders: make_binders(struct_datum_bound, num_params),
411 flags,
360 }; 412 };
361 let struct_datum =
362 StructDatum { id: struct_id, binders: make_binders(struct_datum_bound, num_params), flags };
363 Arc::new(struct_datum) 413 Arc::new(struct_datum)
364} 414}
365 415
@@ -370,11 +420,8 @@ pub(crate) fn impl_datum_query(
370) -> Arc<ImplDatum> { 420) -> Arc<ImplDatum> {
371 let _p = ra_prof::profile("impl_datum"); 421 let _p = ra_prof::profile("impl_datum");
372 debug!("impl_datum {:?}", impl_id); 422 debug!("impl_datum {:?}", impl_id);
373 let impl_: Impl = from_chalk(db, impl_id); 423 let impl_: hir_def::ImplId = from_chalk(db, impl_id);
374 match impl_ { 424 impl_def_datum(db, krate, impl_id, impl_)
375 Impl::ImplDef(impl_def) => impl_def_datum(db, krate, impl_id, impl_def),
376 _ => Arc::new(builtin::impl_datum(db, krate, impl_).to_chalk(db)),
377 }
378} 425}
379 426
380fn impl_def_datum( 427fn impl_def_datum(
@@ -425,7 +472,7 @@ fn impl_def_datum(
425 let name = &db.type_alias_data(type_alias).name; 472 let name = &db.type_alias_data(type_alias).name;
426 trait_data.associated_type_by_name(name).is_some() 473 trait_data.associated_type_by_name(name).is_some()
427 }) 474 })
428 .map(|type_alias| AssocTyValue::TypeAlias(type_alias).to_chalk(db)) 475 .map(|type_alias| TypeAliasAsValue(type_alias).to_chalk(db))
429 .collect(); 476 .collect();
430 debug!("impl_datum: {:?}", impl_datum_bound); 477 debug!("impl_datum: {:?}", impl_datum_bound);
431 let impl_datum = ImplDatum { 478 let impl_datum = ImplDatum {
@@ -442,13 +489,8 @@ pub(crate) fn associated_ty_value_query(
442 krate: CrateId, 489 krate: CrateId,
443 id: AssociatedTyValueId, 490 id: AssociatedTyValueId,
444) -> Arc<AssociatedTyValue> { 491) -> Arc<AssociatedTyValue> {
445 let data: AssocTyValue = from_chalk(db, id); 492 let type_alias: TypeAliasAsValue = from_chalk(db, id);
446 match data { 493 type_alias_associated_ty_value(db, krate, type_alias.0)
447 AssocTyValue::TypeAlias(type_alias) => {
448 type_alias_associated_ty_value(db, krate, type_alias)
449 }
450 _ => Arc::new(builtin::associated_ty_value(db, krate, data).to_chalk(db)),
451 }
452} 494}
453 495
454fn type_alias_associated_ty_value( 496fn type_alias_associated_ty_value(
@@ -471,7 +513,7 @@ fn type_alias_associated_ty_value(
471 let ty = db.ty(type_alias.into()); 513 let ty = db.ty(type_alias.into());
472 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) };
473 let value = rust_ir::AssociatedTyValue { 515 let value = rust_ir::AssociatedTyValue {
474 impl_id: Impl::ImplDef(impl_id).to_chalk(db), 516 impl_id: impl_id.to_chalk(db),
475 associated_ty_id: assoc_ty.to_chalk(db), 517 associated_ty_id: assoc_ty.to_chalk(db),
476 value: make_binders(value_bound, ty.num_binders), 518 value: make_binders(value_bound, ty.num_binders),
477 }; 519 };
@@ -483,7 +525,7 @@ pub(crate) fn fn_def_datum_query(
483 _krate: CrateId, 525 _krate: CrateId,
484 fn_def_id: FnDefId, 526 fn_def_id: FnDefId,
485) -> Arc<FnDefDatum> { 527) -> Arc<FnDefDatum> {
486 let callable_def: CallableDef = from_chalk(db, fn_def_id); 528 let callable_def: CallableDefId = from_chalk(db, fn_def_id);
487 let generic_params = generics(db.upcast(), callable_def.into()); 529 let generic_params = generics(db.upcast(), callable_def.into());
488 let sig = db.callable_item_signature(callable_def); 530 let sig = db.callable_item_signature(callable_def);
489 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 531 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
@@ -510,42 +552,18 @@ pub(crate) fn fn_def_datum_query(
510 Arc::new(datum) 552 Arc::new(datum)
511} 553}
512 554
513impl From<AdtId> for crate::TypeCtorId { 555impl From<FnDefId> for crate::db::InternedCallableDefId {
514 fn from(struct_id: AdtId) -> Self {
515 struct_id.0
516 }
517}
518
519impl From<crate::TypeCtorId> for AdtId {
520 fn from(type_ctor_id: crate::TypeCtorId) -> Self {
521 chalk_ir::AdtId(type_ctor_id)
522 }
523}
524
525impl From<FnDefId> for crate::CallableDefId {
526 fn from(fn_def_id: FnDefId) -> Self { 556 fn from(fn_def_id: FnDefId) -> Self {
527 InternKey::from_intern_id(fn_def_id.0) 557 InternKey::from_intern_id(fn_def_id.0)
528 } 558 }
529} 559}
530 560
531impl From<crate::CallableDefId> for FnDefId { 561impl From<crate::db::InternedCallableDefId> for FnDefId {
532 fn from(callable_def_id: crate::CallableDefId) -> Self { 562 fn from(callable_def_id: crate::db::InternedCallableDefId) -> Self {
533 chalk_ir::FnDefId(callable_def_id.as_intern_id()) 563 chalk_ir::FnDefId(callable_def_id.as_intern_id())
534 } 564 }
535} 565}
536 566
537impl From<ImplId> for crate::traits::GlobalImplId {
538 fn from(impl_id: ImplId) -> Self {
539 InternKey::from_intern_id(impl_id.0)
540 }
541}
542
543impl From<crate::traits::GlobalImplId> for ImplId {
544 fn from(impl_id: crate::traits::GlobalImplId) -> Self {
545 chalk_ir::ImplId(impl_id.as_intern_id())
546 }
547}
548
549impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId { 567impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId {
550 fn from(id: OpaqueTyId) -> Self { 568 fn from(id: OpaqueTyId) -> Self {
551 InternKey::from_intern_id(id.0) 569 InternKey::from_intern_id(id.0)
@@ -558,14 +576,14 @@ impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId {
558 } 576 }
559} 577}
560 578
561impl From<rust_ir::AssociatedTyValueId<Interner>> for crate::traits::AssocTyValueId { 579impl From<chalk_ir::ClosureId<Interner>> for crate::db::ClosureId {
562 fn from(id: rust_ir::AssociatedTyValueId<Interner>) -> Self { 580 fn from(id: chalk_ir::ClosureId<Interner>) -> Self {
563 Self::from_intern_id(id.0) 581 Self::from_intern_id(id.0)
564 } 582 }
565} 583}
566 584
567impl From<crate::traits::AssocTyValueId> for rust_ir::AssociatedTyValueId<Interner> { 585impl From<crate::db::ClosureId> for chalk_ir::ClosureId<Interner> {
568 fn from(assoc_ty_value_id: crate::traits::AssocTyValueId) -> Self { 586 fn from(id: crate::db::ClosureId) -> Self {
569 rust_ir::AssociatedTyValueId(assoc_ty_value_id.as_intern_id()) 587 chalk_ir::ClosureId(id.as_intern_id())
570 } 588 }
571} 589}