diff options
author | Florian Diebold <[email protected]> | 2020-02-02 16:11:54 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2020-02-07 17:28:10 +0000 |
commit | a3d8cffde39bfb0d50b87a8ded5e0534adec4cd5 (patch) | |
tree | 3be5406b38c2594808c87d9dbecf7aa14b52b67d /crates/ra_hir_ty/src/lower.rs | |
parent | 86348f5994cdc3831edf3a5582d6d9d576fd1d80 (diff) |
Use variables in predicates as well
Diffstat (limited to 'crates/ra_hir_ty/src/lower.rs')
-rw-r--r-- | crates/ra_hir_ty/src/lower.rs | 73 |
1 files changed, 41 insertions, 32 deletions
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 76e2fbabf..847111748 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs | |||
@@ -10,13 +10,13 @@ use std::sync::Arc; | |||
10 | 10 | ||
11 | use hir_def::{ | 11 | use hir_def::{ |
12 | builtin_type::BuiltinType, | 12 | builtin_type::BuiltinType, |
13 | generics::{WherePredicate, WherePredicateTarget, TypeParamProvenance}, | 13 | generics::{TypeParamProvenance, WherePredicate, WherePredicateTarget}, |
14 | path::{GenericArg, Path, PathSegment, PathSegments}, | 14 | path::{GenericArg, Path, PathSegment, PathSegments}, |
15 | resolver::{HasResolver, Resolver, TypeNs}, | 15 | resolver::{HasResolver, Resolver, TypeNs}, |
16 | type_ref::{TypeBound, TypeRef}, | 16 | type_ref::{TypeBound, TypeRef}, |
17 | AdtId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, | 17 | AdtId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, |
18 | LocalStructFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId, | 18 | LocalStructFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId, |
19 | TypeParamId | 19 | VariantId, |
20 | }; | 20 | }; |
21 | use ra_arena::map::ArenaMap; | 21 | use ra_arena::map::ArenaMap; |
22 | use ra_db::CrateId; | 22 | use ra_db::CrateId; |
@@ -148,7 +148,9 @@ impl Ty { | |||
148 | let generics = generics(ctx.db, def); | 148 | let generics = generics(ctx.db, def); |
149 | let param = generics | 149 | let param = generics |
150 | .iter() | 150 | .iter() |
151 | .filter(|(_, data)| data.provenance == TypeParamProvenance::ArgumentImplTrait) | 151 | .filter(|(_, data)| { |
152 | data.provenance == TypeParamProvenance::ArgumentImplTrait | ||
153 | }) | ||
152 | .nth(idx as usize) | 154 | .nth(idx as usize) |
153 | .map_or(Ty::Unknown, |(id, _)| Ty::Param(id)); | 155 | .map_or(Ty::Unknown, |(id, _)| Ty::Param(id)); |
154 | param | 156 | param |
@@ -338,19 +340,12 @@ impl Ty { | |||
338 | return Ty::Unknown; | 340 | return Ty::Unknown; |
339 | }; | 341 | }; |
340 | param_id | 342 | param_id |
341 | }, | 343 | } |
342 | _ => return Ty::Unknown, // Error: Ambiguous associated type | 344 | _ => return Ty::Unknown, // Error: Ambiguous associated type |
343 | }; | 345 | }; |
344 | let predicates = ctx.db.generic_predicates_for_param(param_id); | 346 | let predicates = ctx.db.generic_predicates_for_param(param_id); |
345 | let traits_from_env = predicates.iter().filter_map(|pred| match pred { | 347 | let traits_from_env = predicates.iter().filter_map(|pred| match &pred.value { |
346 | GenericPredicate::Implemented(tr) => { | 348 | GenericPredicate::Implemented(tr) => Some(tr.trait_), |
347 | if let Ty::Param(id) = tr.self_ty() { | ||
348 | if *id == param_id { | ||
349 | return Some(tr.trait_); | ||
350 | } | ||
351 | } | ||
352 | None | ||
353 | } | ||
354 | _ => None, | 349 | _ => None, |
355 | }); | 350 | }); |
356 | let traits = traits_from_env.flat_map(|t| all_super_traits(ctx.db, t)); | 351 | let traits = traits_from_env.flat_map(|t| all_super_traits(ctx.db, t)); |
@@ -620,8 +615,8 @@ pub(crate) fn field_types_query( | |||
620 | }; | 615 | }; |
621 | let generics = generics(db, def); | 616 | let generics = generics(db, def); |
622 | let mut res = ArenaMap::default(); | 617 | let mut res = ArenaMap::default(); |
623 | let ctx = TyLoweringContext::new(db, &resolver) | 618 | let ctx = |
624 | .with_type_param_mode(TypeParamLoweringMode::Variable); | 619 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
625 | for (field_id, field_data) in var_data.fields().iter() { | 620 | for (field_id, field_data) in var_data.fields().iter() { |
626 | res.insert(field_id, Binders::new(generics.len(), Ty::from_hir(&ctx, &field_data.type_ref))) | 621 | res.insert(field_id, Binders::new(generics.len(), Ty::from_hir(&ctx, &field_data.type_ref))) |
627 | } | 622 | } |
@@ -639,10 +634,11 @@ pub(crate) fn field_types_query( | |||
639 | pub(crate) fn generic_predicates_for_param_query( | 634 | pub(crate) fn generic_predicates_for_param_query( |
640 | db: &impl HirDatabase, | 635 | db: &impl HirDatabase, |
641 | param_id: TypeParamId, | 636 | param_id: TypeParamId, |
642 | ) -> Arc<[GenericPredicate]> { | 637 | ) -> Arc<[Binders<GenericPredicate>]> { |
643 | let resolver = param_id.parent.resolver(db); | 638 | let resolver = param_id.parent.resolver(db); |
644 | let ctx = TyLoweringContext::new(db, &resolver); | 639 | let ctx = |
645 | // let generics = generics(db, def); | 640 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
641 | let generics = generics(db, param_id.parent); | ||
646 | resolver | 642 | resolver |
647 | .where_predicates_in_scope() | 643 | .where_predicates_in_scope() |
648 | // we have to filter out all other predicates *first*, before attempting to lower them | 644 | // we have to filter out all other predicates *first*, before attempting to lower them |
@@ -650,11 +646,12 @@ pub(crate) fn generic_predicates_for_param_query( | |||
650 | WherePredicateTarget::TypeRef(type_ref) => { | 646 | WherePredicateTarget::TypeRef(type_ref) => { |
651 | Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id) | 647 | Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id) |
652 | } | 648 | } |
653 | WherePredicateTarget::TypeParam(local_id) => { | 649 | WherePredicateTarget::TypeParam(local_id) => *local_id == param_id.local_id, |
654 | *local_id == param_id.local_id | 650 | }) |
655 | } | 651 | .flat_map(|pred| { |
652 | GenericPredicate::from_where_predicate(&ctx, pred) | ||
653 | .map(|p| Binders::new(generics.len(), p)) | ||
656 | }) | 654 | }) |
657 | .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) | ||
658 | .collect() | 655 | .collect() |
659 | } | 656 | } |
660 | 657 | ||
@@ -662,13 +659,14 @@ pub(crate) fn generic_predicates_for_param_recover( | |||
662 | _db: &impl HirDatabase, | 659 | _db: &impl HirDatabase, |
663 | _cycle: &[String], | 660 | _cycle: &[String], |
664 | _param_id: &TypeParamId, | 661 | _param_id: &TypeParamId, |
665 | ) -> Arc<[GenericPredicate]> { | 662 | ) -> Arc<[Binders<GenericPredicate>]> { |
666 | Arc::new([]) | 663 | Arc::new([]) |
667 | } | 664 | } |
668 | 665 | ||
669 | impl TraitEnvironment { | 666 | impl TraitEnvironment { |
670 | pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> { | 667 | pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> { |
671 | let ctx = TyLoweringContext::new(db, &resolver); | 668 | let ctx = TyLoweringContext::new(db, &resolver) |
669 | .with_type_param_mode(TypeParamLoweringMode::Placeholder); | ||
672 | let predicates = resolver | 670 | let predicates = resolver |
673 | .where_predicates_in_scope() | 671 | .where_predicates_in_scope() |
674 | .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) | 672 | .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) |
@@ -682,12 +680,17 @@ impl TraitEnvironment { | |||
682 | pub(crate) fn generic_predicates_query( | 680 | pub(crate) fn generic_predicates_query( |
683 | db: &impl HirDatabase, | 681 | db: &impl HirDatabase, |
684 | def: GenericDefId, | 682 | def: GenericDefId, |
685 | ) -> Arc<[GenericPredicate]> { | 683 | ) -> Arc<[Binders<GenericPredicate>]> { |
686 | let resolver = def.resolver(db); | 684 | let resolver = def.resolver(db); |
687 | let ctx = TyLoweringContext::new(db, &resolver); | 685 | let ctx = |
686 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | ||
687 | let generics = generics(db, def); | ||
688 | resolver | 688 | resolver |
689 | .where_predicates_in_scope() | 689 | .where_predicates_in_scope() |
690 | .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) | 690 | .flat_map(|pred| { |
691 | GenericPredicate::from_where_predicate(&ctx, pred) | ||
692 | .map(|p| Binders::new(generics.len(), p)) | ||
693 | }) | ||
691 | .collect() | 694 | .collect() |
692 | } | 695 | } |
693 | 696 | ||
@@ -915,12 +918,18 @@ pub(crate) fn impl_self_ty_recover( | |||
915 | Binders::new(generics.len(), Ty::Unknown) | 918 | Binders::new(generics.len(), Ty::Unknown) |
916 | } | 919 | } |
917 | 920 | ||
918 | pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> { | 921 | pub(crate) fn impl_trait_query( |
922 | db: &impl HirDatabase, | ||
923 | impl_id: ImplId, | ||
924 | ) -> Option<Binders<TraitRef>> { | ||
919 | let impl_data = db.impl_data(impl_id); | 925 | let impl_data = db.impl_data(impl_id); |
920 | let resolver = impl_id.resolver(db); | 926 | let resolver = impl_id.resolver(db); |
921 | let ctx = TyLoweringContext::new(db, &resolver) | 927 | let ctx = |
922 | .with_type_param_mode(TypeParamLoweringMode::Variable); | 928 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
923 | let self_ty = db.impl_self_ty(impl_id); | 929 | let self_ty = db.impl_self_ty(impl_id); |
924 | let target_trait = impl_data.target_trait.as_ref()?; | 930 | let target_trait = impl_data.target_trait.as_ref()?; |
925 | Some(Binders::new(self_ty.num_binders, TraitRef::from_hir(&ctx, target_trait, Some(self_ty.value.clone()))?)) | 931 | Some(Binders::new( |
932 | self_ty.num_binders, | ||
933 | TraitRef::from_hir(&ctx, target_trait, Some(self_ty.value.clone()))?, | ||
934 | )) | ||
926 | } | 935 | } |