about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-05-26 20:58:52 +0000
committerbors <bors@rust-lang.org>2020-05-26 20:58:52 +0000
commite5335592e78354e33d798d20c04bcd677c1df62d (patch)
tree905f866aaef10ee8effbc165b0844a580e68762b
parent5239f5c57bb6eb9e894081727f5aba0a67e89763 (diff)
parente061c402ae3cd22e4b0037c23e4c0be84e7ef695 (diff)
downloadrust-e5335592e78354e33d798d20c04bcd677c1df62d.tar.gz
rust-e5335592e78354e33d798d20c04bcd677c1df62d.zip
Auto merge of #72627 - Dylan-DPC:rollup-bavnoq5, r=Dylan-DPC
Rollup of 6 pull requests

Successful merges:

 - #72270 (add a lint against references to packed fields)
 - #72294 (JS cleanup)
 - #72342 (Warn about unused crate deps)
 - #72401 (Use correct function for detecting `const fn` in unsafety checking)
 - #72581 (Allow unlabeled breaks from desugared `?` in labeled blocks)
 - #72592 (Update books)

Failed merges:

r? @ghost
m---------src/doc/book0
m---------src/doc/edition-guide0
m---------src/doc/embedded-book0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
-rw-r--r--src/librustc_lint/lib.rs1
-rw-r--r--src/librustc_metadata/creader.rs29
-rw-r--r--src/librustc_mir/transform/check_packed_ref.rs66
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs4
-rw-r--r--src/librustc_mir/transform/mod.rs6
-rw-r--r--src/librustc_passes/loops.rs3
-rw-r--r--src/librustc_session/lint/builtin.rs16
-rw-r--r--src/librustdoc/html/static/main.js588
-rw-r--r--src/librustdoc/html/static/settings.js3
-rw-r--r--src/librustdoc/html/static/source-script.js2
-rw-r--r--src/librustdoc/html/static/storage.js9
-rw-r--r--src/test/ui/issues/issue-27060-rpass.rs11
-rw-r--r--src/test/ui/issues/issue-27060.rs5
-rw-r--r--src/test/ui/issues/issue-27060.stderr6
-rw-r--r--src/test/ui/label/label_break_value_desugared_break.rs12
-rw-r--r--src/test/ui/lint/unaligned_references.rs22
-rw-r--r--src/test/ui/lint/unaligned_references.stderr39
-rw-r--r--src/test/ui/unsafe/unsafe-unstable-const-fn.rs13
-rw-r--r--src/test/ui/unsafe/unsafe-unstable-const-fn.stderr11
-rw-r--r--src/test/ui/unused-crate-deps/auxiliary/bar.rs1
-rw-r--r--src/test/ui/unused-crate-deps/auxiliary/foo.rs5
-rw-r--r--src/test/ui/unused-crate-deps/libfib.rs21
-rw-r--r--src/test/ui/unused-crate-deps/libfib.stderr10
-rw-r--r--src/test/ui/unused-crate-deps/suppress.rs11
-rw-r--r--src/test/ui/unused-crate-deps/unused-aliases.rs13
-rw-r--r--src/test/ui/unused-crate-deps/unused-aliases.stderr14
-rw-r--r--src/test/ui/unused-crate-deps/use_extern_crate_2015.rs13
-rw-r--r--src/test/ui/unused-crate-deps/warn-attr.rs10
-rw-r--r--src/test/ui/unused-crate-deps/warn-attr.stderr14
-rw-r--r--src/test/ui/unused-crate-deps/warn-cmdline-static.rs10
-rw-r--r--src/test/ui/unused-crate-deps/warn-cmdline-static.stderr10
-rw-r--r--src/test/ui/unused-crate-deps/warn-cmdline.rs9
-rw-r--r--src/test/ui/unused-crate-deps/warn-cmdline.stderr10
-rw-r--r--src/tools/rustdoc-js/tester.js2
39 files changed, 677 insertions, 322 deletions
diff --git a/src/doc/book b/src/doc/book
-Subproject 6247be15a7f7509559f7981ee2209b9e0cc121d
+Subproject e8a4714a9d8a6136a59b8e63544e149683876e3
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
-Subproject 49270740c7a4bff2763e6bc730b191d45b7d516
+Subproject 0a8ab5046829733eb03df0738c4fafaa9b36b34
diff --git a/src/doc/embedded-book b/src/doc/embedded-book
-Subproject 366c50a03bed928589771eba8a6f18e0c0c01d2
+Subproject 5555a97f04ad7974ac6fb8fb47c267c4274adf4
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 892b928b565e35d25b6f9c47faee03b94bc4148
+Subproject becdca9477c9eafa96a4eea5156fe7a2730d9dd
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject ab072b14393cbd9e8a1d1d75879bf51e27217bb
+Subproject 7aa82129aa23e7e181efbeb8da03a2a897ef6af
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index b791d313fc4..ee27342541c 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -276,6 +276,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
         UNUSED_ALLOCATION,
         UNUSED_DOC_COMMENTS,
         UNUSED_EXTERN_CRATES,
+        UNUSED_CRATE_DEPENDENCIES,
         UNUSED_FEATURES,
         UNUSED_LABELS,
         UNUSED_PARENS,
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index b0220ddd3c3..db29e953899 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -5,6 +5,7 @@ use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob
 
 use rustc_ast::expand::allocator::{global_allocator_spans, AllocatorKind};
 use rustc_ast::{ast, attr};
+use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::struct_span_err;
@@ -18,6 +19,7 @@ use rustc_middle::middle::cstore::{
 };
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::{self, CrateType};
+use rustc_session::lint;
 use rustc_session::output::validate_crate_name;
 use rustc_session::search_paths::PathKind;
 use rustc_session::{CrateDisambiguator, Session};
@@ -49,6 +51,7 @@ pub struct CrateLoader<'a> {
     local_crate_name: Symbol,
     // Mutable output.
     cstore: CStore,
+    used_extern_options: FxHashSet<Symbol>,
 }
 
 pub enum LoadedMacro {
@@ -205,6 +208,7 @@ impl<'a> CrateLoader<'a> {
                 allocator_kind: None,
                 has_global_allocator: false,
             },
+            used_extern_options: Default::default(),
         }
     }
 
@@ -445,6 +449,9 @@ impl<'a> CrateLoader<'a> {
         dep_kind: DepKind,
         dep: Option<(&'b CratePaths, &'b CrateDep)>,
     ) -> CrateNum {
+        if dep.is_none() {
+            self.used_extern_options.insert(name);
+        }
         self.maybe_resolve_crate(name, span, dep_kind, dep).unwrap_or_else(|err| err.report())
     }
 
@@ -839,6 +846,26 @@ impl<'a> CrateLoader<'a> {
         });
     }
 
+    fn report_unused_deps(&mut self, krate: &ast::Crate) {
+        // Make a point span rather than covering the whole file
+        let span = krate.span.shrink_to_lo();
+        // Complain about anything left over
+        for (name, _) in self.sess.opts.externs.iter() {
+            if !self.used_extern_options.contains(&Symbol::intern(name)) {
+                self.sess.parse_sess.buffer_lint(
+                    lint::builtin::UNUSED_CRATE_DEPENDENCIES,
+                    span,
+                    ast::CRATE_NODE_ID,
+                    &format!(
+                        "external crate `{}` unused in `{}`: remove the dependency or add `use {} as _;`",
+                        name,
+                        self.local_crate_name,
+                        name),
+                );
+            }
+        }
+    }
+
     pub fn postprocess(&mut self, krate: &ast::Crate) {
         self.inject_profiler_runtime();
         self.inject_allocator_crate(krate);
@@ -847,6 +874,8 @@ impl<'a> CrateLoader<'a> {
         if log_enabled!(log::Level::Info) {
             dump_crates(&self.cstore);
         }
+
+        self.report_unused_deps(krate);
     }
 
     pub fn process_extern_crate(
diff --git a/src/librustc_mir/transform/check_packed_ref.rs b/src/librustc_mir/transform/check_packed_ref.rs
new file mode 100644
index 00000000000..faad1a72327
--- /dev/null
+++ b/src/librustc_mir/transform/check_packed_ref.rs
@@ -0,0 +1,66 @@
+use rustc_middle::mir::visit::{PlaceContext, Visitor};
+use rustc_middle::mir::*;
+use rustc_middle::ty::{self, TyCtxt};
+use rustc_session::lint::builtin::UNALIGNED_REFERENCES;
+
+use crate::transform::{MirPass, MirSource};
+use crate::util;
+
+pub struct CheckPackedRef;
+
+impl<'tcx> MirPass<'tcx> for CheckPackedRef {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
+        let param_env = tcx.param_env(src.instance.def_id());
+        let source_info = SourceInfo::outermost(body.span);
+        let mut checker = PackedRefChecker { body, tcx, param_env, source_info };
+        checker.visit_body(&body);
+    }
+}
+
+struct PackedRefChecker<'a, 'tcx> {
+    body: &'a Body<'tcx>,
+    tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+    source_info: SourceInfo,
+}
+
+impl<'a, 'tcx> Visitor<'tcx> for PackedRefChecker<'a, 'tcx> {
+    fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
+        // Make sure we know where in the MIR we are.
+        self.source_info = terminator.source_info;
+        self.super_terminator(terminator, location);
+    }
+
+    fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
+        // Make sure we know where in the MIR we are.
+        self.source_info = statement.source_info;
+        self.super_statement(statement, location);
+    }
+
+    fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) {
+        if context.is_borrow() {
+            if util::is_disaligned(self.tcx, self.body, self.param_env, *place) {
+                let source_info = self.source_info;
+                let lint_root = self.body.source_scopes[source_info.scope]
+                    .local_data
+                    .as_ref()
+                    .assert_crate_local()
+                    .lint_root;
+                self.tcx.struct_span_lint_hir(
+                    UNALIGNED_REFERENCES,
+                    lint_root,
+                    source_info.span,
+                    |lint| {
+                        lint.build(&format!("reference to packed field is unaligned",))
+                            .note(
+                                "fields of packed structs are not properly aligned, and creating \
+                                a misaligned reference is undefined behavior (even if that \
+                                reference is never dereferenced)",
+                            )
+                            .emit()
+                    },
+                );
+            }
+        }
+    }
+}
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index 9bcb45f6493..a335fa2de41 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -14,7 +14,7 @@ use rustc_span::symbol::{sym, Symbol};
 
 use std::ops::Bound;
 
-use crate::const_eval::{is_const_fn, is_min_const_fn};
+use crate::const_eval::is_min_const_fn;
 use crate::util;
 
 pub struct UnsafetyChecker<'a, 'tcx> {
@@ -527,7 +527,7 @@ fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: LocalDefId) -> UnsafetyCheckRe
     let (const_context, min_const_fn) = match tcx.hir().body_owner_kind(id) {
         hir::BodyOwnerKind::Closure => (false, false),
         hir::BodyOwnerKind::Fn => {
-            (is_const_fn(tcx, def_id.to_def_id()), is_min_const_fn(tcx, def_id.to_def_id()))
+            (tcx.is_const_fn_raw(def_id.to_def_id()), is_min_const_fn(tcx, def_id.to_def_id()))
         }
         hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => (true, false),
     };
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index af9436d4041..26725a2ac02 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -17,6 +17,7 @@ pub mod add_call_guards;
 pub mod add_moves_for_packed_drops;
 pub mod add_retag;
 pub mod check_consts;
+pub mod check_packed_ref;
 pub mod check_unsafety;
 pub mod cleanup_post_borrowck;
 pub mod const_prop;
@@ -228,10 +229,11 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> ConstQualifs {
     validator.qualifs_in_return_place()
 }
 
+/// Make MIR ready for const evaluation. This is run on all MIR, not just on consts!
 fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> Steal<Body<'_>> {
     let def_id = def_id.expect_local();
 
-    // Unsafety check uses the raw mir, so make sure it is run
+    // Unsafety check uses the raw mir, so make sure it is run.
     let _ = tcx.unsafety_check_result(def_id);
 
     let mut body = tcx.mir_built(def_id).steal();
