about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2016-10-04 02:19:40 +0300
committerEduard Burtescu <edy.burt@gmail.com>2016-11-06 16:22:11 +0200
commitaee1ee3cc298c32a22a5730d7133b64e950a8dec (patch)
tree9ff1a6b7621f81147003c0d5c319c8ff91450059
parent161f2623bd078017dfc9a06bd3417b36f6a58de9 (diff)
downloadrust-aee1ee3cc298c32a22a5730d7133b64e950a8dec.tar.gz
rust-aee1ee3cc298c32a22a5730d7133b64e950a8dec.zip
rustc: harden against InferOk having obligations in more cases.
-rw-r--r--src/librustc/infer/mod.rs13
-rw-r--r--src/librustc/traits/coherence.rs14
-rw-r--r--src/librustc/traits/specialize/mod.rs22
-rw-r--r--src/librustc_typeck/check/compare_method.rs8
-rw-r--r--src/librustc_typeck/check/dropck.rs28
-rw-r--r--src/librustc_typeck/coherence/mod.rs20
-rw-r--r--src/librustc_typeck/lib.rs17
7 files changed, 78 insertions, 44 deletions
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index bbcd87d9cab..21820ca0719 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -1069,7 +1069,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         self.probe(|_| {
             let origin = TypeOrigin::Misc(syntax_pos::DUMMY_SP);
             let trace = TypeTrace::types(origin, true, a, b);
-            self.sub(true, trace, &a, &b).map(|_| ())
+            self.sub(true, trace, &a, &b).map(|InferOk { obligations, .. }| {
+                // FIXME(#32730) propagate obligations
+                assert!(obligations.is_empty());
+            })
         })
     }
 
@@ -1592,8 +1595,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             // anyhow. We should make this typetrace stuff more
             // generic so we don't have to do anything quite this
             // terrible.
-            self.equate(true, TypeTrace::dummy(self.tcx), a, b)
-        }).map(|_| ())
+            let trace = TypeTrace::dummy(self.tcx);
+            self.equate(true, trace, a, b).map(|InferOk { obligations, .. }| {
+                // FIXME(#32730) propagate obligations
+                assert!(obligations.is_empty());
+            })
+        })
     }
 
     pub fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs
index 68c88249ec0..1ccd048cedc 100644
--- a/src/librustc/traits/coherence.rs
+++ b/src/librustc/traits/coherence.rs
@@ -14,7 +14,7 @@ use super::{SelectionContext, Obligation, ObligationCause};
 
 use hir::def_id::{DefId, LOCAL_CRATE};
 use ty::{self, Ty, TyCtxt};
-use infer::{InferCtxt, TypeOrigin};
+use infer::{InferCtxt, InferOk, TypeOrigin};
 use syntax_pos::DUMMY_SP;
 
 #[derive(Copy, Clone)]
@@ -55,11 +55,13 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
     debug!("overlap: b_impl_header={:?}", b_impl_header);
 
     // Do `a` and `b` unify? If not, no overlap.
-    if let Err(_) = selcx.infcx().eq_impl_headers(true,
-                                                  TypeOrigin::Misc(DUMMY_SP),
-                                                  &a_impl_header,
-                                                  &b_impl_header) {
-        return None;
+    match selcx.infcx().eq_impl_headers(true, TypeOrigin::Misc(DUMMY_SP), &a_impl_header,
+                                                                          &b_impl_header) {
+        Ok(InferOk { obligations, .. }) => {
+            // FIXME(#32730) propagate obligations
+            assert!(obligations.is_empty());
+        }
+        Err(_) => return None
     }
 
     debug!("overlap: unification check succeeded");
diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs
index 24cafa7f725..909247d1cb2 100644
--- a/src/librustc/traits/specialize/mod.rs
+++ b/src/librustc/traits/specialize/mod.rs
@@ -22,7 +22,7 @@ use super::util::impl_trait_ref_and_oblig;
 
 use rustc_data_structures::fnv::FnvHashMap;
 use hir::def_id::DefId;
-use infer::{InferCtxt, TypeOrigin};
+use infer::{InferCtxt, InferOk, TypeOrigin};
 use middle::region;
 use ty::subst::{Subst, Substs};
 use traits::{self, Reveal, ObligationCause};
@@ -222,14 +222,18 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
                                                                    target_substs);
 
     // do the impls unify? If not, no specialization.
