aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir/src/lib.rs12
-rw-r--r--crates/hir_def/src/lib.rs10
-rw-r--r--crates/hir_ty/src/db.rs3
-rw-r--r--crates/hir_ty/src/infer.rs4
-rw-r--r--crates/hir_ty/src/lower.rs88
-rw-r--r--crates/hir_ty/src/traits.rs9
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};
60use rustc_hash::FxHashSet; 60use rustc_hash::FxHashSet;
61use stdx::{format_to, impl_from}; 61use 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
342impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId); 342impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId);
343 343
344impl 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)]
345pub enum AssocItemId { 355pub 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
938impl TraitEnvironment { 938pub(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
66impl 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)]
68pub struct InEnvironment<T> { 77pub struct InEnvironment<T> {