about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2015-03-10 07:02:27 -0400
committerNiko Matsakis <niko@alum.mit.edu>2015-03-31 09:51:17 -0400
commit4b0edb96d080fadccc542dad50e6576c8e11bd85 (patch)
tree2265524607aa0249fe2dcc21ba5ce3493dd67e73
parent0939837867e77f478dcd3735f3a6ce8823f5fd48 (diff)
downloadrust-4b0edb96d080fadccc542dad50e6576c8e11bd85.tar.gz
rust-4b0edb96d080fadccc542dad50e6576c8e11bd85.zip
Combine `try` and `commit_if_ok` and make some details of inference
context private.
-rw-r--r--src/librustc/middle/infer/higher_ranked/mod.rs6
-rw-r--r--src/librustc/middle/infer/mod.rs90
-rw-r--r--src/librustc/middle/infer/region_inference/mod.rs10
-rw-r--r--src/librustc/middle/traits/project.rs2
-rw-r--r--src/librustc/middle/traits/select.rs10
-rw-r--r--src/librustc_typeck/check/coercion.rs40
-rw-r--r--src/librustc_typeck/check/compare_method.rs2
-rw-r--r--src/librustc_typeck/check/dropck.rs2
-rw-r--r--src/librustc_typeck/check/regionck.rs2
-rw-r--r--src/test/compile-fail/object-lifetime-default-elision.rs4
-rw-r--r--src/test/compile-fail/object-lifetime-default-from-box-error.rs4
-rw-r--r--src/test/compile-fail/regions-close-over-type-parameter-multiple.rs2
-rw-r--r--src/test/compile-fail/regions-trait-object-subtyping.rs2
13 files changed, 81 insertions, 95 deletions
diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs
index 3754f52d058..9280ffd0654 100644
--- a/src/librustc/middle/infer/higher_ranked/mod.rs
+++ b/src/librustc/middle/infer/higher_ranked/mod.rs
@@ -60,7 +60,7 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
 
         // Start a snapshot so we can examine "all bindings that were
         // created as part of this type comparison".
