about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-01-19 12:04:22 +0000
committerbors <bors@rust-lang.org>2021-01-19 12:04:22 +0000
commitf09fb488f70c5965ec4f64453a6e681fbfcff56c (patch)
treed31d1870ef32e0e3ee3ccb777ba9aa956a313591
parent47121d6d884bb60dad47e345f52f2ad6aadecaaf (diff)
parentdcb74796c0a644bc78fdadbfb2b8df0d9e9d9359 (diff)
downloadrust-f09fb488f70c5965ec4f64453a6e681fbfcff56c.tar.gz
rust-f09fb488f70c5965ec4f64453a6e681fbfcff56c.zip
Auto merge of #81186 - GuillaumeGomez:rollup-y2d04g9, r=GuillaumeGomez
Rollup of 8 pull requests

Successful merges:

 - #80382 (Improve search result tab handling)
 - #81112 (Remove unused alloc::std::ops re-export.)
 - #81115 (BTreeMap: prefer bulk_steal functions over specialized ones)
 - #81147 (Fix structured suggestion for explicit `drop` call)
 - #81161 (Remove inline script tags)
 - #81164 (Fix typo in simplify.rs)
 - #81166 (remove some outdated comments regarding  debug assertions)
 - #81168 (Fixes #81109 - Typo in pointer::wrapping_sub)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_mir_build/src/build/matches/simplify.rs2
-rw-r--r--compiler/rustc_typeck/src/check/callee.rs18
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs2
-rw-r--r--compiler/rustc_typeck/src/check/method/confirm.rs1
-rw-r--r--library/alloc/src/collections/btree/node.rs121
-rw-r--r--library/alloc/src/collections/btree/remove.rs8
-rw-r--r--library/alloc/src/lib.rs5
-rw-r--r--library/core/src/ptr/const_ptr.rs2
-rw-r--r--library/core/src/ptr/mod.rs3
-rw-r--r--library/core/src/ptr/mut_ptr.rs2
-rw-r--r--src/librustdoc/html/layout.rs5
-rw-r--r--src/librustdoc/html/markdown.rs2
-rw-r--r--src/librustdoc/html/render/mod.rs7
-rw-r--r--src/librustdoc/html/static/main.js54
-rw-r--r--src/test/ui/error-codes/E0040.fixed18
-rw-r--r--src/test/ui/error-codes/E0040.rs3
-rw-r--r--src/test/ui/error-codes/E0040.stderr10
-rw-r--r--src/test/ui/explicit/explicit-call-to-dtor.fixed16
-rw-r--r--src/test/ui/explicit/explicit-call-to-dtor.rs2
-rw-r--r--src/test/ui/explicit/explicit-call-to-dtor.stderr10
-rw-r--r--src/test/ui/explicit/explicit-call-to-supertrait-dtor.fixed26
-rw-r--r--src/test/ui/explicit/explicit-call-to-supertrait-dtor.rs5
-rw-r--r--src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr10
-rw-r--r--src/test/ui/illegal-ufcs-drop.fixed10
-rw-r--r--src/test/ui/illegal-ufcs-drop.rs1
-rw-r--r--src/test/ui/illegal-ufcs-drop.stderr2
-rw-r--r--src/tools/rustdoc-js/tester.js3
27 files changed, 166 insertions, 182 deletions
diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs
index 705266d4a0b..f30745d7185 100644
--- a/compiler/rustc_mir_build/src/build/matches/simplify.rs
+++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs
@@ -55,7 +55,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         // * the bindings from the previous iteration of the loop is prepended to the bindings from
         // the current iteration (in the implementation this is done by mem::swap and extend)
         // * after all iterations, these new bindings are then appended to the bindings that were
-        // prexisting (i.e. `candidate.binding` when the function was called).
+        // preexisting (i.e. `candidate.binding` when the function was called).
         //
         // example:
         // candidate.bindings = [1, 2, 3]
diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs
index 116b079e742..4836418b3c2 100644
--- a/compiler/rustc_typeck/src/check/callee.rs
+++ b/compiler/rustc_typeck/src/check/callee.rs
@@ -25,24 +25,24 @@ pub fn check_legal_trait_for_method_call(
     tcx: TyCtxt<'_>,
     span: Span,
     receiver: Option<Span>,
+    expr_span: Span,
     trait_id: DefId,
 ) {
     if tcx.lang_items().drop_trait() == Some(trait_id) {
         let mut err = struct_span_err!(tcx.sess, span, E0040, "explicit use of destructor method");
         err.span_label(span, "explicit destructor calls not allowed");
 
-        let snippet = receiver
+        let (sp, suggestion) = receiver
             .and_then(|s| tcx.sess.source_map().span_to_snippet(s).ok())
-            .unwrap_or_default();
-
-        let suggestion =
-            if snippet.is_empty() { "drop".to_string() } else { format!("drop({})", snippet) };
+            .filter(|snippet| !snippet.is_empty())
+            .map(|snippet| (expr_span, format!("drop({})", snippet)))
+            .unwrap_or_else(|| (span, "drop".to_string()));
 
         err.span_suggestion(
-            span,
-            &format!("consider using `drop` function: `{}`", suggestion),
-            String::new(),
-            Applicability::Unspecified,
+            sp,
+            "consider using `drop` function",
+            suggestion,
+            Applicability::MaybeIncorrect,
         );
 
         err.emit();
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index c491ba30841..ed48a0bc801 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -1163,7 +1163,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
                 match container {
                     ty::TraitContainer(trait_did) => {
-                        callee::check_legal_trait_for_method_call(tcx, span, None, trait_did)
+                        callee::check_legal_trait_for_method_call(tcx, span, None, span, trait_did)
                     }
                     ty::ImplContainer(impl_def_id) => {
                         if segments.len() == 1 {
diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs
index 97c9620eb16..e5f19281b07 100644
--- a/compiler/rustc_typeck/src/check/method/confirm.rs
+++ b/compiler/rustc_typeck/src/check/method/confirm.rs
@@ -508,6 +508,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
                 self.tcx,
                 self.span,
                 Some(self.self_expr.span),
+                self.call_expr.span,
                 trait_def_id,
             ),
             ty::ImplContainer(..) => {}
diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs
index 097e3e6d34e..8ab3f58c1ad 100644
--- a/library/alloc/src/collections/btree/node.rs
+++ b/library/alloc/src/collections/btree/node.rs
@@ -592,17 +592,6 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
             self.val_area_mut(idx).write(val);
         }
     }
-
-    /// Adds a key-value pair to the beginning of the node.
-    fn push_front(&mut self, key: K, val: V) {
-        let new_len = self.len() + 1;
-        assert!(new_len <= CAPACITY);
-        unsafe {
-            slice_insert(self.key_area_mut(..new_len), 0, key);
-            slice_insert(self.val_area_mut(..new_len), 0, val);
-            *self.len_mut() = new_len as u16;
-        }
-    }
 }
 
 impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
@@ -638,88 +627,6 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
             Handle::new_edge(self.reborrow_mut(), idx + 1).correct_parent_link();
         }
     }
