1 use super::program_clauses
::ToProgramClauses
;
2 use crate::clauses
::builder
::ClauseBuilder
;
3 use crate::clauses
::{match_alias_ty, match_ty}
;
6 use crate::ProgramClause
;
7 use crate::RustIrDatabase
;
9 use crate::{debug_span, TyKind}
;
10 use chalk_ir
::interner
::Interner
;
11 use chalk_ir
::visit
::{Visit, Visitor}
;
12 use chalk_ir
::{DebruijnIndex, Environment}
;
13 use rustc_hash
::FxHashSet
;
14 use std
::ops
::ControlFlow
;
15 use tracing
::instrument
;
17 /// When proving a `FromEnv` goal, we elaborate all `FromEnv` goals
18 /// found in the environment.
20 /// For example, when `T: Clone` is in the environment, we can prove
21 /// `T: Copy` by adding the clauses from `trait Clone`, which includes
22 /// the rule `FromEnv(T: Copy) :- FromEnv(T: Clone)
23 pub(super) fn elaborate_env_clauses
<I
: Interner
>(
24 db
: &dyn RustIrDatabase
<I
>,
25 in_clauses
: &[ProgramClause
<I
>],
26 out
: &mut FxHashSet
<ProgramClause
<I
>>,
27 environment
: &Environment
<I
>,
29 let mut this_round
= vec
![];
30 let builder
= &mut ClauseBuilder
::new(db
, &mut this_round
);
31 let mut elaborater
= EnvElaborator
{
36 in_clauses
.visit_with(&mut elaborater
, DebruijnIndex
::INNERMOST
);
37 out
.extend(this_round
);
40 struct EnvElaborator
<'me
, 'builder
, I
: Interner
> {
41 db
: &'me
dyn RustIrDatabase
<I
>,
42 builder
: &'builder
mut ClauseBuilder
<'me
, I
>,
43 environment
: &'me Environment
<I
>,
46 impl<'me
, 'builder
, I
: Interner
> Visitor
<I
> for EnvElaborator
<'me
, 'builder
, I
> {
49 fn as_dyn(&mut self) -> &mut dyn Visitor
<I
, BreakTy
= Self::BreakTy
> {
53 fn interner(&self) -> I
{
56 #[instrument(level = "debug", skip(self, _outer_binder))]
57 fn visit_ty(&mut self, ty
: &Ty
<I
>, _outer_binder
: DebruijnIndex
) -> ControlFlow
<()> {
58 match ty
.kind(self.interner()) {
59 TyKind
::Alias(alias_ty
) => match_alias_ty(self.builder
, self.environment
, alias_ty
),
60 TyKind
::Placeholder(_
) => {}
62 // FIXME(#203) -- We haven't fully figured out the implied
63 // bounds story around `dyn Trait` types.
66 TyKind
::Function(_
) | TyKind
::BoundVar(_
) | TyKind
::InferenceVar(_
, _
) => (),
69 // This shouldn't fail because of the above clauses
70 match_ty(self.builder
, self.environment
, ty
)
75 ControlFlow
::Continue(())
80 domain_goal
: &DomainGoal
<I
>,
81 outer_binder
: DebruijnIndex
,
82 ) -> ControlFlow
<()> {
83 if let DomainGoal
::FromEnv(from_env
) = domain_goal
{
84 debug_span
!("visit_domain_goal", ?from_env
);
86 FromEnv
::Trait(trait_ref
) => {
87 let trait_datum
= self.db
.trait_datum(trait_ref
.trait_id
);
89 trait_datum
.to_program_clauses(self.builder
, self.environment
);
91 // If we know that `T: Iterator`, then we also know
92 // things about `<T as Iterator>::Item`, so push those
93 // implied bounds too:
94 for &associated_ty_id
in &trait_datum
.associated_ty_ids
{
96 .associated_ty_data(associated_ty_id
)
97 .to_program_clauses(self.builder
, self.environment
);
99 ControlFlow
::Continue(())
101 FromEnv
::Ty(ty
) => ty
.visit_with(self, outer_binder
),
104 ControlFlow
::Continue(())