Skip to content

Commit 05814e5

Browse files
Merge #7985
7985: Use Chalk Environment more directly r=flodiebold a=flodiebold Co-authored-by: Florian Diebold <[email protected]>
2 parents c0459c5 + ec70387 commit 05814e5

File tree

5 files changed

+44
-55
lines changed

5 files changed

+44
-55
lines changed

crates/hir_ty/src/lower.rs

+23-8
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use std::{iter, sync::Arc};
99

1010
use base_db::CrateId;
11-
use chalk_ir::Mutability;
11+
use chalk_ir::{cast::Cast, Mutability};
1212
use hir_def::{
1313
adt::StructKind,
1414
builtin_type::BuiltinType,
@@ -27,6 +27,7 @@ use stdx::impl_from;
2727

2828
use crate::{
2929
db::HirDatabase,
30+
traits::chalk::{Interner, ToChalk},
3031
utils::{
3132
all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
3233
make_mut_slice, variant_data,
@@ -914,10 +915,21 @@ impl TraitEnvironment {
914915
pub fn lower(db: &dyn HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> {
915916
let ctx = TyLoweringContext::new(db, &resolver)
916917
.with_type_param_mode(TypeParamLoweringMode::Placeholder);
917-
let mut predicates = resolver
918-
.where_predicates_in_scope()
919-
.flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred))
920-
.collect::<Vec<_>>();
918+
let mut traits_in_scope = Vec::new();
919+
let mut clauses = Vec::new();
920+
for pred in resolver.where_predicates_in_scope() {
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+
}
921933

922934
if let Some(def) = resolver.generic_def() {
923935
let container: Option<AssocContainerId> = match def {
@@ -938,12 +950,15 @@ impl TraitEnvironment {
938950
let substs = Substs::type_params(db, trait_id);
939951
let trait_ref = TraitRef { trait_: trait_id, substs };
940952
let pred = GenericPredicate::Implemented(trait_ref);
941-
942-
predicates.push(pred);
953+
let program_clause: chalk_ir::ProgramClause<Interner> =
954+
pred.clone().to_chalk(db).cast(&Interner);
955+
clauses.push(program_clause.into_from_env_clause(&Interner));
943956
}
944957
}
945958

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 })
947962
}
948963
}
949964

crates/hir_ty/src/method_resolution.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -528,8 +528,7 @@ fn iterate_trait_method_candidates(
528528
self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t));
529529
let env_traits = if let Ty::Placeholder(_) = self_ty.value {
530530
// 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)
532-
.map(|tr| tr.trait_)
531+
env.traits_in_scope_from_clauses(&self_ty.value)
533532
.flat_map(|t| all_super_traits(db.upcast(), t))
534533
.collect()
535534
} else {

crates/hir_ty/src/traits.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,25 @@ fn create_chalk_solver() -> chalk_recursive::RecursiveSolver<Interner> {
3838
/// fn foo<T: Default>(t: T) {}
3939
/// ```
4040
/// we assume that `T: Default`.
41-
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
41+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4242
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>,
4447
}
4548

4649
impl TraitEnvironment {
47-
/// Returns trait refs with the given self type which are supposed to hold
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>(
50+
pub(crate) fn traits_in_scope_from_clauses<'a>(
5151
&'a self,
5252
ty: &'a Ty,
53-
) -> impl Iterator<Item = &'a TraitRef> + 'a {
54-
self.predicates.iter().filter_map(move |pred| match pred {
55-
GenericPredicate::Implemented(tr) if tr.self_ty() == ty => Some(tr),
56-
_ => None,
53+
) -> impl Iterator<Item = TraitId> + 'a {
54+
self.traits_from_clauses.iter().filter_map(move |(self_ty, trait_id)| {
55+
if self_ty == ty {
56+
Some(*trait_id)
57+
} else {
58+
None
59+
}
5760
})
5861
}
5962
}

crates/hir_ty/src/traits/chalk.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ pub(super) mod tls;
3333
mod interner;
3434
mod mapping;
3535

36-
pub(super) trait ToChalk {
36+
pub(crate) trait ToChalk {
3737
type Chalk;
3838
fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk;
3939
fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self;
4040
}
4141

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
4343
where
4444
T: ToChalk<Chalk = ChalkT>,
4545
{

crates/hir_ty/src/traits/chalk/mapping.rs

+5-33
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::{
1717
primitive::UintTy,
1818
traits::{Canonical, Obligation},
1919
AliasTy, CallableDefId, FnPointer, FnSig, GenericPredicate, InEnvironment, OpaqueTy,
20-
OpaqueTyId, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, TraitRef, Ty,
20+
OpaqueTyId, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitRef, Ty,
2121
};
2222

2323
use super::interner::*;
@@ -536,31 +536,6 @@ where
536536
}
537537
}
538538

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-
564539
impl<T: ToChalk> ToChalk for InEnvironment<T>
565540
where
566541
T::Chalk: chalk_ir::interner::HasInterner<Interner = Interner>,
@@ -569,19 +544,16 @@ where
569544

570545
fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> {
571546
chalk_ir::InEnvironment {
572-
environment: self.environment.to_chalk(db),
547+
environment: self.environment.env.clone(),
573548
goal: self.value.to_chalk(db),
574549
}
575550
}
576551

577552
fn from_chalk(
578-
db: &dyn HirDatabase,
579-
in_env: chalk_ir::InEnvironment<T::Chalk>,
553+
_db: &dyn HirDatabase,
554+
_in_env: chalk_ir::InEnvironment<T::Chalk>,
580555
) -> InEnvironment<T> {
581-
InEnvironment {
582-
environment: from_chalk(db, in_env.environment),
583-
value: from_chalk(db, in_env.goal),
584-
}
556+
unimplemented!()
585557
}
586558
}
587559

0 commit comments

Comments
 (0)