-
-    /// Adds a key-value pair, and an edge to go to the left of that pair,
-    /// to the beginning of the node.
-    fn push_front(&mut self, key: K, val: V, edge: Root<K, V>) {
-        let new_len = self.len() + 1;
-        assert!(edge.height == self.height - 1);
-        assert!(new_len <= CAPACITY);
-
-        unsafe {
-            slice_insert(self.key_area_mut(..new_len), 0, key);
-            slice_insert(self.val_area_mut(..new_len), 0, val);
-            slice_insert(self.edge_area_mut(..new_len + 1), 0, edge.node);
-            *self.len_mut() = new_len as u16;
-        }
-
-        self.correct_all_childrens_parent_links();
-    }
-}
-
-impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
-    /// Removes a key-value pair from the end of the node and returns the pair.
-    /// Also removes the edge that was to the right of that pair and, if the node
-    /// is internal, returns the orphaned subtree that this edge owned.
-    ///
-    /// # Safety
-    /// The node must not be empty.
-    unsafe fn pop(&mut self) -> (K, V, Option<Root<K, V>>) {
-        debug_assert!(self.len() > 0);
-
-        let idx = self.len() - 1;
-
-        unsafe {
-            let key = self.key_area_mut(idx).assume_init_read();
-            let val = self.val_area_mut(idx).assume_init_read();
-            let edge = match self.reborrow_mut().force() {
-                ForceResult::Leaf(_) => None,
-                ForceResult::Internal(mut internal) => {
-                    let node = internal.edge_area_mut(idx + 1).assume_init_read();
-                    let mut edge = Root { node, height: internal.height - 1, _marker: PhantomData };
-                    // Currently, clearing the parent link is superfluous, because we will
-                    // insert the node elsewhere and set its parent link again.
-                    edge.clear_parent_link();
-                    Some(edge)
-                }
-            };
-
-            *self.len_mut() -= 1;
-            (key, val, edge)
-        }
-    }
-
-    /// Removes a key-value pair from the beginning of the node and returns the pair.
-    /// Also removes the edge that was to the left of that pair and, if the node is
-    /// internal, returns the orphaned subtree that this edge owned.
-    fn pop_front(&mut self) -> (K, V, Option<Root<K, V>>) {
-        debug_assert!(self.len() > 0);
-
-        let old_len = self.len();
-
-        unsafe {
-            let key = slice_remove(self.key_area_mut(..old_len), 0);
-            let val = slice_remove(self.val_area_mut(..old_len), 0);
-            let edge = match self.reborrow_mut().force() {
-                ForceResult::Leaf(_) => None,
-                ForceResult::Internal(mut internal) => {
-                    let node = slice_remove(internal.edge_area_mut(..old_len + 1), 0);
-                    let mut edge = Root { node, height: internal.height - 1, _marker: PhantomData };
-                    // Currently, clearing the parent link is superfluous, because we will
-                    // insert the node elsewhere and set its parent link again.
-                    edge.clear_parent_link();
-
-                    internal.correct_childrens_parent_links(0..old_len);
-
-                    Some(edge)
-                }
-            };
-
-            *self.len_mut() -= 1;
-
-            (key, val, edge)
-        }
-    }
 }
 
 impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
@@ -1399,18 +1306,8 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
         mut self,
         track_right_edge_idx: usize,
     ) -> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::Edge> {
-        unsafe {
-            let (k, v, edge) = self.left_child.pop();
-
-            let (k, v) = self.parent.replace_kv(k, v);
-
-            match self.right_child.reborrow_mut().force() {
-                ForceResult::Leaf(mut leaf) => leaf.push_front(k, v),
-                ForceResult::Internal(mut internal) => internal.push_front(k, v, edge.unwrap()),
-            }
-
-            Handle::new_edge(self.right_child, 1 + track_right_edge_idx)
-        }
+        self.bulk_steal_left(1);
+        unsafe { Handle::new_edge(self.right_child, 1 + track_right_edge_idx) }
     }
 
     /// Removes a key-value pair from the right child and places it in the key-value storage
@@ -1421,18 +1318,8 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
         mut self,
         track_left_edge_idx: usize,
     ) -> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::Edge> {
-        unsafe {
-            let (k, v, edge) = self.right_child.pop_front();
-
-            let (k, v) = self.parent.replace_kv(k, v);
-
-            match self.left_child.reborrow_mut().force() {
-                ForceResult::Leaf(mut leaf) => leaf.push(k, v),
-                ForceResult::Internal(mut internal) => internal.push(k, v, edge.unwrap()),
-            }
-
-            Handle::new_edge(self.left_child, track_left_edge_idx)
-        }
+        self.bulk_steal_right(1);
+        unsafe { Handle::new_edge(self.left_child, track_left_edge_idx) }
     }
 
     /// This does stealing similar to `steal_left` but steals multiple elements at once.
