about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2015-12-22 19:44:48 -0500
committerNiko Matsakis <niko@alum.mit.edu>2016-01-16 05:22:32 -0500
commitecaa1cbc9c8bcb9a96312f1c017d347c89263094 (patch)
tree332d5a6d532cc136b859218662fb3f4a5a47ab26
parent43756934d255603a0fb7a871f2a145380e488b71 (diff)
downloadrust-ecaa1cbc9c8bcb9a96312f1c017d347c89263094.tar.gz
rust-ecaa1cbc9c8bcb9a96312f1c017d347c89263094.zip
enable coinductive reasoning for structural traits, this is
potentially just a stopgap measure
-rw-r--r--src/librustc/middle/traits/fulfill.rs13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs
index 7e48f20ce10..ca2a9f9ca0b 100644
--- a/src/librustc/middle/traits/fulfill.rs
+++ b/src/librustc/middle/traits/fulfill.rs
@@ -368,6 +368,19 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
     let obligation = &pending_obligation.obligation;
     match obligation.predicate {
         ty::Predicate::Trait(ref data) => {
+            // For defaulted traits, we use a co-inductive strategy to
+            // solve, so that recursion is ok.
+            if selcx.tcx().trait_has_default_impl(data.def_id()) {
+                debug!("process_predicate: trait has default impl");
+                for bt_obligation in backtrace {
+                    debug!("process_predicate: bt_obligation = {:?}", bt_obligation.obligation);
+                    if bt_obligation.obligation.predicate == obligation.predicate {
+                        debug!("process_predicate: found a match!");
+                        return Ok(Some(vec![]));
+                    }
+                }
+            }
+
             let trait_obligation = obligation.with(data.clone());
             match selcx.select(&trait_obligation) {
                 Ok(Some(vtable)) => {