diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/hir_ty/src/chalk_db.rs | 101 | ||||
-rw-r--r-- | crates/hir_ty/src/mapping.rs | 92 |
2 files changed, 93 insertions, 100 deletions
diff --git a/crates/hir_ty/src/chalk_db.rs b/crates/hir_ty/src/chalk_db.rs index f5b2c5ff0..9d07ad597 100644 --- a/crates/hir_ty/src/chalk_db.rs +++ b/crates/hir_ty/src/chalk_db.rs | |||
@@ -4,13 +4,13 @@ use std::sync::Arc; | |||
4 | 4 | ||
5 | use log::debug; | 5 | use log::debug; |
6 | 6 | ||
7 | use chalk_ir::{fold::shift::Shift, CanonicalVarKinds}; | 7 | use chalk_ir::{cast::Cast, fold::shift::Shift, CanonicalVarKinds}; |
8 | use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; | 8 | use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; |
9 | 9 | ||
10 | use base_db::{salsa::InternKey, CrateId}; | 10 | use base_db::CrateId; |
11 | use hir_def::{ | 11 | use hir_def::{ |
12 | lang_item::{lang_attr, LangItemTarget}, | 12 | lang_item::{lang_attr, LangItemTarget}, |
13 | AssocContainerId, AssocItemId, HasModule, Lookup, TypeAliasId, | 13 | AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId, |
14 | }; | 14 | }; |
15 | use hir_expand::name::name; | 15 | use hir_expand::name::name; |
16 | 16 | ||
@@ -18,16 +18,14 @@ use crate::{ | |||
18 | db::HirDatabase, | 18 | db::HirDatabase, |
19 | display::HirDisplay, | 19 | display::HirDisplay, |
20 | from_assoc_type_id, make_only_type_binders, | 20 | from_assoc_type_id, make_only_type_binders, |
21 | mapping::{ | 21 | mapping::{from_chalk, ToChalk, TypeAliasAsValue}, |
22 | convert_where_clauses, from_chalk, generic_predicate_to_inline_bound, ToChalk, | ||
23 | TypeAliasAsValue, | ||
24 | }, | ||
25 | method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, | 22 | method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, |
26 | to_assoc_type_id, to_chalk_trait_id, | 23 | to_assoc_type_id, to_chalk_trait_id, |
27 | traits::ChalkContext, | 24 | traits::ChalkContext, |
28 | utils::generics, | 25 | utils::generics, |
29 | AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, Interner, ProjectionTy, | 26 | AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, Interner, ProjectionTy, |
30 | Substitution, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, WhereClause, | 27 | ProjectionTyExt, QuantifiedWhereClause, Substitution, TraitRef, TraitRefExt, Ty, TyBuilder, |
28 | TyExt, TyKind, WhereClause, | ||
31 | }; | 29 | }; |
32 | 30 | ||
33 | pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>; | 31 | pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>; |
@@ -39,7 +37,6 @@ pub(crate) type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>; | |||
39 | pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>; | 37 | pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>; |
40 | pub(crate) type TraitId = chalk_ir::TraitId<Interner>; | 38 | pub(crate) type TraitId = chalk_ir::TraitId<Interner>; |
41 | pub(crate) type AdtId = chalk_ir::AdtId<Interner>; | 39 | pub(crate) type AdtId = chalk_ir::AdtId<Interner>; |
42 | pub(crate) type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; | ||
43 | pub(crate) type ImplId = chalk_ir::ImplId<Interner>; | 40 | pub(crate) type ImplId = chalk_ir::ImplId<Interner>; |
44 | pub(crate) type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>; | 41 | pub(crate) type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>; |
45 | pub(crate) type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; | 42 | pub(crate) type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; |
@@ -679,38 +676,62 @@ pub(crate) fn adt_variance_query( | |||
679 | ) | 676 | ) |
680 | } | 677 | } |
681 | 678 | ||
682 | impl From<FnDefId> for crate::db::InternedCallableDefId { | 679 | pub(super) fn convert_where_clauses( |
683 | fn from(fn_def_id: FnDefId) -> Self { | 680 | db: &dyn HirDatabase, |
684 | InternKey::from_intern_id(fn_def_id.0) | 681 | def: GenericDefId, |
685 | } | 682 | substs: &Substitution, |
686 | } | 683 | ) -> Vec<chalk_ir::QuantifiedWhereClause<Interner>> { |
687 | 684 | let generic_predicates = db.generic_predicates(def); | |
688 | impl From<crate::db::InternedCallableDefId> for FnDefId { | 685 | let mut result = Vec::with_capacity(generic_predicates.len()); |
689 | fn from(callable_def_id: crate::db::InternedCallableDefId) -> Self { | 686 | for pred in generic_predicates.iter() { |
690 | chalk_ir::FnDefId(callable_def_id.as_intern_id()) | 687 | result.push(pred.clone().substitute(&Interner, substs)); |
691 | } | 688 | } |
692 | } | 689 | result |
693 | |||
694 | impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId { | ||
695 | fn from(id: OpaqueTyId) -> Self { | ||
696 | InternKey::from_intern_id(id.0) | ||
697 | } | ||
698 | } | ||
699 | |||
700 | impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId { | ||
701 | fn from(id: crate::db::InternedOpaqueTyId) -> Self { | ||
702 | chalk_ir::OpaqueTyId(id.as_intern_id()) | ||
703 | } | ||
704 | } | ||
705 | |||
706 | impl From<chalk_ir::ClosureId<Interner>> for crate::db::InternedClosureId { | ||
707 | fn from(id: chalk_ir::ClosureId<Interner>) -> Self { | ||
708 | Self::from_intern_id(id.0) | ||
709 | } | ||
710 | } | 690 | } |
711 | 691 | ||
712 | impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> { | 692 | pub(super) fn generic_predicate_to_inline_bound( |
713 | fn from(id: crate::db::InternedClosureId) -> Self { | 693 | db: &dyn HirDatabase, |
714 | chalk_ir::ClosureId(id.as_intern_id()) | 694 | pred: &QuantifiedWhereClause, |
695 | self_ty: &Ty, | ||
696 | ) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> { | ||
697 | // An InlineBound is like a GenericPredicate, except the self type is left out. | ||
698 | // We don't have a special type for this, but Chalk does. | ||
699 | let self_ty_shifted_in = self_ty.clone().shifted_in_from(&Interner, DebruijnIndex::ONE); | ||
700 | let (pred, binders) = pred.as_ref().into_value_and_skipped_binders(); | ||
701 | match pred { | ||
702 | WhereClause::Implemented(trait_ref) => { | ||
703 | if trait_ref.self_type_parameter(&Interner) != self_ty_shifted_in { | ||
704 | // we can only convert predicates back to type bounds if they | ||
705 | // have the expected self type | ||
706 | return None; | ||
707 | } | ||
708 | let args_no_self = trait_ref.substitution.as_slice(&Interner)[1..] | ||
709 | .iter() | ||
710 | .map(|ty| ty.clone().cast(&Interner)) | ||
711 | .collect(); | ||
712 | let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; | ||
713 | Some(chalk_ir::Binders::new(binders, rust_ir::InlineBound::TraitBound(trait_bound))) | ||
714 | } | ||
715 | WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { | ||
716 | if projection_ty.self_type_parameter(&Interner) != self_ty_shifted_in { | ||
717 | return None; | ||
718 | } | ||
719 | let trait_ = projection_ty.trait_(db); | ||
720 | let args_no_self = projection_ty.substitution.as_slice(&Interner)[1..] | ||
721 | .iter() | ||
722 | .map(|ty| ty.clone().cast(&Interner)) | ||
723 | .collect(); | ||
724 | let alias_eq_bound = rust_ir::AliasEqBound { | ||
725 | value: ty.clone(), | ||
726 | trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self }, | ||
727 | associated_ty_id: projection_ty.associated_ty_id, | ||
728 | parameters: Vec::new(), // FIXME we don't support generic associated types yet | ||
729 | }; | ||
730 | Some(chalk_ir::Binders::new( | ||
731 | binders, | ||
732 | rust_ir::InlineBound::AliasEqBound(alias_eq_bound), | ||
733 | )) | ||
734 | } | ||
735 | _ => None, | ||
715 | } | 736 | } |
716 | } | 737 | } |
diff --git a/crates/hir_ty/src/mapping.rs b/crates/hir_ty/src/mapping.rs index f57115de6..37c935194 100644 --- a/crates/hir_ty/src/mapping.rs +++ b/crates/hir_ty/src/mapping.rs | |||
@@ -3,16 +3,12 @@ | |||
3 | //! Chalk (in both directions); plus some helper functions for more specialized | 3 | //! Chalk (in both directions); plus some helper functions for more specialized |
4 | //! conversions. | 4 | //! conversions. |
5 | 5 | ||
6 | use chalk_ir::{cast::Cast, fold::Shift, DebruijnIndex}; | ||
7 | use chalk_solve::rust_ir; | 6 | use chalk_solve::rust_ir; |
8 | 7 | ||
9 | use base_db::salsa::InternKey; | 8 | use base_db::salsa::InternKey; |
10 | use hir_def::{GenericDefId, TypeAliasId}; | 9 | use hir_def::TypeAliasId; |
11 | 10 | ||
12 | use crate::{ | 11 | use crate::{chalk_db, db::HirDatabase, CallableDefId, FnDefId, Interner, OpaqueTyId}; |
13 | chalk_db, db::HirDatabase, AliasEq, AliasTy, CallableDefId, FnDefId, Interner, ProjectionTyExt, | ||
14 | QuantifiedWhereClause, Substitution, Ty, WhereClause, | ||
15 | }; | ||
16 | 12 | ||
17 | pub(crate) trait ToChalk { | 13 | pub(crate) trait ToChalk { |
18 | type Chalk; | 14 | type Chalk; |
@@ -80,62 +76,38 @@ impl ToChalk for TypeAliasAsValue { | |||
80 | } | 76 | } |
81 | } | 77 | } |
82 | 78 | ||
83 | pub(super) fn convert_where_clauses( | 79 | impl From<FnDefId> for crate::db::InternedCallableDefId { |
84 | db: &dyn HirDatabase, | 80 | fn from(fn_def_id: FnDefId) -> Self { |
85 | def: GenericDefId, | 81 | InternKey::from_intern_id(fn_def_id.0) |
86 | substs: &Substitution, | ||
87 | ) -> Vec<chalk_ir::QuantifiedWhereClause<Interner>> { | ||
88 | let generic_predicates = db.generic_predicates(def); | ||
89 | let mut result = Vec::with_capacity(generic_predicates.len()); | ||
90 | for pred in generic_predicates.iter() { | ||
91 | result.push(pred.clone().substitute(&Interner, substs)); | ||
92 | } | 82 | } |
93 | result | ||
94 | } | 83 | } |
95 | 84 | ||
96 | pub(super) fn generic_predicate_to_inline_bound( | 85 | impl From<crate::db::InternedCallableDefId> for FnDefId { |
97 | db: &dyn HirDatabase, | 86 | fn from(callable_def_id: crate::db::InternedCallableDefId) -> Self { |
98 | pred: &QuantifiedWhereClause, | 87 | chalk_ir::FnDefId(callable_def_id.as_intern_id()) |
99 | self_ty: &Ty, | 88 | } |
100 | ) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> { | 89 | } |
101 | // An InlineBound is like a GenericPredicate, except the self type is left out. | 90 | |
102 | // We don't have a special type for this, but Chalk does. | 91 | impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId { |
103 | let self_ty_shifted_in = self_ty.clone().shifted_in_from(&Interner, DebruijnIndex::ONE); | 92 | fn from(id: OpaqueTyId) -> Self { |
104 | let (pred, binders) = pred.as_ref().into_value_and_skipped_binders(); | 93 | InternKey::from_intern_id(id.0) |
105 | match pred { | 94 | } |
106 | WhereClause::Implemented(trait_ref) => { | 95 | } |
107 | if trait_ref.self_type_parameter(&Interner) != self_ty_shifted_in { | 96 | |
108 | // we can only convert predicates back to type bounds if they | 97 | impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId { |
109 | // have the expected self type | 98 | fn from(id: crate::db::InternedOpaqueTyId) -> Self { |
110 | return None; | 99 | chalk_ir::OpaqueTyId(id.as_intern_id()) |
111 | } | 100 | } |
112 | let args_no_self = trait_ref.substitution.as_slice(&Interner)[1..] | 101 | } |
113 | .iter() | 102 | |
114 | .map(|ty| ty.clone().cast(&Interner)) | 103 | impl From<chalk_ir::ClosureId<Interner>> for crate::db::InternedClosureId { |
115 | .collect(); | 104 | fn from(id: chalk_ir::ClosureId<Interner>) -> Self { |
116 | let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; | 105 | Self::from_intern_id(id.0) |
117 | Some(chalk_ir::Binders::new(binders, rust_ir::InlineBound::TraitBound(trait_bound))) | 106 | } |
118 | } | 107 | } |
119 | WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { | 108 | |
120 | if projection_ty.self_type_parameter(&Interner) != self_ty_shifted_in { | 109 | impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> { |
121 | return None; | 110 | fn from(id: crate::db::InternedClosureId) -> Self { |
122 | } | 111 | chalk_ir::ClosureId(id.as_intern_id()) |
123 | let trait_ = projection_ty.trait_(db); | ||
124 | let args_no_self = projection_ty.substitution.as_slice(&Interner)[1..] | ||
125 | .iter() | ||
126 | .map(|ty| ty.clone().cast(&Interner)) | ||
127 | .collect(); | ||
128 | let alias_eq_bound = rust_ir::AliasEqBound { | ||
129 | value: ty.clone(), | ||
130 | trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self }, | ||
131 | associated_ty_id: projection_ty.associated_ty_id, | ||
132 | parameters: Vec::new(), // FIXME we don't support generic associated types yet | ||
133 | }; | ||
134 | Some(chalk_ir::Binders::new( | ||
135 | binders, | ||
136 | rust_ir::InlineBound::AliasEqBound(alias_eq_bound), | ||
137 | )) | ||
138 | } | ||
139 | _ => None, | ||
140 | } | 112 | } |
141 | } | 113 | } |