Skip to content

Commit

Permalink
Auto merge of #35086 - Manishearth:rollup, r=Manishearth
Browse files Browse the repository at this point in the history
Rollup of 7 pull requests

- Successful merges: #34951, #34963, #34969, #35013, #35037, #35040, #35058
- Failed merges:
  • Loading branch information
bors committed Jul 28, 2016
2 parents cec262e + bc283bb commit 748ecb1
Show file tree
Hide file tree
Showing 18 changed files with 242 additions and 156 deletions.
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

0 comments on commit 748ecb1

Please sign in to comment.