about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-04-30 17:30:55 +0000
committerbors <bors@rust-lang.org>2018-04-30 17:30:55 +0000
commit17841cc97ac950312355403b6cfe11b916e242a6 (patch)
tree5bd04ce4f05ca35b78d7612b13bf3a15f4e49655
parent4745092d608e65ec869c0ebdb27c535f27606ea4 (diff)
parent6166f20571aeadc3e0790ab79b642b0a1d41169d (diff)
downloadrust-17841cc97ac950312355403b6cfe11b916e242a6.tar.gz
rust-17841cc97ac950312355403b6cfe11b916e242a6.zip
Auto merge of #50345 - kennytm:rollup, r=kennytm
Rollup of 7 pull requests

Successful merges:

 - #50233 (Make `Vec::new` a `const fn`)
 - #50312 (Add more links in panic docs)
 - #50316 (Fix some broken links in docs.)
 - #50325 (Add a few more tests for proc macro feature gating)
 - #50327 (Display correct unused field suggestion for nested struct patterns)
 - #50330 (check that #[used] is used only on statics)
 - #50344 (Update Cargo to 2018-04-28 122fd5be5201913d42e219e132d6569493583bca)

Failed merges:
-rw-r--r--src/liballoc/lib.rs1
-rw-r--r--src/liballoc/raw_vec.rs10
-rw-r--r--src/liballoc/vec.rs3
-rw-r--r--src/libcore/iter/iterator.rs2
-rw-r--r--src/libcore/marker.rs2
-rw-r--r--src/libcore/ptr.rs5
-rw-r--r--src/librustc/hir/check_attr.rs12
-rw-r--r--src/librustc/middle/liveness.rs44
-rw-r--r--src/libstd/collections/hash/table.rs2
-rw-r--r--src/libstd/ffi/c_str.rs1
-rw-r--r--src/libstd/panic.rs51
-rw-r--r--src/libstd/panicking.rs8
-rw-r--r--src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs55
-rw-r--r--src/test/compile-fail/used.rs28
-rw-r--r--src/test/run-pass/vec-const-new.rs17
-rw-r--r--src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs43
-rw-r--r--src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr48
m---------src/tools/cargo0
18 files changed, 276 insertions, 56 deletions
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 021395d0c82..0493f92bc52 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -124,6 +124,7 @@
 #![feature(pointer_methods)]
 #![feature(inclusive_range_fields)]
 #![cfg_attr(stage0, feature(generic_param_attrs))]
