diff options
-rw-r--r-- | crates/hir/src/lib.rs | 12 | ||||
-rw-r--r-- | crates/hir_def/src/lib.rs | 10 | ||||
-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 |
6 files changed, 76 insertions, 50 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 571b89bc3..cda050a7d 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -54,8 +54,8 @@ use hir_ty::{ | |||
54 | method_resolution, to_assoc_type_id, | 54 | method_resolution, to_assoc_type_id, |
55 | traits::{FnTrait, Solution, SolutionVariables}, | 55 | traits::{FnTrait, Solution, SolutionVariables}, |
56 | AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, | 56 | AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, |
57 | InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, | 57 | InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, Ty, |
58 | TraitEnvironment, Ty, TyDefId, TyKind, TyVariableKind, | 58 | TyDefId, TyKind, TyVariableKind, |
59 | }; | 59 | }; |
60 | use rustc_hash::FxHashSet; | 60 | use rustc_hash::FxHashSet; |
61 | use stdx::{format_to, impl_from}; | 61 | use stdx::{format_to, impl_from}; |
@@ -817,7 +817,7 @@ impl Function { | |||
817 | let resolver = self.id.resolver(db.upcast()); | 817 | let resolver = self.id.resolver(db.upcast()); |
818 | let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate(); | 818 | let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate(); |
819 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); | 819 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); |
820 | let environment = TraitEnvironment::lower(db, &resolver); | 820 | let environment = db.trait_environment(self.id.into()); |
821 | db.function_data(self.id) | 821 | db.function_data(self.id) |
822 | .params | 822 | .params |
823 | .iter() | 823 | .iter() |
@@ -1563,13 +1563,15 @@ impl Type { | |||
1563 | resolver: &Resolver, | 1563 | resolver: &Resolver, |
1564 | ty: Ty, | 1564 | ty: Ty, |
1565 | ) -> Type { | 1565 | ) -> Type { |
1566 | let environment = TraitEnvironment::lower(db, &resolver); | 1566 | let environment = |
1567 | resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d)); | ||
1567 | Type { krate, ty: InEnvironment { value: ty, environment } } | 1568 | Type { krate, ty: InEnvironment { value: ty, environment } } |
1568 | } | 1569 | } |
1569 | 1570 | ||
1570 | fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type { | 1571 | fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type { |
1571 | let resolver = lexical_env.resolver(db.upcast()); | 1572 | let resolver = lexical_env.resolver(db.upcast()); |
1572 | let environment = TraitEnvironment::lower(db, &resolver); | 1573 | let environment = |
1574 | resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d)); | ||
1573 | Type { krate, ty: InEnvironment { value: ty, environment } } | 1575 | Type { krate, ty: InEnvironment { value: ty, environment } } |
1574 | } | 1576 | } |
1575 | 1577 | ||
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index 6d11c5be4..c6655c5fb 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs | |||
@@ -341,6 +341,16 @@ pub enum DefWithBodyId { | |||
341 | 341 | ||
342 | impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId); | 342 | impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId); |
343 | 343 | ||
344 | impl DefWithBodyId { | ||
345 | pub fn as_generic_def_id(self) -> Option<GenericDefId> { | ||
346 | match self { | ||
347 | DefWithBodyId::FunctionId(f) => Some(f.into()), | ||
348 | DefWithBodyId::StaticId(_) => None, | ||
349 | DefWithBodyId::ConstId(c) => Some(c.into()), | ||
350 | } | ||
351 | } | ||
352 | } | ||
353 | |||
344 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 354 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
345 | pub enum AssocItemId { | 355 | pub enum AssocItemId { |
346 | FunctionId(FunctionId), | 356 | FunctionId(FunctionId), |
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> { |