about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-07-30 01:40:11 +0000
committerbors <bors@rust-lang.org>2017-07-30 01:40:11 +0000
commit5c71e4ef90ef79c1ac79c4132333cbc80f5b85b9 (patch)
tree1efdfb555e8266e747a7e2c453d0ff84d5613c90
parent53bf7903fa7ebabca85f5937667956177989e345 (diff)
parent16c3fd9f3d3dd6667c1966d6a62e56bf9deed0fd (diff)
downloadrust-5c71e4ef90ef79c1ac79c4132333cbc80f5b85b9.tar.gz
rust-5c71e4ef90ef79c1ac79c4132333cbc80f5b85b9.zip
Auto merge of #43551 - Mark-Simulacrum:rollup, r=Mark-Simulacrum
Rollup of 8 pull requests

- Successful merges: #43409, #43501, #43509, #43512, #43513, #43536, #43544, #43549
- Failed merges:
-rw-r--r--src/bootstrap/builder.rs4
-rw-r--r--src/bootstrap/native.rs4
-rwxr-xr-xsrc/ci/docker/run.sh7
-rw-r--r--src/liballoc/allocator.rs1
-rw-r--r--src/libcore/iter/traits.rs33
-rw-r--r--src/librustc/ich/impls_mir.rs16
-rw-r--r--src/librustc/mir/mod.rs20
-rw-r--r--src/librustc_mir/dataflow/move_paths/abs_domain.rs11
-rw-r--r--src/librustdoc/html/render.rs10
-rw-r--r--src/librustdoc/html/static/rustdoc.css4
-rw-r--r--src/libstd/sys/redox/ext/mod.rs3
-rw-r--r--src/libstd/sys/redox/ext/thread.rs47
-rw-r--r--src/libstd/sys/redox/fd.rs4
-rw-r--r--src/libstd/sys/redox/process.rs12
-rw-r--r--src/libstd/sys/redox/syscall/flag.rs6
-rw-r--r--src/libsyntax/ast.rs2
-rw-r--r--src/libsyntax/fold.rs5
-rw-r--r--src/libsyntax/parse/mod.rs1
-rw-r--r--src/libsyntax/parse/parser.rs4
-rw-r--r--src/libsyntax/print/pprust.rs2
-rw-r--r--src/libsyntax_ext/deriving/generic/ty.rs1
-rw-r--r--src/test/codegen/vec-optimizes-away.rs21
22 files changed, 160 insertions, 58 deletions
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 2f6e3ca9253..811c7df5d99 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -28,6 +28,7 @@ use check;
 use flags::Subcommand;
 use doc;
 use tool;
+use native;
 
 pub use Compiler;
 
@@ -256,7 +257,8 @@ impl<'a> Builder<'a> {
                 compile::StartupObjects, tool::BuildManifest, tool::Rustbook, tool::ErrorIndex,
                 tool::UnstableBookGen, tool::Tidy, tool::Linkchecker, tool::CargoTest,
                 tool::Compiletest, tool::RemoteTestServer, tool::RemoteTestClient,
-                tool::RustInstaller, tool::Cargo, tool::Rls, tool::Rustdoc),
+                tool::RustInstaller, tool::Cargo, tool::Rls, tool::Rustdoc,
+                native::Llvm),
             Kind::Test => describe!(check::Tidy, check::Bootstrap, check::DefaultCompiletest,
                 check::HostCompiletest, check::Crate, check::CrateLibrustc, check::Linkcheck,
                 check::Cargotest, check::Cargo, check::Rls, check::Docs, check::ErrorIndex,
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index bb80674c887..1da277cf181 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -48,6 +48,10 @@ impl Step for Llvm {
         run.path("src/llvm")
     }
 
+    fn make_run(run: RunConfig) {
+        run.builder.ensure(Llvm { target: run.target })
+    }
+
     /// Compile LLVM for `target`.
     fn run(self, builder: &Builder) {
         let build = builder.build;
diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh
index da74ffb41ff..d3f339bc15f 100755
--- a/src/ci/docker/run.sh
+++ b/src/ci/docker/run.sh
@@ -67,6 +67,13 @@ else
     args="$args --env SCCACHE_DIR=/sccache --volume $HOME/.cache/sccache:/sccache"
 fi
 
+# Run containers as privileged as it should give them access to some more
+# syscalls such as ptrace and whatnot. In the upgrade to LLVM 5.0 it was
+# discovered that the leak sanitizer apparently needs these syscalls nowadays so
+# we'll need `--privileged` for at least the `x86_64-gnu` builder, so this just
+# goes ahead and sets it for all builders.
+args="$args --privileged"
+
 exec docker \
   run \
   --volume "$root_dir:/checkout:ro" \
diff --git a/src/liballoc/allocator.rs b/src/liballoc/allocator.rs
index 66e0bf81c90..42111301a9f 100644
--- a/src/liballoc/allocator.rs
+++ b/src/liballoc/allocator.rs
@@ -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,
diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs
index d35aa026685..ccfeb91aff1 100644
--- a/src/libcore/iter/traits.rs
+++ b/src/libcore/iter/traits.rs
@@ -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:
 ///
 /// ```
@@ -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;
diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs
index cb017b7f886..6dadb702b9f 100644
--- a/src/librustc/ich/impls_mir.rs
+++ b/src/librustc/ich/impls_mir.rs
@@ -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>,
@@ -276,9 +277,10 @@ 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>,
@@ -286,7 +288,7 @@ for mir::ProjectionElem<'tcx, V>
         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);
             }
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index d78e17ce03c..3dcd64af2ed 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -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
@@ -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");
 