+#![feature(rustc_const_unstable)]
 
 #![cfg_attr(not(test), feature(fn_traits, i128))]
 #![cfg_attr(test, feature(test))]
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index 7ef0a27fc72..eb25ae17511 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -56,14 +56,16 @@ pub struct RawVec<T, A: Alloc = Global> {
 impl<T, A: Alloc> RawVec<T, A> {
     /// Like `new` but parameterized over the choice of allocator for
     /// the returned RawVec.
-    pub fn new_in(a: A) -> Self {
+    pub const fn new_in(a: A) -> Self {
         // !0 is usize::MAX. This branch should be stripped at compile time.
-        let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
+        // FIXME(mark-i-m): use this line when `if`s are allowed in `const`
+        //let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
 
         // Unique::empty() doubles as "unallocated" and "zero-sized allocation"
         RawVec {
             ptr: Unique::empty(),
-            cap,
+            // FIXME(mark-i-m): use `cap` when ifs are allowed in const
+            cap: [0, !0][(mem::size_of::<T>() == 0) as usize],
             a,
         }
     }
@@ -120,7 +122,7 @@ impl<T> RawVec<T, Global> {
     /// RawVec with capacity 0. If T has 0 size, then it makes a
     /// RawVec with capacity `usize::MAX`. Useful for implementing
     /// delayed allocation.
-    pub fn new() -> Self {
+    pub const fn new() -> Self {
         Self::new_in(Global)
     }
 
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index b184404c15b..35d0a69a05a 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -322,7 +322,8 @@ impl<T> Vec<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn new() -> Vec<T> {
+    #[rustc_const_unstable(feature = "const_vec_new")]
+    pub const fn new() -> Vec<T> {
         Vec {
             buf: RawVec::new(),
             len: 0,
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs
index 6a77de2c986..b27bd3142e1 100644
--- a/src/libcore/iter/iterator.rs
+++ b/src/libcore/iter/iterator.rs
@@ -1094,6 +1094,8 @@ pub trait Iterator {
     /// `flatten()` a three-dimensional array the result will be
     /// two-dimensional and not one-dimensional. To get a one-dimensional
     /// structure, you have to `flatten()` again.
+    ///
+    /// [`flat_map()`]: #method.flat_map
     #[inline]
     #[unstable(feature = "iterator_flatten", issue = "48213")]
     fn flatten(self) -> Flatten<Self>
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index feb689dbc1f..c074adfd570 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -602,6 +602,8 @@ unsafe impl<'a, T: ?Sized> Freeze for &'a mut T {}
 /// `Pin` pointer.
 ///
 /// This trait is automatically implemented for almost every type.
+///
+/// [`Pin`]: ../mem/struct.Pin.html
 #[unstable(feature = "pin", issue = "49150")]
 pub unsafe auto trait Unpin {}
 
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index c61bdfc9c4f..5d0b675e8e4 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -2552,10 +2552,9 @@ impl<T: Sized> Unique<T> {
     /// This is useful for initializing types which lazily allocate, like
     /// `Vec::new` does.
     // FIXME: rename to dangling() to match NonNull?
-    pub fn empty() -> Self {
+    pub const fn empty() -> Self {
         unsafe {
-            let ptr = mem::align_of::<T>() as *mut T;
-            Unique::new_unchecked(ptr)
+            Unique::new_unchecked(mem::align_of::<T>() as *mut T)
         }
     }
 }
diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs
index 19f8d15662d..cad6ff8ae9f 100644
--- a/src/librustc/hir/check_attr.rs
+++ b/src/librustc/hir/check_attr.rs
@@ -31,6 +31,7 @@ enum Target {
     Expression,
     Statement,
     Closure,
+    Static,
     Other,
 }
 
@@ -43,6 +44,7 @@ impl Target {
             hir::ItemEnum(..) => Target::Enum,
             hir::ItemConst(..) => Target::Const,
             hir::ItemForeignMod(..) => Target::ForeignMod,
+            hir::ItemStatic(..) => Target::Static,
             _ => Target::Other,
         }
     }
@@ -102,6 +104,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
         }
 
         self.check_repr(item, target);
+        self.check_used(item, target);
     }
 
     /// Check if an `#[inline]` is applied to a function or a closure.
@@ -305,6 +308,15 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
             }
         }
     }
+
+    fn check_used(&self, item: &hir::Item, target: Target) {
+        for attr in &item.attrs {
+            if attr.name().map(|name| name == "used").unwrap_or(false) && target != Target::Static {
+                self.tcx.sess
+                    .span_err(attr.span, "attribute must be applied to a `static` variable");
+            }
+        }
+    }
 }
 
 impl<'a, 'tcx> Visitor<'tcx> for CheckAttrVisitor<'a, 'tcx> {
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 17c114bc3b3..d1a46f5f155 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -111,6 +111,7 @@ use ty::{self, TyCtxt};
 use lint;
 use util::nodemap::{NodeMap, NodeSet};
 
+use std::collections::VecDeque;
 use std::{fmt, usize};
 use std::io::prelude::*;
 use std::io;
@@ -412,18 +413,43 @@ fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) {
 }
 
 fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) {
-    for pat in &arm.pats {
-        // for struct patterns, take note of which fields used shorthand (`x` rather than `x: x`)
+    for mut pat in &arm.pats {
+        // For struct patterns, take note of which fields used shorthand
+        // (`x` rather than `x: x`).
         //
-        // FIXME: according to the rust-lang-nursery/rustc-guide book, `NodeId`s are to be phased
-        // out in favor of `HirId`s; however, we need to match the signature of `each_binding`,
-        // which uses `NodeIds`.
+        // FIXME: according to the rust-lang-nursery/rustc-guide book, `NodeId`s are to be
+        // phased out in favor of `HirId`s; however, we need to match the signature of
+        // `each_binding`, which uses `NodeIds`.
         let mut shorthand_field_ids = NodeSet();
-        if let hir::PatKind::Struct(_, ref fields, _) = pat.node {
-            for field in fields {
-                if field.node.is_shorthand {
-                    shorthand_field_ids.insert(field.node.pat.id);
+        let mut pats = VecDeque::new();
+        pats.push_back(pat);
+        while let Some(pat) = pats.pop_front() {
+            use hir::PatKind::*;
+            match pat.node {
+                Binding(_, _, _, ref inner_pat) => {
+                    pats.extend(inner_pat.iter());
                 }
+                Struct(_, ref fields, _) => {
+                    for field in fields {
+                        if field.node.is_shorthand {
+                            shorthand_field_ids.insert(field.node.pat.id);
+                        }
+                    }
+                }
+                Ref(ref inner_pat, _) |
+                Box(ref inner_pat) => {
+                    pats.push_back(inner_pat);
+                }
+                TupleStruct(_, ref inner_pats, _) |
+                Tuple(ref inner_pats, _) => {
+                    pats.extend(inner_pats.iter());
+                }
+                Slice(ref pre_pats, ref inner_pat, ref post_pats) => {
+                    pats.extend(pre_pats.iter());
+                    pats.extend(inner_pat.iter());
+                    pats.extend(post_pats.iter());
+                }
+                _ => {}
             }
         }
 
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index 52c53dc3b12..b50652ed6b5 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -79,7 +79,7 @@ impl TaggedHashUintPtr {
 ///
 /// Essential invariants of this structure:
 ///
-///   - if t.hashes[i] == EMPTY_BUCKET, then `Bucket::at_index(&t, i).raw`
+///   - if `t.hashes[i] == EMPTY_BUCKET`, then `Bucket::at_index(&t, i).raw`
 ///     points to 'undefined' contents. Don't read from it. This invariant is
 ///     enforced outside this module with the `EmptyBucket`, `FullBucket`,
 ///     and `SafeHash` types.
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index c88c2bc9137..8164f52d3c3 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -1118,6 +1118,7 @@ impl CStr {
     ///
     /// [`Cow`]: ../borrow/enum.Cow.html
     /// [`Borrowed`]: ../borrow/enum.Cow.html#variant.Borrowed
+    /// [`Owned`]: ../borrow/enum.Cow.html#variant.Owned
     /// [`str`]: ../primitive.str.html
     /// [`String`]: ../string/struct.String.html
     ///
diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs
index 28c178307a5..229034eb779 100644
--- a/src/libstd/panic.rs
+++ b/src/libstd/panic.rs
@@ -31,10 +31,14 @@ pub use core::panic::{PanicInfo, Location};
 /// A marker trait which represents "panic safe" types in Rust.
 ///
 /// This trait is implemented by default for many types and behaves similarly in
-/// terms of inference of implementation to the `Send` and `Sync` traits. The
-/// purpose of this trait is to encode what types are safe to cross a `catch_unwind`
+/// terms of inference of implementation to the [`Send`] and [`Sync`] traits. The
+/// purpose of this trait is to encode what types are safe to cross a [`catch_unwind`]
 /// boundary with no fear of unwind safety.
 ///
+/// [`Send`]: ../marker/trait.Send.html
+/// [`Sync`]: ../marker/trait.Sync.html
+/// [`catch_unwind`]: ./fn.catch_unwind.html
+///
 /// ## What is unwind safety?
 ///
 /// In Rust a function can "return" early if it either panics or calls a
@@ -95,12 +99,13 @@ pub use core::panic::{PanicInfo, Location};
 ///
 /// ## When should `UnwindSafe` be used?
 ///
-/// Is not intended that most types or functions need to worry about this trait.
-/// It is only used as a bound on the `catch_unwind` function and as mentioned above,
-/// the lack of `unsafe` means it is mostly an advisory. The `AssertUnwindSafe`
-/// wrapper struct in this module can be used to force this trait to be
-/// implemented for any closed over variables passed to the `catch_unwind` function
-/// (more on this below).
+/// It is not intended that most types or functions need to worry about this trait.
+/// It is only used as a bound on the `catch_unwind` function and as mentioned
+/// above, the lack of `unsafe` means it is mostly an advisory. The
+/// [`AssertUnwindSafe`] wrapper struct can be used to force this trait to be
+/// implemented for any closed over variables passed to `catch_unwind`.
+///
+/// [`AssertUnwindSafe`]: ./struct.AssertUnwindSafe.html
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 #[rustc_on_unimplemented = "the type {Self} may not be safely transferred \
                             across an unwind boundary"]
@@ -109,11 +114,14 @@ pub auto trait UnwindSafe {}
 /// A marker trait representing types where a shared reference is considered
 /// unwind safe.
 ///
-/// This trait is namely not implemented by `UnsafeCell`, the root of all
+/// This trait is namely not implemented by [`UnsafeCell`], the root of all
 /// interior mutability.
 ///
 /// This is a "helper marker trait" used to provide impl blocks for the
-/// `UnwindSafe` trait, for more information see that documentation.
+/// [`UnwindSafe`] trait, for more information see that documentation.
+///
+/// [`UnsafeCell`]: ../cell/struct.UnsafeCell.html
+/// [`UnwindSafe`]: ./trait.UnwindSafe.html
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 #[rustc_on_unimplemented = "the type {Self} may contain interior mutability \
                             and a reference may not be safely transferrable \
@@ -122,14 +130,15 @@ pub auto trait RefUnwindSafe {}
 
 /// A simple wrapper around a type to assert that it is unwind safe.
 ///
-/// When using `catch_unwind` it may be the case that some of the closed over
+/// When using [`catch_unwind`] it may be the case that some of the closed over
 /// variables are not unwind safe. For example if `&mut T` is captured the
 /// compiler will generate a warning indicating that it is not unwind safe. It
 /// may not be the case, however, that this is actually a problem due to the
-/// specific usage of `catch_unwind` if unwind safety is specifically taken into
+/// specific usage of [`catch_unwind`] if unwind safety is specifically taken into
 /// account. This wrapper struct is useful for a quick and lightweight
 /// annotation that a variable is indeed unwind safe.
 ///
+/// [`catch_unwind`]: ./fn.catch_unwind.html
 /// # Examples
 ///
 /// One way to use `AssertUnwindSafe` is to assert that the entire closure
@@ -318,18 +327,22 @@ impl<T: fmt::Debug> fmt::Debug for AssertUnwindSafe<T> {
 /// panic and allowing a graceful handling of the error.
 ///
 /// It is **not** recommended to use this function for a general try/catch
-/// mechanism. The `Result` type is more appropriate to use for functions that
+/// mechanism. The [`Result`] type is more appropriate to use for functions that
 /// can fail on a regular basis. Additionally, this function is not guaranteed
 /// to catch all panics, see the "Notes" section below.
 ///
-/// The closure provided is required to adhere to the `UnwindSafe` trait to ensure
+/// [`Result`]: ../result/enum.Result.html
+///
+/// The closure provided is required to adhere to the [`UnwindSafe`] trait to ensure
 /// that all captured variables are safe to cross this boundary. The purpose of
 /// this bound is to encode the concept of [exception safety][rfc] in the type
 /// system. Most usage of this function should not need to worry about this
 /// bound as programs are naturally unwind safe without `unsafe` code. If it
-/// becomes a problem the associated `AssertUnwindSafe` wrapper type in this
-/// module can be used to quickly assert that the usage here is indeed unwind
-/// safe.
+/// becomes a problem the [`AssertUnwindSafe`] wrapper struct can be used to quickly
+/// assert that the usage here is indeed unwind safe.
+///
+/// [`AssertUnwindSafe`]: ./struct.AssertUnwindSafe.html
+/// [`UnwindSafe`]: ./trait.UnwindSafe.html
 ///
 /// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md
 ///
@@ -364,9 +377,11 @@ pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
 
 /// Triggers a panic without invoking the panic hook.
 ///
-/// This is designed to be used in conjunction with `catch_unwind` to, for
+/// This is designed to be used in conjunction with [`catch_unwind`] to, for
 /// example, carry a panic across a layer of C code.
 ///
+/// [`catch_unwind`]: ./fn.catch_unwind.html
+///
 /// # Notes
 ///
 /// Note that panics in Rust are not always implemented via unwinding, but they
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 24eae6a4c82..403056240bf 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -76,7 +76,9 @@ static mut HOOK: Hook = Hook::Default;
 /// is invoked. As such, the hook will run with both the aborting and unwinding
 /// runtimes. The default hook prints a message to standard error and generates
 /// a backtrace if requested, but this behavior can be customized with the
-/// `set_hook` and `take_hook` functions.
+/// `set_hook` and [`take_hook`] functions.
+///
+/// [`take_hook`]: ./fn.take_hook.html
 ///
 /// The hook is provided with a `PanicInfo` struct which contains information
 /// about the origin of the panic, including the payload passed to `panic!` and
@@ -121,6 +123,10 @@ pub fn set_hook(hook: Box<Fn(&PanicInfo) + 'static + Sync + Send>) {
 
 /// Unregisters the current panic hook, returning it.
 ///
+/// *See also the function [`set_hook`].*
+///
+/// [`set_hook`]: ./fn.set_hook.html
+///
 /// If no custom hook is registered, the default hook will be returned.
 ///
 /// # Panics
diff --git a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs
index 0dc1c2ab2da..fff433b90ce 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs
+++ b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs
@@ -24,9 +24,17 @@ use foo::*;
 #[foo::a] //~ ERROR: paths of length greater than one
 fn _test() {}
 
+fn _test_inner() {
+    #![a] // OK
+}
+
 #[a] //~ ERROR: custom attributes cannot be applied to modules
 mod _test2 {}
 
+mod _test2_inner {
+    #![a] //~ ERROR: custom attributes cannot be applied to modules
+}
+
 #[a = y] //~ ERROR: must only be followed by a delimiter token
 fn _test3() {}
 
@@ -36,19 +44,40 @@ fn _test4() {}
 #[a () = ] //~ ERROR: must only be followed by a delimiter token
 fn _test5() {}
 
-fn main() {
+fn attrs() {
+    // Statement, item
+    #[a] // OK
+    struct S;
+
+    // Statement, macro
+    #[a] //~ ERROR: custom attributes cannot be applied to statements
+    println!();
+
+    // Statement, semi
+    #[a] //~ ERROR: custom attributes cannot be applied to statements
+    S;
+
+    // Statement, local
     #[a] //~ ERROR: custom attributes cannot be applied to statements
     let _x = 2;
-    let _x = #[a] 2;
-    //~^ ERROR: custom attributes cannot be applied to expressions
-
-    let _x: m!(u32) = 3;
-    //~^ ERROR: procedural macros cannot be expanded to types
-    if let m!(Some(_x)) = Some(3) {
-    //~^ ERROR: procedural macros cannot be expanded to patterns
-    }
-    let _x = m!(3);
-    //~^ ERROR: procedural macros cannot be expanded to expressions
-    m!(let _x = 3;);
-    //~^ ERROR: procedural macros cannot be expanded to statements
+
+    // Expr
+    let _x = #[a] 2; //~ ERROR: custom attributes cannot be applied to expressions
+
+    // Opt expr
+    let _x = [#[a] 2]; //~ ERROR: custom attributes cannot be applied to expressions
+
+    // Expr macro
+    let _x = #[a] println!(); //~ ERROR: custom attributes cannot be applied to expressions
+}
+
+fn main() {
+    let _x: m!(u32) = 3; //~ ERROR: procedural macros cannot be expanded to types
+    if let m!(Some(_x)) = Some(3) {} //~ ERROR: procedural macros cannot be expanded to patterns
+
+    m!(struct S;); //~ ERROR: procedural macros cannot be expanded to statements
+    m!(let _x = 3;); //~ ERROR: procedural macros cannot be expanded to statements
+
+    let _x = m!(3); //~ ERROR: procedural macros cannot be expanded to expressions
+    let _x = [m!(3)]; //~ ERROR: procedural macros cannot be expanded to expressions
 }
diff --git a/src/test/compile-fail/used.rs b/src/test/compile-fail/used.rs
new file mode 100644
index 00000000000..f170d9c25f5
--- /dev/null
+++ b/src/test/compile-fail/used.rs
@@ -0,0 +1,28 @@
+// Copyright 2018 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.
+
+#![feature(used)]
+
+#[used]
+static FOO: u32 = 0; // OK
+
+#[used] //~ ERROR attribute must be applied to a `static` variable
+fn foo() {}
+
+#[used] //~ ERROR attribute must be applied to a `static` variable
+struct Foo {}
+
+#[used] //~ ERROR attribute must be applied to a `static` variable
+trait Bar {}
+
+#[used] //~ ERROR attribute must be applied to a `static` variable
+impl Bar for Foo {}
+
+fn main() {}
diff --git a/src/test/run-pass/vec-const-new.rs b/src/test/run-pass/vec-const-new.rs
new file mode 100644
index 00000000000..62e2a36d7cc
--- /dev/null
+++ b/src/test/run-pass/vec-const-new.rs
@@ -0,0 +1,17 @@
+// Copyright 2012 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.
+
+// Test that Vec::new() can be used for constants
+
+#![feature(const_vec_new)]
+
+const MY_VEC: Vec<usize> = Vec::new();
+
+pub fn main() {}
diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs
index 18b83370355..6994a377a06 100644
--- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs
+++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs
@@ -10,6 +10,8 @@
 
 // compile-pass
 
+#![feature(box_syntax)]
+#![feature(box_patterns)]
 #![warn(unused)] // UI tests pass `-A unused` (#43896)
 
 struct SoulHistory {
@@ -18,6 +20,13 @@ struct SoulHistory {
     endless_and_singing: bool
 }
 
+#[derive(Clone, Copy)]
+enum Large {
+    Suit { case: () }
+}
+
+struct Tuple(Large, ());
+
 fn main() {
     let i_think_continually = 2;
     let who_from_the_womb_remembered = SoulHistory {
@@ -31,4 +40,38 @@ fn main() {
                          endless_and_singing: true } = who_from_the_womb_remembered {
         hours_are_suns = false;
     }
+
+    let bag = Large::Suit {
+        case: ()
+    };
+
+    // Plain struct
+    match bag {
+        Large::Suit { case } => {}
+    };
+
+    // Referenced struct
+    match &bag {
+        &Large::Suit { case } => {}
+    };
+
+    // Boxed struct
+    match box bag {
+        box Large::Suit { case } => {}
+    };
+
+    // Tuple with struct
+    match (bag,) {
+        (Large::Suit { case },) => {}
+    };
+
+    // Slice with struct
+    match [bag] {
+        [Large::Suit { case }] => {}
+    };
+
+    // Tuple struct with struct
+    match Tuple(bag, ()) {
+        Tuple(Large::Suit { case }, ()) => {}
+    };
 }
diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
index 35fe5479406..7bfe2c9162e 100644
--- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
+++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
@@ -1,24 +1,24 @@
 warning: unused variable: `i_think_continually`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:22:9
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:31:9
    |
 LL |     let i_think_continually = 2;
    |         ^^^^^^^^^^^^^^^^^^^ help: consider using `_i_think_continually` instead
    |
 note: lint level defined here
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:13:9
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:15:9
    |
 LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
    |         ^^^^^^
    = note: #[warn(unused_variables)] implied by #[warn(unused)]
 
 warning: unused variable: `corridors_of_light`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:29:26
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:38:26
    |
 LL |     if let SoulHistory { corridors_of_light,
    |                          ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _`
 
 warning: variable `hours_are_suns` is assigned to, but never used
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:30:26
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:39:26
    |
 LL |                          mut hours_are_suns,
    |                          ^^^^^^^^^^^^^^^^^^
@@ -26,15 +26,51 @@ LL |                          mut hours_are_suns,
    = note: consider using `_hours_are_suns` instead
 
 warning: value assigned to `hours_are_suns` is never read
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:32:9
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:41:9
    |
 LL |         hours_are_suns = false;
    |         ^^^^^^^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:13:9
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:15:9
    |
 LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
    |         ^^^^^^
    = note: #[warn(unused_assignments)] implied by #[warn(unused)]
 
+warning: unused variable: `case`
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:50:23
+   |
+LL |         Large::Suit { case } => {}
+   |                       ^^^^ help: try ignoring the field: `case: _`
+
+warning: unused variable: `case`
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:55:24
+   |
+LL |         &Large::Suit { case } => {}
+   |                        ^^^^ help: try ignoring the field: `case: _`
+
+warning: unused variable: `case`
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:60:27
+   |
+LL |         box Large::Suit { case } => {}
+   |                           ^^^^ help: try ignoring the field: `case: _`
+
+warning: unused variable: `case`
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:65:24
+   |
+LL |         (Large::Suit { case },) => {}
+   |                        ^^^^ help: try ignoring the field: `case: _`
+
+warning: unused variable: `case`
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:70:24
+   |
+LL |         [Large::Suit { case }] => {}
+   |                        ^^^^ help: try ignoring the field: `case: _`
+
+warning: unused variable: `case`
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:75:29
+   |
+LL |         Tuple(Large::Suit { case }, ()) => {}
+   |                             ^^^^ help: try ignoring the field: `case: _`
+
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 0a1add2d8689ad12a86f6c32d0a5cd0393dc5d8
+Subproject 122fd5be5201913d42e219e132d6569493583bc