diff --git a/library/alloc/src/collections/btree/remove.rs b/library/alloc/src/collections/btree/remove.rs
index 04683e01de3..ff842197d19 100644
--- a/library/alloc/src/collections/btree/remove.rs
+++ b/library/alloc/src/collections/btree/remove.rs
@@ -121,25 +121,25 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
         self,
     ) -> Option<NodeRef<marker::Mut<'a>, K, V, marker::Internal>> {
         match self.forget_type().choose_parent_kv() {
-            Ok(Left(left_parent_kv)) => {
+            Ok(Left(mut left_parent_kv)) => {
                 debug_assert_eq!(left_parent_kv.right_child_len(), MIN_LEN - 1);
                 if left_parent_kv.can_merge() {
                     let parent = left_parent_kv.merge_tracking_parent();
                     Some(parent)
                 } else {
                     debug_assert!(left_parent_kv.left_child_len() > MIN_LEN);
-                    left_parent_kv.steal_left(0);
+                    left_parent_kv.bulk_steal_left(1);
                     None
                 }
             }
-            Ok(Right(right_parent_kv)) => {
+            Ok(Right(mut right_parent_kv)) => {
                 debug_assert_eq!(right_parent_kv.left_child_len(), MIN_LEN - 1);
                 if right_parent_kv.can_merge() {
                     let parent = right_parent_kv.merge_tracking_parent();
                     Some(parent)
                 } else {
                     debug_assert!(right_parent_kv.right_child_len() > MIN_LEN);
-                    right_parent_kv.steal_right(0);
+                    right_parent_kv.bulk_steal_right(1);
                     None
                 }
             }
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 14a10aac061..8d721ed7487 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -185,11 +185,6 @@ pub mod task;
 mod tests;
 pub mod vec;
 
-#[cfg(not(test))]
-mod std {
-    pub use core::ops; // RangeFull
-}
-
 #[doc(hidden)]
 #[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")]
 pub mod __export {
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 66300116786..28de28c70e4 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -633,7 +633,7 @@ impl<T: ?Sized> *const T {
     }
 
     /// Calculates the offset from a pointer using wrapping arithmetic.
-    /// (convenience for `.wrapping_offset((count as isize).wrapping_sub())`)
+    /// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`)
     ///
     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index d2e1bac58f4..8d901c08f91 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -687,7 +687,6 @@ pub unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
 pub const unsafe fn read<T>(src: *const T) -> T {
-    // `copy_nonoverlapping` takes care of debug_assert.
     let mut tmp = MaybeUninit::<T>::uninit();
     // SAFETY: the caller must guarantee that `src` is valid for reads.
     // `src` cannot overlap `tmp` because `tmp` was just allocated on
@@ -787,7 +786,6 @@ pub const unsafe fn read<T>(src: *const T) -> T {
 #[stable(feature = "ptr_unaligned", since = "1.17.0")]
 #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
 pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
-    // `copy_nonoverlapping` takes care of debug_assert.
     let mut tmp = MaybeUninit::<T>::uninit();
     // SAFETY: the caller must guarantee that `src` is valid for reads.
     // `src` cannot overlap `tmp` because `tmp` was just allocated on
@@ -988,7 +986,6 @@ pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
     // `dst` cannot overlap `src` because the caller has mutable access
     // to `dst` while `src` is owned by this function.
     unsafe {
-        // `copy_nonoverlapping` takes care of debug_assert.
         copy_nonoverlapping(&src as *const T as *const u8, dst as *mut u8, mem::size_of::<T>());
     }
     mem::forget(src);
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 785bf70c299..99744fc7112 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -740,7 +740,7 @@ impl<T: ?Sized> *mut T {
     }
 
     /// Calculates the offset from a pointer using wrapping arithmetic.
-    /// (convenience for `.wrapping_offset((count as isize).wrapping_sub())`)
+    /// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`)
     ///
     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index b5169b05997..4458eea95f3 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -111,10 +111,7 @@ crate fn render<T: Print, S: Print>(
     <section id=\"search\" class=\"content hidden\"></section>\
     <section class=\"footer\"></section>\
     {after_content}\
-    <script>\
-        window.rootPath = \"{root_path}\";\
-        window.currentCrate = \"{krate}\";\
-    </script>\
+    <div id=\"rustdoc-vars\" data-root-path=\"{root_path}\" data-current-crate=\"{krate}\"></div>
     <script src=\"{static_root_path}main{suffix}.js\"></script>\
     {static_extra_scripts}\
     {extra_scripts}\
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 33639055b59..cfa6cd96595 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -1313,6 +1313,8 @@ fn init_id_map() -> FxHashMap<String, usize> {
     map.insert("toggle-all-docs".to_owned(), 1);
     map.insert("all-types".to_owned(), 1);
     map.insert("default-settings".to_owned(), 1);
+    map.insert("rustdoc-vars".to_owned(), 1);
+    map.insert("sidebar-vars".to_owned(), 1);
     // This is the list of IDs used by rustdoc sections.
     map.insert("fields".to_owned(), 1);
     map.insert("variants".to_owned(), 1);
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 2db89e8a7ca..03e091297e5 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -4216,11 +4216,8 @@ fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer, cache:
     let relpath = if it.is_mod() { "../" } else { "" };
     write!(
         buffer,
-        "<script>window.sidebarCurrent = {{\
-                name: \"{name}\", \
-                ty: \"{ty}\", \
-                relpath: \"{path}\"\
-            }};</script>",
+        "<div id=\"sidebar-vars\" data-name=\"{name}\" data-ty=\"{ty}\" data-relpath=\"{path}\">\
+        </div>",
         name = it.name.unwrap_or(kw::Empty),
         ty = it.type_(),
         path = relpath
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 3ffb72ba3ee..74bd348e9ac 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -1,5 +1,5 @@
 // From rust:
-/* global ALIASES, currentCrate, rootPath */
+/* global ALIASES */
 
 // Local js definitions:
 /* global addClass, getCurrentValue, hasClass */
@@ -40,6 +40,21 @@ if (!DOMTokenList.prototype.remove) {
     };
 }
 
+(function () {
+    var rustdocVars = document.getElementById("rustdoc-vars");
+    if (rustdocVars) {
+        window.rootPath = rustdocVars.attributes["data-root-path"].value;
+        window.currentCrate = rustdocVars.attributes["data-current-crate"].value;
+    }
+    var sidebarVars = document.getElementById("sidebar-vars");
+    if (sidebarVars) {
+        window.sidebarCurrent = {
+            name: sidebarVars.attributes["data-name"].value,
+            ty: sidebarVars.attributes["data-ty"].value,
+            relpath: sidebarVars.attributes["data-relpath"].value,
+        };
+    }
+}());
 
 // Gets the human-readable string for the virtual-key code of the
 // given KeyboardEvent, ev.
@@ -565,7 +580,7 @@ function defocusSearchBar() {
                 var i, match,
                     url = document.location.href,
                     stripped = "",
-                    len = rootPath.match(/\.\.\//g).length + 1;
+                    len = window.rootPath.match(/\.\.\//g).length + 1;
 
                 for (i = 0; i < len; ++i) {
                     match = url.match(/\/[^\/]*$/);
@@ -1504,15 +1519,15 @@ function defocusSearchBar() {
 
             if (type === "mod") {
                 displayPath = path + "::";
-                href = rootPath + path.replace(/::/g, "/") + "/" +
+                href = window.rootPath + path.replace(/::/g, "/") + "/" +
                        name + "/index.html";
             } else if (type === "primitive" || type === "keyword") {
                 displayPath = "";
-                href = rootPath + path.replace(/::/g, "/") +
+                href = window.rootPath + path.replace(/::/g, "/") +
                        "/" + type + "." + name + ".html";
             } else if (type === "externcrate") {
                 displayPath = "";
-                href = rootPath + name + "/index.html";
+                href = window.rootPath + name + "/index.html";
             } else if (item.parent !== undefined) {
                 var myparent = item.parent;
                 var anchor = "#" + type + "." + name;
@@ -1535,13 +1550,13 @@ function defocusSearchBar() {
                 } else {
                     displayPath = path + "::" + myparent.name + "::";
                 }
-                href = rootPath + path.replace(/::/g, "/") +
+                href = window.rootPath + path.replace(/::/g, "/") +
                        "/" + pageType +
                        "." + pageName +
                        ".html" + anchor;
             } else {
                 displayPath = item.path + "::";
-                href = rootPath + item.path.replace(/::/g, "/") +
+                href = window.rootPath + item.path.replace(/::/g, "/") +
                        "/" + type + "." + name + ".html";
             }
             return [displayPath, href];
@@ -1650,6 +1665,21 @@ function defocusSearchBar() {
             var ret_in_args = addTab(results.in_args, query, false);
             var ret_returned = addTab(results.returned, query, false);
 
+            // Navigate to the relevant tab if the current tab is empty, like in case users search
+            // for "-> String". If they had selected another tab previously, they have to click on
+            // it again.
+            if ((currentTab === 0 && ret_others[1] === 0) ||
+                    (currentTab === 1 && ret_in_args[1] === 0) ||
+                    (currentTab === 2 && ret_returned[1] === 0)) {
+                if (ret_others[1] !== 0) {
+                    currentTab = 0;
+                } else if (ret_in_args[1] !== 0) {
+                    currentTab = 1;
+                } else if (ret_returned[1] !== 0) {
+                    currentTab = 2;
+                }
+            }
+
             var output = "<h1>Results for " + escape(query.query) +
                 (query.type ? " (type: " + escape(query.type) + ")" : "") + "</h1>" +
                 "<div id=\"titles\">" +
@@ -1973,7 +2003,7 @@ function defocusSearchBar() {
         startSearch();
 
         // Draw a convenient sidebar of known crates if we have a listing
-        if (rootPath === "../" || rootPath === "./") {
+        if (window.rootPath === "../" || window.rootPath === "./") {
             var sidebar = document.getElementsByClassName("sidebar-elems")[0];
             if (sidebar) {
                 var div = document.createElement("div");
@@ -1992,11 +2022,11 @@ function defocusSearchBar() {
                 crates.sort();
                 for (var i = 0; i < crates.length; ++i) {
                     var klass = "crate";
-                    if (rootPath !== "./" && crates[i] === window.currentCrate) {
+                    if (window.rootPath !== "./" && crates[i] === window.currentCrate) {
                         klass += " current";
                     }
                     var link = document.createElement("a");
-                    link.href = rootPath + crates[i] + "/index.html";
+                    link.href = window.rootPath + crates[i] + "/index.html";
                     // The summary in the search index has HTML, so we need to
                     // dynamically render it as plaintext.
                     link.title = convertHTMLToPlaintext(rawSearchIndex[crates[i]].doc);
@@ -2118,7 +2148,7 @@ function defocusSearchBar() {
 
         var libs = Object.getOwnPropertyNames(imp);
         for (var i = 0, llength = libs.length; i < llength; ++i) {
-            if (libs[i] === currentCrate) { continue; }
+            if (libs[i] === window.currentCrate) { continue; }
             var structs = imp[libs[i]];
 
             struct_loop:
@@ -2143,7 +2173,7 @@ function defocusSearchBar() {
                     var href = elem.getAttribute("href");
 
                     if (href && href.indexOf("http") !== 0) {
-                        elem.setAttribute("href", rootPath + href);
+                        elem.setAttribute("href", window.rootPath + href);
                     }
                 });
 
diff --git a/src/test/ui/error-codes/E0040.fixed b/src/test/ui/error-codes/E0040.fixed
new file mode 100644
index 00000000000..139dc8f9496
--- /dev/null
+++ b/src/test/ui/error-codes/E0040.fixed
@@ -0,0 +1,18 @@
+// run-rustfix
+struct Foo {
+    x: i32,
+}
+
+impl Drop for Foo {
+    fn drop(&mut self) {
+        println!("kaboom");
+    }
+}
+
+fn main() {
+    let mut x = Foo { x: -7 };
+    x.x = 0;
+    println!("{}", x.x);
+    drop(x);
+    //~^ ERROR E0040
+}
diff --git a/src/test/ui/error-codes/E0040.rs b/src/test/ui/error-codes/E0040.rs
index 113efae82c5..9ffc42d0c78 100644
--- a/src/test/ui/error-codes/E0040.rs
+++ b/src/test/ui/error-codes/E0040.rs
@@ -1,3 +1,4 @@
+// run-rustfix
 struct Foo {
     x: i32,
 }
@@ -10,6 +11,8 @@ impl Drop for Foo {
 
 fn main() {
     let mut x = Foo { x: -7 };
+    x.x = 0;
+    println!("{}", x.x);
     x.drop();
     //~^ ERROR E0040
 }
diff --git a/src/test/ui/error-codes/E0040.stderr b/src/test/ui/error-codes/E0040.stderr
index 69cf28b2970..9fcda1a9385 100644
--- a/src/test/ui/error-codes/E0040.stderr
+++ b/src/test/ui/error-codes/E0040.stderr
@@ -1,11 +1,11 @@
 error[E0040]: explicit use of destructor method
-  --> $DIR/E0040.rs:13:7
+  --> $DIR/E0040.rs:16:7
    |
 LL |     x.drop();
-   |       ^^^^
-   |       |
-   |       explicit destructor calls not allowed
-   |       help: consider using `drop` function: `drop(x)`
+   |     --^^^^--
+   |     | |
+   |     | explicit destructor calls not allowed
+   |     help: consider using `drop` function: `drop(x)`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/explicit/explicit-call-to-dtor.fixed b/src/test/ui/explicit/explicit-call-to-dtor.fixed
new file mode 100644
index 00000000000..91a4ca608da
--- /dev/null
+++ b/src/test/ui/explicit/explicit-call-to-dtor.fixed
@@ -0,0 +1,16 @@
+// run-rustfix
+struct Foo {
+    x: isize
+}
+
+impl Drop for Foo {
+    fn drop(&mut self) {
+        println!("kaboom");
+    }
+}
+
+fn main() {
+    let x = Foo { x: 3 };
+    println!("{}", x.x);
+    drop(x);   //~ ERROR explicit use of destructor method
+}
diff --git a/src/test/ui/explicit/explicit-call-to-dtor.rs b/src/test/ui/explicit/explicit-call-to-dtor.rs
index a6f9acc37a1..0656871eb1b 100644
--- a/src/test/ui/explicit/explicit-call-to-dtor.rs
+++ b/src/test/ui/explicit/explicit-call-to-dtor.rs
@@ -1,3 +1,4 @@
+// run-rustfix
 struct Foo {
     x: isize
 }
@@ -10,5 +11,6 @@ impl Drop for Foo {
 
 fn main() {
     let x = Foo { x: 3 };
+    println!("{}", x.x);
     x.drop();   //~ ERROR explicit use of destructor method
 }
diff --git a/src/test/ui/explicit/explicit-call-to-dtor.stderr b/src/test/ui/explicit/explicit-call-to-dtor.stderr
index 5ebe4ee4b90..f3c9bf6cccd 100644
--- a/src/test/ui/explicit/explicit-call-to-dtor.stderr
+++ b/src/test/ui/explicit/explicit-call-to-dtor.stderr
@@ -1,11 +1,11 @@
 error[E0040]: explicit use of destructor method
-  --> $DIR/explicit-call-to-dtor.rs:13:7
+  --> $DIR/explicit-call-to-dtor.rs:15:7
    |
 LL |     x.drop();
-   |       ^^^^
-   |       |
-   |       explicit destructor calls not allowed
-   |       help: consider using `drop` function: `drop(x)`
+   |     --^^^^--
+   |     | |
+   |     | explicit destructor calls not allowed
+   |     help: consider using `drop` function: `drop(x)`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/explicit/explicit-call-to-supertrait-dtor.fixed b/src/test/ui/explicit/explicit-call-to-supertrait-dtor.fixed
new file mode 100644
index 00000000000..47c4c9f67b6
--- /dev/null
+++ b/src/test/ui/explicit/explicit-call-to-supertrait-dtor.fixed
@@ -0,0 +1,26 @@
+// run-rustfix
+struct Foo {
+    x: isize
+}
+
+#[allow(drop_bounds)]
+trait Bar: Drop {
+    fn blah(&self);
+}
+
+impl Drop for Foo {
+    fn drop(&mut self) {
+        println!("kaboom");
+    }
+}
+
+impl Bar for Foo {
+    fn blah(&self) {
+        drop(self);    //~ ERROR explicit use of destructor method
+    }
+}
+
+fn main() {
+    let x = Foo { x: 3 };
+    println!("{}", x.x);
+}
diff --git a/src/test/ui/explicit/explicit-call-to-supertrait-dtor.rs b/src/test/ui/explicit/explicit-call-to-supertrait-dtor.rs
index ff56b9a8ae4..c698de50c75 100644
--- a/src/test/ui/explicit/explicit-call-to-supertrait-dtor.rs
+++ b/src/test/ui/explicit/explicit-call-to-supertrait-dtor.rs
@@ -1,8 +1,10 @@
+// run-rustfix
 struct Foo {
     x: isize
 }
 
-trait Bar : Drop {
+#[allow(drop_bounds)]
+trait Bar: Drop {
     fn blah(&self);
 }
 
@@ -20,4 +22,5 @@ impl Bar for Foo {
 
 fn main() {
     let x = Foo { x: 3 };
+    println!("{}", x.x);
 }
diff --git a/src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr b/src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr
index cd3fb3119a5..7f5106eb57e 100644
--- a/src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr
+++ b/src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr
@@ -1,11 +1,11 @@
 error[E0040]: explicit use of destructor method
-  --> $DIR/explicit-call-to-supertrait-dtor.rs:17:14
+  --> $DIR/explicit-call-to-supertrait-dtor.rs:19:14
    |
 LL |         self.drop();
-   |              ^^^^
-   |              |
-   |              explicit destructor calls not allowed
-   |              help: consider using `drop` function: `drop(self)`
+   |         -----^^^^--
+   |         |    |
+   |         |    explicit destructor calls not allowed
+   |         help: consider using `drop` function: `drop(self)`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/illegal-ufcs-drop.fixed b/src/test/ui/illegal-ufcs-drop.fixed
new file mode 100644
index 00000000000..d73b391be06
--- /dev/null
+++ b/src/test/ui/illegal-ufcs-drop.fixed
@@ -0,0 +1,10 @@
+// run-rustfix
+struct Foo;
+
+impl Drop for Foo {
+    fn drop(&mut self) {}
+}
+
+fn main() {
+    drop(&mut Foo) //~ ERROR explicit use of destructor method
+}
diff --git a/src/test/ui/illegal-ufcs-drop.rs b/src/test/ui/illegal-ufcs-drop.rs
index 5c072663eda..11411f55494 100644
--- a/src/test/ui/illegal-ufcs-drop.rs
+++ b/src/test/ui/illegal-ufcs-drop.rs
@@ -1,3 +1,4 @@
+// run-rustfix
 struct Foo;
 
 impl Drop for Foo {
diff --git a/src/test/ui/illegal-ufcs-drop.stderr b/src/test/ui/illegal-ufcs-drop.stderr
index 57c99739afd..91f47d5e456 100644
--- a/src/test/ui/illegal-ufcs-drop.stderr
+++ b/src/test/ui/illegal-ufcs-drop.stderr
@@ -1,5 +1,5 @@
 error[E0040]: explicit use of destructor method
-  --> $DIR/illegal-ufcs-drop.rs:8:5
+  --> $DIR/illegal-ufcs-drop.rs:9:5
    |
 LL |     Drop::drop(&mut Foo)
    |     ^^^^^^^^^^
diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js
index 63f2d2f5d2f..3f6bd603975 100644
--- a/src/tools/rustdoc-js/tester.js
+++ b/src/tools/rustdoc-js/tester.js
@@ -263,8 +263,7 @@ function loadMainJsAndIndex(mainJs, searchIndex, storageJs, crate) {
                            "handleAliases", "getQuery", "buildIndex", "execQuery", "execSearch"];
 
     ALIASES = {};
-    finalJS += 'window = { "currentCrate": "' + crate + '" };\n';
-    finalJS += 'var rootPath = "../";\n';
+    finalJS += 'window = { "currentCrate": "' + crate + '", rootPath: "../" };\n';
     finalJS += loadThings(["hasOwnProperty", "onEach"], 'function', extractFunction, storageJs);
     finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs);
     finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs);