about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-05-19 22:33:57 +0000
committerbors <bors@rust-lang.org>2018-05-19 22:33:57 +0000
commit3ea24915894d49cb93eab52e65f1e4f0baa1bc32 (patch)
treef38831d29ae06bc543df2e693d0135868c849128
parenta3085756edf66459109c4b07948b08fe3e78bc3b (diff)
parentada5feedda21ed5baab6cce914d26eaff0d7e7c4 (diff)
Auto merge of #50893 - kennytm:rollup, r=kennytm
Rollup of 8 pull requests

Successful merges:

 - #50531 (Cleanup uses of TypeIdHasher and replace them with StableHasher)
 - #50819 (Fix potential divide by zero)
 - #50827 (Update LLVM to 56c931901cfb85cd6f7ed44c7d7520a8de1edf97)
 - #50829 (CheckLoopVisitor: also visit break expressions)
 - #50854 (in which the unused shorthand field pattern debacle/saga continues)
 - #50858 (Reorder description for snippets in rustdoc documentation)
 - #50883 (Fix warning when building stage0 libcore)
 - #50889 (Update clippy)

Failed merges:
-rw-r--r--src/Cargo.lock28
-rw-r--r--src/Cargo.toml1
-rw-r--r--src/doc/rustdoc/src/documentation-tests.md16
-rw-r--r--src/libcore/slice/mod.rs1
-rw-r--r--src/librustc/ich/impls_ty.rs2
-rw-r--r--src/librustc/middle/liveness.rs106
-rw-r--r--src/librustc/ty/util.rs151
-rw-r--r--src/librustc_codegen_llvm/abi.rs8
-rw-r--r--src/librustc_codegen_llvm/debuginfo/metadata.rs17
-rw-r--r--src/librustc_codegen_utils/symbol_names.rs136
-rw-r--r--src/librustc_passes/loops.rs2
m---------src/llvm0
-rw-r--r--src/rustllvm/llvm-rebuild-trigger2
-rw-r--r--src/test/ui/issue-50761.rs33
-rw-r--r--src/test/ui/issue-50802.rs18
-rw-r--r--src/test/ui/issue-50802.stderr9
-rw-r--r--src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs9
-rw-r--r--src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr36
m---------src/tools/clippy25
19 files changed, 273 insertions, 327 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock
index 64f550be514..8c2d8fc989b 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -288,12 +288,12 @@ dependencies = [
 
 [[package]]
 name = "clippy"
-version = "0.0.200"
+version = "0.0.202"
 dependencies = [
  "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "clippy-mini-macro-test 0.2.0",
- "clippy_lints 0.0.200",
+ "clippy_lints 0.0.202",
  "compiletest_rs 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -311,6 +311,27 @@ version = "0.2.0"
 [[package]]
 name = "clippy_lints"
 version = "0.0.200"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "clippy_lints"
+version = "0.0.202"
 dependencies = [
  "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1624,7 +1645,7 @@ version = "0.128.0"
 dependencies = [
  "cargo 0.29.0",
  "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "clippy_lints 0.0.200",
+ "clippy_lints 0.0.200 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2978,6 +2999,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
 "checksum chrono 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ba5f60682a4c264e7f8d77b82e7788938a76befdf949d4a98026d19099c9d873"
 "checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536"
+"checksum clippy_lints 0.0.200 (registry+https://github.com/rust-lang/crates.io-index)" = "d2432663f6bdb90255dcf9df5ca504f99b575bb471281591138f62f9d31f863b"
 "checksum cmake 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "5cf678ceebedde428000cb3a34465cf3606d1a48da17014948a916deac39da7c"
 "checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc"
 "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007"
diff --git a/src/Cargo.toml b/src/Cargo.toml
index 1518e8d910f..7504b43e20c 100644
--- a/src/Cargo.toml
+++ b/src/Cargo.toml
@@ -64,4 +64,3 @@ cargo = { path = "tools/cargo" }
 # RLS depends on `rustfmt` from crates.io, so we put this in a `[patch]` section
 # for crates.io
 rustfmt-nightly = { path = "tools/rustfmt" }
-clippy_lints = { path = "tools/clippy/clippy_lints" }
diff --git a/src/doc/rustdoc/src/documentation-tests.md b/src/doc/rustdoc/src/documentation-tests.md
index 3098587a8a4..fd7d1713ca5 100644
--- a/src/doc/rustdoc/src/documentation-tests.md
+++ b/src/doc/rustdoc/src/documentation-tests.md
@@ -268,10 +268,10 @@ not actually pass as a test.
 # fn foo() {}
 ```
 
-`compile_fail` tells `rustdoc` that the compilation should fail. If it
-compiles, then the test will fail. However please note that code failing
-with the current Rust release may work in a future release, as new features
-are added.
+The `no_run` attribute will compile your code, but not run it. This is
+important for examples such as "Here's how to retrieve a web page,"
+which you would want to ensure compiles, but might be run in a test
+environment that has no network access.
 
 ```text
 /// ```compile_fail
@@ -280,7 +280,7 @@ are added.
 /// ```
 ```
 
-The `no_run` attribute will compile your code, but not run it. This is
-important for examples such as "Here's how to retrieve a web page,"
-which you would want to ensure compiles, but might be run in a test
-environment that has no network access.
+`compile_fail` tells `rustdoc` that the compilation should fail. If it
+compiles, then the test will fail. However please note that code failing
+with the current Rust release may work in a future release, as new features
+are added.
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index fdc9aa473e8..3b19a401859 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -1698,6 +1698,7 @@ impl<T> [T] {
     }
 
     /// Function to calculate lenghts of the middle and trailing slice for `align_to{,_mut}`.
+    #[cfg(not(stage0))]
     fn align_to_offsets<U>(&self) -> (usize, usize) {
         // What we gonna do about `rest` is figure out what multiple of `U`s we can put in a
         // lowest number of `T`s. And how many `T`s we need for each such "multiple".
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index 74b8b816848..1b16d93ef27 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -132,7 +132,7 @@ for ty::RegionKind {
             ty::ReLateBound(..) |
             ty::ReVar(..) |
             ty::ReSkolemized(..) => {
-                bug!("TypeIdHasher: unexpected region {:?}", *self)
+                bug!("StableHasher: unexpected region {:?}", *self)
             }
         }
     }
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index b39311a7471..3db8c746713 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -117,6 +117,7 @@ use std::io::prelude::*;
 use std::io;
 use std::rc::Rc;
 use syntax::ast::{self, NodeId};
+use syntax::ptr::P;
 use syntax::symbol::keywords;
 use syntax_pos::Span;
 
@@ -398,72 +399,65 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
     lsets.warn_about_unused_args(body, entry_ln);
 }
 
-fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) {
-    local.pat.each_binding(|_, p_id, sp, path1| {
-        debug!("adding local variable {}", p_id);
+fn add_from_pat<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, pat: &P<hir::Pat>) {
+    // 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`.
+    let mut shorthand_field_ids = NodeSet();
+    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());
+            }
+            _ => {}
+        }
+    }
+
+    pat.each_binding(|_bm, p_id, _sp, path1| {
         let name = path1.node;
-        ir.add_live_node_for_node(p_id, VarDefNode(sp));
+        ir.add_live_node_for_node(p_id, VarDefNode(path1.span));
         ir.add_variable(Local(LocalInfo {
             id: p_id,
             name,
-            is_shorthand: false,
+            is_shorthand: shorthand_field_ids.contains(&p_id)
         }));
     });
