diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/db.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir/src/generics.rs | 19 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 31 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 53 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 41 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 68 |
6 files changed, 188 insertions, 29 deletions
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 689dd6225..8f98ca3a5 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -11,7 +11,7 @@ use crate::{ | |||
11 | DefWithBody, Trait, | 11 | DefWithBody, Trait, |
12 | ids, | 12 | ids, |
13 | nameres::{Namespace, ImportSourceMap, RawItems, CrateDefMap}, | 13 | nameres::{Namespace, ImportSourceMap, RawItems, CrateDefMap}, |
14 | ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef, CallableDef, FnSig, TypeCtor}, | 14 | ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef, CallableDef, FnSig, TypeCtor, GenericPredicate}, |
15 | adt::{StructData, EnumData}, | 15 | adt::{StructData, EnumData}, |
16 | impl_block::{ModuleImplBlocks, ImplSourceMap, ImplBlock}, | 16 | impl_block::{ModuleImplBlocks, ImplSourceMap, ImplBlock}, |
17 | generics::{GenericParams, GenericDef}, | 17 | generics::{GenericParams, GenericDef}, |
@@ -138,6 +138,9 @@ pub trait HirDatabase: DefDatabase { | |||
138 | #[salsa::invoke(crate::ty::callable_item_sig)] | 138 | #[salsa::invoke(crate::ty::callable_item_sig)] |
139 | fn callable_item_signature(&self, def: CallableDef) -> FnSig; | 139 | fn callable_item_signature(&self, def: CallableDef) -> FnSig; |
140 | 140 | ||
141 | #[salsa::invoke(crate::ty::generic_predicates)] | ||
142 | fn generic_predicates(&self, def: GenericDef) -> Arc<[GenericPredicate]>; | ||
143 | |||
141 | #[salsa::invoke(crate::expr::body_with_source_map_query)] | 144 | #[salsa::invoke(crate::expr::body_with_source_map_query)] |
142 | fn body_with_source_map( | 145 | fn body_with_source_map( |
143 | &self, | 146 | &self, |
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs index 2e52c5871..826117ba5 100644 --- a/crates/ra_hir/src/generics.rs +++ b/crates/ra_hir/src/generics.rs | |||
@@ -8,7 +8,7 @@ use std::sync::Arc; | |||
8 | use ra_syntax::ast::{self, NameOwner, TypeParamsOwner, TypeBoundsOwner}; | 8 | use ra_syntax::ast::{self, NameOwner, TypeParamsOwner, TypeBoundsOwner}; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | db::DefDatabase, | 11 | db::{ HirDatabase, DefDatabase}, |
12 | Name, AsName, Function, Struct, Enum, Trait, TypeAlias, ImplBlock, Container, path::Path, type_ref::TypeRef, AdtDef | 12 | Name, AsName, Function, Struct, Enum, Trait, TypeAlias, ImplBlock, Container, path::Path, type_ref::TypeRef, AdtDef |
13 | }; | 13 | }; |
14 | 14 | ||
@@ -32,8 +32,8 @@ pub struct GenericParams { | |||
32 | /// where clauses like `where T: Foo + Bar` are turned into multiple of these. | 32 | /// where clauses like `where T: Foo + Bar` are turned into multiple of these. |
33 | #[derive(Clone, PartialEq, Eq, Debug)] | 33 | #[derive(Clone, PartialEq, Eq, Debug)] |
34 | pub struct WherePredicate { | 34 | pub struct WherePredicate { |
35 | type_ref: TypeRef, | 35 | pub(crate) type_ref: TypeRef, |
36 | trait_ref: Path, | 36 | pub(crate) trait_ref: Path, |
37 | } | 37 | } |
38 | 38 | ||
39 | // FIXME: consts can have type parameters from their parents (i.e. associated consts of traits) | 39 | // FIXME: consts can have type parameters from their parents (i.e. associated consts of traits) |
@@ -148,6 +148,19 @@ impl GenericParams { | |||
148 | } | 148 | } |
149 | } | 149 | } |
150 | 150 | ||
151 | impl GenericDef { | ||
152 | pub(crate) fn resolver(&self, db: &impl HirDatabase) -> crate::Resolver { | ||
153 | match self { | ||
154 | GenericDef::Function(inner) => inner.resolver(db), | ||
155 | GenericDef::Struct(inner) => inner.resolver(db), | ||
156 | GenericDef::Enum(inner) => inner.resolver(db), | ||
157 | GenericDef::Trait(inner) => inner.resolver(db), | ||
158 | GenericDef::TypeAlias(inner) => inner.resolver(db), | ||
159 | GenericDef::ImplBlock(inner) => inner.resolver(db), | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | |||
151 | impl From<Container> for GenericDef { | 164 | impl From<Container> for GenericDef { |
152 | fn from(c: Container) -> Self { | 165 | fn from(c: Container) -> Self { |
153 | match c { | 166 | match c { |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 12429a668..cfe07156b 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -19,7 +19,7 @@ use std::{fmt, mem}; | |||
19 | use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase, Trait, GenericParams}; | 19 | use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase, Trait, GenericParams}; |
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}; | 22 | pub(crate) use lower::{TypableDef, type_for_def, type_for_field, callable_item_sig, generic_predicates}; |
23 | pub(crate) use infer::{infer, InferenceResult, InferTy}; | 23 | pub(crate) use infer::{infer, InferenceResult, InferTy}; |
24 | pub use lower::CallableDef; | 24 | pub use lower::CallableDef; |
25 | 25 | ||
@@ -234,6 +234,35 @@ impl TraitRef { | |||
234 | } | 234 | } |
235 | } | 235 | } |
236 | 236 | ||
237 | /// Like `generics::WherePredicate`, but with resolved types: A condition on the | ||
238 | /// parameters of a generic item. | ||
239 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
240 | pub enum GenericPredicate { | ||
241 | /// The given trait needs to be implemented for its type parameters. | ||
242 | Implemented(TraitRef), | ||
243 | /// We couldn't resolve the trait reference. (If some type parameters can't | ||
244 | /// be resolved, they will just be Unknown). | ||
245 | Error, | ||
246 | } | ||
247 | |||
248 | impl GenericPredicate { | ||
249 | pub fn is_error(&self) -> bool { | ||
250 | match self { | ||
251 | GenericPredicate::Error => true, | ||
252 | _ => false, | ||
253 | } | ||
254 | } | ||
255 | |||
256 | pub fn subst(self, substs: &Substs) -> GenericPredicate { | ||
257 | match self { | ||
258 | GenericPredicate::Implemented(trait_ref) => { | ||
259 | GenericPredicate::Implemented(trait_ref.subst(substs)) | ||
260 | } | ||
261 | GenericPredicate::Error => self, | ||
262 | } | ||
263 | } | ||
264 | } | ||
265 | |||
237 | /// Basically a claim (currently not validated / checked) that the contained | 266 | /// Basically a claim (currently not validated / checked) that the contained |
238 | /// type / trait ref contains no inference variables; any inference variables it | 267 | /// type / trait ref contains no inference variables; any inference variables it |
239 | /// contained have been replaced by bound variables, and `num_vars` tells us how | 268 | /// contained have been replaced by bound variables, and `num_vars` tells us how |
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 8bab7e54b..09d26ce5a 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -5,6 +5,7 @@ | |||
5 | //! - Building the type for an item: This happens through the `type_for_def` query. | 5 | //! - Building the type for an item: This happens through the `type_for_def` query. |
6 | //! | 6 | //! |
7 | //! This usually involves resolving names, collecting generic arguments etc. | 7 | //! This usually involves resolving names, collecting generic arguments etc. |
8 | use std::sync::Arc; | ||
8 | use std::iter; | 9 | use std::iter; |
9 | 10 | ||
10 | use crate::{ | 11 | use crate::{ |
@@ -18,9 +19,9 @@ use crate::{ | |||
18 | resolve::{Resolver, Resolution}, | 19 | resolve::{Resolver, Resolution}, |
19 | path::{PathSegment, GenericArg}, | 20 | path::{PathSegment, GenericArg}, |
20 | generics::{GenericParams, HasGenericParams}, | 21 | generics::{GenericParams, HasGenericParams}, |
21 | adt::VariantDef, Trait | 22 | adt::VariantDef, Trait, generics::{ WherePredicate, GenericDef} |
22 | }; | 23 | }; |
23 | use super::{Ty, primitive, FnSig, Substs, TypeCtor, TraitRef}; | 24 | use super::{Ty, primitive, FnSig, Substs, TypeCtor, TraitRef, GenericPredicate}; |
24 | 25 | ||
25 | impl Ty { | 26 | impl Ty { |
26 | pub(crate) fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self { | 27 | pub(crate) fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self { |
@@ -208,16 +209,12 @@ pub(super) fn substs_from_path_segment( | |||
208 | } | 209 | } |
209 | 210 | ||
210 | impl TraitRef { | 211 | impl TraitRef { |
211 | pub(crate) fn from_hir( | 212 | pub(crate) fn from_path( |
212 | db: &impl HirDatabase, | 213 | db: &impl HirDatabase, |
213 | resolver: &Resolver, | 214 | resolver: &Resolver, |
214 | type_ref: &TypeRef, | 215 | path: &Path, |
215 | explicit_self_ty: Option<Ty>, | 216 | explicit_self_ty: Option<Ty>, |
216 | ) -> Option<Self> { | 217 | ) -> Option<Self> { |
217 | let path = match type_ref { | ||
218 | TypeRef::Path(path) => path, | ||
219 | _ => return None, | ||
220 | }; | ||
221 | let resolved = match resolver.resolve_path(db, &path).take_types()? { | 218 | let resolved = match resolver.resolve_path(db, &path).take_types()? { |
222 | Resolution::Def(ModuleDef::Trait(tr)) => tr, | 219 | Resolution::Def(ModuleDef::Trait(tr)) => tr, |
223 | _ => return None, | 220 | _ => return None, |
@@ -232,6 +229,19 @@ impl TraitRef { | |||
232 | Some(TraitRef { trait_: resolved, substs }) | 229 | Some(TraitRef { trait_: resolved, substs }) |
233 | } | 230 | } |
234 | 231 | ||
232 | pub(crate) fn from_hir( | ||
233 | db: &impl HirDatabase, | ||
234 | resolver: &Resolver, | ||
235 | type_ref: &TypeRef, | ||
236 | explicit_self_ty: Option<Ty>, | ||
237 | ) -> Option<Self> { | ||
238 | let path = match type_ref { | ||
239 | TypeRef::Path(path) => path, | ||
240 | _ => return None, | ||
241 | }; | ||
242 | TraitRef::from_path(db, resolver, path, explicit_self_ty) | ||
243 | } | ||
244 | |||
235 | fn substs_from_path( | 245 | fn substs_from_path( |
236 | db: &impl HirDatabase, | 246 | db: &impl HirDatabase, |
237 | resolver: &Resolver, | 247 | resolver: &Resolver, |
@@ -246,6 +256,15 @@ impl TraitRef { | |||
246 | let substs = Substs::identity(&trait_.generic_params(db)); | 256 | let substs = Substs::identity(&trait_.generic_params(db)); |
247 | TraitRef { trait_, substs } | 257 | TraitRef { trait_, substs } |
248 | } | 258 | } |
259 | |||
260 | pub(crate) fn for_where_predicate( | ||
261 | db: &impl HirDatabase, | ||
262 | resolver: &Resolver, | ||
263 | pred: &WherePredicate, | ||
264 | ) -> Option<TraitRef> { | ||
265 | let self_ty = Ty::from_hir(db, resolver, &pred.type_ref); | ||
266 | TraitRef::from_path(db, resolver, &pred.trait_ref, Some(self_ty)) | ||
267 | } | ||
249 | } | 268 | } |
250 | 269 | ||
251 | /// Build the declared type of an item. This depends on the namespace; e.g. for | 270 | /// Build the declared type of an item. This depends on the namespace; e.g. for |
@@ -294,6 +313,24 @@ pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { | |||
294 | Ty::from_hir(db, &resolver, type_ref) | 313 | Ty::from_hir(db, &resolver, type_ref) |
295 | } | 314 | } |
296 | 315 | ||
316 | /// Resolve the where clause(s) of an item with generics. | ||
317 | pub(crate) fn generic_predicates( | ||
318 | db: &impl HirDatabase, | ||
319 | def: GenericDef, | ||
320 | ) -> Arc<[GenericPredicate]> { | ||
321 | let resolver = def.resolver(db); | ||
322 | let generic_params = def.generic_params(db); | ||
323 | let predicates = generic_params | ||
324 | .where_predicates | ||
325 | .iter() | ||
326 | .map(|pred| { | ||
327 | TraitRef::for_where_predicate(db, &resolver, pred) | ||
328 | .map_or(GenericPredicate::Error, GenericPredicate::Implemented) | ||
329 | }) | ||
330 | .collect::<Vec<_>>(); | ||
331 | predicates.into() | ||
332 | } | ||
333 | |||
297 | fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { | 334 | fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { |
298 | let signature = def.signature(db); | 335 | let signature = def.signature(db); |
299 | let resolver = def.resolver(db); | 336 | let resolver = def.resolver(db); |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index a38fe35c7..c3edf42b1 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -2510,12 +2510,47 @@ fn method_resolution_where_clause_not_met() { | |||
2510 | trait Clone {} | 2510 | trait Clone {} |
2511 | trait Trait { fn foo(self) -> u128; } | 2511 | trait Trait { fn foo(self) -> u128; } |
2512 | struct S; | 2512 | struct S; |
2513 | impl S { fn foo(self) -> i8 { 0 } } | 2513 | impl<T> Trait for T where T: Clone {} |
2514 | impl<T> Trait for T where T: Clone { fn foo(self) -> u128 { 0 } } | ||
2515 | fn test() { (&S).foo()<|>; } | 2514 | fn test() { (&S).foo()<|>; } |
2516 | "#, | 2515 | "#, |
2517 | ); | 2516 | ); |
2518 | assert_eq!(t, "i8"); | 2517 | // This is also to make sure that we don't resolve to the foo method just |
2518 | // because that's the only method named foo we can find, which would make | ||
2519 | // the below tests not work | ||
2520 | assert_eq!(t, "{unknown}"); | ||
2521 | } | ||
2522 | |||
2523 | #[test] | ||
2524 | fn method_resolution_where_clause_1() { | ||
2525 | let t = type_at( | ||
2526 | r#" | ||
2527 | //- /main.rs | ||
2528 | trait Clone {} | ||
2529 | trait Trait { fn foo(self) -> u128; } | ||
2530 | struct S; | ||
2531 | impl Clone for S {}; | ||
2532 | impl<T> Trait for T where T: Clone {} | ||
2533 | fn test() { S.foo()<|>; } | ||
2534 | "#, | ||
2535 | ); | ||
2536 | assert_eq!(t, "u128"); | ||
2537 | } | ||
2538 | |||
2539 | #[test] | ||
2540 | fn method_resolution_where_clause_2() { | ||
2541 | let t = type_at( | ||
2542 | r#" | ||
2543 | //- /main.rs | ||
2544 | trait Into<T> { fn into(self) -> T; } | ||
2545 | trait From<T> { fn from(other: T) -> Self; } | ||
2546 | struct S1; | ||
2547 | struct S2; | ||
2548 | impl From<S2> for S1 {}; | ||
2549 | impl<T, U> Into<U> for T where U: From<T> {} | ||
2550 | fn test() { S2.into()<|>; } | ||
2551 | "#, | ||
2552 | ); | ||
2553 | assert_eq!(t, "S1"); | ||
2519 | } | 2554 | } |
2520 | 2555 | ||
2521 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { | 2556 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { |
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 8b77d21b4..2772a0432 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs | |||
@@ -11,7 +11,7 @@ use ra_db::salsa::{InternId, InternKey}; | |||
11 | use crate::{ | 11 | use crate::{ |
12 | Trait, HasGenericParams, ImplBlock, | 12 | Trait, HasGenericParams, ImplBlock, |
13 | db::HirDatabase, | 13 | db::HirDatabase, |
14 | ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs}, | 14 | ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate}, generics::GenericDef, |
15 | }; | 15 | }; |
16 | use super::ChalkContext; | 16 | use super::ChalkContext; |
17 | 17 | ||
@@ -146,6 +146,27 @@ impl ToChalk for ImplBlock { | |||
146 | } | 146 | } |
147 | } | 147 | } |
148 | 148 | ||
149 | impl ToChalk for GenericPredicate { | ||
150 | type Chalk = chalk_ir::QuantifiedWhereClause; | ||
151 | |||
152 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause { | ||
153 | match self { | ||
154 | GenericPredicate::Implemented(trait_ref) => { | ||
155 | make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0) | ||
156 | } | ||
157 | GenericPredicate::Error => panic!("Trying to pass errored where clause to Chalk"), | ||
158 | } | ||
159 | } | ||
160 | |||
161 | fn from_chalk( | ||
162 | _db: &impl HirDatabase, | ||
163 | _where_clause: chalk_ir::QuantifiedWhereClause, | ||
164 | ) -> GenericPredicate { | ||
165 | // This should never need to be called | ||
166 | unimplemented!() | ||
167 | } | ||
168 | } | ||
169 | |||
149 | fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> { | 170 | fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> { |
150 | chalk_ir::Binders { | 171 | chalk_ir::Binders { |
151 | value, | 172 | value, |
@@ -153,6 +174,25 @@ fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> { | |||
153 | } | 174 | } |
154 | } | 175 | } |
155 | 176 | ||
177 | fn convert_where_clauses( | ||
178 | db: &impl HirDatabase, | ||
179 | def: GenericDef, | ||
180 | substs: &Substs, | ||
181 | ) -> (Vec<chalk_ir::QuantifiedWhereClause>, bool) { | ||
182 | let generic_predicates = db.generic_predicates(def); | ||
183 | let mut result = Vec::with_capacity(generic_predicates.len()); | ||
184 | let mut has_error = false; | ||
185 | for pred in generic_predicates.iter() { | ||
186 | // FIXME: it would probably be nicer if we could just convert errored predicates to a where clause that is never true... | ||
187 | if pred.is_error() { | ||
188 | has_error = true; | ||
189 | } else { | ||
190 | result.push(pred.clone().subst(substs).to_chalk(db)); | ||
191 | } | ||
192 | } | ||
193 | (result, has_error) | ||
194 | } | ||
195 | |||
156 | impl<'a, DB> chalk_solve::RustIrDatabase for ChalkContext<'a, DB> | 196 | impl<'a, DB> chalk_solve::RustIrDatabase for ChalkContext<'a, DB> |
157 | where | 197 | where |
158 | DB: HirDatabase, | 198 | DB: HirDatabase, |
@@ -173,7 +213,7 @@ where | |||
173 | upstream: trait_.module(self.db).krate(self.db) != Some(self.krate), | 213 | upstream: trait_.module(self.db).krate(self.db) != Some(self.krate), |
174 | fundamental: false, | 214 | fundamental: false, |
175 | }; | 215 | }; |
176 | let where_clauses = Vec::new(); // FIXME add where clauses | 216 | let (where_clauses, _) = convert_where_clauses(self.db, trait_.into(), &bound_vars); |
177 | let associated_ty_ids = Vec::new(); // FIXME add associated tys | 217 | let associated_ty_ids = Vec::new(); // FIXME add associated tys |
178 | let trait_datum_bound = | 218 | let trait_datum_bound = |
179 | chalk_rust_ir::TraitDatumBound { trait_ref, where_clauses, flags, associated_ty_ids }; | 219 | chalk_rust_ir::TraitDatumBound { trait_ref, where_clauses, flags, associated_ty_ids }; |
@@ -185,21 +225,26 @@ where | |||
185 | let type_ctor = from_chalk(self.db, struct_id); | 225 | let type_ctor = from_chalk(self.db, struct_id); |
186 | // FIXME might be nicer if we can create a fake GenericParams for the TypeCtor | 226 | // FIXME might be nicer if we can create a fake GenericParams for the TypeCtor |
187 | // FIXME extract this to a method on Ty | 227 | // FIXME extract this to a method on Ty |
188 | let (num_params, upstream) = match type_ctor { | 228 | let (num_params, where_clauses, upstream) = match type_ctor { |
189 | TypeCtor::Bool | 229 | TypeCtor::Bool |
190 | | TypeCtor::Char | 230 | | TypeCtor::Char |
191 | | TypeCtor::Int(_) | 231 | | TypeCtor::Int(_) |
192 | | TypeCtor::Float(_) | 232 | | TypeCtor::Float(_) |
193 | | TypeCtor::Never | 233 | | TypeCtor::Never |
194 | | TypeCtor::Str => (0, true), | 234 | | TypeCtor::Str => (0, vec![], true), |
195 | TypeCtor::Slice | TypeCtor::Array | TypeCtor::RawPtr(_) | TypeCtor::Ref(_) => (1, true), | 235 | TypeCtor::Slice | TypeCtor::Array | TypeCtor::RawPtr(_) | TypeCtor::Ref(_) => { |
196 | TypeCtor::FnPtr { num_args } => (num_args as usize + 1, true), | 236 | (1, vec![], true) |
197 | TypeCtor::Tuple { cardinality } => (cardinality as usize, true), | 237 | } |
238 | TypeCtor::FnPtr { num_args } => (num_args as usize + 1, vec![], true), | ||
239 | TypeCtor::Tuple { cardinality } => (cardinality as usize, vec![], true), | ||
198 | TypeCtor::FnDef(_) => unimplemented!(), | 240 | TypeCtor::FnDef(_) => unimplemented!(), |
199 | TypeCtor::Adt(adt) => { | 241 | TypeCtor::Adt(adt) => { |
200 | let generic_params = adt.generic_params(self.db); | 242 | let generic_params = adt.generic_params(self.db); |
243 | let bound_vars = Substs::bound_vars(&generic_params); | ||
244 | let (where_clauses, _) = convert_where_clauses(self.db, adt.into(), &bound_vars); | ||
201 | ( | 245 | ( |
202 | generic_params.count_params_including_parent(), | 246 | generic_params.count_params_including_parent(), |
247 | where_clauses, | ||
203 | adt.krate(self.db) != Some(self.krate), | 248 | adt.krate(self.db) != Some(self.krate), |
204 | ) | 249 | ) |
205 | } | 250 | } |
@@ -209,7 +254,6 @@ where | |||
209 | // FIXME set fundamental flag correctly | 254 | // FIXME set fundamental flag correctly |
210 | fundamental: false, | 255 | fundamental: false, |
211 | }; | 256 | }; |
212 | let where_clauses = Vec::new(); // FIXME add where clauses | ||
213 | let self_ty = chalk_ir::ApplicationTy { | 257 | let self_ty = chalk_ir::ApplicationTy { |
214 | name: TypeName::TypeKindId(type_ctor.to_chalk(self.db).into()), | 258 | name: TypeName::TypeKindId(type_ctor.to_chalk(self.db).into()), |
215 | parameters: (0..num_params).map(|i| chalk_ir::Ty::BoundVar(i).cast()).collect(), | 259 | parameters: (0..num_params).map(|i| chalk_ir::Ty::BoundVar(i).cast()).collect(), |
@@ -237,10 +281,12 @@ where | |||
237 | } else { | 281 | } else { |
238 | chalk_rust_ir::ImplType::External | 282 | chalk_rust_ir::ImplType::External |
239 | }; | 283 | }; |
284 | let (where_clauses, where_clause_error) = | ||
285 | convert_where_clauses(self.db, impl_block.into(), &bound_vars); | ||
240 | let impl_datum_bound = chalk_rust_ir::ImplDatumBound { | 286 | let impl_datum_bound = chalk_rust_ir::ImplDatumBound { |
241 | // FIXME handle negative impls (impl !Sync for Foo) | 287 | // FIXME handle negative impls (impl !Sync for Foo) |
242 | trait_ref: chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref.to_chalk(self.db)), | 288 | trait_ref: chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref.to_chalk(self.db)), |
243 | where_clauses: Vec::new(), // FIXME add where clauses | 289 | where_clauses, |
244 | associated_ty_values: Vec::new(), // FIXME add associated type values | 290 | associated_ty_values: Vec::new(), // FIXME add associated type values |
245 | impl_type, | 291 | impl_type, |
246 | }; | 292 | }; |
@@ -253,10 +299,6 @@ where | |||
253 | self.db | 299 | self.db |
254 | .impls_for_trait(self.krate, trait_) | 300 | .impls_for_trait(self.krate, trait_) |
255 | .iter() | 301 | .iter() |
256 | // FIXME temporary hack -- as long as we're not lowering where clauses | ||
257 | // correctly, ignore impls with them completely so as to not treat | ||
258 | // impl<T> Trait for T where T: ... as a blanket impl on all types | ||
259 | .filter(|impl_block| impl_block.generic_params(self.db).where_predicates.is_empty()) | ||
260 | .map(|impl_block| impl_block.to_chalk(self.db)) | 302 | .map(|impl_block| impl_block.to_chalk(self.db)) |
261 | .collect() | 303 | .collect() |
262 | } | 304 | } |