Combine try
and commit_if_ok
and make some details of inference
context private.
This commit is contained in:
parent
0939837867
commit
4b0edb96d0
@ -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(
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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 };
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 =
|
||||
|
@ -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)
|
||||
})
|
||||
}));
|
||||
|
@ -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, _) =
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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() {
|
||||
|
@ -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() {
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user