-        return self.infcx().try(|snapshot| {
+        return self.infcx().commit_if_ok(|snapshot| {
             // First, we instantiate each bound region in the subtype with a fresh
             // region variable.
             let (a_prime, _) =
@@ -109,7 +109,7 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
     {
         // Start a snapshot so we can examine "all bindings that were
         // created as part of this type comparison".
-        return self.infcx().try(|snapshot| {
+        return self.infcx().commit_if_ok(|snapshot| {
             // Instantiate each bound region with a fresh region variable.
             let span = self.trace().origin.span();
             let (a_with_fresh, a_map) =
@@ -202,7 +202,7 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
 
         // Make a snapshot so we can examine "all bindings that were
         // created as part of this type comparison".
-        return self.infcx().try(|snapshot| {
+        return self.infcx().commit_if_ok(|snapshot| {
             // Instantiate each bound region with a fresh region variable.
             let (a_with_fresh, a_map) =
                 self.infcx().replace_late_bound_regions_with_fresh_var(
diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs
index bb94d95dc57..31ce8503ed0 100644
--- a/src/librustc/middle/infer/mod.rs
+++ b/src/librustc/middle/infer/mod.rs
@@ -265,7 +265,7 @@ pub enum LateBoundRegionConversionTime {
 ///
 /// See `error_reporting.rs` for more details
 #[derive(Clone, Debug)]
-pub enum RegionVariableOrigin<'tcx> {
+pub enum RegionVariableOrigin {
     // Region variables created for ill-categorized reasons,
     // mostly indicates places in need of refactoring
     MiscVariable(Span),
@@ -280,7 +280,7 @@ pub enum RegionVariableOrigin<'tcx> {
     Autoref(Span),
 
     // Regions created as part of an automatic coercion
-    Coercion(TypeTrace<'tcx>),
+    Coercion(Span),
 
     // Region variables created as the values for early-bound regions
     EarlyBoundRegion(Span, ast::Name),
@@ -343,8 +343,7 @@ pub fn common_supertype<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
         values: Types(expected_found(a_is_expected, a, b))
     };
 
-    let result =
-        cx.commit_if_ok(|| cx.lub(a_is_expected, trace.clone()).tys(a, b));
+    let result = cx.commit_if_ok(|_| cx.lub(a_is_expected, trace.clone()).tys(a, b));
     match result {
         Ok(t) => t,
         Err(ref err) => {
@@ -362,9 +361,7 @@ pub fn mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
                           -> UnitResult<'tcx>
 {
     debug!("mk_subty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
-    cx.commit_if_ok(|| {
-        cx.sub_types(a_is_expected, origin, a, b)
-    })
+    cx.sub_types(a_is_expected, origin, a, b)
 }
 
 pub fn can_mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
@@ -404,8 +401,7 @@ pub fn mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
                          -> UnitResult<'tcx>
 {
     debug!("mk_eqty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
-    cx.commit_if_ok(
-        || cx.eq_types(a_is_expected, origin, a, b))
+    cx.commit_if_ok(|_| cx.eq_types(a_is_expected, origin, a, b))
 }
 
 pub fn mk_sub_poly_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
@@ -417,8 +413,7 @@ pub fn mk_sub_poly_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
 {
     debug!("mk_sub_trait_refs({} <: {})",
            a.repr(cx.tcx), b.repr(cx.tcx));
-    cx.commit_if_ok(
-        || cx.sub_poly_trait_refs(a_is_expected, origin, a.clone(), b.clone()))
+    cx.commit_if_ok(|_| cx.sub_poly_trait_refs(a_is_expected, origin, a.clone(), b.clone()))
 }
 
 fn expected_found<T>(a_is_expected: bool,
@@ -476,25 +471,25 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn combine_fields<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
-                              -> CombineFields<'b, 'tcx> {
+    fn combine_fields<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
+                          -> CombineFields<'b, 'tcx> {
         CombineFields {infcx: self,
                        a_is_expected: a_is_expected,
                        trace: trace}
     }
 
-    pub fn equate<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
-                      -> Equate<'b, 'tcx> {
+    fn equate<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
+                  -> Equate<'b, 'tcx> {
         Equate(self.combine_fields(a_is_expected, trace))
     }
 
-    pub fn sub<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
-                   -> Sub<'b, 'tcx> {
+    fn sub<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
+               -> Sub<'b, 'tcx> {
         Sub(self.combine_fields(a_is_expected, trace))
     }
 
-    pub fn lub<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
-                   -> Lub<'b, 'tcx> {
+    fn lub<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
+               -> Lub<'b, 'tcx> {
         Lub(self.combine_fields(a_is_expected, trace))
     }
 
@@ -558,11 +553,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         r
     }
 
-    /// Execute `f` and commit the bindings if successful
+    /// Execute `f` and commit the bindings if closure `f` returns `Ok(_)`
     pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E> where
-        F: FnOnce() -> Result<T, E>
+        F: FnOnce(&CombinedSnapshot) -> Result<T, E>
     {
-        self.commit_unconditionally(move || self.try(move |_| f()))
+        debug!("commit_if_ok()");
+        let snapshot = self.start_snapshot();
+        let r = f(&snapshot);
+        debug!("commit_if_ok() -- r.is_ok() = {}", r.is_ok());
+        match r {
+            Ok(_) => { self.commit_from(snapshot); }
+            Err(_) => { self.rollback_to(snapshot); }
+        }
+        r
     }
 
     /// Execute `f` and commit only the region bindings if successful.
@@ -577,7 +580,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                                float_snapshot,
                                region_vars_snapshot } = self.start_snapshot();
 
-        let r = self.try(move |_| f());
+        let r = self.commit_if_ok(|_| f());
 
         // Roll back any non-region bindings - they should be resolved
         // inside `f`, with, e.g. `resolve_type_vars_if_possible`.
@@ -598,25 +601,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         r
     }
 
-    /// Execute `f`, unroll bindings on panic
-    pub fn try<T, E, F>(&self, f: F) -> Result<T, E> where
-        F: FnOnce(&CombinedSnapshot) -> Result<T, E>
-    {
-        debug!("try()");
-        let snapshot = self.start_snapshot();
-        let r = f(&snapshot);
-        debug!("try() -- r.is_ok() = {}", r.is_ok());
-        match r {
-            Ok(_) => {
-                self.commit_from(snapshot);
-            }
-            Err(_) => {
-                self.rollback_to(snapshot);
-            }
-        }
-        r
-    }
-
     /// Execute `f` then unroll any bindings it creates
     pub fn probe<R, F>(&self, f: F) -> R where
         F: FnOnce(&CombinedSnapshot) -> R,
@@ -643,7 +627,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                      -> UnitResult<'tcx>
     {
         debug!("sub_types({} <: {})", a.repr(self.tcx), b.repr(self.tcx));
-        self.commit_if_ok(|| {
+        self.commit_if_ok(|_| {
             let trace = TypeTrace::types(origin, a_is_expected, a, b);
             self.sub(a_is_expected, trace).tys(a, b).map(|_| ())
         })
@@ -656,7 +640,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     b: Ty<'tcx>)
                     -> UnitResult<'tcx>
     {
-        self.commit_if_ok(|| {
+        self.commit_if_ok(|_| {
             let trace = TypeTrace::types(origin, a_is_expected, a, b);
             self.equate(a_is_expected, trace).tys(a, b).map(|_| ())
         })
@@ -672,7 +656,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         debug!("sub_trait_refs({} <: {})",
                a.repr(self.tcx),
                b.repr(self.tcx));
-        self.commit_if_ok(|| {
+        self.commit_if_ok(|_| {
             let trace = TypeTrace {
                 origin: origin,
                 values: TraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
@@ -691,7 +675,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         debug!("sub_poly_trait_refs({} <: {})",
                a.repr(self.tcx),
                b.repr(self.tcx));
-        self.commit_if_ok(|| {
+        self.commit_if_ok(|_| {
             let trace = TypeTrace {
                 origin: origin,
                 values: PolyTraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
@@ -749,7 +733,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                               span: Span,
                               predicate: &ty::PolyEquatePredicate<'tcx>)
                               -> UnitResult<'tcx> {
-        self.try(|snapshot| {
+        self.commit_if_ok(|snapshot| {
             let (ty::EquatePredicate(a, b), skol_map) =
                 self.skolemize_late_bound_regions(predicate, snapshot);
             let origin = EquatePredicate(span);
@@ -762,7 +746,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                                      span: Span,
                                      predicate: &ty::PolyRegionOutlivesPredicate)
                                      -> UnitResult<'tcx> {
-        self.try(|snapshot| {
+        self.commit_if_ok(|snapshot| {
             let (ty::OutlivesPredicate(r_a, r_b), skol_map) =
                 self.skolemize_late_bound_regions(predicate, snapshot);
             let origin = RelateRegionParamBound(span);
@@ -801,7 +785,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             .new_key(None)
     }
 
-    pub fn next_region_var(&self, origin: RegionVariableOrigin<'tcx>) -> ty::Region {
+    pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region {
         ty::ReInfer(ty::ReVar(self.region_vars.new_region_var(origin)))
     }
 
@@ -1253,14 +1237,14 @@ impl<'tcx> Repr<'tcx> for SubregionOrigin<'tcx> {
     }
 }
 
-impl<'tcx> RegionVariableOrigin<'tcx> {
+impl RegionVariableOrigin {
     pub fn span(&self) -> Span {
         match *self {
             MiscVariable(a) => a,
             PatternRegion(a) => a,
             AddrOfRegion(a) => a,
             Autoref(a) => a,
-            Coercion(ref a) => a.span(),
+            Coercion(a) => a,
             EarlyBoundRegion(a, _) => a,
             LateBoundRegion(a, _, _) => a,
             BoundRegionInCoherence(_) => codemap::DUMMY_SP,
@@ -1269,7 +1253,7 @@ impl<'tcx> RegionVariableOrigin<'tcx> {
     }
 }
 
-impl<'tcx> Repr<'tcx> for RegionVariableOrigin<'tcx> {
+impl<'tcx> Repr<'tcx> for RegionVariableOrigin {
     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
         match *self {
             MiscVariable(a) => {
@@ -1282,7 +1266,7 @@ impl<'tcx> Repr<'tcx> for RegionVariableOrigin<'tcx> {
                 format!("AddrOfRegion({})", a.repr(tcx))
             }
             Autoref(a) => format!("Autoref({})", a.repr(tcx)),
-            Coercion(ref a) => format!("Coercion({})", a.repr(tcx)),
+            Coercion(a) => format!("Coercion({})", a.repr(tcx)),
             EarlyBoundRegion(a, b) => {
                 format!("EarlyBoundRegion({},{})", a.repr(tcx), b.repr(tcx))
             }
diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs
index e7c5d1111a2..1d15656fea2 100644
--- a/src/librustc/middle/infer/region_inference/mod.rs
+++ b/src/librustc/middle/infer/region_inference/mod.rs
@@ -115,7 +115,7 @@ pub enum RegionResolutionError<'tcx> {
     /// Could not infer a value for `v` because `sub_r <= v` (due to
     /// `sub_origin`) but `v <= sup_r` (due to `sup_origin`) and
     /// `sub_r <= sup_r` does not hold.
-    SubSupConflict(RegionVariableOrigin<'tcx>,
+    SubSupConflict(RegionVariableOrigin,
                    SubregionOrigin<'tcx>, Region,
                    SubregionOrigin<'tcx>, Region),
 
@@ -124,7 +124,7 @@ pub enum RegionResolutionError<'tcx> {
     /// Could not infer a value for `v` because `v <= r1` (due to
     /// `origin1`) and `v <= r2` (due to `origin2`) and
     /// `r1` and `r2` have no intersection.
-    SupSupConflict(RegionVariableOrigin<'tcx>,
+    SupSupConflict(RegionVariableOrigin,
                    SubregionOrigin<'tcx>, Region,
                    SubregionOrigin<'tcx>, Region),
 
@@ -132,7 +132,7 @@ pub enum RegionResolutionError<'tcx> {
     /// more specific errors message by suggesting to the user where they
     /// should put a lifetime. In those cases we process and put those errors
     /// into `ProcessedErrors` before we do any reporting.
-    ProcessedErrors(Vec<RegionVariableOrigin<'tcx>>,
+    ProcessedErrors(Vec<RegionVariableOrigin>,
                     Vec<(TypeTrace<'tcx>, ty::type_err<'tcx>)>,
                     Vec<SameRegions>),
 }
@@ -168,7 +168,7 @@ pub type CombineMap = FnvHashMap<TwoRegions, RegionVid>;
 
 pub struct RegionVarBindings<'a, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
-    var_origins: RefCell<Vec<RegionVariableOrigin<'tcx>>>,
+    var_origins: RefCell<Vec<RegionVariableOrigin>>,
 
     // Constraints of the form `A <= B` introduced by the region
     // checker.  Here at least one of `A` and `B` must be a region
@@ -316,7 +316,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
         len as u32
     }
 
-    pub fn new_region_var(&self, origin: RegionVariableOrigin<'tcx>) -> RegionVid {
+    pub fn new_region_var(&self, origin: RegionVariableOrigin) -> RegionVid {
         let id = self.num_vars();
         self.var_origins.borrow_mut().push(origin.clone());
         let vid = RegionVid { index: id };
diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs
index 1594d8b2e0d..e27b910f6c2 100644
--- a/src/librustc/middle/traits/project.rs
+++ b/src/librustc/middle/traits/project.rs
@@ -81,7 +81,7 @@ pub fn poly_project_and_unify_type<'cx,'tcx>(
            obligation.repr(selcx.tcx()));
 
     let infcx = selcx.infcx();
-    infcx.try(|snapshot| {
+    infcx.commit_if_ok(|snapshot| {
         let (skol_predicate, skol_map) =
             infcx.skolemize_late_bound_regions(&obligation.predicate, snapshot);
 
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index 9e4f63dca45..740bed72d9b 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -1242,7 +1242,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             return;
         }
 
-        self.infcx.try(|snapshot| {
+        self.infcx.commit_if_ok(|snapshot| {
             let bound_self_ty =
                 self.infcx.resolve_type_vars_if_possible(&obligation.self_ty());
             let (self_ty, _) =
@@ -1778,7 +1778,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         // For each type, produce a vector of resulting obligations
         let obligations: Result<Vec<Vec<_>>, _> = bound_types.iter().map(|nested_ty| {
-            self.infcx.try(|snapshot| {
+            self.infcx.commit_if_ok(|snapshot| {
                 let (skol_ty, skol_map) =
                     self.infcx().skolemize_late_bound_regions(nested_ty, snapshot);
                 let Normalized { value: normalized_ty, mut obligations } =
@@ -1888,7 +1888,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                     obligation: &TraitObligation<'tcx>)
     {
         let _: Result<(),()> =
-            self.infcx.try(|snapshot| {
+            self.infcx.commit_if_ok(|snapshot| {
                 let result =
                     self.match_projection_obligation_against_bounds_from_trait(obligation,
                                                                                snapshot);
@@ -2043,7 +2043,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                                                 trait_def_id,
                                                                 nested);
 
-        let trait_obligations: Result<VecPerParamSpace<_>,()> = self.infcx.try(|snapshot| {
+        let trait_obligations: Result<VecPerParamSpace<_>,()> = self.infcx.commit_if_ok(|snapshot| {
             let poly_trait_ref = obligation.predicate.to_poly_trait_ref();
             let (trait_ref, skol_map) =
                 self.infcx().skolemize_late_bound_regions(&poly_trait_ref, snapshot);
@@ -2077,7 +2077,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         // First, create the substitutions by matching the impl again,
         // this time not in a probe.
-        self.infcx.try(|snapshot| {
+        self.infcx.commit_if_ok(|snapshot| {
             let (skol_obligation_trait_ref, skol_map) =
                 self.infcx().skolemize_late_bound_regions(&obligation.predicate, snapshot);
             let substs =
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index d48927c61d2..0765d7294ad 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -76,7 +76,7 @@ use syntax::ast;
 
 struct Coerce<'a, 'tcx: 'a> {
     fcx: &'a FnCtxt<'a, 'tcx>,
-    trace: TypeTrace<'tcx>
+    origin: infer::TypeOrigin,
 }
 
 type CoerceResult<'tcx> = CombineResult<'tcx, Option<ty::AutoAdjustment<'tcx>>>;
@@ -87,14 +87,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
     }
 
     fn subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
-        let sub = Sub(self.fcx.infcx().combine_fields(false, self.trace.clone()));
-        try!(sub.tys(a, b));
+        try!(self.fcx.infcx().sub_types(false, self.origin.clone(), a, b));
         Ok(None) // No coercion required.
     }
 
-    fn outlives(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ()> {
-        let sub = Sub(self.fcx.infcx().combine_fields(false, self.trace.clone()));
-        try!(sub.regions(b, a));
+    fn outlives(&self,
+                origin: infer::SubregionOrigin<'tcx>,
+                a: ty::Region,
+                b: ty::Region)
+                -> RelateResult<'tcx, ()> {
+        infer::mk_subr(self.fcx.infcx(), origin, b, a);
         Ok(())
     }
 
@@ -190,7 +192,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             _ => return self.subtype(a, b)
         }
 
-        let coercion = Coercion(self.trace.clone());
+        let coercion = Coercion(self.origin.span());
         let r_borrow = self.fcx.infcx().next_region_var(coercion);
         let autoref = Some(AutoPtr(r_borrow, mutbl_b, None));
 
@@ -214,7 +216,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             }
             let ty = ty::mk_rptr(self.tcx(), r_borrow,
                                  mt {ty: inner_ty, mutbl: mutbl_b});
-            if let Err(err) = self.fcx.infcx().try(|_| self.subtype(ty, b)) {
+            if let Err(err) = self.subtype(ty, b) {
                 if first_error.is_none() {
                     first_error = Some(err);
                 }
@@ -264,12 +266,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                             return Err(ty::terr_mutability);
                         }
 
-                        let coercion = Coercion(self.trace.clone());
+                        let coercion = Coercion(self.origin.span());
                         let r_borrow = self.fcx.infcx().next_region_var(coercion);
                         let ty = ty::mk_rptr(self.tcx(),
                                              self.tcx().mk_region(r_borrow),
                                              ty::mt{ty: ty, mutbl: mt_b.mutbl});
-                        try!(self.fcx.infcx().try(|_| self.subtype(ty, b)));
+                        try!(self.subtype(ty, b));
                         debug!("Success, coerced with AutoDerefRef(1, \
                                 AutoPtr(AutoUnsize({:?})))", kind);
                         Ok(Some(AdjustDerefRef(AutoDerefRef {
@@ -290,7 +292,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
 
                         let ty = ty::mk_ptr(self.tcx(),
                                              ty::mt{ty: ty, mutbl: mt_b.mutbl});
-                        try!(self.fcx.infcx().try(|_| self.subtype(ty, b)));
+                        try!(self.subtype(ty, b));
                         debug!("Success, coerced with AutoDerefRef(1, \
                                 AutoPtr(AutoUnsize({:?})))", kind);
                         Ok(Some(AdjustDerefRef(AutoDerefRef {
@@ -306,7 +308,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                 match self.unsize_ty(t_a, t_b) {
                     Some((ty, kind)) => {
                         let ty = ty::mk_uniq(self.tcx(), ty);
-                        try!(self.fcx.infcx().try(|_| self.subtype(ty, b)));
+                        try!(self.subtype(ty, b));
                         debug!("Success, coerced with AutoDerefRef(1, \
                                 AutoUnsizeUniq({:?}))", kind);
                         Ok(Some(AdjustDerefRef(AutoDerefRef {
@@ -365,9 +367,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                             let ty_a1 = ty::mk_trait(tcx, data_a.principal.clone(), bounds_a1);
 
                             // relate `a1` to `b`
-                            let result = self.fcx.infcx().try(|_| {
+                            let result = self.fcx.infcx().commit_if_ok(|_| {
                                 // it's ok to upcast from Foo+'a to Foo+'b so long as 'a : 'b
-                                try!(self.outlives(data_a.bounds.region_bound,
+                                try!(self.outlives(infer::RelateObjectBound(self.origin.span()),
+                                                   data_a.bounds.region_bound,
                                                    data_b.bounds.region_bound));
                                 self.subtype(ty_a1, ty_b)
                             });
@@ -399,7 +402,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                         let mut result = None;
                         let tps = ty_substs_a.iter().zip(ty_substs_b.iter()).enumerate();
                         for (i, (tp_a, tp_b)) in tps {
-                            if self.fcx.infcx().try(|_| self.subtype(*tp_a, *tp_b)).is_ok() {
+                            if self.subtype(*tp_a, *tp_b).is_ok() {
                                 continue;
                             }
                             match self.unsize_ty(*tp_a, *tp_b) {
@@ -408,7 +411,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                                     let mut new_substs = substs_a.clone();
                                     new_substs.types.get_mut_slice(subst::TypeSpace)[i] = new_tp;
                                     let ty = ty::mk_struct(tcx, did_a, tcx.mk_substs(new_substs));
-                                    if self.fcx.infcx().try(|_| self.subtype(ty, ty_b)).is_err() {
+                                    if self.subtype(ty, ty_b).is_err() {
                                         debug!("Unsized type parameter '{}', but still \
                                                 could not match types {} and {}",
                                                ppaux::ty_to_string(tcx, *tp_a),
@@ -537,11 +540,10 @@ pub fn mk_assignty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                              -> CombineResult<'tcx, ()> {
     debug!("mk_assignty({} -> {})", a.repr(fcx.tcx()), b.repr(fcx.tcx()));
     let adjustment = try!(indent(|| {
-        fcx.infcx().commit_if_ok(|| {
-            let origin = infer::ExprAssignable(expr.span);
+        fcx.infcx().commit_if_ok(|_| {
             Coerce {
                 fcx: fcx,
-                trace: infer::TypeTrace::types(origin, false, a, b)
+                origin: infer::ExprAssignable(expr.span),
             }.coerce(expr, a, b)
         })
     }));
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 1c5f2c56078..532277d75b2 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -282,7 +282,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
     let trait_fty = ty::mk_bare_fn(tcx, None, tcx.mk_bare_fn(trait_m.fty.clone()));
     let trait_fty = trait_fty.subst(tcx, &trait_to_skol_substs);
 
-    let err = infcx.try(|snapshot| {
+    let err = infcx.commit_if_ok(|snapshot| {
         let origin = infer::MethodCompatCheck(impl_m_span);
 
         let (impl_sig, _) =
diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs
index 49f4399b2c7..2f7e0073e17 100644
--- a/src/librustc_typeck/check/dropck.rs
+++ b/src/librustc_typeck/check/dropck.rs
@@ -95,7 +95,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
         ty::lookup_item_type(tcx, self_type_did);
 
     let infcx = infer::new_infer_ctxt(tcx);
-    infcx.try(|snapshot| {
+    infcx.commit_if_ok(|snapshot| {
         let (named_type_to_skolem, skol_map) =
             infcx.construct_skolemized_subst(named_type_generics, snapshot);
         let named_type_skolem = named_type.subst(tcx, &named_type_to_skolem);
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index 3edea6d3004..91713674680 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -1542,7 +1542,7 @@ fn projection_bounds<'a,'tcx>(rcx: &Rcx<'a, 'tcx>,
             debug!("projection_bounds: outlives={} (2)",
                    outlives.repr(tcx));
 
-            let region_result = infcx.try(|_| {
+            let region_result = infcx.commit_if_ok(|_| {
                 let (outlives, _) =
                     infcx.replace_late_bound_regions_with_fresh_var(
                         span,
diff --git a/src/test/compile-fail/object-lifetime-default-elision.rs b/src/test/compile-fail/object-lifetime-default-elision.rs
index 0077d10e6ca..4fba45e2a66 100644
--- a/src/test/compile-fail/object-lifetime-default-elision.rs
+++ b/src/test/compile-fail/object-lifetime-default-elision.rs
@@ -81,8 +81,8 @@ fn load3<'a,'b>(ss: &'a SomeTrait) -> &'b SomeTrait {
     // which fails to type check.
 
     ss
-        //~^ ERROR cannot infer
-        //~| ERROR mismatched types
+        //~^ ERROR lifetime of the source pointer does not outlive lifetime bound
+        //~| ERROR cannot infer
 }
 
 fn main() {
diff --git a/src/test/compile-fail/object-lifetime-default-from-box-error.rs b/src/test/compile-fail/object-lifetime-default-from-box-error.rs
index 70752cbfda1..7fae530984f 100644
--- a/src/test/compile-fail/object-lifetime-default-from-box-error.rs
+++ b/src/test/compile-fail/object-lifetime-default-from-box-error.rs
@@ -25,7 +25,7 @@ fn load(ss: &mut SomeStruct) -> Box<SomeTrait> {
     // `Box<SomeTrait>` defaults to a `'static` bound, so this return
     // is illegal.
 
-    ss.r //~ ERROR mismatched types
+    ss.r //~ ERROR lifetime of the source pointer does not outlive lifetime bound
 }
 
 fn store(ss: &mut SomeStruct, b: Box<SomeTrait>) {
@@ -38,7 +38,7 @@ fn store(ss: &mut SomeStruct, b: Box<SomeTrait>) {
 fn store1<'b>(ss: &mut SomeStruct, b: Box<SomeTrait+'b>) {
     // Here we override the lifetimes explicitly, and so naturally we get an error.
 
-    ss.r = b; //~ ERROR mismatched types
+    ss.r = b; //~ ERROR lifetime of the source pointer does not outlive lifetime bound
 }
 
 fn main() {
diff --git a/src/test/compile-fail/regions-close-over-type-parameter-multiple.rs b/src/test/compile-fail/regions-close-over-type-parameter-multiple.rs
index 0f8bc6d684f..10b883d4dc8 100644
--- a/src/test/compile-fail/regions-close-over-type-parameter-multiple.rs
+++ b/src/test/compile-fail/regions-close-over-type-parameter-multiple.rs
@@ -27,7 +27,7 @@ fn make_object_good2<'a,'b,A:SomeTrait+'a+'b>(v: A) -> Box<SomeTrait+'b> {
 
 fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box<SomeTrait+'c> {
     // A outlives 'a AND 'b...but not 'c.
-    box v as Box<SomeTrait+'a> //~ ERROR mismatched types
+    box v as Box<SomeTrait+'a> //~ ERROR lifetime of the source pointer does not outlive
 }
 
 fn main() {
diff --git a/src/test/compile-fail/regions-trait-object-subtyping.rs b/src/test/compile-fail/regions-trait-object-subtyping.rs
index 8d05cb67e77..f3722690ef8 100644
--- a/src/test/compile-fail/regions-trait-object-subtyping.rs
+++ b/src/test/compile-fail/regions-trait-object-subtyping.rs
@@ -22,7 +22,7 @@ fn foo2<'a:'b,'b>(x: &'b mut (Dummy+'a)) -> &'b mut (Dummy+'b) {
 
 fn foo3<'a,'b>(x: &'a mut Dummy) -> &'b mut Dummy {
     // Without knowing 'a:'b, we can't coerce
-    x //~ ERROR mismatched types
+    x //~ ERROR lifetime of the source pointer does not outlive
      //~^ ERROR cannot infer
 }