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 | |
parent | 86348f5994cdc3831edf3a5582d6d9d576fd1d80 (diff) |
Use variables in predicates as well
Diffstat (limited to 'crates/ra_hir_ty/src')
-rw-r--r-- | crates/ra_hir_ty/src/db.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/expr.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lib.rs | 28 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lower.rs | 73 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk.rs | 6 |
5 files changed, 52 insertions, 63 deletions
diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs index 7684ade06..21ab22fa9 100644 --- a/crates/ra_hir_ty/src/db.rs +++ b/crates/ra_hir_ty/src/db.rs | |||
@@ -50,10 +50,10 @@ pub trait HirDatabase: DefDatabase { | |||
50 | fn generic_predicates_for_param( | 50 | fn generic_predicates_for_param( |
51 | &self, | 51 | &self, |
52 | param_id: TypeParamId, | 52 | param_id: TypeParamId, |
53 | ) -> Arc<[GenericPredicate]>; | 53 | ) -> Arc<[Binders<GenericPredicate>]>; |
54 | 54 | ||
55 | #[salsa::invoke(crate::lower::generic_predicates_query)] | 55 | #[salsa::invoke(crate::lower::generic_predicates_query)] |
56 | fn generic_predicates(&self, def: GenericDefId) -> Arc<[GenericPredicate]>; | 56 | fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<GenericPredicate>]>; |
57 | 57 | ||
58 | #[salsa::invoke(crate::lower::generic_defaults_query)] | 58 | #[salsa::invoke(crate::lower::generic_defaults_query)] |
59 | fn generic_defaults(&self, def: GenericDefId) -> Substs; | 59 | fn generic_defaults(&self, def: GenericDefId) -> Substs; |
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index b32df8e90..b69785e55 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs | |||
@@ -20,7 +20,7 @@ use crate::{ | |||
20 | traits::InEnvironment, | 20 | traits::InEnvironment, |
21 | utils::{generics, variant_data, Generics}, | 21 | utils::{generics, variant_data, Generics}, |
22 | ApplicationTy, CallableDef, InferTy, IntTy, Mutability, Obligation, Substs, TraitRef, Ty, | 22 | ApplicationTy, CallableDef, InferTy, IntTy, Mutability, Obligation, Substs, TraitRef, Ty, |
23 | TypeCtor, TypeWalk, Uncertain, Binders, | 23 | TypeCtor, Uncertain, Binders, |
24 | }; | 24 | }; |
25 | 25 | ||
26 | use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; | 26 | use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; |
@@ -686,7 +686,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
686 | if let TypeCtor::FnDef(def) = a_ty.ctor { | 686 | if let TypeCtor::FnDef(def) = a_ty.ctor { |
687 | let generic_predicates = self.db.generic_predicates(def.into()); | 687 | let generic_predicates = self.db.generic_predicates(def.into()); |
688 | for predicate in generic_predicates.iter() { | 688 | for predicate in generic_predicates.iter() { |
689 | let predicate = predicate.clone().subst_type_params(self.db, def.into(), &a_ty.parameters); | 689 | let predicate = predicate.clone().subst(&a_ty.parameters); |
690 | if let Some(obligation) = Obligation::from_predicate(predicate) { | 690 | if let Some(obligation) = Obligation::from_predicate(predicate) { |
691 | self.obligations.push(obligation); | 691 | self.obligations.push(obligation); |
692 | } | 692 | } |
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 1da4bcc19..a685e70c2 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs | |||
@@ -749,28 +749,7 @@ pub trait TypeWalk { | |||
749 | self | 749 | self |
750 | } | 750 | } |
751 | 751 | ||
752 | /// Replaces type parameters in this type using the given `Substs`. (So e.g. | 752 | /// Substitutes `Ty::Bound` vars with the given substitution. |
753 | /// if `self` is `&[T]`, where type parameter T has index 0, and the | ||
754 | /// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.) | ||
755 | // TODO: this should mostly not be used anymore | ||
756 | fn subst_type_params(self, db: &impl HirDatabase, def: GenericDefId, substs: &Substs) -> Self | ||
757 | where | ||
758 | Self: Sized, | ||
759 | { | ||
760 | let generics = generics(db, def); | ||
761 | self.fold(&mut |ty| match ty { | ||
762 | Ty::Param(id) => { | ||
763 | if let Some(idx) = generics.param_idx(id) { | ||
764 | substs.get(idx as usize).cloned().unwrap_or(Ty::Param(id)) | ||
765 | } else { | ||
766 | ty | ||
767 | } | ||
768 | } | ||
769 | ty => ty, | ||
770 | }) | ||
771 | } | ||
772 | |||
773 | /// Substitutes `Ty::Bound` vars (as opposed to type parameters). | ||
774 | fn subst_bound_vars(mut self, substs: &Substs) -> Self | 753 | fn subst_bound_vars(mut self, substs: &Substs) -> Self |
775 | where | 754 | where |
776 | Self: Sized, | 755 | Self: Sized, |
@@ -1045,9 +1024,10 @@ impl HirDisplay for Ty { | |||
1045 | write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? | 1024 | write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? |
1046 | } | 1025 | } |
1047 | TypeParamProvenance::ArgumentImplTrait => { | 1026 | TypeParamProvenance::ArgumentImplTrait => { |
1048 | let bounds = f.db.generic_predicates_for_param(*id); | ||
1049 | write!(f, "impl ")?; | 1027 | write!(f, "impl ")?; |
1050 | write_bounds_like_dyn_trait(&bounds, f)?; | 1028 | let bounds = f.db.generic_predicates_for_param(*id); |
1029 | let substs = Substs::type_params(&generics); | ||
1030 | write_bounds_like_dyn_trait(&bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(), f)?; | ||
1051 | } | 1031 | } |
1052 | } | 1032 | } |
1053 | } | 1033 | } |
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 | } |
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs index 6e97f7dd2..8260bd157 100644 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs | |||
@@ -14,7 +14,7 @@ use ra_db::{ | |||
14 | use super::{builtin, AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; | 14 | use super::{builtin, AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; |
15 | use crate::{ | 15 | use crate::{ |
16 | db::HirDatabase, display::HirDisplay, utils::generics, ApplicationTy, GenericPredicate, | 16 | db::HirDatabase, display::HirDisplay, utils::generics, ApplicationTy, GenericPredicate, |
17 | ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, | 17 | ProjectionTy, Substs, TraitRef, Ty, TypeCtor, |
18 | }; | 18 | }; |
19 | 19 | ||
20 | #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] | 20 | #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] |
@@ -522,11 +522,11 @@ fn convert_where_clauses( | |||
522 | let generic_predicates = db.generic_predicates(def); | 522 | let generic_predicates = db.generic_predicates(def); |
523 | let mut result = Vec::with_capacity(generic_predicates.len()); | 523 | let mut result = Vec::with_capacity(generic_predicates.len()); |
524 | for pred in generic_predicates.iter() { | 524 | for pred in generic_predicates.iter() { |
525 | if pred.is_error() { | 525 | if pred.value.is_error() { |
526 | // skip errored predicates completely | 526 | // skip errored predicates completely |
527 | continue; | 527 | continue; |
528 | } | 528 | } |
529 | result.push(pred.clone().subst_type_params(db, def, substs).to_chalk(db)); | 529 | result.push(pred.clone().subst(substs).to_chalk(db)); |
530 | } | 530 | } |
531 | result | 531 | result |
532 | } | 532 | } |