]> git.lizzy.rs Git - rust.git/commitdiff
Implement `is_coinductive`
authorscalexm <alexandre@scalexm.fr>
Fri, 23 Nov 2018 18:16:02 +0000 (19:16 +0100)
committerscalexm <alexandre@scalexm.fr>
Thu, 27 Dec 2018 18:21:15 +0000 (19:21 +0100)
Fixes #55096.

src/librustc_traits/chalk_context/mod.rs

index 4f6ad83f2e634089bdd33ff53eab9c1888ef62ac..41b7e73e5537e6a834436845f09f1b269092d5e7 100644 (file)
@@ -155,12 +155,29 @@ fn make_solution(
 }
 
 impl context::ContextOps<ChalkArenas<'gcx>> for ChalkContext<'cx, 'gcx> {
-    /// True if this is a coinductive goal -- e.g., proving an auto trait.
+    /// True if this is a coinductive goal: basically proving that an auto trait
+    /// is implemented or proving that a trait reference is well-formed.
     fn is_coinductive(
         &self,
-        _goal: &Canonical<'gcx, InEnvironment<'gcx, Goal<'gcx>>>
+        goal: &Canonical<'gcx, InEnvironment<'gcx, Goal<'gcx>>>
     ) -> bool {
-        unimplemented!()
+        use rustc::traits::{WellFormed, WhereClause};
+
+        let mut goal = goal.value.goal;
+        loop {
+            match goal {
+                GoalKind::DomainGoal(domain_goal) => match domain_goal {
+                    DomainGoal::WellFormed(WellFormed::Trait(..)) => return true,
+                    DomainGoal::Holds(WhereClause::Implemented(trait_predicate)) => {
+                        return self.tcx.trait_is_auto(trait_predicate.def_id());
+                    }
+                    _ => return false,
+                }
+
+                GoalKind::Quantified(_, bound_goal) => goal = *bound_goal.skip_binder(),
+                _ => return false,
+            }
+        }
     }
 
     /// Create an inference table for processing a new goal and instantiate that goal