chalk_solve/
coinductive_goal.rs1use crate::RustIrDatabase;
2use chalk_ir::interner::Interner;
3use chalk_ir::*;
4
5pub trait IsCoinductive<I: Interner> {
6 fn is_coinductive(&self, db: &dyn RustIrDatabase<I>) -> bool;
15}
16
17impl<I: Interner> IsCoinductive<I> for Goal<I> {
18 fn is_coinductive(&self, db: &dyn RustIrDatabase<I>) -> bool {
19 let interner = db.interner();
20 match self.data(interner) {
21 GoalData::DomainGoal(DomainGoal::Holds(wca)) => match wca {
22 WhereClause::Implemented(tr) => {
23 db.trait_datum(tr.trait_id).is_auto_trait()
24 || db.trait_datum(tr.trait_id).is_coinductive_trait()
25 }
26 WhereClause::AliasEq(..) => false,
27 WhereClause::LifetimeOutlives(..) => false,
28 WhereClause::TypeOutlives(..) => false,
29 },
30 GoalData::DomainGoal(DomainGoal::WellFormed(WellFormed::Trait(..))) => true,
31 GoalData::Quantified(QuantifierKind::ForAll, goal) => {
32 goal.skip_binders().is_coinductive(db)
33 }
34 _ => false,
35 }
36 }
37}
38
39impl<I: Interner> IsCoinductive<I> for UCanonical<InEnvironment<Goal<I>>> {
40 fn is_coinductive(&self, db: &dyn RustIrDatabase<I>) -> bool {
41 self.canonical.value.goal.is_coinductive(db)
42 }
43}