@@ -247,6 +249,8 @@ fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> Steal<Body<'_>> {
         None,
         MirPhase::Const,
         &[&[
+            // MIR-level lints.
+            &check_packed_ref::CheckPackedRef,
             // What we need to do constant evaluation.
             &simplify::SimplifyCfg::new("initial"),
             &rustc_peek::SanityCheck,
diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs
index 09b3d44020d..767a6909d31 100644
--- a/src/librustc_passes/loops.rs
+++ b/src/librustc_passes/loops.rs
@@ -9,6 +9,7 @@ use rustc_middle::hir::map::Map;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::Session;
+use rustc_span::hygiene::DesugaringKind;
 use rustc_span::Span;
 
 #[derive(Clone, Copy, Debug, PartialEq)]
@@ -203,7 +204,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
         label: &Destination,
         cf_type: &str,
     ) -> bool {
-        if self.cx == LabeledBlock {
+        if !span.is_desugaring(DesugaringKind::QuestionMark) && self.cx == LabeledBlock {
             if label.label.is_none() {
                 struct_span_err!(
                     self.sess,
diff --git a/src/librustc_session/lint/builtin.rs b/src/librustc_session/lint/builtin.rs
index 3d03e46683e..e55ddc26a94 100644
--- a/src/librustc_session/lint/builtin.rs
+++ b/src/librustc_session/lint/builtin.rs
@@ -72,6 +72,12 @@ declare_lint! {
 }
 
 declare_lint! {
+    pub UNUSED_CRATE_DEPENDENCIES,
+    Allow,
+    "crate dependencies that are never used"
+}
+
+declare_lint! {
     pub UNUSED_QUALIFICATIONS,
     Allow,
     "detects unnecessarily qualified names"
@@ -217,9 +223,15 @@ declare_lint! {
 }
 
 declare_lint! {
+    pub UNALIGNED_REFERENCES,
+    Allow,
+    "detects unaligned references to fields of packed structs",
+}
+
+declare_lint! {
     pub SAFE_PACKED_BORROWS,
     Warn,
-    "safe borrows of fields of packed structs were was erroneously allowed",
+    "safe borrows of fields of packed structs were erroneously allowed",
     @future_incompatible = FutureIncompatibleInfo {
         reference: "issue #46043 <https://github.com/rust-lang/rust/issues/46043>",
         edition: None,
@@ -523,6 +535,7 @@ declare_lint_pass! {
         UNCONDITIONAL_PANIC,
         UNUSED_IMPORTS,
         UNUSED_EXTERN_CRATES,
+        UNUSED_CRATE_DEPENDENCIES,
         UNUSED_QUALIFICATIONS,
         UNKNOWN_LINTS,
         UNUSED_VARIABLES,
@@ -545,6 +558,7 @@ declare_lint_pass! {
         INVALID_TYPE_PARAM_DEFAULT,
         CONST_ERR,
         RENAMED_AND_REMOVED_LINTS,
+        UNALIGNED_REFERENCES,
         SAFE_PACKED_BORROWS,
         PATTERNS_IN_FNS_WITHOUT_BODY,
         MISSING_FRAGMENT_SPECIFIER,
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 9869c50fbb0..22c9426db20 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -3,7 +3,7 @@
 
 // Local js definitions:
 /* global addClass, getCurrentValue, hasClass */
-/* global onEach, removeClass, updateLocalStorage */
+/* global onEachLazy, hasOwnProperty, removeClass, updateLocalStorage */
 
 if (!String.prototype.startsWith) {
     String.prototype.startsWith = function(searchString, position) {
@@ -47,6 +47,16 @@ function getSearchElement() {
     return document.getElementById("search");
 }
 
+// Sets the focus on the search bar at the top of the page
+function focusSearchBar() {
+    getSearchInput().focus();
+}
+
+// Removes the focus from the search bar
+function defocusSearchBar() {
+    getSearchInput().blur();
+}
+
 (function() {
     "use strict";
 
@@ -181,6 +191,7 @@ function getSearchElement() {
     var savedHash = "";
 
     function handleHashes(ev) {
+        var elem;
         var search = getSearchElement();
         if (ev !== null && search && !hasClass(search, "hidden") && ev.newURL) {
             // This block occurs when clicking on an element in the navbar while
@@ -190,7 +201,7 @@ function getSearchElement() {
             if (browserSupportsHistoryApi()) {
                 history.replaceState(hash, "", "?search=#" + hash);
             }
-            var elem = document.getElementById(hash);
+            elem = document.getElementById(hash);
             if (elem) {
                 elem.scrollIntoView();
             }
@@ -201,7 +212,7 @@ function getSearchElement() {
             if (savedHash.length === 0) {
                 return;
             }
-            var elem = document.getElementById(savedHash.slice(1)); // we remove the '#'
+            elem = document.getElementById(savedHash.slice(1)); // we remove the '#'
             if (!elem || !isHidden(elem)) {
                 return;
             }
@@ -324,7 +335,7 @@ function getSearchElement() {
     }
 
     function displayHelp(display, ev, help) {
-        var help = help ? help : getHelpElement();
+        help = help ? help : getHelpElement();
         if (display === true) {
             if (hasClass(help, "hidden")) {
                 ev.preventDefault();
@@ -438,8 +449,8 @@ function getSearchElement() {
 
                 set_fragment(cur_line_id);
             }
-        }
-    })();
+        };
+    }());
 
     document.addEventListener("click", function(ev) {
         if (hasClass(ev.target, "collapse-toggle")) {
@@ -465,27 +476,30 @@ function getSearchElement() {
         }
     });
 
-    var x = document.getElementsByClassName("version-selector");
-    if (x.length > 0) {
-        x[0].onchange = function() {
-            var i, match,
-                url = document.location.href,
-                stripped = "",
-                len = rootPath.match(/\.\.\//g).length + 1;
+    (function() {
+        var x = document.getElementsByClassName("version-selector");
+        if (x.length > 0) {
+            x[0].onchange = function() {
+                var i, match,
+                    url = document.location.href,
+                    stripped = "",
+                    len = rootPath.match(/\.\.\//g).length + 1;
 
-            for (i = 0; i < len; ++i) {
-                match = url.match(/\/[^\/]*$/);
-                if (i < len - 1) {
-                    stripped = match[0] + stripped;
+                for (i = 0; i < len; ++i) {
+                    match = url.match(/\/[^\/]*$/);
+                    if (i < len - 1) {
+                        stripped = match[0] + stripped;
+                    }
+                    url = url.substring(0, url.length - match[0].length);
                 }
-                url = url.substring(0, url.length - match[0].length);
-            }
 
-            url += "/" + document.getElementsByClassName("version-selector")[0].value + stripped;
+                var selectedVersion = document.getElementsByClassName("version-selector")[0].value;
+                url += "/" + selectedVersion + stripped;
 
-            document.location.href = url;
-        };
-    }
+                document.location.href = url;
+            };
+        }
+    }());
 
     /**
      * A function to compute the Levenshtein distance between two strings
@@ -522,7 +536,7 @@ function getSearchElement() {
         return s1_len + s2_len;
     }
 
-    function initSearch(rawSearchIndex) {
+    window.initSearch = function(rawSearchIndex) {
         var MAX_LEV_DISTANCE = 3;
         var MAX_RESULTS = 200;
         var GENERICS_DATA = 1;
@@ -602,7 +616,7 @@ function getSearchElement() {
             function sortResults(results, isType) {
                 var ar = [];
                 for (var entry in results) {
-                    if (results.hasOwnProperty(entry)) {
+                    if (hasOwnProperty(results, entry)) {
                         ar.push(results[entry]);
                     }
                 }
@@ -1100,8 +1114,6 @@ function getSearchElement() {
                     }
                     fullId = generateId(ty);
 
-                    // allow searching for void (no output) functions as well
-                    var typeOutput = type.length > OUTPUT_DATA ? type[OUTPUT_DATA].name : "";
                     returned = checkReturned(ty, output, true, NO_TYPE_FILTER);
                     if (output.name === "*" || returned === true) {
                         in_args = false;
@@ -1164,7 +1176,6 @@ function getSearchElement() {
                 var contains = paths.slice(0, paths.length > 1 ? paths.length - 1 : 1);
 
                 var lev;
-                var lev_distance;
                 for (j = 0; j < nSearchWords; ++j) {
                     ty = searchIndex[j];
                     if (!ty || (filterCrates !== undefined && ty.crate !== filterCrates)) {
@@ -1661,7 +1672,7 @@ function getSearchElement() {
         function getFilterCrates() {
             var elem = document.getElementById("crate-search");
 
-            if (elem && elem.value !== "All crates" && rawSearchIndex.hasOwnProperty(elem.value)) {
+            if (elem && elem.value !== "All crates" && hasOwnProperty(rawSearchIndex, elem.value)) {
                 return elem.value;
             }
             return undefined;
@@ -1709,7 +1720,7 @@ function getSearchElement() {
             var currentIndex = 0;
 
             for (var crate in rawSearchIndex) {
-                if (!rawSearchIndex.hasOwnProperty(crate)) { continue; }
+                if (!hasOwnProperty(rawSearchIndex, crate)) { continue; }
 
                 var crateSize = 0;
 
@@ -1893,7 +1904,7 @@ function getSearchElement() {
 
                 var crates = [];
                 for (var crate in rawSearchIndex) {
-                    if (!rawSearchIndex.hasOwnProperty(crate)) {
+                    if (!hasOwnProperty(rawSearchIndex, crate)) {
                         continue;
                     }
                     crates.push(crate);
@@ -1917,12 +1928,11 @@ function getSearchElement() {
                 sidebar.appendChild(div);
             }
         }
-    }
+    };
 
-    window.initSearch = initSearch;
 
     // delayed sidebar rendering.
-    function initSidebarItems(items) {
+    window.initSidebarItems = function(items) {
         var sidebar = document.getElementsByClassName("sidebar-elems")[0];
         var current = window.sidebarCurrent;
 
@@ -1984,9 +1994,7 @@ function getSearchElement() {
         block("foreigntype", "Foreign Types");
         block("keyword", "Keywords");
         block("traitalias", "Trait Aliases");
-    }
-
-    window.initSidebarItems = initSidebarItems;
+    };
 
     window.register_implementors = function(imp) {
         var implementors = document.getElementById("implementors-list");
@@ -2163,19 +2171,13 @@ function getSearchElement() {
                         }
                     }
                     var ns = n.nextElementSibling;
-                    while (true) {
-                        if (ns && (
-                                hasClass(ns, "docblock") ||
-                                hasClass(ns, "stability"))) {
-                            if (addOrRemove) {
-                                addClass(ns, "hidden-by-impl-hider");
-                            } else {
-                                removeClass(ns, "hidden-by-impl-hider");
-                            }
-                            ns = ns.nextElementSibling;
-                            continue;
+                    while (ns && (hasClass(ns, "docblock") || hasClass(ns, "stability"))) {
+                        if (addOrRemove) {
+                            addClass(ns, "hidden-by-impl-hider");
+                        } else {
+                            removeClass(ns, "hidden-by-impl-hider");
                         }
-                        break;
+                        ns = ns.nextElementSibling;
                     }
                 }
             };
@@ -2248,7 +2250,7 @@ function getSearchElement() {
         }
     }
 
-    function collapser(e, collapse) {
+    function collapser(pageId, e, collapse) {
         // inherent impl ids are like "impl" or impl-<number>'.
         // they will never be hidden by default.
         var n = e.parentElement;
@@ -2268,7 +2270,7 @@ function getSearchElement() {
 
             if (impl_list !== null) {
                 onEachLazy(impl_list.getElementsByClassName("collapse-toggle"), function(e) {
-                    collapser(e, collapse);
+                    collapser(pageId, e, collapse);
                 });
             }
 
@@ -2276,7 +2278,7 @@ function getSearchElement() {
 
             if (blanket_list !== null) {
                 onEachLazy(blanket_list.getElementsByClassName("collapse-toggle"), function(e) {
-                    collapser(e, collapse);
+                    collapser(pageId, e, collapse);
                 });
             }
         }
@@ -2300,103 +2302,7 @@ function getSearchElement() {
         return toggle;
     }
 
-    var toggle = createSimpleToggle(false);
-    var hideMethodDocs = getCurrentValue("rustdoc-auto-hide-method-docs") === "true";
-    var pageId = getPageId();
-
-    var func = function(e) {
-        var next = e.nextElementSibling;
-        if (!next) {
-            return;
-        }
-        if (hasClass(next, "docblock") === true ||
-            (hasClass(next, "stability") === true &&
-             hasClass(next.nextElementSibling, "docblock") === true)) {
-            var newToggle = toggle.cloneNode(true);
-            insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]);
-            if (hideMethodDocs === true && hasClass(e, "method") === true) {
-                collapseDocs(newToggle, "hide", pageId);
-            }
-        }
-    };
-
-    var funcImpl = function(e) {
-        var next = e.nextElementSibling;
-        if (next && hasClass(next, "docblock")) {
-            next = next.nextElementSibling;
-        }
-        if (!next) {
-            return;
-        }
-        if (next.getElementsByClassName("method").length > 0 && hasClass(e, "impl")) {
-            insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]);
-        }
-    };
-
-    onEachLazy(document.getElementsByClassName("method"), func);
-    onEachLazy(document.getElementsByClassName("associatedconstant"), func);
-    onEachLazy(document.getElementsByClassName("impl"), funcImpl);
-    var impl_call = function() {};
-    if (hideMethodDocs === true) {
-        impl_call = function(e, newToggle, pageId) {
-            if (e.id.match(/^impl(?:-\d+)?$/) === null) {
-                // Automatically minimize all non-inherent impls
-                if (hasClass(e, "impl") === true) {
-                    collapseDocs(newToggle, "hide", pageId);
-                }
-            }
-        };
-    }
-    var newToggle = document.createElement("a");
-    newToggle.href = "javascript:void(0)";
-    newToggle.className = "collapse-toggle hidden-default collapsed";
-    newToggle.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(true) +
-                          "</span>] Show hidden undocumented items";
-    function toggleClicked() {
-        if (hasClass(this, "collapsed")) {
-            removeClass(this, "collapsed");
-            onEachLazy(this.parentNode.getElementsByClassName("hidden"), function(x) {
-                if (hasClass(x, "content") === false) {
-                    removeClass(x, "hidden");
-                    addClass(x, "x");
-                }
-            }, true);
-            this.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(false) +
-                             "</span>] Hide undocumented items";
-        } else {
-            addClass(this, "collapsed");
-            onEachLazy(this.parentNode.getElementsByClassName("x"), function(x) {
-                if (hasClass(x, "content") === false) {
-                    addClass(x, "hidden");
-                    removeClass(x, "x");
-                }
-            }, true);
-            this.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(true) +
-                             "</span>] Show hidden undocumented items";
-        }
-    }
-    onEachLazy(document.getElementsByClassName("impl-items"), function(e) {
-        onEachLazy(e.getElementsByClassName("associatedconstant"), func);
-        var hiddenElems = e.getElementsByClassName("hidden");
-        var needToggle = false;
-
-        var hlength = hiddenElems.length;
-        for (var i = 0; i < hlength; ++i) {
-            if (hasClass(hiddenElems[i], "content") === false &&
-                hasClass(hiddenElems[i], "docblock") === false) {
-                needToggle = true;
-                break;
-            }
-        }
-        if (needToggle === true) {
-            var inner_toggle = newToggle.cloneNode(true);
-            inner_toggle.onclick = toggleClicked;
-            e.insertBefore(inner_toggle, e.firstChild);
-            impl_call(e.previousSibling, inner_toggle, pageId);
-        }
-    });
-
-    function createToggle(otherMessage, fontSize, extraClass, show) {
+    function createToggle(toggle, otherMessage, fontSize, extraClass, show) {
         var span = document.createElement("span");
         span.className = "toggle-label";
         if (show) {
@@ -2431,97 +2337,197 @@ function getSearchElement() {
         return wrapper;
     }
 
-    var currentType = document.getElementsByClassName("type-decl")[0];
-    var className = null;
-    if (currentType) {
-        currentType = currentType.getElementsByClassName("rust")[0];
-        if (currentType) {
-            currentType.classList.forEach(function(item) {
-                if (item !== "main") {
-                    className = item;
-                    return true;
+    (function() {
+        var toggle = createSimpleToggle(false);
+        var hideMethodDocs = getCurrentValue("rustdoc-auto-hide-method-docs") === "true";
+        var pageId = getPageId();
+
+        var func = function(e) {
+            var next = e.nextElementSibling;
+            if (!next) {
+                return;
+            }
+            if (hasClass(next, "docblock") === true ||
+                (hasClass(next, "stability") === true &&
+                 hasClass(next.nextElementSibling, "docblock") === true)) {
+                var newToggle = toggle.cloneNode(true);
+                insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]);
+                if (hideMethodDocs === true && hasClass(e, "method") === true) {
+                    collapseDocs(newToggle, "hide", pageId);
                 }
-            });
+            }
+        };
+
+        var funcImpl = function(e) {
+            var next = e.nextElementSibling;
+            if (next && hasClass(next, "docblock")) {
+                next = next.nextElementSibling;
+            }
+            if (!next) {
+                return;
+            }
+            if (next.getElementsByClassName("method").length > 0 && hasClass(e, "impl")) {
+                insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]);
+            }
+        };
+
+        onEachLazy(document.getElementsByClassName("method"), func);
+        onEachLazy(document.getElementsByClassName("associatedconstant"), func);
+        onEachLazy(document.getElementsByClassName("impl"), funcImpl);
+        var impl_call = function() {};
+        if (hideMethodDocs === true) {
+            impl_call = function(e, newToggle) {
+                if (e.id.match(/^impl(?:-\d+)?$/) === null) {
+                    // Automatically minimize all non-inherent impls
+                    if (hasClass(e, "impl") === true) {
+                        collapseDocs(newToggle, "hide", pageId);
+                    }
+                }
+            };
         }
-    }
-    var showItemDeclarations = getCurrentValue("rustdoc-auto-hide-" + className);
-    if (showItemDeclarations === null) {
-        if (className === "enum" || className === "macro") {
-            showItemDeclarations = "false";
-        } else if (className === "struct" || className === "union" || className === "trait") {
-            showItemDeclarations = "true";
-        } else {
-            // In case we found an unknown type, we just use the "parent" value.
-            showItemDeclarations = getCurrentValue("rustdoc-auto-hide-declarations");
+        var newToggle = document.createElement("a");
+        newToggle.href = "javascript:void(0)";
+        newToggle.className = "collapse-toggle hidden-default collapsed";
+        newToggle.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(true) +
+                              "</span>] Show hidden undocumented items";
+        function toggleClicked() {
+            if (hasClass(this, "collapsed")) {
+                removeClass(this, "collapsed");
+                onEachLazy(this.parentNode.getElementsByClassName("hidden"), function(x) {
+                    if (hasClass(x, "content") === false) {
+                        removeClass(x, "hidden");
+                        addClass(x, "x");
+                    }
+                }, true);
+                this.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(false) +
+                                 "</span>] Hide undocumented items";
+            } else {
+                addClass(this, "collapsed");
+                onEachLazy(this.parentNode.getElementsByClassName("x"), function(x) {
+                    if (hasClass(x, "content") === false) {
+                        addClass(x, "hidden");
+                        removeClass(x, "x");
+                    }
+                }, true);
+                this.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(true) +
+                                 "</span>] Show hidden undocumented items";
+            }
         }
-    }
-    showItemDeclarations = showItemDeclarations === "false";
-    function buildToggleWrapper(e) {
-        if (hasClass(e, "autohide")) {
-            var wrap = e.previousElementSibling;
-            if (wrap && hasClass(wrap, "toggle-wrapper")) {
-                var inner_toggle = wrap.childNodes[0];
-                var extra = e.childNodes[0].tagName === "H3";
-
-                e.style.display = "none";
-                addClass(wrap, "collapsed");
-                onEachLazy(inner_toggle.getElementsByClassName("inner"), function(e) {
-                    e.innerHTML = labelForToggleButton(true);
-                });
-                onEachLazy(inner_toggle.getElementsByClassName("toggle-label"), function(e) {
-                    e.style.display = "inline-block";
-                    if (extra === true) {
-                        i_e.innerHTML = " Show " + e.childNodes[0].innerHTML;
+        onEachLazy(document.getElementsByClassName("impl-items"), function(e) {
+            onEachLazy(e.getElementsByClassName("associatedconstant"), func);
+            var hiddenElems = e.getElementsByClassName("hidden");
+            var needToggle = false;
+
+            var hlength = hiddenElems.length;
+            for (var i = 0; i < hlength; ++i) {
+                if (hasClass(hiddenElems[i], "content") === false &&
+                    hasClass(hiddenElems[i], "docblock") === false) {
+                    needToggle = true;
+                    break;
+                }
+            }
+            if (needToggle === true) {
+                var inner_toggle = newToggle.cloneNode(true);
+                inner_toggle.onclick = toggleClicked;
+                e.insertBefore(inner_toggle, e.firstChild);
+                impl_call(e.previousSibling, inner_toggle);
+            }
+        });
+
+        var currentType = document.getElementsByClassName("type-decl")[0];
+        var className = null;
+        if (currentType) {
+            currentType = currentType.getElementsByClassName("rust")[0];
+            if (currentType) {
+                currentType.classList.forEach(function(item) {
+                    if (item !== "main") {
+                        className = item;
+                        return true;
                     }
                 });
             }
         }
-        if (e.parentNode.id === "main") {
-            var otherMessage = "";
-            var fontSize;
-            var extraClass;
-
-            if (hasClass(e, "type-decl")) {
-                fontSize = "20px";
-                otherMessage = "&nbsp;Show&nbsp;declaration";
-                if (showItemDeclarations === false) {
-                    extraClass = "collapsed";
-                }
-            } else if (hasClass(e, "sub-variant")) {
-                otherMessage = "&nbsp;Show&nbsp;fields";
-            } else if (hasClass(e, "non-exhaustive")) {
-                otherMessage = "&nbsp;This&nbsp;";
-                if (hasClass(e, "non-exhaustive-struct")) {
-                    otherMessage += "struct";
-                } else if (hasClass(e, "non-exhaustive-enum")) {
-                    otherMessage += "enum";
-                } else if (hasClass(e, "non-exhaustive-variant")) {
-                    otherMessage += "enum variant";
-                } else if (hasClass(e, "non-exhaustive-type")) {
-                    otherMessage += "type";
-                }
-                otherMessage += "&nbsp;is&nbsp;marked&nbsp;as&nbsp;non-exhaustive";
-            } else if (hasClass(e.childNodes[0], "impl-items")) {
-                extraClass = "marg-left";
-            }
-
-            e.parentNode.insertBefore(
-                createToggle(otherMessage,
-                             fontSize,
-                             extraClass,
-                             hasClass(e, "type-decl") === false || showItemDeclarations === true),
-                e);
-            if (hasClass(e, "type-decl") === true && showItemDeclarations === true) {
-                collapseDocs(e.previousSibling.childNodes[0], "toggle");
-            }
-            if (hasClass(e, "non-exhaustive") === true) {
-                collapseDocs(e.previousSibling.childNodes[0], "toggle");
+        var showItemDeclarations = getCurrentValue("rustdoc-auto-hide-" + className);
+        if (showItemDeclarations === null) {
+            if (className === "enum" || className === "macro") {
+                showItemDeclarations = "false";
+            } else if (className === "struct" || className === "union" || className === "trait") {
+                showItemDeclarations = "true";
+            } else {
+                // In case we found an unknown type, we just use the "parent" value.
+                showItemDeclarations = getCurrentValue("rustdoc-auto-hide-declarations");
+            }
+        }
+        showItemDeclarations = showItemDeclarations === "false";
+        function buildToggleWrapper(e) {
+            if (hasClass(e, "autohide")) {
+                var wrap = e.previousElementSibling;
+                if (wrap && hasClass(wrap, "toggle-wrapper")) {
+                    var inner_toggle = wrap.childNodes[0];
+                    var extra = e.childNodes[0].tagName === "H3";
+
+                    e.style.display = "none";
+                    addClass(wrap, "collapsed");
+                    onEachLazy(inner_toggle.getElementsByClassName("inner"), function(e) {
+                        e.innerHTML = labelForToggleButton(true);
+                    });
+                    onEachLazy(inner_toggle.getElementsByClassName("toggle-label"), function(e) {
+                        e.style.display = "inline-block";
+                        if (extra === true) {
+                            e.innerHTML = " Show " + e.childNodes[0].innerHTML;
+                        }
+                    });
+                }
+            }
+            if (e.parentNode.id === "main") {
+                var otherMessage = "";
+                var fontSize;
+                var extraClass;
+
+                if (hasClass(e, "type-decl")) {
+                    fontSize = "20px";
+                    otherMessage = "&nbsp;Show&nbsp;declaration";
+                    if (showItemDeclarations === false) {
+                        extraClass = "collapsed";
+                    }
+                } else if (hasClass(e, "sub-variant")) {
+                    otherMessage = "&nbsp;Show&nbsp;fields";
+                } else if (hasClass(e, "non-exhaustive")) {
+                    otherMessage = "&nbsp;This&nbsp;";
+                    if (hasClass(e, "non-exhaustive-struct")) {
+                        otherMessage += "struct";
+                    } else if (hasClass(e, "non-exhaustive-enum")) {
+                        otherMessage += "enum";
+                    } else if (hasClass(e, "non-exhaustive-variant")) {
+                        otherMessage += "enum variant";
+                    } else if (hasClass(e, "non-exhaustive-type")) {
+                        otherMessage += "type";
+                    }
+                    otherMessage += "&nbsp;is&nbsp;marked&nbsp;as&nbsp;non-exhaustive";
+                } else if (hasClass(e.childNodes[0], "impl-items")) {
+                    extraClass = "marg-left";
+                }
+
+                e.parentNode.insertBefore(
+                    createToggle(
+                        toggle,
+                        otherMessage,
+                        fontSize,
+                        extraClass,
+                        hasClass(e, "type-decl") === false || showItemDeclarations === true),
+                    e);
+                if (hasClass(e, "type-decl") === true && showItemDeclarations === true) {
+                    collapseDocs(e.previousSibling.childNodes[0], "toggle");
+                }
+                if (hasClass(e, "non-exhaustive") === true) {
+                    collapseDocs(e.previousSibling.childNodes[0], "toggle");
+                }
             }
         }
-    }
 
-    onEachLazy(document.getElementsByClassName("docblock"), buildToggleWrapper);
-    onEachLazy(document.getElementsByClassName("sub-variant"), buildToggleWrapper);
+        onEachLazy(document.getElementsByClassName("docblock"), buildToggleWrapper);
+        onEachLazy(document.getElementsByClassName("sub-variant"), buildToggleWrapper);
+    }());
 
     function createToggleWrapper(tog) {
         var span = document.createElement("span");
@@ -2536,56 +2542,60 @@ function getSearchElement() {
         return wrapper;
     }
 
-    // To avoid checking on "rustdoc-item-attributes" value on every loop...
-    var itemAttributesFunc = function() {};
-    if (getCurrentValue("rustdoc-auto-hide-attributes") !== "false") {
-        itemAttributesFunc = function(x) {
-            collapseDocs(x.previousSibling.childNodes[0], "toggle");
-        };
-    }
-    var attributesToggle = createToggleWrapper(createSimpleToggle(false));
-    onEachLazy(main.getElementsByClassName("attributes"), function(i_e) {
-        var attr_tog = attributesToggle.cloneNode(true);
-        if (hasClass(i_e, "top-attr") === true) {
-            addClass(attr_tog, "top-attr");
-        }
-        i_e.parentNode.insertBefore(attr_tog, i_e);
-        itemAttributesFunc(i_e);
-    });
-
-    // To avoid checking on "rustdoc-line-numbers" value on every loop...
-    var lineNumbersFunc = function() {};
-    if (getCurrentValue("rustdoc-line-numbers") === "true") {
-        lineNumbersFunc = function(x) {
-            var count = x.textContent.split("\n").length;
-            var elems = [];
-            for (var i = 0; i < count; ++i) {
-                elems.push(i + 1);
-            }
-            var node = document.createElement("pre");
-            addClass(node, "line-number");
-            node.innerHTML = elems.join("\n");
-            x.parentNode.insertBefore(node, x);
-        };
-    }
-    onEachLazy(document.getElementsByClassName("rust-example-rendered"), function(e) {
-        if (hasClass(e, "compile_fail")) {
-            e.addEventListener("mouseover", function(event) {
-                this.parentElement.previousElementSibling.childNodes[0].style.color = "#f00";
-            });
-            e.addEventListener("mouseout", function(event) {
-                this.parentElement.previousElementSibling.childNodes[0].style.color = "";
-            });
-        } else if (hasClass(e, "ignore")) {
-            e.addEventListener("mouseover", function(event) {
-                this.parentElement.previousElementSibling.childNodes[0].style.color = "#ff9200";
-            });
-            e.addEventListener("mouseout", function(event) {
-                this.parentElement.previousElementSibling.childNodes[0].style.color = "";
-            });
+    (function() {
+        // To avoid checking on "rustdoc-item-attributes" value on every loop...
+        var itemAttributesFunc = function() {};
+        if (getCurrentValue("rustdoc-auto-hide-attributes") !== "false") {
+            itemAttributesFunc = function(x) {
+                collapseDocs(x.previousSibling.childNodes[0], "toggle");
+            };
         }
-        lineNumbersFunc(e);
-    });
+        var attributesToggle = createToggleWrapper(createSimpleToggle(false));
+        onEachLazy(main.getElementsByClassName("attributes"), function(i_e) {
+            var attr_tog = attributesToggle.cloneNode(true);
+            if (hasClass(i_e, "top-attr") === true) {
+                addClass(attr_tog, "top-attr");
+            }
+            i_e.parentNode.insertBefore(attr_tog, i_e);
+            itemAttributesFunc(i_e);
+        });
+    }());
+
+    (function() {
+        // To avoid checking on "rustdoc-line-numbers" value on every loop...
+        var lineNumbersFunc = function() {};
+        if (getCurrentValue("rustdoc-line-numbers") === "true") {
+            lineNumbersFunc = function(x) {
+                var count = x.textContent.split("\n").length;
+                var elems = [];
+                for (var i = 0; i < count; ++i) {
+                    elems.push(i + 1);
+                }
+                var node = document.createElement("pre");
+                addClass(node, "line-number");
+                node.innerHTML = elems.join("\n");
+                x.parentNode.insertBefore(node, x);
+            };
+        }
+        onEachLazy(document.getElementsByClassName("rust-example-rendered"), function(e) {
+            if (hasClass(e, "compile_fail")) {
+                e.addEventListener("mouseover", function() {
+                    this.parentElement.previousElementSibling.childNodes[0].style.color = "#f00";
+                });
+                e.addEventListener("mouseout", function() {
+                    this.parentElement.previousElementSibling.childNodes[0].style.color = "";
+                });
+            } else if (hasClass(e, "ignore")) {
+                e.addEventListener("mouseover", function() {
+                    this.parentElement.previousElementSibling.childNodes[0].style.color = "#ff9200";
+                });
+                e.addEventListener("mouseout", function() {
+                    this.parentElement.previousElementSibling.childNodes[0].style.color = "";
+                });
+            }
+            lineNumbersFunc(e);
+        });
+    }());
 
     // In the search display, allows to switch between tabs.
     function printTab(nb) {
@@ -2678,7 +2688,7 @@ function getSearchElement() {
         });
     }
 
-    function addSearchOptions(crates) {
+    window.addSearchOptions = function(crates) {
         var elem = document.getElementById("crate-search");
 
         if (!elem) {
@@ -2687,7 +2697,7 @@ function getSearchElement() {
         var crates_text = [];
         if (Object.keys(crates).length > 1) {
             for (var crate in crates) {
-                if (crates.hasOwnProperty(crate)) {
+                if (hasOwnProperty(crates, crate)) {
                     crates_text.push(crate);
                 }
             }
@@ -2722,10 +2732,8 @@ function getSearchElement() {
 
         if (search_input) {
             search_input.removeAttribute('disabled');
-        };
-    }
-
-    window.addSearchOptions = addSearchOptions;
+        }
+    };
 
     function buildHelperPopup() {
         var popup = document.createElement("aside");
@@ -2778,16 +2786,6 @@ function getSearchElement() {
     buildHelperPopup();
 }());
 
-// Sets the focus on the search bar at the top of the page
-function focusSearchBar() {
-    getSearchInput().focus();
-}
-
-// Removes the focus from the search bar
-function defocusSearchBar() {
-    getSearchInput().blur();
-}
-
 // This is required in firefox. Explanations: when going back in the history, firefox doesn't re-run
 // the JS, therefore preventing rustdoc from setting a few things required to be able to reload the
 // previous search results (if you navigated to a search result with the keyboard, pressed enter on
diff --git a/src/librustdoc/html/static/settings.js b/src/librustdoc/html/static/settings.js
index c21db7371f3..427a74c0c87 100644
--- a/src/librustdoc/html/static/settings.js
+++ b/src/librustdoc/html/static/settings.js
@@ -1,3 +1,6 @@
+// Local js definitions:
+/* global getCurrentValue, updateLocalStorage */
+
 (function () {
     function changeSetting(settingName, isEnabled) {
         updateLocalStorage('rustdoc-' + settingName, isEnabled);
diff --git a/src/librustdoc/html/static/source-script.js b/src/librustdoc/html/static/source-script.js
index 567022b4139..cfbfe6675f5 100644
--- a/src/librustdoc/html/static/source-script.js
+++ b/src/librustdoc/html/static/source-script.js
@@ -1,5 +1,5 @@
 // From rust:
-/* global sourcesIndex */
+/* global search, sourcesIndex */
 
 // Local js definitions:
 /* global addClass, getCurrentValue, hasClass, removeClass, updateLocalStorage */
diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js
index d142d99ac70..0a2fae274fa 100644
--- a/src/librustdoc/html/static/storage.js
+++ b/src/librustdoc/html/static/storage.js
@@ -27,14 +27,15 @@ function removeClass(elem, className) {
 function onEach(arr, func, reversed) {
     if (arr && arr.length > 0 && func) {
         var length = arr.length;
+        var i;
         if (reversed !== true) {
-            for (var i = 0; i < length; ++i) {
+            for (i = 0; i < length; ++i) {
                 if (func(arr[i]) === true) {
                     return true;
                 }
             }
         } else {
-            for (var i = length - 1; i >= 0; --i) {
+            for (i = length - 1; i >= 0; --i) {
                 if (func(arr[i]) === true) {
                     return true;
                 }
@@ -51,6 +52,10 @@ function onEachLazy(lazyArray, func, reversed) {
         reversed);
 }
 
+function hasOwnProperty(obj, property) {
+    return Object.prototype.hasOwnProperty.call(obj, property);
+}
+
 function usableLocalStorage() {
     // Check if the browser supports localStorage at all:
     if (typeof Storage === "undefined") {
diff --git a/src/test/ui/issues/issue-27060-rpass.rs b/src/test/ui/issues/issue-27060-rpass.rs
index b6ffc3ecb51..b20d614b303 100644
--- a/src/test/ui/issues/issue-27060-rpass.rs
+++ b/src/test/ui/issues/issue-27060-rpass.rs
@@ -7,19 +7,10 @@ pub struct Good {
     aligned: [u8; 32],
 }
 
-#[repr(packed)]
-pub struct JustArray {
-    array: [u32]
-}
-
 // kill this test when that turns to a hard error
 #[allow(safe_packed_borrows)]
 fn main() {
-    let good = Good {
-        data: &0,
-        data2: [&0, &0],
-        aligned: [0; 32]
-    };
+    let good = Good { data: &0, data2: [&0, &0], aligned: [0; 32] };
 
     unsafe {
         let _ = &good.data; // ok
diff --git a/src/test/ui/issues/issue-27060.rs b/src/test/ui/issues/issue-27060.rs
index 4caad03a361..78f2022ed38 100644
--- a/src/test/ui/issues/issue-27060.rs
+++ b/src/test/ui/issues/issue-27060.rs
@@ -5,11 +5,6 @@ pub struct Good {
     aligned: [u8; 32],
 }
 
-#[repr(packed)]
-pub struct JustArray {
-    array: [u32]
-}
-
 #[deny(safe_packed_borrows)]
 fn main() {
     let good = Good {
diff --git a/src/test/ui/issues/issue-27060.stderr b/src/test/ui/issues/issue-27060.stderr
index 6bf6348631a..d14ae4d41d5 100644
--- a/src/test/ui/issues/issue-27060.stderr
+++ b/src/test/ui/issues/issue-27060.stderr
@@ -1,11 +1,11 @@
 error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
-  --> $DIR/issue-27060.rs:26:13
+  --> $DIR/issue-27060.rs:21:13
    |
 LL |     let _ = &good.data;
    |             ^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/issue-27060.rs:13:8
+  --> $DIR/issue-27060.rs:8:8
    |
 LL | #[deny(safe_packed_borrows)]
    |        ^^^^^^^^^^^^^^^^^^^
@@ -14,7 +14,7 @@ LL | #[deny(safe_packed_borrows)]
    = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
 
 error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
-  --> $DIR/issue-27060.rs:28:13
+  --> $DIR/issue-27060.rs:23:13
    |
 LL |     let _ = &good.data2[0];
    |             ^^^^^^^^^^^^^^
diff --git a/src/test/ui/label/label_break_value_desugared_break.rs b/src/test/ui/label/label_break_value_desugared_break.rs
new file mode 100644
index 00000000000..de883b61111
--- /dev/null
+++ b/src/test/ui/label/label_break_value_desugared_break.rs
@@ -0,0 +1,12 @@
+// compile-flags: --edition 2018
+#![feature(label_break_value, try_blocks)]
+
+// run-pass
+fn main() {
+    let _: Result<(), ()> = try {
+        'foo: {
+            Err(())?;
+            break 'foo;
+        }
+    };
+}
diff --git a/src/test/ui/lint/unaligned_references.rs b/src/test/ui/lint/unaligned_references.rs
new file mode 100644
index 00000000000..1d9f4c3db2e
--- /dev/null
+++ b/src/test/ui/lint/unaligned_references.rs
@@ -0,0 +1,22 @@
+#![deny(unaligned_references)]
+
+#[repr(packed)]
+pub struct Good {
+    data: &'static u32,
+    data2: [&'static u32; 2],
+    aligned: [u8; 32],
+}
+
+fn main() {
+    unsafe {
+        let good = Good { data: &0, data2: [&0, &0], aligned: [0; 32] };
+
+        let _ = &good.data; //~ ERROR reference to packed field
+        let _ = &good.data as *const _; //~ ERROR reference to packed field
+        let _: *const _ = &good.data; //~ ERROR reference to packed field
+        let _ = &good.data2[0]; //~ ERROR reference to packed field
+        let _ = &*good.data; // ok, behind a pointer
+        let _ = &good.aligned; // ok, has align 1
+        let _ = &good.aligned[2]; // ok, has align 1
+    }
+}
diff --git a/src/test/ui/lint/unaligned_references.stderr b/src/test/ui/lint/unaligned_references.stderr
new file mode 100644
index 00000000000..0c594cdb30a
--- /dev/null
+++ b/src/test/ui/lint/unaligned_references.stderr
@@ -0,0 +1,39 @@
+error: reference to packed field is unaligned
+  --> $DIR/unaligned_references.rs:14:17
+   |
+LL |         let _ = &good.data;
+   |                 ^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/unaligned_references.rs:1:9
+   |
+LL | #![deny(unaligned_references)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+
+error: reference to packed field is unaligned
+  --> $DIR/unaligned_references.rs:15:17
+   |
+LL |         let _ = &good.data as *const _;
+   |                 ^^^^^^^^^^
+   |
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+
+error: reference to packed field is unaligned
+  --> $DIR/unaligned_references.rs:16:27
+   |
+LL |         let _: *const _ = &good.data;
+   |                           ^^^^^^^^^^
+   |
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+
+error: reference to packed field is unaligned
+  --> $DIR/unaligned_references.rs:17:17
+   |
+LL |         let _ = &good.data2[0];
+   |                 ^^^^^^^^^^^^^^
+   |
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/unsafe/unsafe-unstable-const-fn.rs b/src/test/ui/unsafe/unsafe-unstable-const-fn.rs
new file mode 100644
index 00000000000..d9d85ee9132
--- /dev/null
+++ b/src/test/ui/unsafe/unsafe-unstable-const-fn.rs
@@ -0,0 +1,13 @@
+#![stable(feature = "foo", since = "1.33.0")]
+#![feature(staged_api)]
+#![feature(const_compare_raw_pointers)]
+#![feature(const_fn)]
+
+#[stable(feature = "foo", since = "1.33.0")]
+#[rustc_const_unstable(feature = "const_foo", issue = "none")]
+const fn unstable(a: *const i32, b: *const i32) -> bool {
+    a == b
+    //~^ pointer operation is unsafe
+}
+
+fn main() {}
diff --git a/src/test/ui/unsafe/unsafe-unstable-const-fn.stderr b/src/test/ui/unsafe/unsafe-unstable-const-fn.stderr
new file mode 100644
index 00000000000..d8f3737c8f5
--- /dev/null
+++ b/src/test/ui/unsafe/unsafe-unstable-const-fn.stderr
@@ -0,0 +1,11 @@
+error[E0133]: pointer operation is unsafe and requires unsafe function or block
+  --> $DIR/unsafe-unstable-const-fn.rs:9:5
+   |
+LL |     a == b
+   |     ^^^^^^ pointer operation
+   |
+   = note: operations on pointers in constants
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unused-crate-deps/auxiliary/bar.rs b/src/test/ui/unused-crate-deps/auxiliary/bar.rs
new file mode 100644
index 00000000000..1d3824e7a44
--- /dev/null
+++ b/src/test/ui/unused-crate-deps/auxiliary/bar.rs
@@ -0,0 +1 @@
+pub const BAR: &str = "bar";
diff --git a/src/test/ui/unused-crate-deps/auxiliary/foo.rs b/src/test/ui/unused-crate-deps/auxiliary/foo.rs
new file mode 100644
index 00000000000..0ef03eb9edf
--- /dev/null
+++ b/src/test/ui/unused-crate-deps/auxiliary/foo.rs
@@ -0,0 +1,5 @@
+// edition:2018
+// aux-crate:bar=bar.rs
+
+pub const FOO: &str = "foo";
+pub use bar::BAR;
diff --git a/src/test/ui/unused-crate-deps/libfib.rs b/src/test/ui/unused-crate-deps/libfib.rs
new file mode 100644
index 00000000000..c1545dca99f
--- /dev/null
+++ b/src/test/ui/unused-crate-deps/libfib.rs
@@ -0,0 +1,21 @@
+// Test warnings for a library crate
+
+// check-pass
+// aux-crate:bar=bar.rs
+// compile-flags:--crate-type lib -Wunused-crate-dependencies
+
+pub fn fib(n: u32) -> Vec<u32> {
+//~^ WARNING external crate `bar` unused in
+let mut prev = 0;
+    let mut cur = 1;
+    let mut v = vec![];
+
+    for _ in 0..n {
+        v.push(prev);
+        let n = prev + cur;
+        prev = cur;
+        cur = n;
+    }
+
+    v
+}
diff --git a/src/test/ui/unused-crate-deps/libfib.stderr b/src/test/ui/unused-crate-deps/libfib.stderr
new file mode 100644
index 00000000000..15833126bd6
--- /dev/null
+++ b/src/test/ui/unused-crate-deps/libfib.stderr
@@ -0,0 +1,10 @@
+warning: external crate `bar` unused in `libfib`: remove the dependency or add `use bar as _;`
+  --> $DIR/libfib.rs:7:1
+   |
+LL | pub fn fib(n: u32) -> Vec<u32> {
+   | ^
+   |
+   = note: requested on the command line with `-W unused-crate-dependencies`
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/unused-crate-deps/suppress.rs b/src/test/ui/unused-crate-deps/suppress.rs
new file mode 100644
index 00000000000..8904d04bc14
--- /dev/null
+++ b/src/test/ui/unused-crate-deps/suppress.rs
@@ -0,0 +1,11 @@
+// Suppress by using crate
+
+// edition:2018
+// check-pass
+// aux-crate:bar=bar.rs
+
+#![warn(unused_crate_dependencies)]
+
+use bar as _;
+
+fn main() {}
diff --git a/src/test/ui/unused-crate-deps/unused-aliases.rs b/src/test/ui/unused-crate-deps/unused-aliases.rs
new file mode 100644
index 00000000000..1b7cb9b970e
--- /dev/null
+++ b/src/test/ui/unused-crate-deps/unused-aliases.rs
@@ -0,0 +1,13 @@
+// Warn about unused aliased for the crate
+
+// edition:2018
+// check-pass
+// aux-crate:bar=bar.rs
+// aux-crate:barbar=bar.rs
+
+#![warn(unused_crate_dependencies)]
+//~^ WARNING external crate `barbar` unused in
+
+use bar as _;
+
+fn main() {}
diff --git a/src/test/ui/unused-crate-deps/unused-aliases.stderr b/src/test/ui/unused-crate-deps/unused-aliases.stderr
new file mode 100644
index 00000000000..c8c6c4507b0
--- /dev/null
+++ b/src/test/ui/unused-crate-deps/unused-aliases.stderr
@@ -0,0 +1,14 @@
+warning: external crate `barbar` unused in `unused_aliases`: remove the dependency or add `use barbar as _;`
+  --> $DIR/unused-aliases.rs:8:1
+   |
+LL | #![warn(unused_crate_dependencies)]
+   | ^
+   |
+note: the lint level is defined here
+  --> $DIR/unused-aliases.rs:8:9
+   |
+LL | #![warn(unused_crate_dependencies)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/unused-crate-deps/use_extern_crate_2015.rs b/src/test/ui/unused-crate-deps/use_extern_crate_2015.rs
new file mode 100644
index 00000000000..f15c87fa0b2
--- /dev/null
+++ b/src/test/ui/unused-crate-deps/use_extern_crate_2015.rs
@@ -0,0 +1,13 @@
+// Suppress by using crate
+
+// edition:2015
+// check-pass
+// aux-crate:bar=bar.rs
+
+#![warn(unused_crate_dependencies)]
+
+extern crate bar;
+
+fn main() {
+    println!("bar {}", bar::BAR);
+}
diff --git a/src/test/ui/unused-crate-deps/warn-attr.rs b/src/test/ui/unused-crate-deps/warn-attr.rs
new file mode 100644
index 00000000000..1acb307ab21
--- /dev/null
+++ b/src/test/ui/unused-crate-deps/warn-attr.rs
@@ -0,0 +1,10 @@
+// Check for unused crate dep, no path
+
+// edition:2018
+// check-pass
+// aux-crate:bar=bar.rs
+
+#![warn(unused_crate_dependencies)]
+//~^ WARNING external crate `bar` unused in
+
+fn main() {}
diff --git a/src/test/ui/unused-crate-deps/warn-attr.stderr b/src/test/ui/unused-crate-deps/warn-attr.stderr
new file mode 100644
index 00000000000..0d38315704b
--- /dev/null
+++ b/src/test/ui/unused-crate-deps/warn-attr.stderr
@@ -0,0 +1,14 @@
+warning: external crate `bar` unused in `warn_attr`: remove the dependency or add `use bar as _;`
+  --> $DIR/warn-attr.rs:7:1
+   |
+LL | #![warn(unused_crate_dependencies)]
+   | ^
+   |
+note: the lint level is defined here
+  --> $DIR/warn-attr.rs:7:9
+   |
+LL | #![warn(unused_crate_dependencies)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/unused-crate-deps/warn-cmdline-static.rs b/src/test/ui/unused-crate-deps/warn-cmdline-static.rs
new file mode 100644
index 00000000000..c609529a6c6
--- /dev/null
+++ b/src/test/ui/unused-crate-deps/warn-cmdline-static.rs
@@ -0,0 +1,10 @@
+// Check for unused crate dep, no path
+
+// edition:2018
+// check-pass
+// compile-flags: -Wunused-crate-dependencies
+// aux-crate:bar=bar.rs
+// no-prefer-dynamic
+
+fn main() {}
+//~^ WARNING external crate `bar` unused in
diff --git a/src/test/ui/unused-crate-deps/warn-cmdline-static.stderr b/src/test/ui/unused-crate-deps/warn-cmdline-static.stderr
new file mode 100644
index 00000000000..65956461d64
--- /dev/null
+++ b/src/test/ui/unused-crate-deps/warn-cmdline-static.stderr
@@ -0,0 +1,10 @@
+warning: external crate `bar` unused in `warn_cmdline_static`: remove the dependency or add `use bar as _;`
+  --> $DIR/warn-cmdline-static.rs:9:1
+   |
+LL | fn main() {}
+   | ^
+   |
+   = note: requested on the command line with `-W unused-crate-dependencies`
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/unused-crate-deps/warn-cmdline.rs b/src/test/ui/unused-crate-deps/warn-cmdline.rs
new file mode 100644
index 00000000000..3bae61c3ea2
--- /dev/null
+++ b/src/test/ui/unused-crate-deps/warn-cmdline.rs
@@ -0,0 +1,9 @@
+// Check for unused crate dep, no path
+
+// edition:2018
+// check-pass
+// compile-flags: -Wunused-crate-dependencies
+// aux-crate:bar=bar.rs
+
+fn main() {}
+//~^ WARNING external crate `bar` unused in
diff --git a/src/test/ui/unused-crate-deps/warn-cmdline.stderr b/src/test/ui/unused-crate-deps/warn-cmdline.stderr
new file mode 100644
index 00000000000..ea675ba9a1e
--- /dev/null
+++ b/src/test/ui/unused-crate-deps/warn-cmdline.stderr
@@ -0,0 +1,10 @@
+warning: external crate `bar` unused in `warn_cmdline`: remove the dependency or add `use bar as _;`
+  --> $DIR/warn-cmdline.rs:8:1
+   |
+LL | fn main() {}
+   | ^
+   |
+   = note: requested on the command line with `-W unused-crate-dependencies`
+
+warning: 1 warning emitted
+
diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js
index 1fa46ce99f5..163571bc5b9 100644
--- a/src/tools/rustdoc-js/tester.js
+++ b/src/tools/rustdoc-js/tester.js
@@ -241,7 +241,7 @@ function loadMainJsAndIndex(mainJs, searchIndex, storageJs, crate) {
     ALIASES = {};
     finalJS += 'window = { "currentCrate": "' + crate + '" };\n';
     finalJS += 'var rootPath = "../";\n';
-    finalJS += loadThings(["onEach"], 'function', extractFunction, storageJs);
+    finalJS += loadThings(["hasOwnProperty", "onEach"], 'function', extractFunction, storageJs);
     finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs);
     finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs);
     finalJS += loadThings(functionsToLoad, 'function', extractFunction, mainJs);