+}
+
+fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) {
+    add_from_pat(ir, &local.pat);
     intravisit::walk_local(ir, local);
 }
 
 fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) {
-    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`.
-        let mut shorthand_field_ids = NodeSet();
-        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());
-                }
-                _ => {}
-            }
-        }
-
-        pat.each_binding(|bm, p_id, _sp, path1| {
-            debug!("adding local variable {} from match with bm {:?}",
-                   p_id, bm);
-            let name = path1.node;
-            ir.add_live_node_for_node(p_id, VarDefNode(path1.span));
-            ir.add_variable(Local(LocalInfo {
-                id: p_id,
-                name: name,
-                is_shorthand: shorthand_field_ids.contains(&p_id)
-            }));
-        })
+    for pat in &arm.pats {
+        add_from_pat(ir, pat);
     }
     intravisit::walk_arm(ir, arm);
 }
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index d5532f8f835..7cfcbcb86af 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -15,10 +15,8 @@ use hir::def_id::DefId;
 use hir::map::{DefPathData, Node};
 use hir;
 use ich::NodeIdHashingMode;
-use middle::const_val::ConstVal;
 use traits::{self, ObligationCause};
 use ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable};
-use ty::fold::TypeVisitor;
 use ty::subst::{Substs, UnpackedKind};
 use ty::maps::TyCtxtAt;
 use ty::TypeVariants::*;
@@ -26,12 +24,9 @@ use ty::layout::{Integer, IntegerExt};
 use util::common::ErrorReported;
 use middle::lang_items;
 
-use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
-                                           HashStable};
+use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
 use rustc_data_structures::fx::FxHashMap;
 use std::{cmp, fmt};
-use std::hash::Hash;
-use std::intrinsics;
 use syntax::ast;
 use syntax::attr::{self, SignedInt, UnsignedInt};
 use syntax_pos::{Span, DUMMY_SP};
@@ -615,150 +610,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     }
 }
 
-pub struct TypeIdHasher<'a, 'gcx: 'a+'tcx, 'tcx: 'a, W> {
-    tcx: TyCtxt<'a, 'gcx, 'tcx>,
-    state: StableHasher<W>,
-}
-
-impl<'a, 'gcx, 'tcx, W> TypeIdHasher<'a, 'gcx, 'tcx, W>
-    where W: StableHasherResult
-{
-    pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Self {
-        TypeIdHasher { tcx: tcx, state: StableHasher::new() }
-    }
-
-    pub fn finish(self) -> W {
-        self.state.finish()
-    }
-
-    pub fn hash<T: Hash>(&mut self, x: T) {
-        x.hash(&mut self.state);
-    }
-
-    fn hash_discriminant_u8<T>(&mut self, x: &T) {
-        let v = unsafe {
-            intrinsics::discriminant_value(x)
-        };
-        let b = v as u8;
-        assert_eq!(v, b as u64);
-        self.hash(b)
-    }
-
-    fn def_id(&mut self, did: DefId) {
-        // Hash the DefPath corresponding to the DefId, which is independent
-        // of compiler internal state. We already have a stable hash value of
-        // all DefPaths available via tcx.def_path_hash(), so we just feed that
-        // into the hasher.
-        let hash = self.tcx.def_path_hash(did);
-        self.hash(hash);
-    }
-}
-
-impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W>
-    where W: StableHasherResult
-{
-    fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
-        // Distinguish between the Ty variants uniformly.
-        self.hash_discriminant_u8(&ty.sty);
-
-        match ty.sty {
-            TyInt(i) => self.hash(i),
-            TyUint(u) => self.hash(u),
-            TyFloat(f) => self.hash(f),
-            TyArray(_, n) => {
-                self.hash_discriminant_u8(&n.val);
-                match n.val {
-                    ConstVal::Value(alloc) => self.hash(alloc),
-                    ConstVal::Unevaluated(def_id, _) => self.def_id(def_id),
-                }
-            }
-            TyRawPtr(m) => self.hash(m.mutbl),
-            TyRef(_, _, mutbl) => self.hash(mutbl),
-            TyClosure(def_id, _) |
-            TyGenerator(def_id, _, _) |
-            TyAnon(def_id, _) |
-            TyFnDef(def_id, _) => self.def_id(def_id),
-            TyAdt(d, _) => self.def_id(d.did),
-            TyForeign(def_id) => self.def_id(def_id),
-            TyFnPtr(f) => {
-                self.hash(f.unsafety());
-                self.hash(f.abi());
-                self.hash(f.variadic());
-                self.hash(f.inputs().skip_binder().len());
-            }
-            TyDynamic(ref data, ..) => {
-                if let Some(p) = data.principal() {
-                    self.def_id(p.def_id());
-                }
-                for d in data.auto_traits() {
-                    self.def_id(d);
-                }
-            }
-            TyGeneratorWitness(tys) => {
-                self.hash(tys.skip_binder().len());
-            }
-            TyTuple(tys) => {
-                self.hash(tys.len());
-            }
-            TyParam(p) => {
-                self.hash(p.idx);
-                self.hash(p.name);
-            }
-            TyProjection(ref data) => {
-                self.def_id(data.item_def_id);
-            }
-            TyNever |
-            TyBool |
-            TyChar |
-            TyStr |
-            TySlice(_) => {}
-
-            TyError |
-            TyInfer(_) => bug!("TypeIdHasher: unexpected type {}", ty)
-        }
-
-        ty.super_visit_with(self)
-    }
-
-    fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
-        self.hash_discriminant_u8(r);
-        match *r {
-            ty::ReErased |
-            ty::ReStatic |
-            ty::ReEmpty => {
-                // No variant fields to hash for these ...
-            }
-            ty::ReCanonical(c) => {
-                self.hash(c);
-            }
-            ty::ReLateBound(db, ty::BrAnon(i)) => {
-                self.hash(db.depth);
-                self.hash(i);
-            }
-            ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, .. }) => {
-                self.def_id(def_id);
-            }
-
-            ty::ReClosureBound(..) |
-            ty::ReLateBound(..) |
-            ty::ReFree(..) |
-            ty::ReScope(..) |
-            ty::ReVar(..) |
-            ty::ReSkolemized(..) => {
-                bug!("TypeIdHasher: unexpected region {:?}", r)
-            }
-        }
-        false
-    }
-
-    fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, x: &ty::Binder<T>) -> bool {
-        // Anonymize late-bound regions so that, for example:
-        // `for<'a, b> fn(&'a &'b T)` and `for<'a, b> fn(&'b &'a T)`
-        // result in the same TypeId (the two types are equivalent).
-        self.tcx.anonymize_late_bound_regions(x).super_visit_with(self)
-    }
-}
-
 impl<'a, 'tcx> ty::TyS<'tcx> {
     pub fn moves_by_default(&'tcx self,
                             tcx: TyCtxt<'a, 'tcx, 'tcx>,
diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs
index 25c598c532c..221012903d9 100644
--- a/src/librustc_codegen_llvm/abi.rs
+++ b/src/librustc_codegen_llvm/abi.rs
@@ -127,8 +127,12 @@ impl LlvmType for Reg {
 impl LlvmType for CastTarget {
     fn llvm_type(&self, cx: &CodegenCx) -> Type {
         let rest_ll_unit = self.rest.unit.llvm_type(cx);
-        let rest_count = self.rest.total.bytes() / self.rest.unit.size.bytes();
-        let rem_bytes = self.rest.total.bytes() % self.rest.unit.size.bytes();
+        let (rest_count, rem_bytes) = if self.rest.unit.size.bytes() == 0 {
+            (0, 0)
+        } else {
+            (self.rest.total.bytes() / self.rest.unit.size.bytes(),
+            self.rest.total.bytes() % self.rest.unit.size.bytes())
+        };
 
         if self.prefix.iter().all(|x| x.is_none()) {
             // Simplify to a single unit when there is no prefix and size <= unit size
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index ee60711c11d..ae0f6067f47 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -23,12 +23,11 @@ use llvm::{self, ValueRef};
 use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor,
                       DICompositeType, DILexicalBlock, DIFlags};
 
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc::hir::CodegenFnAttrFlags;
 use rustc::hir::def::CtorKind;
 use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
-use rustc::ty::fold::TypeVisitor;
-use rustc::ty::util::TypeIdHasher;
-use rustc::ich::Fingerprint;
+use rustc::ich::{Fingerprint, NodeIdHashingMode};
 use rustc::ty::Instance;
 use common::CodegenCx;
 use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
@@ -144,9 +143,15 @@ impl<'tcx> TypeMap<'tcx> {
 
         // The hasher we are using to generate the UniqueTypeId. We want
         // something that provides more than the 64 bits of the DefaultHasher.
-        let mut type_id_hasher = TypeIdHasher::<Fingerprint>::new(cx.tcx);
-        type_id_hasher.visit_ty(type_);
-        let unique_type_id = type_id_hasher.finish().to_hex();
+        let mut hasher = StableHasher::<Fingerprint>::new();
+        let mut hcx = cx.tcx.create_stable_hashing_context();
+        let type_ = cx.tcx.erase_regions(&type_);
+        hcx.while_hashing_spans(false, |hcx| {
+            hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
+                type_.hash_stable(hcx, &mut hasher);
+            });
+        });
+        let unique_type_id = hasher.finish().to_hex();
 
         let key = self.unique_id_interner.intern(&unique_type_id);
         self.type_to_unique_id.insert(type_, UniqueTypeId(key));
diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs
index 1a62f39ae3d..2063db6dc53 100644
--- a/src/librustc_codegen_utils/symbol_names.rs
+++ b/src/librustc_codegen_utils/symbol_names.rs
@@ -97,18 +97,19 @@
 //! virtually impossible. Thus, symbol hash generation exclusively relies on
 //! DefPaths which are much more robust in the face of changes to the code base.
 
-use rustc::middle::weak_lang_items;
-use rustc_mir::monomorphize::Instance;
-use rustc_mir::monomorphize::item::{MonoItem, MonoItemExt, InstantiationMode};
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::hir::map as hir_map;
-use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
-use rustc::ty::fold::TypeVisitor;
+use rustc::hir::map::definitions::DefPathData;
+use rustc::ich::NodeIdHashingMode;
+use rustc::middle::weak_lang_items;
 use rustc::ty::item_path::{self, ItemPathBuffer, RootMode};
 use rustc::ty::maps::Providers;
 use rustc::ty::subst::Substs;
-use rustc::hir::map::definitions::DefPathData;
+use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc::util::common::record_time;
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+use rustc_mir::monomorphize::item::{InstantiationMode, MonoItem, MonoItemExt};
+use rustc_mir::monomorphize::Instance;
 
 use syntax::attr;
 use syntax_pos::symbol::Symbol;
@@ -124,51 +125,60 @@ pub fn provide(providers: &mut Providers) {
     };
 }
 
-fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+fn get_symbol_hash<'a, 'tcx>(
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
-                             // the DefId of the item this name is for
-                             def_id: DefId,
+    // the DefId of the item this name is for
+    def_id: DefId,
 
-                             // instance this name will be for
-                             instance: Instance<'tcx>,
+    // instance this name will be for
+    instance: Instance<'tcx>,
 
-                             // type of the item, without any generic
-                             // parameters substituted; this is
-                             // included in the hash as a kind of
-                             // safeguard.
-                             item_type: Ty<'tcx>,
+    // type of the item, without any generic
+    // parameters substituted; this is
+    // included in the hash as a kind of
+    // safeguard.
+    item_type: Ty<'tcx>,
 
-                             // values for generic type parameters,
-                             // if any.
-                             substs: &'tcx Substs<'tcx>)
-                             -> u64 {
-    debug!("get_symbol_hash(def_id={:?}, parameters={:?})", def_id, substs);
+    // values for generic type parameters,
+    // if any.
+    substs: &'tcx Substs<'tcx>,
+) -> u64 {
+    debug!(
+        "get_symbol_hash(def_id={:?}, parameters={:?})",
+        def_id, substs
+    );
 
-    let mut hasher = ty::util::TypeIdHasher::<u64>::new(tcx);
+    let mut hasher = StableHasher::<u64>::new();
+    let mut hcx = tcx.create_stable_hashing_context();
 
     record_time(&tcx.sess.perf_stats.symbol_hash_time, || {
         // the main symbol name is not necessarily unique; hash in the
         // compiler's internal def-path, guaranteeing each symbol has a
         // truly unique path
-        hasher.hash(tcx.def_path_hash(def_id));
+        tcx.def_path_hash(def_id).hash_stable(&mut hcx, &mut hasher);
 
         // Include the main item-type. Note that, in this case, the
         // assertions about `needs_subst` may not hold, but this item-type
         // ought to be the same for every reference anyway.
         assert!(!item_type.has_erasable_regions());
-        hasher.visit_ty(item_type);
+        hcx.while_hashing_spans(false, |hcx| {
+            hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
+                item_type.hash_stable(hcx, &mut hasher);
+            });
+        });
 
         // If this is a function, we hash the signature as well.
         // This is not *strictly* needed, but it may help in some
         // situations, see the `run-make/a-b-a-linker-guard` test.
         if let ty::TyFnDef(..) = item_type.sty {
-            item_type.fn_sig(tcx).visit_with(&mut hasher);
+            item_type.fn_sig(tcx).hash_stable(&mut hcx, &mut hasher);
         }
 
         // also include any type parameters (for generic items)
         assert!(!substs.has_erasable_regions());
         assert!(!substs.needs_subst());
-        substs.visit_with(&mut hasher);
+        substs.hash_stable(&mut hcx, &mut hasher);
 
         let is_generic = substs.types().next().is_some();
         let avoid_cross_crate_conflicts =
@@ -194,12 +204,11 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 if !def_id.is_local() && tcx.share_generics() {
                     // If we are re-using a monomorphization from another crate,
                     // we have to compute the symbol hash accordingly.
-                    let upstream_monomorphizations =
-                        tcx.upstream_monomorphizations_for(def_id);
+                    let upstream_monomorphizations = tcx.upstream_monomorphizations_for(def_id);
 
-                    upstream_monomorphizations.and_then(|monos| monos.get(&substs)
-                                                                     .cloned())
-                                              .unwrap_or(LOCAL_CRATE)
+                    upstream_monomorphizations
+                        .and_then(|monos| monos.get(&substs).cloned())
+                        .unwrap_or(LOCAL_CRATE)
                 } else {
                     LOCAL_CRATE
                 }
@@ -207,8 +216,9 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 LOCAL_CRATE
             };
 
-            hasher.hash(&tcx.original_crate_name(instantiating_crate).as_str()[..]);
-            hasher.hash(&tcx.crate_disambiguator(instantiating_crate));
+            (&tcx.original_crate_name(instantiating_crate).as_str()[..])
+                .hash_stable(&mut hcx, &mut hasher);
+            (&tcx.crate_disambiguator(instantiating_crate)).hash_stable(&mut hcx, &mut hasher);
         }
     });
 
@@ -216,9 +226,7 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     hasher.finish()
 }
 
-fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
-                             -> ty::SymbolName
-{
+fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName {
     let mut buffer = SymbolPathBuffer::new();
     item_path::with_forced_absolute_paths(|| {
         tcx.push_item_path(&mut buffer, def_id);
@@ -226,20 +234,17 @@ fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
     buffer.into_interned()
 }
 
-fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>)
-                         -> ty::SymbolName
-{
-    ty::SymbolName { name: Symbol::intern(&compute_symbol_name(tcx, instance)).as_interned_str() }
+fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> ty::SymbolName {
+    ty::SymbolName {
+        name: Symbol::intern(&compute_symbol_name(tcx, instance)).as_interned_str(),
+    }
 }
 
-fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>)
-    -> String
-{
+fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> String {
     let def_id = instance.def_id();
     let substs = instance.substs;
 
-    debug!("symbol_name(def_id={:?}, substs={:?})",
-           def_id, substs);
+    debug!("symbol_name(def_id={:?}, substs={:?})", def_id, substs);
 
     let node_id = tcx.hir.as_local_node_id(def_id);
 
@@ -259,7 +264,7 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
     let is_foreign = if let Some(id) = node_id {
         match tcx.hir.get(id) {
             hir_map::NodeForeignItem(_) => true,
-            _ => false
+            _ => false,
         }
     } else {
         tcx.is_foreign_item(def_id)
@@ -296,8 +301,7 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
     loop {
         let key = tcx.def_key(ty_def_id);
         match key.disambiguated_data.data {
-            DefPathData::TypeNs(_) |
-            DefPathData::ValueNs(_) => {
+            DefPathData::TypeNs(_) | DefPathData::ValueNs(_) => {
                 instance_ty = tcx.type_of(ty_def_id);
                 break;
             }
@@ -306,8 +310,12 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
                 // to be a value or type-def or something in there
                 // *somewhere*
                 ty_def_id.index = key.parent.unwrap_or_else(|| {
-                    bug!("finding type for {:?}, encountered def-id {:?} with no \
-                          parent", def_id, ty_def_id);
+                    bug!(
+                        "finding type for {:?}, encountered def-id {:?} with no \
+                         parent",
+                        def_id,
+                        ty_def_id
+                    );
                 });
             }
         }
@@ -337,14 +345,14 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
 // use C++ name-mangling.
 struct SymbolPathBuffer {
     result: String,
-    temp_buf: String
+    temp_buf: String,
 }
 
 impl SymbolPathBuffer {
     fn new() -> Self {
         let mut result = SymbolPathBuffer {
             result: String::with_capacity(64),
-            temp_buf: String::with_capacity(16)
+            temp_buf: String::with_capacity(16),
         };
         result.result.push_str("_ZN"); // _Z == Begin name-sequence, N == nested
         result
@@ -353,14 +361,16 @@ impl SymbolPathBuffer {
     fn from_interned(symbol: ty::SymbolName) -> Self {
         let mut result = SymbolPathBuffer {
             result: String::with_capacity(64),
-            temp_buf: String::with_capacity(16)
+            temp_buf: String::with_capacity(16),
         };
         result.result.push_str(&symbol.name.as_str());
         result
     }
 
     fn into_interned(self) -> ty::SymbolName {
-        ty::SymbolName { name: Symbol::intern(&self.result).as_interned_str() }
+        ty::SymbolName {
+            name: Symbol::intern(&self.result).as_interned_str(),
+        }
     }
 
     fn finish(mut self, hash: u64) -> String {
@@ -379,7 +389,11 @@ impl ItemPathBuffer for SymbolPathBuffer {
     fn push(&mut self, text: &str) {
         self.temp_buf.clear();
         let need_underscore = sanitize(&mut self.temp_buf, text);
-        let _ = write!(self.result, "{}", self.temp_buf.len() + (need_underscore as usize));
+        let _ = write!(
+            self.result,
+            "{}",
+            self.temp_buf.len() + (need_underscore as usize)
+        );
         if need_underscore {
             self.result.push('_');
         }
@@ -410,16 +424,13 @@ pub fn sanitize(result: &mut String, s: &str) -> bool {
             '-' | ':' => result.push('.'),
 
             // These are legal symbols
-            'a' ... 'z'
-            | 'A' ... 'Z'
-            | '0' ... '9'
-            | '_' | '.' | '$' => result.push(c),
+            'a'...'z' | 'A'...'Z' | '0'...'9' | '_' | '.' | '$' => result.push(c),
 
             _ => {
                 result.push('$');
                 for c in c.escape_unicode().skip(1) {
                     match c {
-                        '{' => {},
+                        '{' => {}
                         '}' => result.push('$'),
                         c => result.push(c),
                     }
@@ -429,7 +440,6 @@ pub fn sanitize(result: &mut String, s: &str) -> bool {
     }
 
     // Underscore-qualify anything that didn't start as an ident.
-    !result.is_empty() &&
-        result.as_bytes()[0] != '_' as u8 &&
-        ! (result.as_bytes()[0] as char).is_xid_start()
+    !result.is_empty() && result.as_bytes()[0] != '_' as u8
+        && !(result.as_bytes()[0] as char).is_xid_start()
 }
diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs
index 2368b1aca69..ac37937509e 100644
--- a/src/librustc_passes/loops.rs
+++ b/src/librustc_passes/loops.rs
@@ -89,6 +89,8 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
                 self.with_context(LabeledBlock, |v| v.visit_block(&b));
             }
             hir::ExprBreak(label, ref opt_expr) => {
+                opt_expr.as_ref().map(|e| self.visit_expr(e));
+
                 if self.require_label_in_labeled_block(e.span, &label, "break") {
                     // If we emitted an error about an unlabeled break in a labeled
                     // block, we don't need any further checking for this break any more
diff --git a/src/llvm b/src/llvm
-Subproject 1abfd0e562cc8f7a9577d97ee92246699093b95
+Subproject 56c931901cfb85cd6f7ed44c7d7520a8de1edf9
diff --git a/src/rustllvm/llvm-rebuild-trigger b/src/rustllvm/llvm-rebuild-trigger
index c3fc3e5452c..5a0292bb6a1 100644
--- a/src/rustllvm/llvm-rebuild-trigger
+++ b/src/rustllvm/llvm-rebuild-trigger
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be (optionally) cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2018-04-05
+2018-05-18
\ No newline at end of file
diff --git a/src/test/ui/issue-50761.rs b/src/test/ui/issue-50761.rs
new file mode 100644
index 00000000000..b8a7a089c23
--- /dev/null
+++ b/src/test/ui/issue-50761.rs
@@ -0,0 +1,33 @@
+// 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.
+
+// Confirm that we don't accidently divide or mod by zero in llvm_type
+
+// compile-pass
+
+mod a {
+    pub trait A {}
+}
+
+mod b {
+    pub struct Builder {}
+
+    pub fn new() -> Builder {
+        Builder {}
+    }
+
+    impl Builder {
+        pub fn with_a(&mut self, _a: fn() -> ::a::A) {}
+    }
+}
+
+pub use self::b::new;
+
+fn main() {}
diff --git a/src/test/ui/issue-50802.rs b/src/test/ui/issue-50802.rs
new file mode 100644
index 00000000000..6342d0757ee
--- /dev/null
+++ b/src/test/ui/issue-50802.rs
@@ -0,0 +1,18 @@
+// 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.
+
+#[allow(unreachable_code)]
+
+fn main() {
+    loop {
+        break while continue { //~ ERROR E0590
+        }
+    }
+}
diff --git a/src/test/ui/issue-50802.stderr b/src/test/ui/issue-50802.stderr
new file mode 100644
index 00000000000..9da2648b376
--- /dev/null
+++ b/src/test/ui/issue-50802.stderr
@@ -0,0 +1,9 @@
+error[E0590]: `break` or `continue` with no label in the condition of a `while` loop
+  --> $DIR/issue-50802.rs:15:21
+   |
+LL |         break while continue { //~ ERROR E0590
+   |                     ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0590`.
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 100fb6d3533..bac3f00ffc7 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
@@ -20,6 +20,11 @@ struct SoulHistory {
     endless_and_singing: bool
 }
 
+struct LovelyAmbition {
+    lips: usize,
+    fire: usize
+}
+
 #[derive(Clone, Copy)]
 enum Large {
     Suit { case: () }
@@ -45,6 +50,10 @@ fn main() {
         hours_are_suns = false;
     }
 
+    let the_spirit = LovelyAmbition { lips: 1, fire: 2 };
+    let LovelyAmbition { lips, fire } = the_spirit;
+    println!("{}", lips);
+
     let bag = 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 992be2c0a28..a8b0e3e4250 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,5 +1,5 @@
 warning: unused variable: `i_think_continually`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:31:9
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:36:9
    |
 LL |     let i_think_continually = 2;
    |         ^^^^^^^^^^^^^^^^^^^ help: consider using `_i_think_continually` instead
@@ -12,31 +12,31 @@ LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
    = note: #[warn(unused_variables)] implied by #[warn(unused)]
 
 warning: unused variable: `mut_unused_var`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:38:13
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:43:13
    |
 LL |     let mut mut_unused_var = 1;
    |             ^^^^^^^^^^^^^^ help: consider using `_mut_unused_var` instead
 
 warning: unused variable: `var`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:40:14
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:45:14
    |
 LL |     let (mut var, unused_var) = (1, 2);
    |              ^^^ help: consider using `_var` instead
 
 warning: unused variable: `unused_var`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:40:19
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:45:19
    |
 LL |     let (mut var, unused_var) = (1, 2);
    |                   ^^^^^^^^^^ help: consider using `_unused_var` instead
 
 warning: unused variable: `corridors_of_light`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:42:26
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:47: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:43:30
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:48:30
    |
 LL |                          mut hours_are_suns,
    |                              ^^^^^^^^^^^^^^
@@ -44,7 +44,7 @@ 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:45:9
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:50:9
    |
 LL |         hours_are_suns = false;
    |         ^^^^^^^^^^^^^^
@@ -56,44 +56,50 @@ LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
    |         ^^^^^^
    = note: #[warn(unused_assignments)] implied by #[warn(unused)]
 
+warning: unused variable: `fire`
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:54:32
+   |
+LL |     let LovelyAmbition { lips, fire } = the_spirit;
+   |                                ^^^^ help: try ignoring the field: `fire: _`
+
 warning: unused variable: `case`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:54:23
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:63:23
    |
 LL |         Large::Suit { case } => {}
    |                       ^^^^ help: try ignoring the field: `case: _`
 
 warning: unused variable: `case`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:59:24
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:68:24
    |
 LL |         &Large::Suit { case } => {}
    |                        ^^^^ help: try ignoring the field: `case: _`
 
 warning: unused variable: `case`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:64:27
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:73: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:69:24
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:78:24
    |
 LL |         (Large::Suit { case },) => {}
    |                        ^^^^ help: try ignoring the field: `case: _`
 
 warning: unused variable: `case`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:74:24
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:83:24
    |
 LL |         [Large::Suit { case }] => {}
    |                        ^^^^ help: try ignoring the field: `case: _`
 
 warning: unused variable: `case`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:79:29
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:88:29
    |
 LL |         Tuple(Large::Suit { case }, ()) => {}
    |                             ^^^^ help: try ignoring the field: `case: _`
 
 warning: variable does not need to be mutable
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:38:9
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:43:9
    |
 LL |     let mut mut_unused_var = 1;
    |         ----^^^^^^^^^^^^^^
@@ -108,7 +114,7 @@ LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
    = note: #[warn(unused_mut)] implied by #[warn(unused)]
 
 warning: variable does not need to be mutable
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:40:10
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:45:10
    |
 LL |     let (mut var, unused_var) = (1, 2);
    |          ----^^^
diff --git a/src/tools/clippy b/src/tools/clippy
-Subproject c658fc8cbcd1f199edd445a49cb43139ebdc5f0
+Subproject ebe0b0eed596243a2839867363cb31d93f0b975