aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/lower.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/lower.rs')
-rw-r--r--crates/ra_hir/src/ty/lower.rs85
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 @@
8use std::iter; 8use std::iter;
9use std::sync::Arc; 9use std::sync::Arc;
10 10
11use super::{FnSig, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor}; 11use super::{
12 FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
13};
12use crate::{ 14use 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
351impl GenericPredicate { 348impl 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
374fn 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}