diff options
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | crates/ra_hir/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 21 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 14 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits.rs | 33 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 110 | ||||
-rw-r--r-- | crates/ra_hir/src/type_alias.rs | 18 |
9 files changed, 190 insertions, 21 deletions
diff --git a/Cargo.lock b/Cargo.lock index 03b5794fa..42b8ce7c2 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -1079,6 +1079,7 @@ dependencies = [ | |||
1079 | "flexi_logger 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)", | 1079 | "flexi_logger 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)", |
1080 | "insta 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1080 | "insta 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1081 | "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", | 1081 | "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", |
1082 | "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1082 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", | 1083 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", |
1083 | "once_cell 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1084 | "once_cell 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1084 | "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1085 | "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", |
diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml index 12d849f37..aaace85e5 100644 --- a/crates/ra_hir/Cargo.toml +++ b/crates/ra_hir/Cargo.toml | |||
@@ -25,6 +25,7 @@ ra_prof = { path = "../ra_prof" } | |||
25 | chalk-solve = { git = "https://github.com/flodiebold/chalk.git", branch = "fuel" } | 25 | chalk-solve = { git = "https://github.com/flodiebold/chalk.git", branch = "fuel" } |
26 | chalk-rust-ir = { git = "https://github.com/flodiebold/chalk.git", branch = "fuel" } | 26 | chalk-rust-ir = { git = "https://github.com/flodiebold/chalk.git", branch = "fuel" } |
27 | chalk-ir = { git = "https://github.com/flodiebold/chalk.git", branch = "fuel" } | 27 | chalk-ir = { git = "https://github.com/flodiebold/chalk.git", branch = "fuel" } |
28 | lalrpop-intern = "0.15.1" | ||
28 | 29 | ||
29 | [dev-dependencies] | 30 | [dev-dependencies] |
30 | flexi_logger = "0.11.0" | 31 | flexi_logger = "0.11.0" |
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 830aea1f3..4fbb1fc8f 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -779,6 +779,19 @@ impl Trait { | |||
779 | self.trait_data(db).items().to_vec() | 779 | self.trait_data(db).items().to_vec() |
780 | } | 780 | } |
781 | 781 | ||
782 | pub fn associated_type_by_name(self, db: &impl DefDatabase, name: Name) -> Option<TypeAlias> { | ||
783 | let trait_data = self.trait_data(db); | ||
784 | trait_data | ||
785 | .items() | ||
786 | .iter() | ||
787 | .filter_map(|item| match item { | ||
788 | TraitItem::TypeAlias(t) => Some(*t), | ||
789 | _ => None, | ||
790 | }) | ||
791 | .filter(|t| t.name(db) == name) | ||
792 | .next() | ||
793 | } | ||
794 | |||
782 | pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc<TraitData> { | 795 | pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc<TraitData> { |
783 | db.trait_data(self) | 796 | db.trait_data(self) |
784 | } | 797 | } |
@@ -831,8 +844,12 @@ impl TypeAlias { | |||
831 | } | 844 | } |
832 | } | 845 | } |
833 | 846 | ||
834 | pub fn type_ref(self, db: &impl DefDatabase) -> Arc<TypeRef> { | 847 | pub fn type_ref(self, db: &impl DefDatabase) -> Option<TypeRef> { |
835 | db.type_alias_ref(self) | 848 | db.type_alias_data(self).type_ref.clone() |
849 | } | ||
850 | |||
851 | pub fn name(self, db: &impl DefDatabase) -> Name { | ||
852 | db.type_alias_data(self).name.clone() | ||
836 | } | 853 | } |
837 | 854 | ||
838 | /// Builds a resolver for the type references in this type alias. | 855 | /// Builds a resolver for the type references in this type alias. |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index d2d6f95b7..651f0d4ca 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -16,9 +16,8 @@ use crate::{ | |||
16 | adt::{StructData, EnumData}, | 16 | adt::{StructData, EnumData}, |
17 | impl_block::{ModuleImplBlocks, ImplSourceMap, ImplBlock}, | 17 | impl_block::{ModuleImplBlocks, ImplSourceMap, ImplBlock}, |
18 | generics::{GenericParams, GenericDef}, | 18 | generics::{GenericParams, GenericDef}, |
19 | type_ref::TypeRef, | ||
20 | traits::TraitData, | 19 | traits::TraitData, |
21 | lang_item::{LangItems, LangItemTarget}, | 20 | lang_item::{LangItems, LangItemTarget}, type_alias::TypeAliasData, |
22 | }; | 21 | }; |
23 | 22 | ||
24 | // This database has access to source code, so queries here are not really | 23 | // This database has access to source code, so queries here are not really |
@@ -113,8 +112,8 @@ pub trait DefDatabase: SourceDatabase { | |||
113 | #[salsa::invoke(crate::FnSignature::fn_signature_query)] | 112 | #[salsa::invoke(crate::FnSignature::fn_signature_query)] |
114 | fn fn_signature(&self, func: Function) -> Arc<FnSignature>; | 113 | fn fn_signature(&self, func: Function) -> Arc<FnSignature>; |
115 | 114 | ||
116 | #[salsa::invoke(crate::type_alias::type_alias_ref_query)] | 115 | #[salsa::invoke(crate::type_alias::type_alias_data_query)] |
117 | fn type_alias_ref(&self, typ: TypeAlias) -> Arc<TypeRef>; | 116 | fn type_alias_data(&self, typ: TypeAlias) -> Arc<TypeAliasData>; |
118 | 117 | ||
119 | #[salsa::invoke(crate::ConstSignature::const_signature_query)] | 118 | #[salsa::invoke(crate::ConstSignature::const_signature_query)] |
120 | fn const_signature(&self, konst: Const) -> Arc<ConstSignature>; | 119 | fn const_signature(&self, konst: Const) -> Arc<ConstSignature>; |
@@ -185,6 +184,13 @@ pub trait HirDatabase: DefDatabase + AstDatabase { | |||
185 | krate: Crate, | 184 | krate: Crate, |
186 | goal: crate::ty::Canonical<crate::ty::TraitRef>, | 185 | goal: crate::ty::Canonical<crate::ty::TraitRef>, |
187 | ) -> Option<crate::ty::traits::Solution>; | 186 | ) -> Option<crate::ty::traits::Solution>; |
187 | |||
188 | #[salsa::invoke(crate::ty::traits::normalize)] | ||
189 | fn normalize( | ||
190 | &self, | ||
191 | krate: Crate, | ||
192 | goal: crate::ty::Canonical<crate::ty::traits::ProjectionPredicate>, | ||
193 | ) -> Option<crate::ty::traits::Solution>; | ||
188 | } | 194 | } |
189 | 195 | ||
190 | #[test] | 196 | #[test] |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 4a37e0268..d9a50b230 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -16,7 +16,7 @@ use std::sync::Arc; | |||
16 | use std::ops::Deref; | 16 | use std::ops::Deref; |
17 | use std::{fmt, mem}; | 17 | use std::{fmt, mem}; |
18 | 18 | ||
19 | use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase, Trait, GenericParams}; | 19 | use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase, Trait, GenericParams, TypeAlias}; |
20 | use display::{HirDisplay, HirFormatter}; | 20 | use display::{HirDisplay, HirFormatter}; |
21 | 21 | ||
22 | pub(crate) use lower::{TypableDef, type_for_def, type_for_field, callable_item_sig, generic_predicates, generic_defaults}; | 22 | pub(crate) use lower::{TypableDef, type_for_def, type_for_field, callable_item_sig, generic_predicates, generic_defaults}; |
@@ -100,6 +100,15 @@ pub struct ApplicationTy { | |||
100 | pub parameters: Substs, | 100 | pub parameters: Substs, |
101 | } | 101 | } |
102 | 102 | ||
103 | /// A "projection" type corresponds to an (unnormalized) | ||
104 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the | ||
105 | /// trait and all its parameters are fully known. | ||
106 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
107 | pub struct ProjectionTy { | ||
108 | pub associated_ty: TypeAlias, | ||
109 | pub parameters: Substs, | ||
110 | } | ||
111 | |||
103 | /// A type. | 112 | /// A type. |
104 | /// | 113 | /// |
105 | /// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents | 114 | /// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents |
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 26c213a41..300616a53 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -460,7 +460,7 @@ fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { | |||
460 | let resolver = t.resolver(db); | 460 | let resolver = t.resolver(db); |
461 | let type_ref = t.type_ref(db); | 461 | let type_ref = t.type_ref(db); |
462 | let substs = Substs::identity(&generics); | 462 | let substs = Substs::identity(&generics); |
463 | let inner = Ty::from_hir(db, &resolver, &type_ref); | 463 | let inner = Ty::from_hir(db, &resolver, &type_ref.unwrap_or(TypeRef::Error)); |
464 | inner.subst(&substs) | 464 | inner.subst(&substs) |
465 | } | 465 | } |
466 | 466 | ||
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index fda7f9c04..f3e488403 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs | |||
@@ -8,7 +8,7 @@ use chalk_ir::cast::Cast; | |||
8 | use ra_prof::profile; | 8 | use ra_prof::profile; |
9 | 9 | ||
10 | use crate::{Crate, Trait, db::HirDatabase, ImplBlock}; | 10 | use crate::{Crate, Trait, db::HirDatabase, ImplBlock}; |
11 | use super::{TraitRef, Ty, Canonical}; | 11 | use super::{TraitRef, Ty, Canonical, ProjectionTy}; |
12 | 12 | ||
13 | use self::chalk::{ToChalk, from_chalk}; | 13 | use self::chalk::{ToChalk, from_chalk}; |
14 | 14 | ||
@@ -75,6 +75,13 @@ pub enum Obligation { | |||
75 | /// Prove that a certain type implements a trait (the type is the `Self` type | 75 | /// Prove that a certain type implements a trait (the type is the `Self` type |
76 | /// parameter to the `TraitRef`). | 76 | /// parameter to the `TraitRef`). |
77 | Trait(TraitRef), | 77 | Trait(TraitRef), |
78 | // Projection(ProjectionPredicate), | ||
79 | } | ||
80 | |||
81 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
82 | pub struct ProjectionPredicate { | ||
83 | projection_ty: ProjectionTy, | ||
84 | ty: Ty, | ||
78 | } | 85 | } |
79 | 86 | ||
80 | /// Check using Chalk whether trait is implemented for given parameters including `Self` type. | 87 | /// Check using Chalk whether trait is implemented for given parameters including `Self` type. |
@@ -98,6 +105,30 @@ pub(crate) fn implements_query( | |||
98 | solution.map(|solution| solution_from_chalk(db, solution)) | 105 | solution.map(|solution| solution_from_chalk(db, solution)) |
99 | } | 106 | } |
100 | 107 | ||
108 | pub(crate) fn normalize( | ||
109 | db: &impl HirDatabase, | ||
110 | krate: Crate, | ||
111 | projection: Canonical<ProjectionPredicate>, | ||
112 | ) -> Option<Solution> { | ||
113 | let goal: chalk_ir::Goal = chalk_ir::Normalize { | ||
114 | projection: projection.value.projection_ty.to_chalk(db), | ||
115 | ty: projection.value.ty.to_chalk(db), | ||
116 | } | ||
117 | .cast(); | ||
118 | debug!("goal: {:?}", goal); | ||
119 | // FIXME unify with `implements` | ||
120 | let env = chalk_ir::Environment::new(); | ||
121 | let in_env = chalk_ir::InEnvironment::new(&env, goal); | ||
122 | let parameter = chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex::ROOT); | ||
123 | let canonical = | ||
124 | chalk_ir::Canonical { value: in_env, binders: vec![parameter; projection.num_vars] }; | ||
125 | // We currently don't deal with universes (I think / hope they're not yet | ||
126 | // relevant for our use cases?) | ||
127 | let u_canonical = chalk_ir::UCanonical { canonical, universes: 1 }; | ||
128 | let solution = solve(db, krate, &u_canonical); | ||
129 | solution.map(|solution| solution_from_chalk(db, solution)) | ||
130 | } | ||
131 | |||
101 | fn solution_from_chalk(db: &impl HirDatabase, solution: chalk_solve::Solution) -> Solution { | 132 | fn solution_from_chalk(db: &impl HirDatabase, solution: chalk_solve::Solution) -> Solution { |
102 | let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution>| { | 133 | let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution>| { |
103 | let value = subst | 134 | let value = subst |
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 1e4806db0..1e1b6f406 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/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::{TypeId, ImplId, TypeKindId, ProjectionTy, Parameter, Identifier, cast::Cast, PlaceholderIndex, UniverseIndex, TypeName}; | 6 | use chalk_ir::{TypeId, ImplId, TypeKindId, Parameter, Identifier, cast::Cast, PlaceholderIndex, UniverseIndex, TypeName}; |
7 | use chalk_rust_ir::{AssociatedTyDatum, TraitDatum, StructDatum, ImplDatum}; | 7 | use chalk_rust_ir::{AssociatedTyDatum, TraitDatum, StructDatum, ImplDatum}; |
8 | 8 | ||
9 | use test_utils::tested_by; | 9 | use test_utils::tested_by; |
@@ -12,9 +12,9 @@ use ra_db::salsa::{InternId, InternKey}; | |||
12 | use crate::{ | 12 | use crate::{ |
13 | Trait, HasGenericParams, ImplBlock, | 13 | Trait, HasGenericParams, ImplBlock, |
14 | db::HirDatabase, | 14 | db::HirDatabase, |
15 | ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate, CallableDef}, | 15 | ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate, CallableDef, ProjectionTy}, |
16 | ty::display::HirDisplay, | 16 | ty::display::HirDisplay, |
17 | generics::GenericDef, | 17 | generics::GenericDef, TypeAlias, ImplItem, |
18 | }; | 18 | }; |
19 | use super::ChalkContext; | 19 | use super::ChalkContext; |
20 | 20 | ||
@@ -156,6 +156,18 @@ impl ToChalk for ImplBlock { | |||
156 | } | 156 | } |
157 | } | 157 | } |
158 | 158 | ||
159 | impl ToChalk for TypeAlias { | ||
160 | type Chalk = chalk_ir::TypeId; | ||
161 | |||
162 | fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TypeId { | ||
163 | self.id.into() | ||
164 | } | ||
165 | |||
166 | fn from_chalk(_db: &impl HirDatabase, impl_id: chalk_ir::TypeId) -> TypeAlias { | ||
167 | TypeAlias { id: impl_id.into() } | ||
168 | } | ||
169 | } | ||
170 | |||
159 | impl ToChalk for GenericPredicate { | 171 | impl ToChalk for GenericPredicate { |
160 | type Chalk = chalk_ir::QuantifiedWhereClause; | 172 | type Chalk = chalk_ir::QuantifiedWhereClause; |
161 | 173 | ||
@@ -183,6 +195,24 @@ impl ToChalk for GenericPredicate { | |||
183 | } | 195 | } |
184 | } | 196 | } |
185 | 197 | ||
198 | impl ToChalk for ProjectionTy { | ||
199 | type Chalk = chalk_ir::ProjectionTy; | ||
200 | |||
201 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ProjectionTy { | ||
202 | chalk_ir::ProjectionTy { | ||
203 | associated_ty_id: self.associated_ty.to_chalk(db), | ||
204 | parameters: self.parameters.to_chalk(db), | ||
205 | } | ||
206 | } | ||
207 | |||
208 | fn from_chalk(db: &impl HirDatabase, projection_ty: chalk_ir::ProjectionTy) -> ProjectionTy { | ||
209 | ProjectionTy { | ||
210 | associated_ty: from_chalk(db, projection_ty.associated_ty_id), | ||
211 | parameters: from_chalk(db, projection_ty.parameters), | ||
212 | } | ||
213 | } | ||
214 | } | ||
215 | |||
186 | fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> { | 216 | fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> { |
187 | chalk_ir::Binders { | 217 | chalk_ir::Binders { |
188 | value, | 218 | value, |
@@ -225,8 +255,28 @@ impl<'a, DB> chalk_solve::RustIrDatabase for ChalkContext<'a, DB> | |||
225 | where | 255 | where |
226 | DB: HirDatabase, | 256 | DB: HirDatabase, |
227 | { | 257 | { |
228 | fn associated_ty_data(&self, _ty: TypeId) -> Arc<AssociatedTyDatum> { | 258 | fn associated_ty_data(&self, id: TypeId) -> Arc<AssociatedTyDatum> { |
229 | unimplemented!() | 259 | debug!("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 | bounds: vec![], // FIXME | ||
277 | where_clauses: vec![], // FIXME | ||
278 | }; | ||
279 | Arc::new(datum) | ||
230 | } | 280 | } |
231 | fn trait_datum(&self, trait_id: chalk_ir::TraitId) -> Arc<TraitDatum> { | 281 | fn trait_datum(&self, trait_id: chalk_ir::TraitId) -> Arc<TraitDatum> { |
232 | debug!("trait_datum {:?}", trait_id); | 282 | debug!("trait_datum {:?}", trait_id); |
@@ -260,7 +310,15 @@ where | |||
260 | fundamental: false, | 310 | fundamental: false, |
261 | }; | 311 | }; |
262 | let where_clauses = convert_where_clauses(self.db, trait_.into(), &bound_vars); | 312 | let where_clauses = convert_where_clauses(self.db, trait_.into(), &bound_vars); |
263 | let associated_ty_ids = Vec::new(); // FIXME add associated tys | 313 | let associated_ty_ids = trait_ |
314 | .items(self.db) | ||
315 | .into_iter() | ||
316 | .filter_map(|trait_item| match trait_item { | ||
317 | crate::traits::TraitItem::TypeAlias(type_alias) => Some(type_alias), | ||
318 | _ => None, | ||
319 | }) | ||
320 | .map(|type_alias| type_alias.to_chalk(self.db)) | ||
321 | .collect(); | ||
264 | let trait_datum_bound = | 322 | let trait_datum_bound = |
265 | chalk_rust_ir::TraitDatumBound { trait_ref, where_clauses, flags, associated_ty_ids }; | 323 | chalk_rust_ir::TraitDatumBound { trait_ref, where_clauses, flags, associated_ty_ids }; |
266 | let trait_datum = TraitDatum { binders: make_binders(trait_datum_bound, bound_vars.len()) }; | 324 | let trait_datum = TraitDatum { binders: make_binders(trait_datum_bound, bound_vars.len()) }; |
@@ -359,7 +417,30 @@ where | |||
359 | trait_ref.display(self.db), | 417 | trait_ref.display(self.db), |
360 | where_clauses | 418 | where_clauses |
361 | ); | 419 | ); |
420 | let trait_ = trait_ref.trait_; | ||
362 | let trait_ref = trait_ref.to_chalk(self.db); | 421 | let trait_ref = trait_ref.to_chalk(self.db); |
422 | let associated_ty_values = impl_block | ||
423 | .items(self.db) | ||
424 | .into_iter() | ||
425 | .filter_map(|item| match item { | ||
426 | ImplItem::TypeAlias(t) => Some(t), | ||
427 | _ => None, | ||
428 | }) | ||
429 | .filter_map(|t| { | ||
430 | let assoc_ty = trait_.associated_type_by_name(self.db, t.name(self.db))?; | ||
431 | let ty = self.db.type_for_def(t.into(), crate::Namespace::Types).subst(&bound_vars); | ||
432 | debug!("ty = {}", ty.display(self.db)); | ||
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![], // FIXME add generic params (generic associated types) | ||
439 | }, | ||
440 | }) | ||
441 | }) | ||
442 | .collect(); | ||
443 | |||
363 | let impl_datum_bound = chalk_rust_ir::ImplDatumBound { | 444 | let impl_datum_bound = chalk_rust_ir::ImplDatumBound { |
364 | trait_ref: if negative { | 445 | trait_ref: if negative { |
365 | chalk_rust_ir::PolarizedTraitRef::Negative(trait_ref) | 446 | chalk_rust_ir::PolarizedTraitRef::Negative(trait_ref) |
@@ -367,9 +448,10 @@ where | |||
367 | chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref) | 448 | chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref) |
368 | }, | 449 | }, |
369 | where_clauses, | 450 | where_clauses, |
370 | associated_ty_values: Vec::new(), // FIXME add associated type values | 451 | associated_ty_values, |
371 | impl_type, | 452 | impl_type, |
372 | }; | 453 | }; |
454 | debug!("impl_datum: {:?}", impl_datum_bound); | ||
373 | let impl_datum = ImplDatum { binders: make_binders(impl_datum_bound, bound_vars.len()) }; | 455 | let impl_datum = ImplDatum { binders: make_binders(impl_datum_bound, bound_vars.len()) }; |
374 | Arc::new(impl_datum) | 456 | Arc::new(impl_datum) |
375 | } | 457 | } |
@@ -405,7 +487,7 @@ where | |||
405 | } | 487 | } |
406 | fn split_projection<'p>( | 488 | fn split_projection<'p>( |
407 | &self, | 489 | &self, |
408 | projection: &'p ProjectionTy, | 490 | projection: &'p chalk_ir::ProjectionTy, |
409 | ) -> (Arc<AssociatedTyDatum>, &'p [Parameter], &'p [Parameter]) { | 491 | ) -> (Arc<AssociatedTyDatum>, &'p [Parameter], &'p [Parameter]) { |
410 | debug!("split_projection {:?}", projection); | 492 | debug!("split_projection {:?}", projection); |
411 | unimplemented!() | 493 | unimplemented!() |
@@ -440,6 +522,18 @@ impl From<crate::ids::TraitId> for chalk_ir::TraitId { | |||
440 | } | 522 | } |
441 | } | 523 | } |
442 | 524 | ||
525 | impl From<chalk_ir::TypeId> for crate::ids::TypeAliasId { | ||
526 | fn from(type_id: chalk_ir::TypeId) -> Self { | ||
527 | id_from_chalk(type_id.0) | ||
528 | } | ||
529 | } | ||
530 | |||
531 | impl From<crate::ids::TypeAliasId> for chalk_ir::TypeId { | ||
532 | fn from(type_id: crate::ids::TypeAliasId) -> Self { | ||
533 | chalk_ir::TypeId(id_to_chalk(type_id)) | ||
534 | } | ||
535 | } | ||
536 | |||
443 | impl From<chalk_ir::StructId> for crate::ids::TypeCtorId { | 537 | impl From<chalk_ir::StructId> for crate::ids::TypeCtorId { |
444 | fn from(struct_id: chalk_ir::StructId) -> Self { | 538 | fn from(struct_id: chalk_ir::StructId) -> Self { |
445 | id_from_chalk(struct_id.0) | 539 | id_from_chalk(struct_id.0) |
diff --git a/crates/ra_hir/src/type_alias.rs b/crates/ra_hir/src/type_alias.rs index 87b9caa8a..eada37274 100644 --- a/crates/ra_hir/src/type_alias.rs +++ b/crates/ra_hir/src/type_alias.rs | |||
@@ -2,12 +2,22 @@ | |||
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use crate::{TypeAlias, DefDatabase, AstDatabase, HasSource, type_ref::TypeRef}; | 5 | use ra_syntax::ast::NameOwner; |
6 | 6 | ||
7 | pub(crate) fn type_alias_ref_query( | 7 | use crate::{TypeAlias, db::{DefDatabase, AstDatabase}, type_ref::TypeRef, name::{Name, AsName}, HasSource}; |
8 | |||
9 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
10 | pub struct TypeAliasData { | ||
11 | pub(crate) name: Name, | ||
12 | pub(crate) type_ref: Option<TypeRef>, | ||
13 | } | ||
14 | |||
15 | pub(crate) fn type_alias_data_query( | ||
8 | db: &(impl DefDatabase + AstDatabase), | 16 | db: &(impl DefDatabase + AstDatabase), |
9 | typ: TypeAlias, | 17 | typ: TypeAlias, |
10 | ) -> Arc<TypeRef> { | 18 | ) -> Arc<TypeAliasData> { |
11 | let node = typ.source(db).ast; | 19 | let node = typ.source(db).ast; |
12 | Arc::new(TypeRef::from_ast_opt(node.type_ref())) | 20 | let name = node.name().map_or_else(Name::missing, |n| n.as_name()); |
21 | let type_ref = node.type_ref().map(TypeRef::from_ast); | ||
22 | Arc::new(TypeAliasData { name, type_ref }) | ||
13 | } | 23 | } |