diff options
author | Florian Diebold <[email protected]> | 2021-03-12 18:12:17 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2021-03-12 18:12:17 +0000 |
commit | ec70387a4cac131f34847c94e9fe7de66acc241e (patch) | |
tree | eba9f9c4fe5c807b3ac27f0bc9d841f693843226 /crates | |
parent | c0459c53572f90fa9134192e432562af3daba5fa (diff) |
Use Chalk Environment more directly
Diffstat (limited to 'crates')
-rw-r--r-- | crates/hir_ty/src/lower.rs | 31 | ||||
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 3 | ||||
-rw-r--r-- | crates/hir_ty/src/traits.rs | 23 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk.rs | 4 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 38 |
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 @@ | |||
8 | use std::{iter, sync::Arc}; | 8 | use std::{iter, sync::Arc}; |
9 | 9 | ||
10 | use base_db::CrateId; | 10 | use base_db::CrateId; |
11 | use chalk_ir::Mutability; | 11 | use chalk_ir::{cast::Cast, Mutability}; |
12 | use hir_def::{ | 12 | use 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 | ||
28 | use crate::{ | 28 | use 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)] |
42 | pub struct TraitEnvironment { | 42 | pub 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 | ||
46 | impl TraitEnvironment { | 49 | impl 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; | |||
33 | mod interner; | 33 | mod interner; |
34 | mod mapping; | 34 | mod mapping; |
35 | 35 | ||
36 | pub(super) trait ToChalk { | 36 | pub(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 | ||
42 | pub(super) fn from_chalk<T, ChalkT>(db: &dyn HirDatabase, chalk: ChalkT) -> T | 42 | pub(crate) fn from_chalk<T, ChalkT>(db: &dyn HirDatabase, chalk: ChalkT) -> T |
43 | where | 43 | where |
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 | ||
23 | use super::interner::*; | 23 | use super::interner::*; |
@@ -536,31 +536,6 @@ where | |||
536 | } | 536 | } |
537 | } | 537 | } |
538 | 538 | ||
539 | impl 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 | |||
564 | impl<T: ToChalk> ToChalk for InEnvironment<T> | 539 | impl<T: ToChalk> ToChalk for InEnvironment<T> |
565 | where | 540 | where |
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 | ||