1
Fork 0

Use &mut for CombineFields in inference relations

This commit is contained in:
Masood Malekghassemi 2016-07-25 16:37:30 -07:00
parent dddaf34cfc
commit e88df943dd
9 changed files with 58 additions and 78 deletions

View file

@ -32,18 +32,18 @@ use ty::{self, Ty, TyCtxt};
use ty::TyVar; use ty::TyVar;
use ty::relate::{Relate, RelateResult, TypeRelation}; use ty::relate::{Relate, RelateResult, TypeRelation};
pub struct Bivariate<'infcx, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> { pub struct Bivariate<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
fields: CombineFields<'infcx, 'gcx, 'tcx>, fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>,
a_is_expected: bool, a_is_expected: bool,
} }
impl<'infcx, 'gcx, 'tcx> Bivariate<'infcx, 'gcx, 'tcx> { impl<'combine, 'infcx, 'gcx, 'tcx> Bivariate<'combine, 'infcx, 'gcx, 'tcx> {
pub fn new(fields: CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool) -> Bivariate<'infcx, 'gcx, 'tcx> { pub fn new(fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool) -> Bivariate<'combine, 'infcx, 'gcx, 'tcx> {
Bivariate { fields: fields, a_is_expected: a_is_expected } Bivariate { fields: fields, a_is_expected: a_is_expected }
} }
} }
impl<'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> for Bivariate<'infcx, 'gcx, 'tcx> { impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> for Bivariate<'combine, 'infcx, 'gcx, 'tcx> {
fn tag(&self) -> &'static str { "Bivariate" } fn tag(&self) -> &'static str { "Bivariate" }
fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() } fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() }

View file

@ -154,27 +154,27 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
self.infcx.tcx self.infcx.tcx
} }
pub fn equate(&self, a_is_expected: bool) -> Equate<'infcx, 'gcx, 'tcx> { pub fn equate<'a>(&'a mut self, a_is_expected: bool) -> Equate<'a, 'infcx, 'gcx, 'tcx> {
Equate::new(self.clone(), a_is_expected) Equate::new(self, a_is_expected)
} }
pub fn bivariate(&self, a_is_expected: bool) -> Bivariate<'infcx, 'gcx, 'tcx> { pub fn bivariate<'a>(&'a mut self, a_is_expected: bool) -> Bivariate<'a, 'infcx, 'gcx, 'tcx> {
Bivariate::new(self.clone(), a_is_expected) Bivariate::new(self, a_is_expected)
} }
pub fn sub(&self, a_is_expected: bool) -> Sub<'infcx, 'gcx, 'tcx> { pub fn sub<'a>(&'a mut self, a_is_expected: bool) -> Sub<'a, 'infcx, 'gcx, 'tcx> {
Sub::new(self.clone(), a_is_expected) Sub::new(self, a_is_expected)
} }
pub fn lub(&self, a_is_expected: bool) -> Lub<'infcx, 'gcx, 'tcx> { pub fn lub<'a>(&'a mut self, a_is_expected: bool) -> Lub<'a, 'infcx, 'gcx, 'tcx> {
Lub::new(self.clone(), a_is_expected) Lub::new(self, a_is_expected)
} }
pub fn glb(&self, a_is_expected: bool) -> Glb<'infcx, 'gcx, 'tcx> { pub fn glb<'a>(&'a mut self, a_is_expected: bool) -> Glb<'a, 'infcx, 'gcx, 'tcx> {
Glb::new(self.clone(), a_is_expected) Glb::new(self, a_is_expected)
} }
pub fn instantiate(&self, pub fn instantiate(&mut self,
a_ty: Ty<'tcx>, a_ty: Ty<'tcx>,
dir: RelationDir, dir: RelationDir,
b_vid: ty::TyVid, b_vid: ty::TyVid,

View file

@ -15,25 +15,20 @@ use super::type_variable::{EqTo};
use ty::{self, Ty, TyCtxt}; use ty::{self, Ty, TyCtxt};
use ty::TyVar; use ty::TyVar;
use ty::relate::{Relate, RelateResult, TypeRelation}; use ty::relate::{Relate, RelateResult, TypeRelation};
use traits::PredicateObligations;
/// Ensures `a` is made equal to `b`. Returns `a` on success. /// Ensures `a` is made equal to `b`. Returns `a` on success.
pub struct Equate<'infcx, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> { pub struct Equate<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
fields: CombineFields<'infcx, 'gcx, 'tcx>, fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>,
a_is_expected: bool, a_is_expected: bool,
} }
impl<'infcx, 'gcx, 'tcx> Equate<'infcx, 'gcx, 'tcx> { impl<'combine, 'infcx, 'gcx, 'tcx> Equate<'combine, 'infcx, 'gcx, 'tcx> {
pub fn new(fields: CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool) -> Equate<'infcx, 'gcx, 'tcx> { pub fn new(fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool) -> Equate<'combine, 'infcx, 'gcx, 'tcx> {
Equate { fields: fields, a_is_expected: a_is_expected } Equate { fields: fields, a_is_expected: a_is_expected }
} }
pub fn obligations(self) -> PredicateObligations<'tcx> {
self.fields.obligations
}
} }
impl<'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> for Equate<'infcx, 'gcx, 'tcx> { impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> for Equate<'combine, 'infcx, 'gcx, 'tcx> {
fn tag(&self) -> &'static str { "Equate" } fn tag(&self) -> &'static str { "Equate" }
fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() } fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() }

