Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use &mut for CombineFields in inference relations #35040

Merged
merged 5 commits into from
Jul 28, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions src/librustc/infer/bivariate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,27 @@ use ty::{self, Ty, TyCtxt};
use ty::TyVar;
use ty::relate::{Relate, RelateResult, TypeRelation};

pub struct Bivariate<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
fields: CombineFields<'a, 'gcx, 'tcx>
pub struct Bivariate<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>,
a_is_expected: bool,
}

impl<'a, 'gcx, 'tcx> Bivariate<'a, 'gcx, 'tcx> {
pub fn new(fields: CombineFields<'a, 'gcx, 'tcx>) -> Bivariate<'a, 'gcx, 'tcx> {
Bivariate { fields: fields }
impl<'combine, 'infcx, 'gcx, 'tcx> Bivariate<'combine, '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 }
}
}

impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Bivariate<'a, 'gcx, 'tcx> {
impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
for Bivariate<'combine, 'infcx, 'gcx, 'tcx>
{
fn tag(&self) -> &'static str { "Bivariate" }

fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> { self.fields.tcx() }
fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() }

fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
fn a_is_expected(&self) -> bool { self.a_is_expected }

fn relate_with_variance<T: Relate<'tcx>>(&mut self,
variance: ty::Variance,
Expand Down Expand Up @@ -86,12 +91,12 @@ impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Bivariate<'a, 'gcx, 'tcx>
}

(&ty::TyInfer(TyVar(a_id)), _) => {
self.fields.instantiate(b, BiTo, a_id)?;
self.fields.instantiate(b, BiTo, a_id, self.a_is_expected)?;
Ok(a)
}

(_, &ty::TyInfer(TyVar(b_id))) => {
self.fields.instantiate(a, BiTo, b_id)?;
self.fields.instantiate(a, BiTo, b_id, self.a_is_expected)?;
Ok(a)
}

Expand Down
54 changes: 24 additions & 30 deletions src/librustc/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,21 +52,20 @@ use syntax::ast;
use syntax_pos::Span;

#[derive(Clone)]
pub struct CombineFields<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
pub infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
pub a_is_expected: bool,
pub struct CombineFields<'infcx, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
pub infcx: &'infcx InferCtxt<'infcx, 'gcx, 'tcx>,
pub trace: TypeTrace<'tcx>,
pub cause: Option<ty::relate::Cause>,
pub obligations: PredicateObligations<'tcx>,
}

impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
impl<'infcx, 'gcx, 'tcx> InferCtxt<'infcx, 'gcx, 'tcx> {
pub fn super_combine_tys<R>(&self,
relation: &mut R,
a: Ty<'tcx>,
b: Ty<'tcx>)
-> RelateResult<'tcx, Ty<'tcx>>
where R: TypeRelation<'a, 'gcx, 'tcx>
where R: TypeRelation<'infcx, 'gcx, 'tcx>
{
let a_is_expected = relation.a_is_expected();

Expand Down Expand Up @@ -150,42 +149,36 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
}

impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
pub fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
pub fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> {
self.infcx.tcx
}

pub fn switch_expected(&self) -> CombineFields<'a, 'gcx, 'tcx> {
CombineFields {
a_is_expected: !self.a_is_expected,
..(*self).clone()
}
}

pub fn equate(&self) -> Equate<'a, 'gcx, 'tcx> {
Equate::new(self.clone())
pub fn equate<'a>(&'a mut self, a_is_expected: bool) -> Equate<'a, 'infcx, 'gcx, 'tcx> {
Equate::new(self, a_is_expected)
}

pub fn bivariate(&self) -> Bivariate<'a, 'gcx, 'tcx> {
Bivariate::new(self.clone())
pub fn bivariate<'a>(&'a mut self, a_is_expected: bool) -> Bivariate<'a, 'infcx, 'gcx, 'tcx> {
Bivariate::new(self, a_is_expected)
}

pub fn sub(&self) -> Sub<'a, 'gcx, 'tcx> {
Sub::new(self.clone())
pub fn sub<'a>(&'a mut self, a_is_expected: bool) -> Sub<'a, 'infcx, 'gcx, 'tcx> {
Sub::new(self, a_is_expected)
}

pub fn lub(&self) -> Lub<'a, 'gcx, 'tcx> {
Lub::new(self.clone())
pub fn lub<'a>(&'a mut self, a_is_expected: bool) -> Lub<'a, 'infcx, 'gcx, 'tcx> {
Lub::new(self, a_is_expected)
}

pub fn glb(&self) -> Glb<'a, 'gcx, 'tcx> {
Glb::new(self.clone())
pub fn glb<'a>(&'a mut self, a_is_expected: bool) -> Glb<'a, 'infcx, 'gcx, 'tcx> {
Glb::new(self, a_is_expected)
}

