提交 4b0edb96 编写于 作者: N Niko Matsakis

Combine `try` and `commit_if_ok` and make some details of inference

context private.
上级 09398378
......@@ -60,7 +60,7 @@ fn higher_ranked_sub<T>(&self, a: &Binder<T>, b: &Binder<T>)
// 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 @@ fn higher_ranked_lub<T>(&self, a: &Binder<T>, b: &Binder<T>) -> CombineResult<'t
{
// 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 @@ fn higher_ranked_glb<T>(&self, a: &Binder<T>, b: &Binder<T>) -> CombineResult<'t
// 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)
})
}
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,24 +471,24 @@ pub fn type_is_unconstrained_numeric(&'a self, ty: Ty) -> UnconstrainedNumeric {
}
}
pub fn combine_fields<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'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>)
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>)
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>)
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 @@ pub fn commit_unconditionally<R, F>(&self, f: F) -> R where
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 @@ pub fn commit_regions_if_ok<T, E, F>(&self, f: F) -> Result<T, E> where
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 @@ pub fn commit_regions_if_ok<T, E, F>(&self, f: F) -> Result<T, E> where
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 @@ pub fn sub_types(&self,
-> 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 @@ pub fn eq_types(&self,
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 @@ pub fn sub_trait_refs(&self,
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 @@ pub fn sub_poly_trait_refs(&self,
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 @@ pub fn equality_predicate(&self,
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 @@ pub fn region_outlives_predicate(&self,
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 @@ pub fn next_float_var_id(&self) -> FloatVid {
.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 @@ fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
}
}
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 @@ pub fn span(&self) -> Span {
}
}
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 @@ fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
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 fn push(&mut self, other: BoundRegion) {
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 @@ pub fn num_vars(&self) -> u32 {
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 @@ fn assemble_candidates_from_object_ty(&mut self,
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 @@ fn collect_predicates_for_types(&mut self,
// 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 @@ fn confirm_projection_candidate(&mut self,
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 @@ fn vtable_default_impl(&mut self,
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 @@ fn confirm_impl_candidate(&mut self,
// 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 @@
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 @@ fn tcx(&self) -> &ty::ctxt<'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 @@ fn coerce_borrowed_pointer(&self,
_ => 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 @@ fn coerce_borrowed_pointer(&self,
}
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 @@ fn coerce_unsized(&self,
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 @@ fn coerce_unsized(&self,
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 @@ fn coerce_unsized(&self,
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 @@ fn unsize_ty(&self,
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 @@ fn unsize_ty(&self,
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 @@ fn unsize_ty(&self,
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
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册