View file

@ -15,25 +15,20 @@ use super::Subtype;
use ty::{self, Ty, TyCtxt}; use ty::{self, Ty, TyCtxt};
use ty::relate::{Relate, RelateResult, TypeRelation}; use ty::relate::{Relate, RelateResult, TypeRelation};
use traits::PredicateObligations;
/// "Greatest lower bound" (common subtype) /// "Greatest lower bound" (common subtype)
pub struct Glb<'infcx, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> { pub struct Glb<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
fields: CombineFields<'infcx, 'gcx, 'tcx>, fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>,
a_is_expected: bool, a_is_expected: bool,
} }
impl<'infcx, 'gcx, 'tcx> Glb<'infcx, 'gcx, 'tcx> { impl<'combine, 'infcx, 'gcx, 'tcx> Glb<'combine, 'infcx, 'gcx, 'tcx> {
pub fn new(fields: CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool) -> Glb<'infcx, 'gcx, 'tcx> { pub fn new(fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool) -> Glb<'combine, 'infcx, 'gcx, 'tcx> {
Glb { fields: fields, a_is_expected: a_is_expected } Glb { fields: fields, a_is_expected: a_is_expected }
} }
pub fn obligations(self) -> PredicateObligations<'tcx> {
self.fields.obligations
}
} }
impl<'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> for Glb<'infcx, 'gcx, 'tcx> { impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> for Glb<'combine, 'infcx, 'gcx, 'tcx> {
fn tag(&self) -> &'static str { "Glb" } fn tag(&self) -> &'static str { "Glb" }
fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() } fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() }
@ -76,12 +71,12 @@ impl<'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> for Glb<'infcx, 'gcx,
} }
} }
impl<'infcx, 'gcx, 'tcx> LatticeDir<'infcx, 'gcx, 'tcx> for Glb<'infcx, 'gcx, 'tcx> { impl<'combine, 'infcx, 'gcx, 'tcx> LatticeDir<'infcx, 'gcx, 'tcx> for Glb<'combine, 'infcx, 'gcx, 'tcx> {
fn infcx(&self) -> &'infcx InferCtxt<'infcx, 'gcx, 'tcx> { fn infcx(&self) -> &'infcx InferCtxt<'infcx, 'gcx, 'tcx> {
self.fields.infcx self.fields.infcx
} }
fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> { fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
let mut sub = self.fields.sub(self.a_is_expected); let mut sub = self.fields.sub(self.a_is_expected);
sub.relate(&v, &a)?; sub.relate(&v, &a)?;
sub.relate(&v, &b)?; sub.relate(&v, &b)?;

View file

@ -40,7 +40,7 @@ pub struct HrMatchResult<U> {
} }
impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
pub fn higher_ranked_sub<T>(&self, a: &Binder<T>, b: &Binder<T>, a_is_expected: bool) pub fn higher_ranked_sub<T>(&mut self, a: &Binder<T>, b: &Binder<T>, a_is_expected: bool)
-> RelateResult<'tcx, Binder<T>> -> RelateResult<'tcx, Binder<T>>
where T: Relate<'tcx> where T: Relate<'tcx>
{ {
@ -106,7 +106,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
/// NB. It should not happen that there are LBR appearing in `U` /// NB. It should not happen that there are LBR appearing in `U`
/// that do not appear in `T`. If that happens, those regions are /// that do not appear in `T`. If that happens, those regions are
/// unconstrained, and this routine replaces them with `'static`. /// unconstrained, and this routine replaces them with `'static`.
pub fn higher_ranked_match<T, U>(&self, pub fn higher_ranked_match<T, U>(&mut self,
span: Span, span: Span,
a_pair: &Binder<(T, U)>, a_pair: &Binder<(T, U)>,
b_match: &T, b_match: &T,
@ -222,7 +222,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
}); });
} }
pub fn higher_ranked_lub<T>(&self, a: &Binder<T>, b: &Binder<T>, a_is_expected: bool) pub fn higher_ranked_lub<T>(&mut self, a: &Binder<T>, b: &Binder<T>, a_is_expected: bool)
-> RelateResult<'tcx, Binder<T>> -> RelateResult<'tcx, Binder<T>>
where T: Relate<'tcx> where T: Relate<'tcx>
{ {
@ -312,7 +312,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
} }
} }
pub fn higher_ranked_glb<T>(&self, a: &Binder<T>, b: &Binder<T>, a_is_expected: bool) pub fn higher_ranked_glb<T>(&mut self, a: &Binder<T>, b: &Binder<T>, a_is_expected: bool)
-> RelateResult<'tcx, Binder<T>> -> RelateResult<'tcx, Binder<T>>
where T: Relate<'tcx> where T: Relate<'tcx>
{ {

View file

@ -40,7 +40,7 @@ pub trait LatticeDir<'f, 'gcx: 'f+'tcx, 'tcx: 'f> : TypeRelation<'f, 'gcx, 'tcx>
// Relates the type `v` to `a` and `b` such that `v` represents // Relates the type `v` to `a` and `b` such that `v` represents
// the LUB/GLB of `a` and `b` as appropriate. // the LUB/GLB of `a` and `b` as appropriate.
fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()>; fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()>;
} }
pub fn super_lattice_tys<'a, 'gcx, 'tcx, L>(this: &mut L, pub fn super_lattice_tys<'a, 'gcx, 'tcx, L>(this: &mut L,

View file

@ -15,25 +15,20 @@ use super::Subtype;
use ty::{self, Ty, TyCtxt}; use ty::{self, Ty, TyCtxt};
use ty::relate::{Relate, RelateResult, TypeRelation}; use ty::relate::{Relate, RelateResult, TypeRelation};
use traits::PredicateObligations;
/// "Least upper bound" (common supertype) /// "Least upper bound" (common supertype)
pub struct Lub<'infcx, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> { pub struct Lub<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
fields: CombineFields<'infcx, 'gcx, 'tcx>, fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>,
a_is_expected: bool, a_is_expected: bool,
} }
impl<'infcx, 'gcx, 'tcx> Lub<'infcx, 'gcx, 'tcx> { impl<'combine, 'infcx, 'gcx, 'tcx> Lub<'combine, 'infcx, 'gcx, 'tcx> {
pub fn new(fields: CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool) -> Lub<'infcx, 'gcx, 'tcx> { pub fn new(fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool) -> Lub<'combine, 'infcx, 'gcx, 'tcx> {
Lub { fields: fields, a_is_expected: a_is_expected } Lub { fields: fields, a_is_expected: a_is_expected }
} }
pub fn obligations(self) -> PredicateObligations<'tcx> {
self.fields.obligations
}
} }
impl<'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> for Lub<'infcx, 'gcx, 'tcx> { impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> for Lub<'combine, 'infcx, 'gcx, 'tcx> {
fn tag(&self) -> &'static str { "Lub" } fn tag(&self) -> &'static str { "Lub" }
fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() } fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() }
@ -76,12 +71,12 @@ impl<'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> for Lub<'infcx, 'gcx,
} }
} }
impl<'infcx, 'gcx, 'tcx> LatticeDir<'infcx, 'gcx, 'tcx> for Lub<'infcx, 'gcx, 'tcx> { impl<'combine, 'infcx, 'gcx, 'tcx> LatticeDir<'infcx, 'gcx, 'tcx> for Lub<'combine, 'infcx, 'gcx, 'tcx> {
fn infcx(&self) -> &'infcx InferCtxt<'infcx, 'gcx, 'tcx> { fn infcx(&self) -> &'infcx InferCtxt<'infcx, 'gcx, 'tcx> {
self.fields.infcx self.fields.infcx
} }
fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> { fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
let mut sub = self.fields.sub(self.a_is_expected); let mut sub = self.fields.sub(self.a_is_expected);
sub.relate(&a, &v)?; sub.relate(&a, &v)?;
sub.relate(&b, &v)?; sub.relate(&b, &v)?;

View file

@ -813,36 +813,36 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
-> InferResult<'tcx, T> -> InferResult<'tcx, T>
where T: Relate<'tcx> where T: Relate<'tcx>
{ {
let mut equate = self.combine_fields(trace).equate(a_is_expected); let mut fields = self.combine_fields(trace);
let result = equate.relate(a, b); let result = fields.equate(a_is_expected).relate(a, b);
result.map(|t| InferOk { value: t, obligations: equate.obligations() }) result.map(move |t| InferOk { value: t, obligations: fields.obligations })
} }
pub fn sub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T) pub fn sub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
-> InferResult<'tcx, T> -> InferResult<'tcx, T>
where T: Relate<'tcx> where T: Relate<'tcx>
{ {
let mut sub = self.combine_fields(trace).sub(a_is_expected); let mut fields = self.combine_fields(trace);
let result = sub.relate(a, b); let result = fields.sub(a_is_expected).relate(a, b);
result.map(|t| InferOk { value: t, obligations: sub.obligations() }) result.map(move |t| InferOk { value: t, obligations: fields.obligations })
} }
pub fn lub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T) pub fn lub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
-> InferResult<'tcx, T> -> InferResult<'tcx, T>
where T: Relate<'tcx> where T: Relate<'tcx>
{ {
let mut lub = self.combine_fields(trace).lub(a_is_expected); let mut fields = self.combine_fields(trace);
let result = lub.relate(a, b); let result = fields.lub(a_is_expected).relate(a, b);
result.map(|t| InferOk { value: t, obligations: lub.obligations() }) result.map(move |t| InferOk { value: t, obligations: fields.obligations })
} }
pub fn glb<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T) pub fn glb<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
-> InferResult<'tcx, T> -> InferResult<'tcx, T>
where T: Relate<'tcx> where T: Relate<'tcx>
{ {
let mut glb = self.combine_fields(trace).glb(a_is_expected); let mut fields = self.combine_fields(trace);
let result = glb.relate(a, b); let result = fields.glb(a_is_expected).relate(a, b);
result.map(|t| InferOk { value: t, obligations: glb.obligations() }) result.map(move |t| InferOk { value: t, obligations: fields.obligations })
} }
fn start_snapshot(&self) -> CombinedSnapshot { fn start_snapshot(&self) -> CombinedSnapshot {
@ -1645,7 +1645,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}; };
let match_pair = match_a.map_bound(|p| (p.projection_ty.trait_ref, p.ty)); let match_pair = match_a.map_bound(|p| (p.projection_ty.trait_ref, p.ty));
let combine = self.combine_fields(trace); let mut combine = self.combine_fields(trace);
let result = combine.higher_ranked_match(span, &match_pair, &match_b, true)?; let result = combine.higher_ranked_match(span, &match_pair, &match_b, true)?;
Ok(InferOk { value: result, obligations: combine.obligations }) Ok(InferOk { value: result, obligations: combine.obligations })
} }

