aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-02-02 16:11:54 +0000
committerFlorian Diebold <[email protected]>2020-02-07 17:28:10 +0000
commita3d8cffde39bfb0d50b87a8ded5e0534adec4cd5 (patch)
tree3be5406b38c2594808c87d9dbecf7aa14b52b67d /crates/ra_hir_ty
parent86348f5994cdc3831edf3a5582d6d9d576fd1d80 (diff)
Use variables in predicates as well
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r--crates/ra_hir_ty/src/db.rs4
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs4
-rw-r--r--crates/ra_hir_ty/src/lib.rs28
-rw-r--r--crates/ra_hir_ty/src/lower.rs73
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs6
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
26use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; 26use 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
11use hir_def::{ 11use 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};
21use ra_arena::map::ArenaMap; 21use ra_arena::map::ArenaMap;
22use ra_db::CrateId; 22use 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(
639pub(crate) fn generic_predicates_for_param_query( 634pub(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
669impl TraitEnvironment { 666impl 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 {
682pub(crate) fn generic_predicates_query( 680pub(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
918pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> { 921pub(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::{
14use super::{builtin, AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; 14use super::{builtin, AssocTyValue, Canonical, ChalkContext, Impl, Obligation};
15use crate::{ 15use 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}