pub fn instantiate(&self,
pub fn instantiate(&mut self,
a_ty: Ty<'tcx>,
dir: RelationDir,
b_vid: ty::TyVid)
b_vid: ty::TyVid,
a_is_expected: bool)
-> RelateResult<'tcx, ()>
{
let mut stack = Vec::new();
Expand Down Expand Up @@ -255,10 +248,11 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
// to associate causes/spans with each of the relations in
// the stack to get this right.
match dir {
BiTo => self.bivariate().relate(&a_ty, &b_ty),
EqTo => self.equate().relate(&a_ty, &b_ty),
SubtypeOf => self.sub().relate(&a_ty, &b_ty),
SupertypeOf => self.sub().relate_with_variance(ty::Contravariant, &a_ty, &b_ty),
BiTo => self.bivariate(a_is_expected).relate(&a_ty, &b_ty),
EqTo => self.equate(a_is_expected).relate(&a_ty, &b_ty),
SubtypeOf => self.sub(a_is_expected).relate(&a_ty, &b_ty),
SupertypeOf => self.sub(a_is_expected).relate_with_variance(
ty::Contravariant, &a_ty, &b_ty),
}?;
}

Expand Down
34 changes: 17 additions & 17 deletions src/librustc/infer/equate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,29 @@ use super::type_variable::{EqTo};
use ty::{self, Ty, TyCtxt};
use ty::TyVar;
use ty::relate::{Relate, RelateResult, TypeRelation};
use traits::PredicateObligations;

/// Ensures `a` is made equal to `b`. Returns `a` on success.
pub struct Equate<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
fields: CombineFields<'a, 'gcx, 'tcx>
pub struct Equate<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>,
a_is_expected: bool,
}

impl<'a, 'gcx, 'tcx> Equate<'a, 'gcx, 'tcx> {
pub fn new(fields: CombineFields<'a, 'gcx, 'tcx>) -> Equate<'a, 'gcx, 'tcx> {
Equate { fields: fields }
}

pub fn obligations(self) -> PredicateObligations<'tcx> {
self.fields.obligations
impl<'combine, 'infcx, 'gcx, 'tcx> Equate<'combine, '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 }
}
}

impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Equate<'a, 'gcx, 'tcx> {
impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
for Equate<'combine, 'infcx, 'gcx, 'tcx>
{
fn tag(&self) -> &'static str { "Equate" }

fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> { self.fields.tcx() }
fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() }

fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
fn a_is_expected(&self) -> bool { self.a_is_expected }

fn relate_with_variance<T: Relate<'tcx>>(&mut self,
_: ty::Variance,
Expand All @@ -63,12 +63,12 @@ impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Equate<'a, 'gcx, 'tcx> {
}

(&ty::TyInfer(TyVar(a_id)), _) => {
self.fields.instantiate(b, EqTo, a_id)?;
self.fields.instantiate(b, EqTo, a_id, self.a_is_expected)?;
Ok(a)
}

(_, &ty::TyInfer(TyVar(b_id))) => {
self.fields.instantiate(a, EqTo, b_id)?;
self.fields.instantiate(a, EqTo, b_id, self.a_is_expected)?;
Ok(a)
}

Expand All @@ -93,7 +93,7 @@ impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Equate<'a, 'gcx, 'tcx> {
-> RelateResult<'tcx, ty::Binder<T>>
where T: Relate<'tcx>
{
self.fields.higher_ranked_sub(a, b)?;
self.fields.higher_ranked_sub(b, a)
self.fields.higher_ranked_sub(a, b, self.a_is_expected)?;
self.fields.higher_ranked_sub(b, a, self.a_is_expected)
}
}
44 changes: 23 additions & 21 deletions src/librustc/infer/glb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,29 @@ use super::Subtype;

use ty::{self, Ty, TyCtxt};
use ty::relate::{Relate, RelateResult, TypeRelation};
use traits::PredicateObligations;

/// "Greatest lower bound" (common subtype)
pub struct Glb<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
fields: CombineFields<'a, 'gcx, 'tcx>
pub struct Glb<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>,
a_is_expected: bool,
}

impl<'a, 'gcx, 'tcx> Glb<'a, 'gcx, 'tcx> {
pub fn new(fields: CombineFields<'a, 'gcx, 'tcx>) -> Glb<'a, 'gcx, 'tcx> {
Glb { fields: fields }
}

pub fn obligations(self) -> PredicateObligations<'tcx> {
self.fields.obligations
impl<'combine, 'infcx, 'gcx, 'tcx> Glb<'combine, '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 }
}
}

impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Glb<'a, 'gcx, 'tcx> {
impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
for Glb<'combine, 'infcx, 'gcx, 'tcx>
{
fn tag(&self) -> &'static str { "Glb" }

fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> { self.fields.tcx() }
fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() }

fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
fn a_is_expected(&self) -> bool { self.a_is_expected }

