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 13 pull requests #41930

Closed
wants to merge 29 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
cf05cd8
bootstrap: Output name of failed config in case of errors
devurandom May 7, 2017
defcfb2
Remove wrong or outdated info from CString docs.
mbrubeck May 9, 2017
e42875c
doc: break into 2 sentences
tshepang May 11, 2017
67a0d27
Ensure we walk the root module of the crate
nrc May 11, 2017
43349e6
Upgrade some comments to doc comments
oli-obk May 11, 2017
641d053
Fix typo in size_hint example comment
mglagla May 11, 2017
a950c37
replace the type generalizer with one based on variance
nikomatsakis May 2, 2017
a4151ff
add a WF obligation if a type variable appears in bivariant position
nikomatsakis May 2, 2017
2490ee5
correct various error messages that changed
nikomatsakis May 3, 2017
fb7ba47
Pass crate attributes in visit.rs
nrc May 11, 2017
084b67f
Annotate the license exceptions
brson May 11, 2017
b0c80a9
remove the #[inline] attribute from drop_in_place
arielb1 May 11, 2017
e6cde9f
Number of filtered out tests in tests summary
mersinvald May 11, 2017
75b69c4
Fix search when looking to sources
GuillaumeGomez May 11, 2017
68c1ce9
rustc_trans: do not attempt to truncate an i1 const to i1.
eddyb May 11, 2017
c85501b
box large variants in MIR
arielb1 May 11, 2017
c8b1559
Rollup merge of #41716 - nikomatsakis:issue-41677, r=arielb1
Mark-Simulacrum May 12, 2017
cf1594e
Rollup merge of #41820 - devurandom:patch-1, r=alexcrichton
Mark-Simulacrum May 12, 2017
323560e
Rollup merge of #41860 - mbrubeck:docs, r=nagisa
Mark-Simulacrum May 12, 2017
1db0f2b
Rollup merge of #41896 - tshepang:too-long, r=steveklabnik
Mark-Simulacrum May 12, 2017
18c7a45
Rollup merge of #41910 - mersinvald:master, r=Mark-Simulacrum
Mark-Simulacrum May 12, 2017
ec7c175
Rollup merge of #41912 - oli-obk:patch-3, r=eddyb
Mark-Simulacrum May 12, 2017
6d8c4ee
Rollup merge of #41916 - mglagla:typo, r=sfackler
Mark-Simulacrum May 12, 2017
2db3722
Rollup merge of #41918 - brson:lic, r=alexcrichton
Mark-Simulacrum May 12, 2017
329afe8
Rollup merge of #41919 - nrc:save-crate, r=eddyb
Mark-Simulacrum May 12, 2017
01dfd18
Rollup merge of #41920 - arielb1:inline-drop, r=eddyb
Mark-Simulacrum May 12, 2017
8467fd6
Rollup merge of #41921 - GuillaumeGomez:fix-search-style, r=steveklabnik
Mark-Simulacrum May 12, 2017
11475b3
Rollup merge of #41923 - eddyb:issue-41744, r=arielb1
Mark-Simulacrum May 12, 2017
b93dfec
Rollup merge of #41926 - arielb1:box-mir, r=eddyb
Mark-Simulacrum May 12, 2017
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
2 changes: 1 addition & 1 deletion src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ impl Config {
let table = match p.parse() {
Some(table) => table,
None => {
println!("failed to parse TOML configuration:");
println!("failed to parse TOML configuration '{}':", file.to_str().unwrap());
for err in p.errors.iter() {
let (loline, locol) = p.to_linecol(err.lo);
let (hiline, hicol) = p.to_linecol(err.hi);
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/iter/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ pub trait Iterator {
/// // exactly wouldn't be possible without executing filter().
/// assert_eq!((0, Some(10)), iter.size_hint());
///
/// // Let's add one five more numbers with chain()
/// // Let's add five more numbers with chain()
/// let iter = (0..10).filter(|x| x % 2 == 0).chain(15..20);
///
/// // now both bounds are increased by five
Expand Down
1 change: 0 additions & 1 deletion src/libcore/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ pub use intrinsics::write_bytes;
/// invalid pointers, types, and double drops.
#[stable(feature = "drop_in_place", since = "1.8.0")]
#[lang="drop_in_place"]
#[inline]
#[allow(unconditional_recursion)]
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
// Code here does not matter - this is replaced by the
Expand Down
184 changes: 143 additions & 41 deletions src/librustc/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,8 @@ use super::{MiscVariable, TypeTrace};
use ty::{IntType, UintType};
use ty::{self, Ty, TyCtxt};
use ty::error::TypeError;
use ty::fold::TypeFoldable;
use ty::relate::{RelateResult, TypeRelation};
use traits::PredicateObligations;
use ty::relate::{self, Relate, RelateResult, TypeRelation};
use traits::{Obligation, PredicateObligations};

use syntax::ast;
use syntax_pos::Span;
Expand Down Expand Up @@ -207,11 +206,16 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
// `'?2` and `?3` are fresh region/type inference
// variables. (Down below, we will relate `a_ty <: b_ty`,
// adding constraints like `'x: '?2` and `?1 <: ?3`.)
let b_ty = self.generalize(a_ty, b_vid, dir == EqTo)?;
let Generalization { ty: b_ty, needs_wf } = self.generalize(a_ty, b_vid, dir)?;
debug!("instantiate(a_ty={:?}, dir={:?}, b_vid={:?}, generalized b_ty={:?})",
a_ty, dir, b_vid, b_ty);
self.infcx.type_variables.borrow_mut().instantiate(b_vid, b_ty);

if needs_wf {
self.obligations.push(Obligation::new(self.trace.cause.clone(),
ty::Predicate::WellFormed(b_ty)));
}

// Finally, relate `b_ty` to `a_ty`, as described in previous comment.
//
// FIXME(#16847): This code is non-ideal because all these subtype
Expand All @@ -230,50 +234,125 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {

/// Attempts to generalize `ty` for the type variable `for_vid`.
/// This checks for cycle -- that is, whether the type `ty`
/// references `for_vid`. If `is_eq_relation` is false, it will
/// also replace all regions/unbound-type-variables with fresh
/// variables. Returns `TyError` in the case of a cycle, `Ok`
/// otherwise.
/// references `for_vid`. The `dir` is the "direction" for which we
/// a performing the generalization (i.e., are we producing a type
/// that can be used as a supertype etc).
///
/// Preconditions:
///
/// - `for_vid` is a "root vid"
fn generalize(&self,
ty: Ty<'tcx>,
for_vid: ty::TyVid,
is_eq_relation: bool)
-> RelateResult<'tcx, Ty<'tcx>>
dir: RelationDir)
-> RelateResult<'tcx, Generalization<'tcx>>
{
// Determine the ambient variance within which `ty` appears.
// The surrounding equation is:
//
// ty [op] ty2
//
// where `op` is either `==`, `<:`, or `:>`. This maps quite
// naturally.
let ambient_variance = match dir {
RelationDir::EqTo => ty::Invariant,
RelationDir::SubtypeOf => ty::Covariant,
RelationDir::SupertypeOf => ty::Contravariant,
};

let mut generalize = Generalizer {
infcx: self.infcx,
span: self.trace.cause.span,
for_vid_sub_root: self.infcx.type_variables.borrow_mut().sub_root_var(for_vid),
is_eq_relation: is_eq_relation,
cycle_detected: false
ambient_variance: ambient_variance,
needs_wf: false,
};
let u = ty.fold_with(&mut generalize);
if generalize.cycle_detected {
Err(TypeError::CyclicTy)
} else {
Ok(u)
}

let ty = generalize.relate(&ty, &ty)?;
let needs_wf = generalize.needs_wf;
Ok(Generalization { ty, needs_wf })
}
}

struct Generalizer<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
span: Span,
for_vid_sub_root: ty::TyVid,
is_eq_relation: bool,
cycle_detected: bool,
ambient_variance: ty::Variance,
needs_wf: bool, // see the field `needs_wf` in `Generalization`
}

impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx, 'tcx> {
fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx> {
/// Result from a generalization operation. This includes
/// not only the generalized type, but also a bool flag
/// indicating whether further WF checks are needed.q
struct Generalization<'tcx> {
ty: Ty<'tcx>,

/// If true, then the generalized type may not be well-formed,
/// even if the source type is well-formed, so we should add an
/// additional check to enforce that it is. This arises in
/// particular around 'bivariant' type parameters that are only
/// constrained by a where-clause. As an example, imagine a type:
///
/// struct Foo<A, B> where A: Iterator<Item=B> {
/// data: A
/// }
///
/// here, `A` will be covariant, but `B` is
/// unconstrained. However, whatever it is, for `Foo` to be WF, it
/// must be equal to `A::Item`. If we have an input `Foo<?A, ?B>`,
/// then after generalization we will wind up with a type like
/// `Foo<?C, ?D>`. When we enforce that `Foo<?A, ?B> <: Foo<?C,
/// ?D>` (or `>:`), we will wind up with the requirement that `?A
/// <: ?C`, but no particular relationship between `?B` and `?D`
/// (after all, we do not know the variance of the normalized form
/// of `A::Item` with respect to `A`). If we do nothing else, this
/// may mean that `?D` goes unconstrained (as in #41677). So, in
/// this scenario where we create a new type variable in a
/// bivariant context, we set the `needs_wf` flag to true. This
/// will force the calling code to check that `WF(Foo<?C, ?D>)`
/// holds, which in turn implies that `?C::Item == ?D`. So once
/// `?C` is constrained, that should suffice to restrict `?D`.
needs_wf: bool,
}

impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, 'tcx> {
fn tcx(&self) -> TyCtxt<'cx, 'gcx, 'tcx> {
self.infcx.tcx
}

fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
fn tag(&self) -> &'static str {
"Generalizer"
}

fn a_is_expected(&self) -> bool {
true
}

fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
-> RelateResult<'tcx, ty::Binder<T>>
where T: Relate<'tcx>
{
Ok(ty::Binder(self.relate(a.skip_binder(), b.skip_binder())?))
}

fn relate_with_variance<T: Relate<'tcx>>(&mut self,
variance: ty::Variance,
a: &T,
b: &T)
-> RelateResult<'tcx, T>
{
let old_ambient_variance = self.ambient_variance;
self.ambient_variance = self.ambient_variance.xform(variance);

let result = self.relate(a, b);
self.ambient_variance = old_ambient_variance;
result
}

fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
assert_eq!(t, t2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==

// Check to see whether the type we are genealizing references
// any other type variable related to `vid` via
// subtyping. This is basically our "occurs check", preventing
Expand All @@ -286,41 +365,63 @@ impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx
if sub_vid == self.for_vid_sub_root {
// If sub-roots are equal, then `for_vid` and
// `vid` are related via subtyping.
self.cycle_detected = true;
self.tcx().types.err
return Err(TypeError::CyclicTy);
} else {
match variables.probe_root(vid) {
Some(u) => {
drop(variables);
self.fold_ty(u)
self.relate(&u, &u)
}
None => {
if !self.is_eq_relation {
let origin = variables.origin(vid);
let new_var_id = variables.new_var(false, origin, None);
let u = self.tcx().mk_var(new_var_id);
debug!("generalize: replacing original vid={:?} with new={:?}",
vid, u);
u
} else {
t
match self.ambient_variance {
// Invariant: no need to make a fresh type variable.
ty::Invariant => return Ok(t),

// Bivariant: make a fresh var, but we
// may need a WF predicate. See
// comment on `needs_wf` field for
// more info.
ty::Bivariant => self.needs_wf = true,

// Co/contravariant: this will be
// sufficiently constrained later on.
ty::Covariant | ty::Contravariant => (),
}

let origin = variables.origin(vid);
let new_var_id = variables.new_var(false, origin, None);
let u = self.tcx().mk_var(new_var_id);
debug!("generalize: replacing original vid={:?} with new={:?}",
vid, u);
return Ok(u);
}
}
}
}
ty::TyInfer(ty::IntVar(_)) |
ty::TyInfer(ty::FloatVar(_)) => {
// No matter what mode we are in,
// integer/floating-point types must be equal to be
// relatable.
Ok(t)
}
_ => {
t.super_fold_with(self)
relate::super_relate_tys(self, t, t)
}
}
}

fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
fn regions(&mut self, r: ty::Region<'tcx>, r2: ty::Region<'tcx>)
-> RelateResult<'tcx, ty::Region<'tcx>> {
assert_eq!(r, r2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==

match *r {
// Never make variables for regions bound within the type itself,
// nor for erased regions.
ty::ReLateBound(..) |
ty::ReErased => { return r; }
ty::ReErased => {
return Ok(r);
}

// Early-bound regions should really have been substituted away before
// we get to this point.
Expand All @@ -342,15 +443,16 @@ impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx
ty::ReScope(..) |
ty::ReVar(..) |
ty::ReFree(..) => {
if self.is_eq_relation {
return r;
match self.ambient_variance {
ty::Invariant => return Ok(r),
ty::Bivariant | ty::Covariant | ty::Contravariant => (),
}
}
}

// FIXME: This is non-ideal because we don't give a
// very descriptive origin for this region variable.
self.infcx.next_region_var(MiscVariable(self.span))
Ok(self.infcx.next_region_var(MiscVariable(self.span)))
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1055,7 +1055,7 @@ impl<'a> ast_visit::Visitor<'a> for EarlyContext<'a> {
run_lints!(self, check_ident, early_passes, sp, id);
}

fn visit_mod(&mut self, m: &'a ast::Mod, s: Span, n: ast::NodeId) {
fn visit_mod(&mut self, m: &'a ast::Mod, s: Span, _a: &[ast::Attribute], n: ast::NodeId) {
run_lints!(self, check_mod, early_passes, m, s, n);
ast_visit::walk_mod(self, m);
run_lints!(self, check_mod_post, early_passes, m, s, n);
Expand Down
14 changes: 7 additions & 7 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,7 @@ pub enum StatementKind<'tcx> {
StorageDead(Lvalue<'tcx>),

InlineAsm {
asm: InlineAsm,
asm: Box<InlineAsm>,
outputs: Vec<Lvalue<'tcx>>,
inputs: Vec<Operand<'tcx>>
},
Expand Down Expand Up @@ -995,7 +995,7 @@ pub struct VisibilityScopeData {
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)]
pub enum Operand<'tcx> {
Consume(Lvalue<'tcx>),
Constant(Constant<'tcx>),
Constant(Box<Constant<'tcx>>),
}

impl<'tcx> Debug for Operand<'tcx> {
Expand All @@ -1015,7 +1015,7 @@ impl<'tcx> Operand<'tcx> {
substs: &'tcx Substs<'tcx>,
span: Span,
) -> Self {
Operand::Constant(Constant {
Operand::Constant(box Constant {
span: span,
ty: tcx.type_of(def_id).subst(tcx, substs),
literal: Literal::Value { value: ConstVal::Function(def_id, substs) },
Expand Down Expand Up @@ -1062,7 +1062,7 @@ pub enum Rvalue<'tcx> {
/// ..., y: ... }` from `dest.x = ...; dest.y = ...;` in the case
/// that `Foo` has a destructor. These rvalues can be optimized
/// away after type-checking and before lowering.
Aggregate(AggregateKind<'tcx>, Vec<Operand<'tcx>>),
Aggregate(Box<AggregateKind<'tcx>>, Vec<Operand<'tcx>>),
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
Expand Down Expand Up @@ -1185,7 +1185,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
tuple_fmt.finish()
}

match *kind {
match **kind {
AggregateKind::Array(_) => write!(fmt, "{:?}", lvs),

AggregateKind::Tuple => {
Expand Down Expand Up @@ -1603,7 +1603,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
Discriminant(ref lval) => Discriminant(lval.fold_with(folder)),
Box(ty) => Box(ty.fold_with(folder)),
Aggregate(ref kind, ref fields) => {
let kind = match *kind {
let kind = box match **kind {
AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)),
AggregateKind::Tuple => AggregateKind::Tuple,
AggregateKind::Adt(def, v, substs, n) =>
Expand Down Expand Up @@ -1631,7 +1631,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
Discriminant(ref lval) => lval.visit_with(visitor),
Box(ty) => ty.visit_with(visitor),
Aggregate(ref kind, ref fields) => {
(match *kind {
(match **kind {
AggregateKind::Array(ty) => ty.visit_with(visitor),
AggregateKind::Tuple => false,
AggregateKind::Adt(_, _, substs, _) => substs.visit_with(visitor),
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/mir/tcx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ impl<'tcx> Rvalue<'tcx> {
tcx.mk_box(t)
}
Rvalue::Aggregate(ref ak, ref ops) => {
match *ak {
match **ak {
AggregateKind::Array(ty) => {
tcx.mk_array(ty, ops.len())
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ macro_rules! make_mir_visitor {

Rvalue::Aggregate(ref $($mutability)* kind,
ref $($mutability)* operands) => {
let kind = &$($mutability)* **kind;
match *kind {
AggregateKind::Array(ref $($mutability)* ty) => {
self.visit_ty(ty);
Expand Down
Loading