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.rs205
1 files changed, 109 insertions, 96 deletions
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 8ef4941c0..1c7065364 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,45 +71,58 @@ 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
79 // and will panic if the trait can't be resolved. 102 // and will panic if the trait can't be resolved.
80 let in_deps = self.db.impls_from_deps(self.krate); 103 let in_deps = self.db.trait_impls_in_deps(self.krate);
81 let in_self = self.db.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
88 .iter() 112 .iter()
89 .flat_map(|crate_impl_defs| { 113 .flat_map(|crate_impl_defs| crate_impl_defs.for_trait(trait_).map(id_to_chalk))
90 crate_impl_defs.lookup_impl_defs_for_trait_and_ty(trait_, fp).map(id_to_chalk) 114 .collect()
91 }) 115 } else {
92 .collect(), 116 impl_maps
93 None => impl_maps
94 .iter() 117 .iter()
95 .flat_map(|crate_impl_defs| { 118 .flat_map(|crate_impl_defs| {
96 crate_impl_defs.lookup_impl_defs_for_trait(trait_).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 })
97 }) 122 })
98 .collect(), 123 .collect()
99 }; 124 };
100 125
101 let arg: Option<Ty> =
102 parameters.get(1).map(|p| from_chalk(self.db, p.assert_ty_ref(&Interner).clone()));
103
104 builtin::get_builtin_impls(self.db, self.krate, &ty, &arg, trait_, |i| {
105 result.push(i.to_chalk(self.db))
106 });
107
108 debug!("impls_for_trait returned {} impls", result.len()); 126 debug!("impls_for_trait returned {} impls", result.len());
109 result 127 result
110 } 128 }
@@ -165,6 +183,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
165 .collect(), 183 .collect(),
166 1, 184 1,
167 ), 185 ),
186 where_clauses: make_binders(vec![], 0),
168 }; 187 };
169 let num_vars = datas.num_binders; 188 let num_vars = datas.num_binders;
170 Arc::new(OpaqueTyDatum { opaque_ty_id: id, bound: make_binders(bound, num_vars) }) 189 Arc::new(OpaqueTyDatum { opaque_ty_id: id, bound: make_binders(bound, num_vars) })
@@ -175,15 +194,6 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
175 Ty::Unknown.to_chalk(self.db) 194 Ty::Unknown.to_chalk(self.db)
176 } 195 }
177 196
178 fn force_impl_for(
179 &self,
180 _well_known: rust_ir::WellKnownTrait,
181 _ty: &chalk_ir::TyData<Interner>,
182 ) -> Option<bool> {
183 // this method is mostly for rustc
184 None
185 }
186
187 fn is_object_safe(&self, _trait_id: chalk_ir::TraitId<Interner>) -> bool { 197 fn is_object_safe(&self, _trait_id: chalk_ir::TraitId<Interner>) -> bool {
188 // FIXME: implement actual object safety 198 // FIXME: implement actual object safety
189 true 199 true
@@ -194,31 +204,55 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
194 _closure_id: chalk_ir::ClosureId<Interner>, 204 _closure_id: chalk_ir::ClosureId<Interner>,
195 _substs: &chalk_ir::Substitution<Interner>, 205 _substs: &chalk_ir::Substitution<Interner>,
196 ) -> rust_ir::ClosureKind { 206 ) -> rust_ir::ClosureKind {
197 // FIXME: implement closure support 207 // Fn is the closure kind that implements all three traits
198 unimplemented!() 208 rust_ir::ClosureKind::Fn
199 } 209 }
200 fn closure_inputs_and_output( 210 fn closure_inputs_and_output(
201 &self, 211 &self,
202 _closure_id: chalk_ir::ClosureId<Interner>, 212 _closure_id: chalk_ir::ClosureId<Interner>,
203 _substs: &chalk_ir::Substitution<Interner>, 213 substs: &chalk_ir::Substitution<Interner>,
204 ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> { 214 ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> {
205 // FIXME: implement closure support 215 let sig_ty: Ty =
206 unimplemented!() 216 from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone());
217 let sig = FnSig::from_fn_ptr_substs(
218 &sig_ty.substs().expect("first closure param should be fn ptr"),
219 false,
220 );
221 let io = rust_ir::FnDefInputsAndOutputDatum {
222 argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(),
223 return_type: sig.ret().clone().to_chalk(self.db),
224 };
225 make_binders(io.shifted_in(&Interner), 0)
207 } 226 }
208 fn closure_upvars( 227 fn closure_upvars(
209 &self, 228 &self,
210 _closure_id: chalk_ir::ClosureId<Interner>, 229 _closure_id: chalk_ir::ClosureId<Interner>,
211 _substs: &chalk_ir::Substitution<Interner>, 230 _substs: &chalk_ir::Substitution<Interner>,
212 ) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> { 231 ) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> {
213 // FIXME: implement closure support 232 let ty = Ty::unit().to_chalk(self.db);
214 unimplemented!() 233 make_binders(ty, 0)
215 } 234 }
216 fn closure_fn_substitution( 235 fn closure_fn_substitution(
217 &self, 236 &self,
218 _closure_id: chalk_ir::ClosureId<Interner>, 237 _closure_id: chalk_ir::ClosureId<Interner>,
219 _substs: &chalk_ir::Substitution<Interner>, 238 _substs: &chalk_ir::Substitution<Interner>,
220 ) -> chalk_ir::Substitution<Interner> { 239 ) -> chalk_ir::Substitution<Interner> {
221 // FIXME: implement closure support 240 Substs::empty().to_chalk(self.db)
241 }
242
243 fn trait_name(&self, _trait_id: chalk_ir::TraitId<Interner>) -> String {
244 unimplemented!()
245 }
246 fn adt_name(&self, _struct_id: chalk_ir::AdtId<Interner>) -> String {
247 unimplemented!()
248 }
249 fn assoc_type_name(&self, _assoc_ty_id: chalk_ir::AssocTypeId<Interner>) -> String {
250 unimplemented!()
251 }
252 fn opaque_type_name(&self, _opaque_ty_id: chalk_ir::OpaqueTyId<Interner>) -> String {
253 unimplemented!()
254 }
255 fn fn_def_name(&self, _fn_def_id: chalk_ir::FnDefId<Interner>) -> String {
222 unimplemented!() 256 unimplemented!()
223 } 257 }
224} 258}
@@ -356,12 +390,18 @@ pub(crate) fn struct_datum_query(
356 fundamental: false, 390 fundamental: false,
357 phantom_data: false, 391 phantom_data: false,
358 }; 392 };
359 let struct_datum_bound = rust_ir::AdtDatumBound { 393 // FIXME provide enum variants properly (for auto traits)
360 fields: Vec::new(), // FIXME add fields (only relevant for auto traits) 394 let variant = rust_ir::AdtVariantDatum {
361 where_clauses, 395 fields: Vec::new(), // FIXME add fields (only relevant for auto traits),
396 };
397 let struct_datum_bound = rust_ir::AdtDatumBound { variants: vec![variant], where_clauses };
398 let struct_datum = StructDatum {
399 // FIXME set ADT kind
400 kind: rust_ir::AdtKind::Struct,
401 id: struct_id,
402 binders: make_binders(struct_datum_bound, num_params),
403 flags,
362 }; 404 };
363 let struct_datum =
364 StructDatum { id: struct_id, binders: make_binders(struct_datum_bound, num_params), flags };
365 Arc::new(struct_datum) 405 Arc::new(struct_datum)
366} 406}
367 407
@@ -372,11 +412,8 @@ pub(crate) fn impl_datum_query(
372) -> Arc<ImplDatum> { 412) -> Arc<ImplDatum> {
373 let _p = ra_prof::profile("impl_datum"); 413 let _p = ra_prof::profile("impl_datum");
374 debug!("impl_datum {:?}", impl_id); 414 debug!("impl_datum {:?}", impl_id);
375 let impl_: Impl = from_chalk(db, impl_id); 415 let impl_: hir_def::ImplId = from_chalk(db, impl_id);
376 match impl_ { 416 impl_def_datum(db, krate, impl_id, impl_)
377 Impl::ImplDef(impl_def) => impl_def_datum(db, krate, impl_id, impl_def),
378 _ => Arc::new(builtin::impl_datum(db, krate, impl_).to_chalk(db)),
379 }
380} 417}
381 418
382fn impl_def_datum( 419fn impl_def_datum(
@@ -427,7 +464,7 @@ fn impl_def_datum(
427 let name = &db.type_alias_data(type_alias).name; 464 let name = &db.type_alias_data(type_alias).name;
428 trait_data.associated_type_by_name(name).is_some() 465 trait_data.associated_type_by_name(name).is_some()
429 }) 466 })
430 .map(|type_alias| AssocTyValue::TypeAlias(type_alias).to_chalk(db)) 467 .map(|type_alias| TypeAliasAsValue(type_alias).to_chalk(db))
431 .collect(); 468 .collect();
432 debug!("impl_datum: {:?}", impl_datum_bound); 469 debug!("impl_datum: {:?}", impl_datum_bound);
433 let impl_datum = ImplDatum { 470 let impl_datum = ImplDatum {
@@ -444,13 +481,8 @@ pub(crate) fn associated_ty_value_query(
444 krate: CrateId, 481 krate: CrateId,
445 id: AssociatedTyValueId, 482 id: AssociatedTyValueId,
446) -> Arc<AssociatedTyValue> { 483) -> Arc<AssociatedTyValue> {
447 let data: AssocTyValue = from_chalk(db, id); 484 let type_alias: TypeAliasAsValue = from_chalk(db, id);
448 match data { 485 type_alias_associated_ty_value(db, krate, type_alias.0)
449 AssocTyValue::TypeAlias(type_alias) => {
450 type_alias_associated_ty_value(db, krate, type_alias)
451 }
452 _ => Arc::new(builtin::associated_ty_value(db, krate, data).to_chalk(db)),
453 }
454} 486}
455 487
456fn type_alias_associated_ty_value( 488fn type_alias_associated_ty_value(
@@ -473,7 +505,7 @@ fn type_alias_associated_ty_value(
473 let ty = db.ty(type_alias.into()); 505 let ty = db.ty(type_alias.into());
474 let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) }; 506 let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) };
475 let value = rust_ir::AssociatedTyValue { 507 let value = rust_ir::AssociatedTyValue {
476 impl_id: Impl::ImplDef(impl_id).to_chalk(db), 508 impl_id: impl_id.to_chalk(db),
477 associated_ty_id: assoc_ty.to_chalk(db), 509 associated_ty_id: assoc_ty.to_chalk(db),
478 value: make_binders(value_bound, ty.num_binders), 510 value: make_binders(value_bound, ty.num_binders),
479 }; 511 };
@@ -485,7 +517,7 @@ pub(crate) fn fn_def_datum_query(
485 _krate: CrateId, 517 _krate: CrateId,
486 fn_def_id: FnDefId, 518 fn_def_id: FnDefId,
487) -> Arc<FnDefDatum> { 519) -> Arc<FnDefDatum> {
488 let callable_def: CallableDef = from_chalk(db, fn_def_id); 520 let callable_def: CallableDefId = from_chalk(db, fn_def_id);
489 let generic_params = generics(db.upcast(), callable_def.into()); 521 let generic_params = generics(db.upcast(), callable_def.into());
490 let sig = db.callable_item_signature(callable_def); 522 let sig = db.callable_item_signature(callable_def);
491 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 523 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
@@ -507,47 +539,28 @@ pub(crate) fn fn_def_datum_query(
507 ), 539 ),
508 where_clauses, 540 where_clauses,
509 }; 541 };
510 let datum = 542 let datum = FnDefDatum {
511 FnDefDatum { id: fn_def_id, binders: make_binders(bound, sig.num_binders), abi: () }; 543 id: fn_def_id,
544 abi: (),
545 safety: chalk_ir::Safety::Safe,
546 variadic: sig.value.is_varargs,
547 binders: make_binders(bound, sig.num_binders),
548 };
512 Arc::new(datum) 549 Arc::new(datum)
513} 550}
514 551
515impl From<AdtId> for crate::TypeCtorId { 552impl From<FnDefId> for crate::db::InternedCallableDefId {
516 fn from(struct_id: AdtId) -> Self {
517 struct_id.0
518 }
519}
520
521impl From<crate::TypeCtorId> for AdtId {
522 fn from(type_ctor_id: crate::TypeCtorId) -> Self {
523 chalk_ir::AdtId(type_ctor_id)
524 }
525}
526
527impl From<FnDefId> for crate::CallableDefId {
528 fn from(fn_def_id: FnDefId) -> Self { 553 fn from(fn_def_id: FnDefId) -> Self {
529 InternKey::from_intern_id(fn_def_id.0) 554 InternKey::from_intern_id(fn_def_id.0)
530 } 555 }
531} 556}
532 557
533impl From<crate::CallableDefId> for FnDefId { 558impl From<crate::db::InternedCallableDefId> for FnDefId {
534 fn from(callable_def_id: crate::CallableDefId) -> Self { 559 fn from(callable_def_id: crate::db::InternedCallableDefId) -> Self {
535 chalk_ir::FnDefId(callable_def_id.as_intern_id()) 560 chalk_ir::FnDefId(callable_def_id.as_intern_id())
536 } 561 }
537} 562}
538 563
539impl From<ImplId> for crate::traits::GlobalImplId {
540 fn from(impl_id: ImplId) -> Self {
541 InternKey::from_intern_id(impl_id.0)
542 }
543}
544
545impl From<crate::traits::GlobalImplId> for ImplId {
546 fn from(impl_id: crate::traits::GlobalImplId) -> Self {
547 chalk_ir::ImplId(impl_id.as_intern_id())
548 }
549}
550
551impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId { 564impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId {
552 fn from(id: OpaqueTyId) -> Self { 565 fn from(id: OpaqueTyId) -> Self {
553 InternKey::from_intern_id(id.0) 566 InternKey::from_intern_id(id.0)
@@ -560,14 +573,14 @@ impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId {
560 } 573 }
561} 574}
562 575
563impl From<rust_ir::AssociatedTyValueId<Interner>> for crate::traits::AssocTyValueId { 576impl From<chalk_ir::ClosureId<Interner>> for crate::db::ClosureId {
564 fn from(id: rust_ir::AssociatedTyValueId<Interner>) -> Self { 577 fn from(id: chalk_ir::ClosureId<Interner>) -> Self {
565 Self::from_intern_id(id.0) 578 Self::from_intern_id(id.0)
566 } 579 }
567} 580}
568 581
569impl From<crate::traits::AssocTyValueId> for rust_ir::AssociatedTyValueId<Interner> { 582impl From<crate::db::ClosureId> for chalk_ir::ClosureId<Interner> {
570 fn from(assoc_ty_value_id: crate::traits::AssocTyValueId) -> Self { 583 fn from(id: crate::db::ClosureId) -> Self {
571 rust_ir::AssociatedTyValueId(assoc_ty_value_id.as_intern_id()) 584 chalk_ir::ClosureId(id.as_intern_id())
572 } 585 }
573} 586}