diff options
Diffstat (limited to 'crates/ra_hir_ty/src/traits/chalk.rs')
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk.rs | 182 |
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 | ||
4 | use log::debug; | 4 | use log::debug; |
5 | 5 | ||
6 | use chalk_ir::{fold::shift::Shift, GenericArg, TypeName}; | 6 | use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg, TypeName}; |
7 | use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; | 7 | use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; |
8 | 8 | ||
9 | use hir_def::{ | 9 | use hir_def::{ |
@@ -12,12 +12,17 @@ use hir_def::{ | |||
12 | }; | 12 | }; |
13 | use ra_db::{salsa::InternKey, CrateId}; | 13 | use ra_db::{salsa::InternKey, CrateId}; |
14 | 14 | ||
15 | use super::{builtin, AssocTyValue, ChalkContext, Impl}; | 15 | use super::ChalkContext; |
16 | use crate::{ | 16 | use 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 | }; | ||
23 | use mapping::{ | ||
24 | convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, | ||
19 | }; | 25 | }; |
20 | use mapping::{convert_where_clauses, generic_predicate_to_inline_bound, make_binders}; | ||
21 | 26 | ||
22 | pub use self::interner::*; | 27 | pub 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 | ||
380 | fn impl_def_datum( | 427 | fn 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 | ||
454 | fn type_alias_associated_ty_value( | 496 | fn 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 | ||
513 | impl From<AdtId> for crate::TypeCtorId { | 555 | impl From<FnDefId> for crate::db::InternedCallableDefId { |
514 | fn from(struct_id: AdtId) -> Self { | ||
515 | struct_id.0 | ||
516 | } | ||
517 | } | ||
518 | |||
519 | impl From<crate::TypeCtorId> for AdtId { | ||
520 | fn from(type_ctor_id: crate::TypeCtorId) -> Self { | ||
521 | chalk_ir::AdtId(type_ctor_id) | ||
522 | } | ||
523 | } | ||
524 | |||
525 | impl 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 | ||
531 | impl From<crate::CallableDefId> for FnDefId { | 561 | impl 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 | ||
537 | impl From<ImplId> for crate::traits::GlobalImplId { | ||
538 | fn from(impl_id: ImplId) -> Self { | ||
539 | InternKey::from_intern_id(impl_id.0) | ||
540 | } | ||
541 | } | ||
542 | |||
543 | impl 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 | |||
549 | impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId { | 567 | impl 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 | ||
561 | impl From<rust_ir::AssociatedTyValueId<Interner>> for crate::traits::AssocTyValueId { | 579 | impl 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 | ||
567 | impl From<crate::traits::AssocTyValueId> for rust_ir::AssociatedTyValueId<Interner> { | 585 | impl 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 | } |