View file

@ -15,24 +15,19 @@ use super::type_variable::{SubtypeOf, SupertypeOf};
use ty::{self, Ty, TyCtxt}; use ty::{self, Ty, TyCtxt};
use ty::TyVar; use ty::TyVar;
use ty::relate::{Cause, Relate, RelateResult, TypeRelation}; use ty::relate::{Cause, Relate, RelateResult, TypeRelation};
use traits::PredicateObligations;
use std::mem; use std::mem;
/// Ensures `a` is made a subtype of `b`. Returns `a` on success. /// Ensures `a` is made a subtype of `b`. Returns `a` on success.
pub struct Sub<'infcx, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> { pub struct Sub<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
fields: CombineFields<'infcx, 'gcx, 'tcx>, fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>,
a_is_expected: bool, a_is_expected: bool,
} }
impl<'infcx, 'gcx, 'tcx> Sub<'infcx, 'gcx, 'tcx> { impl<'combine, 'infcx, 'gcx, 'tcx> Sub<'combine, 'infcx, 'gcx, 'tcx> {
pub fn new(f: CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool) -> Sub<'infcx, 'gcx, 'tcx> { pub fn new(f: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool) -> Sub<'combine, 'infcx, 'gcx, 'tcx> {
Sub { fields: f, a_is_expected: a_is_expected } Sub { fields: f, a_is_expected: a_is_expected }
} }
pub fn obligations(self) -> PredicateObligations<'tcx> {
self.fields.obligations
}
fn with_expected_switched<R, F: FnOnce(&mut Self) -> R>(&mut self, f: F) -> R { fn with_expected_switched<R, F: FnOnce(&mut Self) -> R>(&mut self, f: F) -> R {
self.a_is_expected = !self.a_is_expected; self.a_is_expected = !self.a_is_expected;
let result = f(self); let result = f(self);
@ -41,7 +36,7 @@ impl<'infcx, 'gcx, 'tcx> Sub<'infcx, 'gcx, 'tcx> {
} }
} }
impl<'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> for Sub<'infcx, 'gcx, 'tcx> { impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> for Sub<'combine, 'infcx, 'gcx, 'tcx> {
fn tag(&self) -> &'static str { "Sub" } fn tag(&self) -> &'static str { "Sub" }
fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.infcx.tcx } fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.infcx.tcx }
fn a_is_expected(&self) -> bool { self.a_is_expected } fn a_is_expected(&self) -> bool { self.a_is_expected }