diff options
author | Florian Diebold <[email protected]> | 2021-03-13 19:38:11 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2021-03-13 19:38:45 +0000 |
commit | c82d1823a1624f4990b1ebaba5b6173f15631381 (patch) | |
tree | 6c59a0786f78cc5878ddb74a589f1d221d907137 /crates/hir_ty/src | |
parent | 17eeb2a6d2ea81b302b6707c63bf8fba489c2bdd (diff) |
Create TraitEnvironment through a query
Diffstat (limited to 'crates/hir_ty/src')
-rw-r--r-- | crates/hir_ty/src/db.rs | 3 | ||||
-rw-r--r-- | crates/hir_ty/src/infer.rs | 4 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 88 | ||||
-rw-r--r-- | crates/hir_ty/src/traits.rs | 9 |
4 files changed, 59 insertions, 45 deletions
diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs index 8a3cc0283..74a048672 100644 --- a/crates/hir_ty/src/db.rs +++ b/crates/hir_ty/src/db.rs | |||
@@ -65,6 +65,9 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> { | |||
65 | #[salsa::invoke(crate::lower::generic_predicates_query)] | 65 | #[salsa::invoke(crate::lower::generic_predicates_query)] |
66 | fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<GenericPredicate>]>; | 66 | fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<GenericPredicate>]>; |
67 | 67 | ||
68 | #[salsa::invoke(crate::lower::trait_environment_query)] | ||
69 | fn trait_environment(&self, def: GenericDefId) -> Arc<crate::TraitEnvironment>; | ||
70 | |||
68 | #[salsa::invoke(crate::lower::generic_defaults_query)] | 71 | #[salsa::invoke(crate::lower::generic_defaults_query)] |
69 | fn generic_defaults(&self, def: GenericDefId) -> Arc<[Binders<Ty>]>; | 72 | fn generic_defaults(&self, def: GenericDefId) -> Arc<[Binders<Ty>]>; |
70 | 73 | ||
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index 4f7463422..bc52f447d 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs | |||
@@ -228,7 +228,9 @@ impl<'a> InferenceContext<'a> { | |||
228 | table: unify::InferenceTable::new(), | 228 | table: unify::InferenceTable::new(), |
229 | obligations: Vec::default(), | 229 | obligations: Vec::default(), |
230 | return_ty: TyKind::Unknown.intern(&Interner), // set in collect_fn_signature | 230 | return_ty: TyKind::Unknown.intern(&Interner), // set in collect_fn_signature |
231 | trait_env: TraitEnvironment::lower(db, &resolver), | 231 | trait_env: owner |
232 | .as_generic_def_id() | ||
233 | .map_or_else(Default::default, |d| db.trait_environment(d)), | ||
232 | db, | 234 | db, |
233 | owner, | 235 | owner, |
234 | body: db.body(owner), | 236 | body: db.body(owner), |
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index e57d5970f..3b0706530 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs | |||
@@ -935,55 +935,55 @@ pub(crate) fn generic_predicates_for_param_recover( | |||
935 | Arc::new([]) | 935 | Arc::new([]) |
936 | } | 936 | } |
937 | 937 | ||
938 | impl TraitEnvironment { | 938 | pub(crate) fn trait_environment_query( |
939 | pub fn lower(db: &dyn HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> { | 939 | db: &dyn HirDatabase, |
940 | let ctx = TyLoweringContext::new(db, &resolver) | 940 | def: GenericDefId, |
941 | .with_type_param_mode(TypeParamLoweringMode::Placeholder); | 941 | ) -> Arc<TraitEnvironment> { |
942 | let mut traits_in_scope = Vec::new(); | 942 | let resolver = def.resolver(db.upcast()); |
943 | let mut clauses = Vec::new(); | 943 | let ctx = TyLoweringContext::new(db, &resolver) |
944 | for pred in resolver.where_predicates_in_scope() { | 944 | .with_type_param_mode(TypeParamLoweringMode::Placeholder); |
945 | for pred in GenericPredicate::from_where_predicate(&ctx, pred) { | 945 | let mut traits_in_scope = Vec::new(); |
946 | if pred.is_error() { | 946 | let mut clauses = Vec::new(); |
947 | continue; | 947 | for pred in resolver.where_predicates_in_scope() { |
948 | } | 948 | for pred in GenericPredicate::from_where_predicate(&ctx, pred) { |
949 | if let GenericPredicate::Implemented(tr) = &pred { | 949 | if pred.is_error() { |
950 | traits_in_scope.push((tr.self_ty().clone(), tr.trait_)); | 950 | continue; |
951 | } | ||
952 | let program_clause: chalk_ir::ProgramClause<Interner> = | ||
953 | pred.clone().to_chalk(db).cast(&Interner); | ||
954 | clauses.push(program_clause.into_from_env_clause(&Interner)); | ||
955 | } | 951 | } |
956 | } | 952 | if let GenericPredicate::Implemented(tr) = &pred { |
957 | 953 | traits_in_scope.push((tr.self_ty().clone(), tr.trait_)); | |
958 | if let Some(def) = resolver.generic_def() { | ||
959 | let container: Option<AssocContainerId> = match def { | ||
960 | // FIXME: is there a function for this? | ||
961 | GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container), | ||
962 | GenericDefId::AdtId(_) => None, | ||
963 | GenericDefId::TraitId(_) => None, | ||
964 | GenericDefId::TypeAliasId(t) => Some(t.lookup(db.upcast()).container), | ||
965 | GenericDefId::ImplId(_) => None, | ||
966 | GenericDefId::EnumVariantId(_) => None, | ||
967 | GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container), | ||
968 | }; | ||
969 | if let Some(AssocContainerId::TraitId(trait_id)) = container { | ||
970 | // add `Self: Trait<T1, T2, ...>` to the environment in trait | ||
971 | // function default implementations (and hypothetical code | ||
972 | // inside consts or type aliases) | ||
973 | cov_mark::hit!(trait_self_implements_self); | ||
974 | let substs = Substs::type_params(db, trait_id); | ||
975 | let trait_ref = TraitRef { trait_: trait_id, substs }; | ||
976 | let pred = GenericPredicate::Implemented(trait_ref); | ||
977 | let program_clause: chalk_ir::ProgramClause<Interner> = | ||
978 | pred.clone().to_chalk(db).cast(&Interner); | ||
979 | clauses.push(program_clause.into_from_env_clause(&Interner)); | ||
980 | } | 954 | } |
955 | let program_clause: chalk_ir::ProgramClause<Interner> = | ||
956 | pred.clone().to_chalk(db).cast(&Interner); | ||
957 | clauses.push(program_clause.into_from_env_clause(&Interner)); | ||
981 | } | 958 | } |
959 | } | ||
982 | 960 | ||
983 | let env = chalk_ir::Environment::new(&Interner).add_clauses(&Interner, clauses); | 961 | let container: Option<AssocContainerId> = match def { |
984 | 962 | // FIXME: is there a function for this? | |
985 | Arc::new(TraitEnvironment { traits_from_clauses: traits_in_scope, env }) | 963 | GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container), |
964 | GenericDefId::AdtId(_) => None, | ||
965 | GenericDefId::TraitId(_) => None, | ||
966 | GenericDefId::TypeAliasId(t) => Some(t.lookup(db.upcast()).container), | ||
967 | GenericDefId::ImplId(_) => None, | ||
968 | GenericDefId::EnumVariantId(_) => None, | ||
969 | GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container), | ||
970 | }; | ||
971 | if let Some(AssocContainerId::TraitId(trait_id)) = container { | ||
972 | // add `Self: Trait<T1, T2, ...>` to the environment in trait | ||
973 | // function default implementations (and hypothetical code | ||
974 | // inside consts or type aliases) | ||
975 | cov_mark::hit!(trait_self_implements_self); | ||
976 | let substs = Substs::type_params(db, trait_id); | ||
977 | let trait_ref = TraitRef { trait_: trait_id, substs }; | ||
978 | let pred = GenericPredicate::Implemented(trait_ref); | ||
979 | let program_clause: chalk_ir::ProgramClause<Interner> = | ||
980 | pred.clone().to_chalk(db).cast(&Interner); | ||
981 | clauses.push(program_clause.into_from_env_clause(&Interner)); | ||
986 | } | 982 | } |
983 | |||
984 | let env = chalk_ir::Environment::new(&Interner).add_clauses(&Interner, clauses); | ||
985 | |||
986 | Arc::new(TraitEnvironment { traits_from_clauses: traits_in_scope, env }) | ||
987 | } | 987 | } |
988 | 988 | ||
989 | /// Resolve the where clause(s) of an item with generics. | 989 | /// Resolve the where clause(s) of an item with generics. |
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs index 500d1781c..edfafdff8 100644 --- a/crates/hir_ty/src/traits.rs +++ b/crates/hir_ty/src/traits.rs | |||
@@ -63,6 +63,15 @@ impl TraitEnvironment { | |||
63 | } | 63 | } |
64 | } | 64 | } |
65 | 65 | ||
66 | impl Default for TraitEnvironment { | ||
67 | fn default() -> Self { | ||
68 | TraitEnvironment { | ||
69 | traits_from_clauses: Vec::new(), | ||
70 | env: chalk_ir::Environment::new(&Interner), | ||
71 | } | ||
72 | } | ||
73 | } | ||
74 | |||
66 | /// Something (usually a goal), along with an environment. | 75 | /// Something (usually a goal), along with an environment. |
67 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | 76 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] |
68 | pub struct InEnvironment<T> { | 77 | pub struct InEnvironment<T> { |