Create TraitEnvironment through a query

This commit is contained in:
Florian Diebold 2021-03-13 20:38:11 +01:00
parent 17eeb2a6d2
commit c82d1823a1
6 changed files with 77 additions and 51 deletions

View file

@ -54,8 +54,8 @@ use hir_ty::{
method_resolution, to_assoc_type_id, method_resolution, to_assoc_type_id,
traits::{FnTrait, Solution, SolutionVariables}, traits::{FnTrait, Solution, SolutionVariables},
AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate,
InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, Ty,
TraitEnvironment, Ty, TyDefId, TyKind, TyVariableKind, TyDefId, TyKind, TyVariableKind,
}; };
use rustc_hash::FxHashSet; use rustc_hash::FxHashSet;
use stdx::{format_to, impl_from}; use stdx::{format_to, impl_from};
@ -817,7 +817,7 @@ impl Function {
let resolver = self.id.resolver(db.upcast()); let resolver = self.id.resolver(db.upcast());
let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate(); let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate();
let ctx = hir_ty::TyLoweringContext::new(db, &resolver); let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
let environment = TraitEnvironment::lower(db, &resolver); let environment = db.trait_environment(self.id.into());
db.function_data(self.id) db.function_data(self.id)
.params .params
.iter() .iter()
@ -1563,13 +1563,15 @@ impl Type {
resolver: &Resolver, resolver: &Resolver,
ty: Ty, ty: Ty,
) -> Type { ) -> Type {
let environment = TraitEnvironment::lower(db, &resolver); let environment =
resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
Type { krate, ty: InEnvironment { value: ty, environment } } Type { krate, ty: InEnvironment { value: ty, environment } }
} }
fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type { fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type {
let resolver = lexical_env.resolver(db.upcast()); let resolver = lexical_env.resolver(db.upcast());
let environment = TraitEnvironment::lower(db, &resolver); let environment =
resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
Type { krate, ty: InEnvironment { value: ty, environment } } Type { krate, ty: InEnvironment { value: ty, environment } }
} }

View file

@ -341,6 +341,16 @@ pub enum DefWithBodyId {
impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId); impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId);
impl DefWithBodyId {
pub fn as_generic_def_id(self) -> Option<GenericDefId> {
match self {
DefWithBodyId::FunctionId(f) => Some(f.into()),
DefWithBodyId::StaticId(_) => None,
DefWithBodyId::ConstId(c) => Some(c.into()),
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum AssocItemId { pub enum AssocItemId {
FunctionId(FunctionId), FunctionId(FunctionId),

View file

@ -65,6 +65,9 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
#[salsa::invoke(crate::lower::generic_predicates_query)] #[salsa::invoke(crate::lower::generic_predicates_query)]
fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<GenericPredicate>]>; fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<GenericPredicate>]>;
#[salsa::invoke(crate::lower::trait_environment_query)]
fn trait_environment(&self, def: GenericDefId) -> Arc<crate::TraitEnvironment>;
#[salsa::invoke(crate::lower::generic_defaults_query)] #[salsa::invoke(crate::lower::generic_defaults_query)]
fn generic_defaults(&self, def: GenericDefId) -> Arc<[Binders<Ty>]>; fn generic_defaults(&self, def: GenericDefId) -> Arc<[Binders<Ty>]>;

View file

@ -228,7 +228,9 @@ impl<'a> InferenceContext<'a> {
table: unify::InferenceTable::new(), table: unify::InferenceTable::new(),
obligations: Vec::default(), obligations: Vec::default(),
return_ty: TyKind::Unknown.intern(&Interner), // set in collect_fn_signature return_ty: TyKind::Unknown.intern(&Interner), // set in collect_fn_signature
trait_env: TraitEnvironment::lower(db, &resolver), trait_env: owner
.as_generic_def_id()
.map_or_else(Default::default, |d| db.trait_environment(d)),
db, db,
owner, owner,
body: db.body(owner), body: db.body(owner),

View file

@ -935,8 +935,11 @@ pub(crate) fn generic_predicates_for_param_recover(
Arc::new([]) Arc::new([])
} }
impl TraitEnvironment { pub(crate) fn trait_environment_query(
pub fn lower(db: &dyn HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> { db: &dyn HirDatabase,
def: GenericDefId,
) -> Arc<TraitEnvironment> {
let resolver = def.resolver(db.upcast());
let ctx = TyLoweringContext::new(db, &resolver) let ctx = TyLoweringContext::new(db, &resolver)
.with_type_param_mode(TypeParamLoweringMode::Placeholder); .with_type_param_mode(TypeParamLoweringMode::Placeholder);
let mut traits_in_scope = Vec::new(); let mut traits_in_scope = Vec::new();
@ -955,7 +958,6 @@ impl TraitEnvironment {
} }
} }
if let Some(def) = resolver.generic_def() {
let container: Option<AssocContainerId> = match def { let container: Option<AssocContainerId> = match def {
// FIXME: is there a function for this? // FIXME: is there a function for this?
GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container), GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container),
@ -978,13 +980,11 @@ impl TraitEnvironment {
pred.clone().to_chalk(db).cast(&Interner); pred.clone().to_chalk(db).cast(&Interner);
clauses.push(program_clause.into_from_env_clause(&Interner)); clauses.push(program_clause.into_from_env_clause(&Interner));
} }
}
let env = chalk_ir::Environment::new(&Interner).add_clauses(&Interner, clauses); let env = chalk_ir::Environment::new(&Interner).add_clauses(&Interner, clauses);
Arc::new(TraitEnvironment { traits_from_clauses: traits_in_scope, env }) Arc::new(TraitEnvironment { traits_from_clauses: traits_in_scope, env })
} }
}
/// Resolve the where clause(s) of an item with generics. /// Resolve the where clause(s) of an item with generics.
pub(crate) fn generic_predicates_query( pub(crate) fn generic_predicates_query(

View file

@ -63,6 +63,15 @@ impl TraitEnvironment {
} }
} }
impl Default for TraitEnvironment {
fn default() -> Self {
TraitEnvironment {
traits_from_clauses: Vec::new(),
env: chalk_ir::Environment::new(&Interner),
}
}
}
/// Something (usually a goal), along with an environment. /// Something (usually a goal), along with an environment.
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct InEnvironment<T> { pub struct InEnvironment<T> {