@@ -1720,8 +1720,8 @@ 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::*;
@@ -1729,7 +1729,7 @@ impl<'tcx, B, V> TypeFoldable<'tcx> for Projection<'tcx, B, V>
         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()
         };
@@ -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
             }
diff --git a/src/librustc_mir/dataflow/move_paths/abs_domain.rs b/src/librustc_mir/dataflow/move_paths/abs_domain.rs
index 5e61c2ec7a2..1255209322b 100644
--- a/src/librustc_mir/dataflow/move_paths/abs_domain.rs
+++ b/src/librustc_mir/dataflow/move_paths/abs_domain.rs
@@ -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;
@@ -37,6 +40,10 @@ 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 {
@@ -44,7 +51,7 @@ impl<'tcx> Lift for LvalueElem<'tcx> {
             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} =>
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index e89bd7aae9b..bf524705dc7 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -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")?;
                 }
             }
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index 9314f57359a..858ef3bf411 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -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;
 }
diff --git a/src/libstd/sys/redox/ext/mod.rs b/src/libstd/sys/redox/ext/mod.rs
index 513ef272e97..0c1bf9e9557 100644
--- a/src/libstd/sys/redox/ext/mod.rs
+++ b/src/libstd/sys/redox/ext/mod.rs
@@ -33,6 +33,7 @@ pub mod ffi;
 pub mod fs;
 pub mod io;
 pub mod process;
+pub mod thread;
 
 /// A prelude for conveniently writing platform-specific code.
 ///
@@ -46,5 +47,7 @@ pub mod prelude {
     #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
     pub use super::fs::{FileTypeExt, PermissionsExt, OpenOptionsExt, MetadataExt};
     #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
+    pub use super::thread::JoinHandleExt;
+    #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
     pub use super::process::{CommandExt, ExitStatusExt};
 }
diff --git a/src/libstd/sys/redox/ext/thread.rs b/src/libstd/sys/redox/ext/thread.rs
new file mode 100644
index 00000000000..52be2ccd9f9
--- /dev/null
+++ b/src/libstd/sys/redox/ext/thread.rs
@@ -0,0 +1,47 @@
+// Copyright 2015 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.
+
+//! Unix-specific extensions to primitives in the `std::thread` module.
+
+#![stable(feature = "thread_extensions", since = "1.9.0")]
+
+use sys_common::{AsInner, IntoInner};
+use thread::JoinHandle;
+
+#[stable(feature = "thread_extensions", since = "1.9.0")]
+#[allow(deprecated)]
+pub type RawPthread = usize;
+
+/// Unix-specific extensions to `std::thread::JoinHandle`
+#[stable(feature = "thread_extensions", since = "1.9.0")]
+pub trait JoinHandleExt {
+    /// Extracts the raw pthread_t without taking ownership
+    #[stable(feature = "thread_extensions", since = "1.9.0")]
+    fn as_pthread_t(&self) -> RawPthread;
+
+    /// Consumes the thread, returning the raw pthread_t
+    ///
+    /// This function **transfers ownership** of the underlying pthread_t to
+    /// the caller. Callers are then the unique owners of the pthread_t and
+    /// must either detach or join the pthread_t once it's no longer needed.
+    #[stable(feature = "thread_extensions", since = "1.9.0")]
+    fn into_pthread_t(self) -> RawPthread;
+}
+
+#[stable(feature = "thread_extensions", since = "1.9.0")]
+impl<T> JoinHandleExt for JoinHandle<T> {
+    fn as_pthread_t(&self) -> RawPthread {
+        self.as_inner().id() as RawPthread
+    }
+
+    fn into_pthread_t(self) -> RawPthread {
+        self.into_inner().into_id() as RawPthread
+    }
+}
diff --git a/src/libstd/sys/redox/fd.rs b/src/libstd/sys/redox/fd.rs
index 1b37aafef56..ba7bbdc657f 100644
--- a/src/libstd/sys/redox/fd.rs
+++ b/src/libstd/sys/redox/fd.rs
@@ -57,9 +57,9 @@ impl FileDesc {
     }
 
     pub fn set_cloexec(&self) -> io::Result<()> {
-        let mut flags = cvt(syscall::fcntl(self.fd, syscall::F_GETFL, 0))?;
+        let mut flags = cvt(syscall::fcntl(self.fd, syscall::F_GETFD, 0))?;
         flags |= syscall::O_CLOEXEC;
-        cvt(syscall::fcntl(self.fd, syscall::F_SETFL, flags)).and(Ok(()))
+        cvt(syscall::fcntl(self.fd, syscall::F_SETFD, flags)).and(Ok(()))
     }
 
     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs
index ff1626d9b31..17fa07b99ae 100644
--- a/src/libstd/sys/redox/process.rs
+++ b/src/libstd/sys/redox/process.rs
@@ -272,21 +272,21 @@ impl Command {
 
         if let Some(fd) = stdio.stderr.fd() {
             t!(cvt(syscall::dup2(fd, 2, &[])));
-            let mut flags = t!(cvt(syscall::fcntl(2, syscall::F_GETFL, 0)));
+            let mut flags = t!(cvt(syscall::fcntl(2, syscall::F_GETFD, 0)));
             flags &= ! syscall::O_CLOEXEC;
-            t!(cvt(syscall::fcntl(2, syscall::F_SETFL, flags)));
+            t!(cvt(syscall::fcntl(2, syscall::F_SETFD, flags)));
         }
         if let Some(fd) = stdio.stdout.fd() {
             t!(cvt(syscall::dup2(fd, 1, &[])));
-            let mut flags = t!(cvt(syscall::fcntl(1, syscall::F_GETFL, 0)));
+            let mut flags = t!(cvt(syscall::fcntl(1, syscall::F_GETFD, 0)));
             flags &= ! syscall::O_CLOEXEC;
-            t!(cvt(syscall::fcntl(1, syscall::F_SETFL, flags)));
+            t!(cvt(syscall::fcntl(1, syscall::F_SETFD, flags)));
         }
         if let Some(fd) = stdio.stdin.fd() {
             t!(cvt(syscall::dup2(fd, 0, &[])));
-            let mut flags = t!(cvt(syscall::fcntl(0, syscall::F_GETFL, 0)));
+            let mut flags = t!(cvt(syscall::fcntl(0, syscall::F_GETFD, 0)));
             flags &= ! syscall::O_CLOEXEC;
-            t!(cvt(syscall::fcntl(0, syscall::F_SETFL, flags)));
+            t!(cvt(syscall::fcntl(0, syscall::F_SETFD, flags)));
         }
 
         if let Some(g) = self.gid {
diff --git a/src/libstd/sys/redox/syscall/flag.rs b/src/libstd/sys/redox/syscall/flag.rs
index 65ad9842d69..892007df2b7 100644
--- a/src/libstd/sys/redox/syscall/flag.rs
+++ b/src/libstd/sys/redox/syscall/flag.rs
@@ -20,8 +20,10 @@ pub const EVENT_NONE: usize = 0;
 pub const EVENT_READ: usize = 1;
 pub const EVENT_WRITE: usize = 2;
 
-pub const F_GETFL: usize = 1;
-pub const F_SETFL: usize = 2;
+pub const F_GETFD: usize = 1;
+pub const F_SETFD: usize = 2;
+pub const F_GETFL: usize = 3;
+pub const F_SETFL: usize = 4;
 
 pub const FUTEX_WAIT: usize = 0;
 pub const FUTEX_WAKE: usize = 1;
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 2b28194c149..857d9a753cc 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -336,6 +336,7 @@ impl Default for Generics {
             where_clause: WhereClause {
                 id: DUMMY_NODE_ID,
                 predicates: Vec::new(),
+                span: DUMMY_SP,
             },
             span: DUMMY_SP,
         }
@@ -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
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 279f63d13a4..a54e2573af4 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -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,
     }
 }
 
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 45e0b8404cc..7b105a8fa14 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -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,
                                     },
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 1cb5a8111dc..ca362ec9368 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -4301,6 +4301,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),
             })
@@ -4368,11 +4369,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.
         //
@@ -4450,6 +4453,7 @@ impl<'a> Parser<'a> {
             }
         }
 
+        where_clause.span = lo.to(self.prev_span);
         Ok(where_clause)
     }
 
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index b052b2cdbbb..e9d11e73837 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -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,
                 };
@@ -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,
         };
diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs
index 9c89f99cbb5..f5ac1743920 100644
--- a/src/libsyntax_ext/deriving/generic/ty.rs
+++ b/src/libsyntax_ext/deriving/generic/ty.rs
@@ -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,
     }
diff --git a/src/test/codegen/vec-optimizes-away.rs b/src/test/codegen/vec-optimizes-away.rs
new file mode 100644
index 00000000000..261564ed51a
--- /dev/null
+++ b/src/test/codegen/vec-optimizes-away.rs
@@ -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: {{^.*:$}}
+    // CHECK-NEXT: ret i32 6
+    vec![1, 2, 3].iter().sum::<i32>()
+}