fn relate_with_variance<T: Relate<'tcx>>(&mut self,
variance: ty::Variance,
Expand All @@ -46,10 +46,10 @@ impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Glb<'a, 'gcx, 'tcx> {
-> RelateResult<'tcx, T>
{
match variance {
ty::Invariant => self.fields.equate().relate(a, b),
ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b),
ty::Covariant => self.relate(a, b),
ty::Bivariant => self.fields.bivariate().relate(a, b),
ty::Contravariant => self.fields.lub().relate(a, b),
ty::Bivariant => self.fields.bivariate(self.a_is_expected).relate(a, b),
ty::Contravariant => self.fields.lub(self.a_is_expected).relate(a, b),
}
}

Expand All @@ -71,17 +71,19 @@ impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Glb<'a, 'gcx, 'tcx> {
-> RelateResult<'tcx, ty::Binder<T>>
where T: Relate<'tcx>
{
self.fields.higher_ranked_glb(a, b)
self.fields.higher_ranked_glb(a, b, self.a_is_expected)
}
}

impl<'a, 'gcx, 'tcx> LatticeDir<'a, 'gcx, 'tcx> for Glb<'a, 'gcx, 'tcx> {
fn infcx(&self) -> &'a InferCtxt<'a, '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> {
self.fields.infcx
}

fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
let mut sub = self.fields.sub();
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);
sub.relate(&v, &a)?;
sub.relate(&v, &b)?;
Ok(())
Expand Down
21 changes: 11 additions & 10 deletions src/librustc/infer/higher_ranked/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub struct HrMatchResult<U> {
}

impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
pub fn higher_ranked_sub<T>(&self, a: &Binder<T>, b: &Binder<T>)
pub fn higher_ranked_sub<T>(&mut self, a: &Binder<T>, b: &Binder<T>, a_is_expected: bool)
-> RelateResult<'tcx, Binder<T>>
where T: Relate<'tcx>
{
Expand Down Expand Up @@ -77,11 +77,11 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
debug!("b_prime={:?}", b_prime);

// Compare types now that bound regions have been replaced.
let result = self.sub().relate(&a_prime, &b_prime)?;
let result = self.sub(a_is_expected).relate(&a_prime, &b_prime)?;

// Presuming type comparison succeeds, we need to check
// that the skolemized regions do not "leak".
self.infcx.leak_check(!self.a_is_expected, span, &skol_map, snapshot)?;
self.infcx.leak_check(!a_is_expected, span, &skol_map, snapshot)?;

// We are finished with the skolemized regions now so pop
// them off.
Expand All @@ -106,10 +106,11 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
/// NB. It should not happen that there are LBR appearing in `U`
/// that do not appear in `T`. If that happens, those regions are
/// 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,
a_pair: &Binder<(T, U)>,
b_match: &T)
b_match: &T,
a_is_expected: bool)
-> RelateResult<'tcx, HrMatchResult<U>>
where T: Relate<'tcx>,
U: TypeFoldable<'tcx>
Expand All @@ -129,7 +130,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
debug!("higher_ranked_match: skol_map={:?}", skol_map);

// Equate types now that bound regions have been replaced.
try!(self.equate().relate(&a_match, &b_match));
try!(self.equate(a_is_expected).relate(&a_match, &b_match));

// Map each skolemized region to a vector of other regions that it
// must be equated with. (Note that this vector may include other
Expand Down Expand Up @@ -221,7 +222,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
});
}

pub fn higher_ranked_lub<T>(&self, a: &Binder<T>, b: &Binder<T>)
pub fn higher_ranked_lub<T>(&mut self, a: &Binder<T>, b: &Binder<T>, a_is_expected: bool)
-> RelateResult<'tcx, Binder<T>>
where T: Relate<'tcx>
{
Expand All @@ -239,7 +240,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {

// Collect constraints.
let result0 =
self.lub().relate(&a_with_fresh, &b_with_fresh)?;
self.lub(a_is_expected).relate(&a_with_fresh, &b_with_fresh)?;
let result0 =
self.infcx.resolve_type_vars_if_possible(&result0);
debug!("lub result0 = {:?}", result0);
Expand Down Expand Up @@ -311,7 +312,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
}
}

pub fn higher_ranked_glb<T>(&self, a: &Binder<T>, b: &Binder<T>)
pub fn higher_ranked_glb<T>(&mut self, a: &Binder<T>, b: &Binder<T>, a_is_expected: bool)
-> RelateResult<'tcx, Binder<T>>
where T: Relate<'tcx>
{
Expand All @@ -333,7 +334,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {

// Collect constraints.
let result0 =
self.glb().relate(&a_with_fresh, &b_with_fresh)?;
self.glb(a_is_expected).relate(&a_with_fresh, &b_with_fresh)?;
let result0 =
self.infcx.resolve_type_vars_if_possible(&result0);
debug!("glb result0 = {:?}", result0);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/infer/lattice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
// 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,
Expand Down
Loading