Skip to content
Closed
1 change: 1 addition & 0 deletions src/liballoc/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ impl Layout {
/// of each element in the array.
///
/// On arithmetic overflow, returns `None`.
#[inline]
pub fn repeat(&self, n: usize) -> Option<(Self, usize)> {
let padded_size = match self.size.checked_add(self.padding_needed_for(self.align)) {
None => return None,
Expand Down
33 changes: 8 additions & 25 deletions src/libcore/iter/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,22 +147,13 @@ pub trait FromIterator<A>: Sized {
///
/// ```
/// let v = vec![1, 2, 3];
///
/// let mut iter = v.into_iter();
///
/// let n = iter.next();
/// assert_eq!(Some(1), n);
///
/// let n = iter.next();
/// assert_eq!(Some(2), n);
///
/// let n = iter.next();
/// assert_eq!(Some(3), n);
///
/// let n = iter.next();
/// assert_eq!(None, n);
/// assert_eq!(Some(1), iter.next());
/// assert_eq!(Some(2), iter.next());
/// assert_eq!(Some(3), iter.next());
/// assert_eq!(None, iter.next());
/// ```
///
/// Implementing `IntoIterator` for your type:
///
/// ```
Expand Down Expand Up @@ -227,20 +218,12 @@ pub trait IntoIterator {
///
/// ```
/// let v = vec![1, 2, 3];
///
/// let mut iter = v.into_iter();
///
/// let n = iter.next();
/// assert_eq!(Some(1), n);
///
/// let n = iter.next();
/// assert_eq!(Some(2), n);
///
/// let n = iter.next();
/// assert_eq!(Some(3), n);
///
/// let n = iter.next();
/// assert_eq!(None, n);
/// assert_eq!(Some(1), iter.next());
/// assert_eq!(Some(2), iter.next());
/// assert_eq!(Some(3), iter.next());
/// assert_eq!(None, iter.next());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn into_iter(self) -> Self::IntoIter;
Expand Down
16 changes: 9 additions & 7 deletions src/librustc/ich/impls_mir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,11 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::L
}
}

impl<'a, 'gcx, 'tcx, B, V> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
for mir::Projection<'tcx, B, V>
impl<'a, 'gcx, 'tcx, B, V, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
for mir::Projection<'tcx, B, V, T>
where B: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
{
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
Expand All @@ -276,17 +277,18 @@ for mir::Projection<'tcx, B, V>
}
}

impl<'a, 'gcx, 'tcx, V> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
for mir::ProjectionElem<'tcx, V>
where V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
impl<'a, 'gcx, 'tcx, V, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
for mir::ProjectionElem<'tcx, V, T>
where V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
{
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
mir::ProjectionElem::Deref => {}
mir::ProjectionElem::Field(field, ty) => {
mir::ProjectionElem::Field(field, ref ty) => {
field.hash_stable(hcx, hasher);
ty.hash_stable(hcx, hasher);
}
Expand Down
20 changes: 10 additions & 10 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -887,15 +887,15 @@ impl_stable_hash_for!(struct Static<'tcx> {
/// shared between `Constant` and `Lvalue`. See the aliases
/// `LvalueProjection` etc below.
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct Projection<'tcx, B, V> {
pub struct Projection<'tcx, B, V, T> {
pub base: B,
pub elem: ProjectionElem<'tcx, V>,
pub elem: ProjectionElem<'tcx, V, T>,
}

#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum ProjectionElem<'tcx, V> {
pub enum ProjectionElem<'tcx, V, T> {
Deref,
Field(Field, Ty<'tcx>),
Field(Field, T),
Index(V),

/// These indices are generated by slice patterns. Easiest to explain
Expand Down Expand Up @@ -932,11 +932,11 @@ pub enum ProjectionElem<'tcx, V> {

/// Alias for projections as they appear in lvalues, where the base is an lvalue
/// and the index is an operand.
pub type LvalueProjection<'tcx> = Projection<'tcx, Lvalue<'tcx>, Operand<'tcx>>;
pub type LvalueProjection<'tcx> = Projection<'tcx, Lvalue<'tcx>, Operand<'tcx>, Ty<'tcx>>;

/// Alias for projections as they appear in lvalues, where the base is an lvalue
/// and the index is an operand.
pub type LvalueElem<'tcx> = ProjectionElem<'tcx, Operand<'tcx>>;
pub type LvalueElem<'tcx> = ProjectionElem<'tcx, Operand<'tcx>, Ty<'tcx>>;

newtype_index!(Field, "field");

Expand Down Expand Up @@ -1720,16 +1720,16 @@ impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
}
}

impl<'tcx, B, V> TypeFoldable<'tcx> for Projection<'tcx, B, V>
where B: TypeFoldable<'tcx>, V: TypeFoldable<'tcx>
impl<'tcx, B, V, T> TypeFoldable<'tcx> for Projection<'tcx, B, V, T>
where B: TypeFoldable<'tcx>, V: TypeFoldable<'tcx>, T: TypeFoldable<'tcx>
{
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
use mir::ProjectionElem::*;

let base = self.base.fold_with(folder);
let elem = match self.elem {
Deref => Deref,
Field(f, ty) => Field(f, ty.fold_with(folder)),
Field(f, ref ty) => Field(f, ty.fold_with(folder)),
Index(ref v) => Index(v.fold_with(folder)),
ref elem => elem.clone()
};
Expand All @@ -1745,7 +1745,7 @@ impl<'tcx, B, V> TypeFoldable<'tcx> for Projection<'tcx, B, V>

self.base.visit_with(visitor) ||
match self.elem {
Field(_, ty) => ty.visit_with(visitor),
Field(_, ref ty) => ty.visit_with(visitor),
Index(ref v) => v.visit_with(visitor),
_ => false
}
Expand Down
11 changes: 9 additions & 2 deletions src/librustc_mir/dataflow/move_paths/abs_domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@

use rustc::mir::LvalueElem;
use rustc::mir::{Operand, ProjectionElem};
use rustc::ty::Ty;

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct AbstractOperand;
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct AbstractType;
pub type AbstractElem<'tcx> =
ProjectionElem<'tcx, AbstractOperand>;
ProjectionElem<'tcx, AbstractOperand, AbstractType>;

pub trait Lift {
type Abstract;
Expand All @@ -37,14 +40,18 @@ impl<'tcx> Lift for Operand<'tcx> {
type Abstract = AbstractOperand;
fn lift(&self) -> Self::Abstract { AbstractOperand }
}
impl<'tcx> Lift for Ty<'tcx> {
type Abstract = AbstractType;
fn lift(&self) -> Self::Abstract { AbstractType }
}
impl<'tcx> Lift for LvalueElem<'tcx> {
type Abstract = AbstractElem<'tcx>;
fn lift(&self) -> Self::Abstract {
match *self {
ProjectionElem::Deref =>
ProjectionElem::Deref,
ProjectionElem::Field(ref f, ty) =>
ProjectionElem::Field(f.clone(), ty.clone()),
ProjectionElem::Field(f.clone(), ty.lift()),
ProjectionElem::Index(ref i) =>
ProjectionElem::Index(i.lift()),
ProjectionElem::Subslice {from, to} =>
Expand Down
10 changes: 9 additions & 1 deletion src/librustdoc/html/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2962,7 +2962,15 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
write!(w, "<code>")?;
render_assoc_item(w, item, link.anchor(&id), ItemType::Impl)?;
write!(w, "</code>")?;
render_stability_since_raw(w, item.stable_since(), outer_version)?;
if let Some(l) = (Item { cx, item }).src_href() {
write!(w, "</span><span class='out-of-band'>")?;
write!(w, "<div class='ghost'></div>")?;
render_stability_since_raw(w, item.stable_since(), outer_version)?;
write!(w, "<a class='srclink' href='{}' title='{}'>[src]</a>",
l, "goto source code")?;
} else {
render_stability_since_raw(w, item.stable_since(), outer_version)?;
}
write!(w, "</span></h4>\n")?;
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/librustdoc/html/static/rustdoc.css
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,10 @@ h3.impl > .out-of-band {
font-size: 21px;
}

h4.method > .out-of-band {
font-size: 19px;
}

h4 > code, h3 > code, .invisible > code {
position: inherit;
}
Expand Down
2 changes: 2 additions & 0 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ impl Default for Generics {
where_clause: WhereClause {
id: DUMMY_NODE_ID,
predicates: Vec::new(),
span: DUMMY_SP,
},
span: DUMMY_SP,
}
Expand All @@ -347,6 +348,7 @@ impl Default for Generics {
pub struct WhereClause {
pub id: NodeId,
pub predicates: Vec<WherePredicate>,
pub span: Span,
}

/// A single predicate in a `where` clause
Expand Down
5 changes: 3 additions & 2 deletions src/libsyntax/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -737,14 +737,15 @@ pub fn noop_fold_generics<T: Folder>(Generics {ty_params, lifetimes, where_claus
}

pub fn noop_fold_where_clause<T: Folder>(
WhereClause {id, predicates}: WhereClause,
WhereClause {id, predicates, span}: WhereClause,
fld: &mut T)
-> WhereClause {
WhereClause {
id: fld.new_id(id),
predicates: predicates.move_map(|predicate| {
fld.fold_where_predicate(predicate)
})
}),
span: span,
}
}

Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/parse/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,7 @@ mod tests {
where_clause: ast::WhereClause {
id: ast::DUMMY_NODE_ID,
predicates: Vec::new(),
span: syntax_pos::DUMMY_SP,
},
span: syntax_pos::DUMMY_SP,
},
Expand Down
4 changes: 4 additions & 0 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4302,6 +4302,7 @@ impl<'a> Parser<'a> {
where_clause: WhereClause {
id: ast::DUMMY_NODE_ID,
predicates: Vec::new(),
span: syntax_pos::DUMMY_SP,
},
span: span_lo.to(self.prev_span),
})
Expand Down Expand Up @@ -4369,11 +4370,13 @@ impl<'a> Parser<'a> {
let mut where_clause = WhereClause {
id: ast::DUMMY_NODE_ID,
predicates: Vec::new(),
span: syntax_pos::DUMMY_SP,
};

if !self.eat_keyword(keywords::Where) {
return Ok(where_clause);
}
let lo = self.prev_span;

// This is a temporary future proofing.
//
Expand Down Expand Up @@ -4451,6 +4454,7 @@ impl<'a> Parser<'a> {
}
}

where_clause.span = lo.to(self.prev_span);
Ok(where_clause)
}

Expand Down
2 changes: 2 additions & 0 deletions src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1041,6 +1041,7 @@ impl<'a> State<'a> {
where_clause: ast::WhereClause {
id: ast::DUMMY_NODE_ID,
predicates: Vec::new(),
span: syntax_pos::DUMMY_SP,
},
span: syntax_pos::DUMMY_SP,
};
Expand Down Expand Up @@ -2983,6 +2984,7 @@ impl<'a> State<'a> {
where_clause: ast::WhereClause {
id: ast::DUMMY_NODE_ID,
predicates: Vec::new(),
span: syntax_pos::DUMMY_SP,
},
span: syntax_pos::DUMMY_SP,
};
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax_ext/deriving/generic/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ fn mk_generics(lifetimes: Vec<ast::LifetimeDef>, ty_params: Vec<ast::TyParam>, s
where_clause: ast::WhereClause {
id: ast::DUMMY_NODE_ID,
predicates: Vec::new(),
span: span,
},
span: span,
}
Expand Down
21 changes: 21 additions & 0 deletions src/test/codegen/vec-optimizes-away.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// no-system-llvm
// compile-flags: -O
#![crate_type="lib"]

#[no_mangle]
pub fn sum_me() -> i32 {
// CHECK-LABEL: @sum_me
// CHECK-NEXT: bb{{.*}}:
// CHECK-NEXT: ret i32 6
vec![1, 2, 3].iter().sum::<i32>()
}