diff options
Diffstat (limited to 'crates/ra_hir/src/ty/lower.rs')
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 85 |
1 files changed, 57 insertions, 28 deletions
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 47d161277..0011c06b4 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -8,7 +8,9 @@ | |||
8 | use std::iter; | 8 | use std::iter; |
9 | use std::sync::Arc; | 9 | use std::sync::Arc; |
10 | 10 | ||
11 | use super::{FnSig, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor}; | 11 | use super::{ |
12 | FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, | ||
13 | }; | ||
12 | use crate::{ | 14 | use crate::{ |
13 | adt::VariantDef, | 15 | adt::VariantDef, |
14 | generics::HasGenericParams, | 16 | generics::HasGenericParams, |
@@ -62,7 +64,9 @@ impl Ty { | |||
62 | let self_ty = Ty::Bound(0); | 64 | let self_ty = Ty::Bound(0); |
63 | let predicates = bounds | 65 | let predicates = bounds |
64 | .iter() | 66 | .iter() |
65 | .map(|b| GenericPredicate::from_type_bound(db, resolver, b, self_ty.clone())) | 67 | .flat_map(|b| { |
68 | GenericPredicate::from_type_bound(db, resolver, b, self_ty.clone()) | ||
69 | }) | ||
66 | .collect::<Vec<_>>(); | 70 | .collect::<Vec<_>>(); |
67 | Ty::Dyn(predicates.into()) | 71 | Ty::Dyn(predicates.into()) |
68 | } | 72 | } |
@@ -70,7 +74,9 @@ impl Ty { | |||
70 | let self_ty = Ty::Bound(0); | 74 | let self_ty = Ty::Bound(0); |
71 | let predicates = bounds | 75 | let predicates = bounds |
72 | .iter() | 76 | .iter() |
73 | .map(|b| GenericPredicate::from_type_bound(db, resolver, b, self_ty.clone())) | 77 | .flat_map(|b| { |
78 | GenericPredicate::from_type_bound(db, resolver, b, self_ty.clone()) | ||
79 | }) | ||
74 | .collect::<Vec<_>>(); | 80 | .collect::<Vec<_>>(); |
75 | Ty::Opaque(predicates.into()) | 81 | Ty::Opaque(predicates.into()) |
76 | } | 82 | } |
@@ -326,15 +332,6 @@ impl TraitRef { | |||
326 | TraitRef { trait_, substs } | 332 | TraitRef { trait_, substs } |
327 | } | 333 | } |
328 | 334 | ||
329 | pub(crate) fn from_where_predicate( | ||
330 | db: &impl HirDatabase, | ||
331 | resolver: &Resolver, | ||
332 | pred: &WherePredicate, | ||
333 | ) -> Option<TraitRef> { | ||
334 | let self_ty = Ty::from_hir(db, resolver, &pred.type_ref); | ||
335 | TraitRef::from_type_bound(db, resolver, &pred.bound, self_ty) | ||
336 | } | ||
337 | |||
338 | pub(crate) fn from_type_bound( | 335 | pub(crate) fn from_type_bound( |
339 | db: &impl HirDatabase, | 336 | db: &impl HirDatabase, |
340 | resolver: &Resolver, | 337 | resolver: &Resolver, |
@@ -349,26 +346,58 @@ impl TraitRef { | |||
349 | } | 346 | } |
350 | 347 | ||
351 | impl GenericPredicate { | 348 | impl GenericPredicate { |
352 | pub(crate) fn from_where_predicate( | 349 | pub(crate) fn from_where_predicate<'a>( |
353 | db: &impl HirDatabase, | 350 | db: &'a impl HirDatabase, |
354 | resolver: &Resolver, | 351 | resolver: &'a Resolver, |
355 | where_predicate: &WherePredicate, | 352 | where_predicate: &'a WherePredicate, |
356 | ) -> GenericPredicate { | 353 | ) -> impl Iterator<Item = GenericPredicate> + 'a { |
357 | TraitRef::from_where_predicate(db, &resolver, where_predicate) | 354 | let self_ty = Ty::from_hir(db, resolver, &where_predicate.type_ref); |
358 | .map_or(GenericPredicate::Error, GenericPredicate::Implemented) | 355 | GenericPredicate::from_type_bound(db, resolver, &where_predicate.bound, self_ty) |
359 | } | 356 | } |
360 | 357 | ||
361 | pub(crate) fn from_type_bound( | 358 | pub(crate) fn from_type_bound<'a>( |
362 | db: &impl HirDatabase, | 359 | db: &'a impl HirDatabase, |
363 | resolver: &Resolver, | 360 | resolver: &'a Resolver, |
364 | bound: &TypeBound, | 361 | bound: &'a TypeBound, |
365 | self_ty: Ty, | 362 | self_ty: Ty, |
366 | ) -> GenericPredicate { | 363 | ) -> impl Iterator<Item = GenericPredicate> + 'a { |
367 | TraitRef::from_type_bound(db, &resolver, bound, self_ty) | 364 | let trait_ref = TraitRef::from_type_bound(db, &resolver, bound, self_ty); |
368 | .map_or(GenericPredicate::Error, GenericPredicate::Implemented) | 365 | iter::once(trait_ref.clone().map_or(GenericPredicate::Error, GenericPredicate::Implemented)) |
366 | .chain( | ||
367 | trait_ref.into_iter().flat_map(move |tr| { | ||
368 | assoc_type_bindings_from_type_bound(db, resolver, bound, tr) | ||
369 | }), | ||
370 | ) | ||
369 | } | 371 | } |
370 | } | 372 | } |
371 | 373 | ||
374 | fn assoc_type_bindings_from_type_bound<'a>( | ||
375 | db: &'a impl HirDatabase, | ||
376 | resolver: &'a Resolver, | ||
377 | bound: &'a TypeBound, | ||
378 | trait_ref: TraitRef, | ||
379 | ) -> impl Iterator<Item = GenericPredicate> + 'a { | ||
380 | let last_segment = match bound { | ||
381 | TypeBound::Path(path) => path.segments.last(), | ||
382 | TypeBound::Error => None, | ||
383 | }; | ||
384 | last_segment | ||
385 | .into_iter() | ||
386 | .flat_map(|segment| segment.args_and_bindings.iter()) | ||
387 | .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) | ||
388 | .map(move |(name, type_ref)| { | ||
389 | let associated_ty = match trait_ref.trait_.associated_type_by_name(db, name.clone()) { | ||
390 | None => return GenericPredicate::Error, | ||
391 | Some(t) => t, | ||
392 | }; | ||
393 | let projection_ty = | ||
394 | ProjectionTy { associated_ty, parameters: trait_ref.substs.clone() }; | ||
395 | let ty = Ty::from_hir(db, resolver, type_ref); | ||
396 | let projection_predicate = ProjectionPredicate { projection_ty, ty }; | ||
397 | GenericPredicate::Projection(projection_predicate) | ||
398 | }) | ||
399 | } | ||
400 | |||
372 | /// Build the declared type of an item. This depends on the namespace; e.g. for | 401 | /// Build the declared type of an item. This depends on the namespace; e.g. for |
373 | /// `struct Foo(usize)`, we have two types: The type of the struct itself, and | 402 | /// `struct Foo(usize)`, we have two types: The type of the struct itself, and |
374 | /// the constructor function `(usize) -> Foo` which lives in the values | 403 | /// the constructor function `(usize) -> Foo` which lives in the values |
@@ -425,7 +454,7 @@ pub(crate) fn trait_env( | |||
425 | ) -> Arc<super::TraitEnvironment> { | 454 | ) -> Arc<super::TraitEnvironment> { |
426 | let predicates = resolver | 455 | let predicates = resolver |
427 | .where_predicates_in_scope() | 456 | .where_predicates_in_scope() |
428 | .map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) | 457 | .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) |
429 | .collect::<Vec<_>>(); | 458 | .collect::<Vec<_>>(); |
430 | 459 | ||
431 | Arc::new(super::TraitEnvironment { predicates }) | 460 | Arc::new(super::TraitEnvironment { predicates }) |
@@ -439,7 +468,7 @@ pub(crate) fn generic_predicates_query( | |||
439 | let resolver = def.resolver(db); | 468 | let resolver = def.resolver(db); |
440 | let predicates = resolver | 469 | let predicates = resolver |
441 | .where_predicates_in_scope() | 470 | .where_predicates_in_scope() |
442 | .map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) | 471 | .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) |
443 | .collect::<Vec<_>>(); | 472 | .collect::<Vec<_>>(); |
444 | predicates.into() | 473 | predicates.into() |
445 | } | 474 | } |