-    if let Err(_) = infcx.eq_trait_refs(true,
-                                        TypeOrigin::Misc(DUMMY_SP),
-                                        source_trait_ref,
-                                        target_trait_ref) {
-        debug!("fulfill_implication: {:?} does not unify with {:?}",
-               source_trait_ref,
-               target_trait_ref);
-        return Err(());
+    match infcx.eq_trait_refs(true, TypeOrigin::Misc(DUMMY_SP), source_trait_ref,
+                                                                target_trait_ref) {
+        Ok(InferOk { obligations, .. }) => {
+            // FIXME(#32730) propagate obligations
+            assert!(obligations.is_empty())
+        }
+        Err(_) => {
+            debug!("fulfill_implication: {:?} does not unify with {:?}",
+                   source_trait_ref,
+                   target_trait_ref);
+            return Err(());
+        }
     }
 
     // attempt to prove all of the predicates for impl2 given those for impl1
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 6f450f57275..2cb719675ac 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -298,7 +298,13 @@ fn compare_predicate_entailment<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
 
         debug!("compare_impl_method: trait_fty={:?}", trait_fty);
 
-        if let Err(terr) = infcx.sub_types(false, origin, impl_fty, trait_fty) {
+        let sub_result = infcx.sub_types(false, origin, impl_fty, trait_fty)
+            .map(|InferOk { obligations, .. }| {
+                // FIXME(#32730) propagate obligations
+                assert!(obligations.is_empty());
+            });
+
+        if let Err(terr) = sub_result {
             debug!("sub_types failed: impl ty {:?}, trait ty {:?}",
                    impl_fty,
                    trait_fty);
diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs
index 5e2b49bac1b..e72bcb3079c 100644
--- a/src/librustc_typeck/check/dropck.rs
+++ b/src/librustc_typeck/check/dropck.rs
@@ -13,7 +13,7 @@ use check::regionck::RegionCtxt;
 
 use hir::def_id::DefId;
 use middle::free_region::FreeRegionMap;
-use rustc::infer;
+use rustc::infer::{self, InferOk};
 use middle::region;
 use rustc::ty::subst::{Subst, Substs};
 use rustc::ty::{self, AdtKind, Ty, TyCtxt};
@@ -93,16 +93,22 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
             infcx.fresh_substs_for_item(drop_impl_span, drop_impl_did);
         let fresh_impl_self_ty = drop_impl_ty.subst(tcx, fresh_impl_substs);
 
-        if let Err(_) = infcx.eq_types(true, infer::TypeOrigin::Misc(drop_impl_span),
-                                       named_type, fresh_impl_self_ty) {
-            let item_span = tcx.map.span(self_type_node_id);
-            struct_span_err!(tcx.sess, drop_impl_span, E0366,
-                             "Implementations of Drop cannot be specialized")
-                .span_note(item_span,
-                           "Use same sequence of generic type and region \
-                            parameters that is on the struct/enum definition")
-                .emit();
-            return Err(());
+        match infcx.eq_types(true, infer::TypeOrigin::Misc(drop_impl_span),
+                             named_type, fresh_impl_self_ty) {
+            Ok(InferOk { obligations, .. }) => {
+                // FIXME(#32730) propagate obligations
+                assert!(obligations.is_empty());
+            }
+            Err(_) => {
+                let item_span = tcx.map.span(self_type_node_id);
+                struct_span_err!(tcx.sess, drop_impl_span, E0366,
+                                 "Implementations of Drop cannot be specialized")
+                    .span_note(item_span,
+                               "Use same sequence of generic type and region \
+                                parameters that is on the struct/enum definition")
+                    .emit();
+                return Err(());
+            }
         }
 
         if let Err(ref errors) = fulfillment_cx.select_all_or_error(&infcx) {
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index ca22faa2ec3..4a4dea5b514 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -415,15 +415,19 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
 
                                 if f.unsubst_ty().is_phantom_data() {
                                     // Ignore PhantomData fields
-                                    None
-                                } else if infcx.sub_types(false, origin, b, a).is_ok() {
-                                    // Ignore fields that aren't significantly changed
-                                    None
-                                } else {
-                                    // Collect up all fields that were significantly changed
-                                    // i.e. those that contain T in coerce_unsized T -> U
-                                    Some((i, a, b))
+                                    return None;
                                 }
+
+                                // Ignore fields that aren't significantly changed
+                                if let Ok(ok) = infcx.sub_types(false, origin, b, a) {
+                                    if ok.obligations.is_empty() {
+                                        return None;
+                                    }
+                                }
+
+                                // Collect up all fields that were significantly changed
+                                // i.e. those that contain T in coerce_unsized T -> U
+                                Some((i, a, b))
                             })
                             .collect::<Vec<_>>();
 
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 671274a4057..75f0dac5950 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -106,7 +106,7 @@ pub use rustc::util;
 
 use dep_graph::DepNode;
 use hir::map as hir_map;
-use rustc::infer::TypeOrigin;
+use rustc::infer::{InferOk, TypeOrigin};
 use rustc::ty::subst::Substs;
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc::traits::{self, Reveal};
@@ -198,11 +198,16 @@ fn require_same_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                 actual: Ty<'tcx>)
                                 -> bool {
     ccx.tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|infcx| {
-        if let Err(err) = infcx.eq_types(false, origin.clone(), expected, actual) {
-            infcx.report_mismatched_types(origin, expected, actual, err);
-            false
-        } else {
-            true
+        match infcx.eq_types(false, origin.clone(), expected, actual) {
+            Ok(InferOk { obligations, .. }) => {
+                // FIXME(#32730) propagate obligations
+                assert!(obligations.is_empty());
+                true
+            }
+            Err(err) => {
+                infcx.report_mismatched_types(origin, expected, actual, err);
+                false
+            }
         }
     })
 }