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

Rollup of 7 pull requests #35086

Merged
merged 18 commits into from
Jul 28, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
11 changes: 6 additions & 5 deletions src/libcollections/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ use core::mem;
use core::ops::{Index, IndexMut};
use core::ops;
use core::ptr;
use core::ptr::Shared;
use core::slice;

use super::SpecExtend;
Expand Down Expand Up @@ -899,8 +900,8 @@ impl<T> Vec<T> {
Drain {
tail_start: end,
tail_len: len - end,
iter: range_slice.iter_mut(),
vec: self as *mut _,
iter: range_slice.iter(),
vec: Shared::new(self as *mut _),
}
}
}
Expand Down Expand Up @@ -1806,8 +1807,8 @@ pub struct Drain<'a, T: 'a> {
/// Length of tail
tail_len: usize,
/// Current remaining range to remove
iter: slice::IterMut<'a, T>,
vec: *mut Vec<T>,
iter: slice::Iter<'a, T>,
vec: Shared<Vec<T>>,
}

#[stable(feature = "drain", since = "1.6.0")]
Expand Down Expand Up @@ -1845,7 +1846,7 @@ impl<'a, T> Drop for Drain<'a, T> {

if self.tail_len > 0 {
unsafe {
let source_vec = &mut *self.vec;
let source_vec = &mut **self.vec;
// memmove back untouched tail, update to new length
let start = source_vec.len();
let tail = self.tail_start;
Expand Down
6 changes: 6 additions & 0 deletions src/libcollectionstest/binary_heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// except according to those terms.

use std::collections::BinaryHeap;
use std::collections::binary_heap::Drain;

#[test]
fn test_iterator() {
Expand Down Expand Up @@ -292,3 +293,8 @@ fn test_extend_specialization() {

assert_eq!(a.into_sorted_vec(), [-20, -10, 1, 2, 3, 3, 5, 43]);
}

#[allow(dead_code)]
fn assert_covariance() {
fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { d }
}
6 changes: 6 additions & 0 deletions src/libcollectionstest/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use std::borrow::Cow;
use std::iter::{FromIterator, repeat};
use std::mem::size_of;
use std::vec::Drain;

use test::Bencher;

Expand Down Expand Up @@ -510,6 +511,11 @@ fn test_cow_from() {
}
}

#[allow(dead_code)]
fn assert_covariance() {
fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { d }
}

#[bench]
fn bench_new(b: &mut Bencher) {
b.iter(|| {
Expand Down
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
Loading