aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir_ty/src/lower.rs31
-rw-r--r--crates/hir_ty/src/method_resolution.rs3
-rw-r--r--crates/hir_ty/src/traits.rs23
-rw-r--r--crates/hir_ty/src/traits/chalk.rs4
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs38
5 files changed, 44 insertions, 55 deletions
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 5fa83567b..d84ec9b7a 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -8,7 +8,7 @@
8use std::{iter, sync::Arc}; 8use std::{iter, sync::Arc};
9 9
10use base_db::CrateId; 10use base_db::CrateId;
11use chalk_ir::Mutability; 11use chalk_ir::{cast::Cast, Mutability};
12use hir_def::{ 12use hir_def::{
13 adt::StructKind, 13 adt::StructKind,
14 builtin_type::BuiltinType, 14 builtin_type::BuiltinType,
@@ -27,6 +27,7 @@ use stdx::impl_from;
27 27
28use crate::{ 28use crate::{
29 db::HirDatabase, 29 db::HirDatabase,
30 traits::chalk::{Interner, ToChalk},
30 utils::{ 31 utils::{
31 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, 32 all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
32 make_mut_slice, variant_data, 33 make_mut_slice, variant_data,
@@ -914,10 +915,21 @@ impl TraitEnvironment {
914 pub fn lower(db: &dyn HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> { 915 pub fn lower(db: &dyn HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> {
915 let ctx = TyLoweringContext::new(db, &resolver) 916 let ctx = TyLoweringContext::new(db, &resolver)
916 .with_type_param_mode(TypeParamLoweringMode::Placeholder); 917 .with_type_param_mode(TypeParamLoweringMode::Placeholder);
917 let mut predicates = resolver 918 let mut traits_in_scope = Vec::new();
918 .where_predicates_in_scope() 919 let mut clauses = Vec::new();
919 .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) 920 for pred in resolver.where_predicates_in_scope() {
920 .collect::<Vec<_>>(); 921 for pred in GenericPredicate::from_where_predicate(&ctx, pred) {
922 if pred.is_error() {
923 continue;
924 }
925 if let GenericPredicate::Implemented(tr) = &pred {
926 traits_in_scope.push((tr.self_ty().clone(), tr.trait_));
927 }
928 let program_clause: chalk_ir::ProgramClause<Interner> =
929 pred.clone().to_chalk(db).cast(&Interner);
930 clauses.push(program_clause.into_from_env_clause(&Interner));
931 }
932 }
921 933
922 if let Some(def) = resolver.generic_def() { 934 if let Some(def) = resolver.generic_def() {
923 let container: Option<AssocContainerId> = match def { 935 let container: Option<AssocContainerId> = match def {
@@ -938,12 +950,15 @@ impl TraitEnvironment {
938 let substs = Substs::type_params(db, trait_id); 950 let substs = Substs::type_params(db, trait_id);
939 let trait_ref = TraitRef { trait_: trait_id, substs }; 951 let trait_ref = TraitRef { trait_: trait_id, substs };
940 let pred = GenericPredicate::Implemented(trait_ref); 952 let pred = GenericPredicate::Implemented(trait_ref);
941 953 let program_clause: chalk_ir::ProgramClause<Interner> =
942 predicates.push(pred); 954 pred.clone().to_chalk(db).cast(&Interner);
955 clauses.push(program_clause.into_from_env_clause(&Interner));
943 } 956 }
944 } 957 }
945 958
946 Arc::new(TraitEnvironment { predicates }) 959 let env = chalk_ir::Environment::new(&Interner).add_clauses(&Interner, clauses);
960
961 Arc::new(TraitEnvironment { traits_from_clauses: traits_in_scope, env })
947 } 962 }
948} 963}
949 964
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index ccc12c075..d57c6de70 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -528,8 +528,7 @@ fn iterate_trait_method_candidates(
528 self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t)); 528 self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t));
529 let env_traits = if let Ty::Placeholder(_) = self_ty.value { 529 let env_traits = if let Ty::Placeholder(_) = self_ty.value {
530 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope 530 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
531 env.trait_predicates_for_self_ty(&self_ty.value) 531 env.traits_in_scope_from_clauses(&self_ty.value)
532 .map(|tr| tr.trait_)
533 .flat_map(|t| all_super_traits(db.upcast(), t)) 532 .flat_map(|t| all_super_traits(db.upcast(), t))
534 .collect() 533 .collect()
535 } else { 534 } else {
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs
index e4cdb6d53..27f350f70 100644
--- a/crates/hir_ty/src/traits.rs
+++ b/crates/hir_ty/src/traits.rs
@@ -38,22 +38,25 @@ fn create_chalk_solver() -> chalk_recursive::RecursiveSolver<Interner> {
38/// fn foo<T: Default>(t: T) {} 38/// fn foo<T: Default>(t: T) {}
39/// ``` 39/// ```
40/// we assume that `T: Default`. 40/// we assume that `T: Default`.
41#[derive(Clone, Debug, PartialEq, Eq, Hash)] 41#[derive(Debug, Clone, PartialEq, Eq, Hash)]
42pub struct TraitEnvironment { 42pub struct TraitEnvironment {
43 pub predicates: Vec<GenericPredicate>, 43 // When we're using Chalk's Ty we can make this a BTreeMap since it's Ord,
44 // but for now it's too annoying...
45 pub(crate) traits_from_clauses: Vec<(Ty, TraitId)>,
46 pub(crate) env: chalk_ir::Environment<Interner>,
44} 47}
45 48
46impl TraitEnvironment { 49impl TraitEnvironment {
47 /// Returns trait refs with the given self type which are supposed to hold 50 pub(crate) fn traits_in_scope_from_clauses<'a>(
48 /// in this trait env. E.g. if we are in `foo<T: SomeTrait>()`, this will
49 /// find that `T: SomeTrait` if we call it for `T`.
50 pub(crate) fn trait_predicates_for_self_ty<'a>(
51 &'a self, 51 &'a self,
52 ty: &'a Ty, 52 ty: &'a Ty,
53 ) -> impl Iterator<Item = &'a TraitRef> + 'a { 53 ) -> impl Iterator<Item = TraitId> + 'a {
54 self.predicates.iter().filter_map(move |pred| match pred { 54 self.traits_from_clauses.iter().filter_map(move |(self_ty, trait_id)| {
55 GenericPredicate::Implemented(tr) if tr.self_ty() == ty => Some(tr), 55 if self_ty == ty {
56 _ => None, 56 Some(*trait_id)
57 } else {
58 None
59 }
57 }) 60 })
58 } 61 }
59} 62}
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index 565672b6b..4e7d43f7e 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -33,13 +33,13 @@ pub(super) mod tls;
33mod interner; 33mod interner;
34mod mapping; 34mod mapping;
35 35
36pub(super) trait ToChalk { 36pub(crate) trait ToChalk {
37 type Chalk; 37 type Chalk;
38 fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk; 38 fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk;
39 fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self; 39 fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self;
40} 40}
41 41
42pub(super) fn from_chalk<T, ChalkT>(db: &dyn HirDatabase, chalk: ChalkT) -> T 42pub(crate) fn from_chalk<T, ChalkT>(db: &dyn HirDatabase, chalk: ChalkT) -> T
43where 43where
44 T: ToChalk<Chalk = ChalkT>, 44 T: ToChalk<Chalk = ChalkT>,
45{ 45{
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index 3a08b67e9..b0415e8b0 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -17,7 +17,7 @@ use crate::{
17 primitive::UintTy, 17 primitive::UintTy,
18 traits::{Canonical, Obligation}, 18 traits::{Canonical, Obligation},
19 AliasTy, CallableDefId, FnPointer, FnSig, GenericPredicate, InEnvironment, OpaqueTy, 19 AliasTy, CallableDefId, FnPointer, FnSig, GenericPredicate, InEnvironment, OpaqueTy,
20 OpaqueTyId, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, TraitRef, Ty, 20 OpaqueTyId, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitRef, Ty,
21}; 21};
22 22
23use super::interner::*; 23use super::interner::*;
@@ -536,31 +536,6 @@ where
536 } 536 }
537} 537}
538 538
539impl ToChalk for Arc<TraitEnvironment> {
540 type Chalk = chalk_ir::Environment<Interner>;
541
542 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Environment<Interner> {
543 let mut clauses = Vec::new();
544 for pred in &self.predicates {
545 if pred.is_error() {
546 // for env, we just ignore errors
547 continue;
548 }
549 let program_clause: chalk_ir::ProgramClause<Interner> =
550 pred.clone().to_chalk(db).cast(&Interner);
551 clauses.push(program_clause.into_from_env_clause(&Interner));
552 }
553 chalk_ir::Environment::new(&Interner).add_clauses(&Interner, clauses)
554 }
555
556 fn from_chalk(
557 _db: &dyn HirDatabase,
558 _env: chalk_ir::Environment<Interner>,
559 ) -> Arc<TraitEnvironment> {
560 unimplemented!()
561 }
562}
563
564impl<T: ToChalk> ToChalk for InEnvironment<T> 539impl<T: ToChalk> ToChalk for InEnvironment<T>
565where 540where
566 T::Chalk: chalk_ir::interner::HasInterner<Interner = Interner>, 541 T::Chalk: chalk_ir::interner::HasInterner<Interner = Interner>,
@@ -569,19 +544,16 @@ where
569 544
570 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> { 545 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> {
571 chalk_ir::InEnvironment { 546 chalk_ir::InEnvironment {
572 environment: self.environment.to_chalk(db), 547 environment: self.environment.env.clone(),
573 goal: self.value.to_chalk(db), 548 goal: self.value.to_chalk(db),
574 } 549 }
575 } 550 }
576 551
577 fn from_chalk( 552 fn from_chalk(
578 db: &dyn HirDatabase, 553 _db: &dyn HirDatabase,
579 in_env: chalk_ir::InEnvironment<T::Chalk>, 554 _in_env: chalk_ir::InEnvironment<T::Chalk>,
580 ) -> InEnvironment<T> { 555 ) -> InEnvironment<T> {
581 InEnvironment { 556 unimplemented!()
582 environment: from_chalk(db, in_env.environment),
583 value: from_chalk(db, in_env.goal),
584 }
585 } 557 }
586} 558}
587 559