about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock4
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs2
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs3
-rw-r--r--compiler/rustc_mir/src/interpret/operand.rs2
-rw-r--r--compiler/rustc_mir/src/interpret/terminator.rs2
-rw-r--r--compiler/rustc_mir/src/transform/simplify_comparison_integral.rs2
-rw-r--r--library/core/src/num/mod.rs2
-rw-r--r--library/core/src/stream/from_iter.rs38
-rw-r--r--library/core/src/stream/mod.rs2
-rw-r--r--library/proc_macro/src/bridge/mod.rs1
-rw-r--r--library/proc_macro/src/lib.rs2
-rw-r--r--library/std/tests/run-time-detect.rs38
m---------library/stdarch0
-rw-r--r--src/librustdoc/clean/mod.rs9
-rw-r--r--src/librustdoc/clean/types.rs2
-rw-r--r--src/librustdoc/formats/cache.rs2
-rw-r--r--src/librustdoc/html/format.rs4
-rw-r--r--src/librustdoc/html/render/cache.rs2
-rw-r--r--src/librustdoc/html/render/write_shared.rs40
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css66
-rw-r--r--src/librustdoc/html/static/css/themes/ayu.css5
-rw-r--r--src/librustdoc/html/static/css/themes/dark.css5
-rw-r--r--src/librustdoc/html/static/images/toggle-minus.svg1
-rw-r--r--src/librustdoc/html/static/images/toggle-plus.svg1
-rw-r--r--src/librustdoc/html/static_files.rs6
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs12
-rw-r--r--src/librustdoc/passes/collect_trait_impls.rs2
-rw-r--r--src/librustdoc/visit_ast.rs4
-rw-r--r--src/test/ui/proc-macro/auxiliary/api/parse.rs6
-rw-r--r--src/test/ui/union/union-drop.rs3
-rw-r--r--src/test/ui/union/union-drop.thirunsafeck.stderr22
-rw-r--r--src/test/ui/unsafe/union-assignop.mirunsafeck.stderr59
-rw-r--r--src/test/ui/unsafe/union-assignop.rs30
-rw-r--r--src/test/ui/unsafe/union-assignop.thirunsafeck.stderr59
m---------src/tools/cargo0
35 files changed, 373 insertions, 65 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 094a738b416..39688b7b7ea 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -255,7 +255,7 @@ checksum = "81a18687293a1546b67c246452202bbbf143d239cb43494cc163da14979082da"
 
 [[package]]
 name = "cargo"
-version = "0.56.0"
+version = "0.57.0"
 dependencies = [
  "anyhow",
  "atty",
@@ -388,7 +388,7 @@ dependencies = [
 
 [[package]]
 name = "cargo-util"
-version = "0.1.0"
+version = "0.1.1"
 dependencies = [
  "anyhow",
  "core-foundation",
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index c89d42ecc58..8d7e9612f47 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -47,8 +47,6 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
     ("sve", Some(sym::aarch64_target_feature)),
     // FEAT_CRC
     ("crc", Some(sym::aarch64_target_feature)),
-    // Cryptographic extension
-    ("crypto", Some(sym::aarch64_target_feature)),
     // FEAT_RAS
     ("ras", Some(sym::aarch64_target_feature)),
     // FEAT_LSE
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 47cc2ecb4bf..42ae8e972c2 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -582,6 +582,9 @@ impl server::Literal for Rustc<'_> {
 
         Ok(Literal { lit, span: self.call_site })
     }
+    fn to_string(&mut self, literal: &Self::Literal) -> String {
+        literal.lit.to_string()
+    }
     fn debug_kind(&mut self, literal: &Self::Literal) -> String {
         format!("{:?}", literal.lit.kind)
     }
diff --git a/compiler/rustc_mir/src/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs
index d5bc2b1e2ea..baef2a5a52c 100644
--- a/compiler/rustc_mir/src/interpret/operand.rs
+++ b/compiler/rustc_mir/src/interpret/operand.rs
@@ -599,7 +599,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 let ptr = self.global_base_pointer(Pointer::new(id, offset))?;
                 Operand::Indirect(MemPlace::from_ptr(ptr.into(), layout.align.abi))
             }
-            ConstValue::Scalar(x) => Operand::Immediate(tag_scalar(x.into())?.into()),
+            ConstValue::Scalar(x) => Operand::Immediate(tag_scalar(x)?.into()),
             ConstValue::Slice { data, start, end } => {
                 // We rely on mutability being set correctly in `data` to prevent writes
                 // where none should happen.
diff --git a/compiler/rustc_mir/src/interpret/terminator.rs b/compiler/rustc_mir/src/interpret/terminator.rs
index f369480d959..35ae07e25ca 100644
--- a/compiler/rustc_mir/src/interpret/terminator.rs
+++ b/compiler/rustc_mir/src/interpret/terminator.rs
@@ -73,7 +73,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     ty::FnPtr(sig) => {
                         let caller_abi = sig.abi();
                         let fn_ptr = self.read_pointer(&func)?;
-                        let fn_val = self.memory.get_fn(fn_ptr.into())?;
+                        let fn_val = self.memory.get_fn(fn_ptr)?;
                         (
                             fn_val,
                             caller_abi,
diff --git a/compiler/rustc_mir/src/transform/simplify_comparison_integral.rs b/compiler/rustc_mir/src/transform/simplify_comparison_integral.rs
index 1ddf7c9cd0c..948fcd9f455 100644
--- a/compiler/rustc_mir/src/transform/simplify_comparison_integral.rs
+++ b/compiler/rustc_mir/src/transform/simplify_comparison_integral.rs
@@ -211,7 +211,7 @@ fn find_branch_value_info<'tcx>(
                 return None;
             };
             let branch_value_scalar = branch_value.literal.try_to_scalar()?;
-            Some((branch_value_scalar.into(), branch_value_ty, *to_switch_on))
+            Some((branch_value_scalar, branch_value_ty, *to_switch_on))
         }
         _ => None,
     }
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 6c43d6d6212..9788404dd05 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -847,7 +847,7 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32) -> Result<T, Par
     use self::ParseIntError as PIE;
 
     assert!(
-        radix >= 2 && radix <= 36,
+        (2..=36).contains(&radix),
         "from_str_radix_int: must lie in the range `[2, 36]` - found {}",
         radix
     );
diff --git a/library/core/src/stream/from_iter.rs b/library/core/src/stream/from_iter.rs
new file mode 100644
index 00000000000..eb9a0fd2842
--- /dev/null
+++ b/library/core/src/stream/from_iter.rs
@@ -0,0 +1,38 @@
+use crate::pin::Pin;
+
+use crate::stream::Stream;
+use crate::task::{Context, Poll};
+
+/// A stream that was created from iterator.
+///
+/// This stream is created by the [`from_iter`] function.
+/// See it documentation for more.
+///
+/// [`from_iter`]: fn.from_iter.html
+#[unstable(feature = "stream_from_iter", issue = "81798")]
+#[derive(Clone, Debug)]
+pub struct FromIter<I> {
+    iter: I,
+}
+
+#[unstable(feature = "stream_from_iter", issue = "81798")]
+impl<I> Unpin for FromIter<I> {}
+
+/// Converts an iterator into a stream.
+#[unstable(feature = "stream_from_iter", issue = "81798")]
+pub fn from_iter<I: IntoIterator>(iter: I) -> FromIter<I::IntoIter> {
+    FromIter { iter: iter.into_iter() }
+}
+
+#[unstable(feature = "stream_from_iter", issue = "81798")]
+impl<I: Iterator> Stream for FromIter<I> {
+    type Item = I::Item;
+
+    fn poll_next(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        Poll::Ready(self.iter.next())
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+}
diff --git a/library/core/src/stream/mod.rs b/library/core/src/stream/mod.rs
index 0df18af65eb..58dc8e1e5e6 100644
--- a/library/core/src/stream/mod.rs
+++ b/library/core/src/stream/mod.rs
@@ -122,6 +122,8 @@
 //! warning: unused result that must be used: streams do nothing unless polled
 //! ```
 
+mod from_iter;
 mod stream;
 
+pub use from_iter::{from_iter, FromIter};
 pub use stream::Stream;
diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs
index b968d44fe48..7001e827ad8 100644
--- a/library/proc_macro/src/bridge/mod.rs
+++ b/library/proc_macro/src/bridge/mod.rs
@@ -109,6 +109,7 @@ macro_rules! with_api {
                 fn drop($self: $S::Literal);
                 fn clone($self: &$S::Literal) -> $S::Literal;
                 fn from_str(s: &str) -> Result<$S::Literal, ()>;
+                fn to_string($self: &$S::Literal) -> String;
                 fn debug_kind($self: &$S::Literal) -> String;
                 fn symbol($self: &$S::Literal) -> String;
                 fn suffix($self: &$S::Literal) -> Option<String>;
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 8138c3882fc..46f564199d0 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -1195,7 +1195,7 @@ impl FromStr for Literal {
 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
 impl ToString for Literal {
     fn to_string(&self) -> String {
-        TokenStream::from(TokenTree::from(self.clone())).to_string()
+        self.0.to_string()
     }
 }
 
diff --git a/library/std/tests/run-time-detect.rs b/library/std/tests/run-time-detect.rs
index c7107b5d0a3..079f00a5753 100644
--- a/library/std/tests/run-time-detect.rs
+++ b/library/std/tests/run-time-detect.rs
@@ -16,22 +16,56 @@
 fn arm_linux() {
     println!("neon: {}", is_arm_feature_detected!("neon"));
     println!("pmull: {}", is_arm_feature_detected!("pmull"));
+    println!("crypto: {}", is_arm_feature_detected!("crypto"));
+    println!("crc: {}", is_arm_feature_detected!("crc"));
+    println!("aes: {}", is_arm_feature_detected!("aes"));
+    println!("sha2: {}", is_arm_feature_detected!("sha2"));
 }
 
 #[test]
 #[cfg(all(target_arch = "aarch64", any(target_os = "linux", target_os = "android")))]
 fn aarch64_linux() {
-    println!("fp: {}", is_aarch64_feature_detected!("fp"));
-    println!("fp16: {}", is_aarch64_feature_detected!("fp16"));
     println!("neon: {}", is_aarch64_feature_detected!("neon"));
     println!("asimd: {}", is_aarch64_feature_detected!("asimd"));
+    println!("pmull: {}", is_aarch64_feature_detected!("pmull"));
+    println!("fp: {}", is_aarch64_feature_detected!("fp"));
+    println!("fp16: {}", is_aarch64_feature_detected!("fp16"));
     println!("sve: {}", is_aarch64_feature_detected!("sve"));
     println!("crc: {}", is_aarch64_feature_detected!("crc"));
     println!("lse: {}", is_aarch64_feature_detected!("lse"));
+    println!("lse2: {}", is_aarch64_feature_detected!("lse2"));
     println!("rdm: {}", is_aarch64_feature_detected!("rdm"));
     println!("rcpc: {}", is_aarch64_feature_detected!("rcpc"));
+    println!("rcpc2: {}", is_aarch64_feature_detected!("rcpc2"));
     println!("dotprod: {}", is_aarch64_feature_detected!("dotprod"));
     println!("tme: {}", is_aarch64_feature_detected!("tme"));
+    println!("fhm: {}", is_aarch64_feature_detected!("fhm"));
+    println!("dit: {}", is_aarch64_feature_detected!("dit"));
+    println!("flagm: {}", is_aarch64_feature_detected!("flagm"));
+    println!("ssbs: {}", is_aarch64_feature_detected!("ssbs"));
+    println!("sb: {}", is_aarch64_feature_detected!("sb"));
+    println!("pauth: {}", is_aarch64_feature_detected!("pauth"));
+    println!("dpb: {}", is_aarch64_feature_detected!("dpb"));
+    println!("dpb2: {}", is_aarch64_feature_detected!("dpb2"));
+    println!("sve2: {}", is_aarch64_feature_detected!("sve2"));
+    println!("sve2-aes: {}", is_aarch64_feature_detected!("sve2-aes"));
+    println!("sve2-sm4: {}", is_aarch64_feature_detected!("sve2-sm4"));
+    println!("sve2-sha3: {}", is_aarch64_feature_detected!("sve2-sha3"));
+    println!("sve2-bitperm: {}", is_aarch64_feature_detected!("sve2-bitperm"));
+    println!("frintts: {}", is_aarch64_feature_detected!("frintts"));
+    println!("i8mm: {}", is_aarch64_feature_detected!("i8mm"));
+    println!("f32mm: {}", is_aarch64_feature_detected!("f32mm"));
+    println!("f64mm: {}", is_aarch64_feature_detected!("f64mm"));
+    println!("bf16: {}", is_aarch64_feature_detected!("bf16"));
+    println!("rand: {}", is_aarch64_feature_detected!("rand"));
+    println!("bti: {}", is_aarch64_feature_detected!("bti"));
+    println!("mte: {}", is_aarch64_feature_detected!("mte"));
+    println!("jsconv: {}", is_aarch64_feature_detected!("jsconv"));
+    println!("fcma: {}", is_aarch64_feature_detected!("fcma"));
+    println!("aes: {}", is_aarch64_feature_detected!("aes"));
+    println!("sha2: {}", is_aarch64_feature_detected!("sha2"));
+    println!("sha3: {}", is_aarch64_feature_detected!("sha3"));
+    println!("sm4: {}", is_aarch64_feature_detected!("sm4"));
 }
 
 #[test]
diff --git a/library/stdarch b/library/stdarch
-Subproject 3001c75a1d2a81d2a76bef139c69387cb2ebb82
+Subproject c158cfd38e20d855f5d6ca8a5a101eefb82604a
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 75ea30bb565..b3fc1e73f78 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -675,11 +675,10 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
                         if let Some(((_, trait_did, name), rhs)) =
                             proj.as_ref().and_then(|(lhs, rhs)| Some((lhs.projection()?, rhs)))
                         {
-                            impl_trait_proj.entry(param_idx).or_default().push((
-                                trait_did.into(),
-                                name,
-                                rhs,
-                            ));
+                            impl_trait_proj
+                                .entry(param_idx)
+                                .or_default()
+                                .push((trait_did, name, rhs));
                         }
 
                         return None;
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 2460fa127f1..5c73d3de5b9 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1614,7 +1614,7 @@ impl Type {
 impl Type {
     fn inner_def_id(&self, cache: Option<&Cache>) -> Option<DefId> {
         let t: PrimitiveType = match *self {
-            ResolvedPath { did, .. } => return Some(did.into()),
+            ResolvedPath { did, .. } => return Some(did),
             DynTrait(ref bounds, _) => return bounds[0].trait_.inner_def_id(cache),
             Primitive(p) => return cache.and_then(|c| c.primitive_locations.get(&p).cloned()),
             BorrowedRef { type_: box Generic(..), .. } => PrimitiveType::Reference,
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index 5ea2cdc2ad9..3d267ca5033 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -228,7 +228,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
                 if i.blanket_impl.is_none() {
                     self.cache
                         .implementors
-                        .entry(did.into())
+                        .entry(did)
                         .or_default()
                         .push(Impl { impl_item: item.clone() });
                 }
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 0291236abdf..8ab6aa775d2 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -688,7 +688,7 @@ crate fn anchor<'a, 'cx: 'a>(
     text: &'a str,
     cx: &'cx Context<'_>,
 ) -> impl fmt::Display + 'a {
-    let parts = href(did.into(), cx);
+    let parts = href(did, cx);
     display_fn(move |f| {
         if let Ok((url, short_ty, fqp)) = parts {
             write!(
@@ -921,7 +921,7 @@ fn fmt_type<'cx>(
                 //        everything comes in as a fully resolved QPath (hard to
                 //        look at).
                 box clean::ResolvedPath { did, .. } => {
-                    match href(did.into(), cx) {
+                    match href(did, cx) {
                         Ok((ref url, _, ref path)) if !f.alternate() => {
                             write!(
                                 f,
diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs
index 0734d2670cc..1c083522bea 100644
--- a/src/librustdoc/html/render/cache.rs
+++ b/src/librustdoc/html/render/cache.rs
@@ -42,7 +42,7 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt<
                 name: item.name.unwrap().to_string(),
                 path: fqp[..fqp.len() - 1].join("::"),
                 desc,
-                parent: Some(did.into()),
+                parent: Some(did),
                 parent_idx: None,
                 search_type: get_index_search_type(&item, tcx),
                 aliases: item.attrs.get_doc_aliases(),
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index 94a902a2d05..4411b7771ed 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -175,9 +175,45 @@ pub(super) fn write_shared(
         cx.write_shared(SharedResource::InvocationSpecific { basename: p }, content, &options.emit)
     };
 
+    fn add_background_image_to_css(
+        cx: &Context<'_>,
+        css: &mut String,
+        rule: &str,
+        file: &'static str,
+    ) {
+        css.push_str(&format!(
+            "{} {{ background-image: url({}); }}",
+            rule,
+            SharedResource::ToolchainSpecific { basename: file }
+                .path(cx)
+                .file_name()
+                .unwrap()
+                .to_str()
+                .unwrap()
+        ))
+    }
+
+    // Add all the static files. These may already exist, but we just
+    // overwrite them anyway to make sure that they're fresh and up-to-date.
+    let mut rustdoc_css = static_files::RUSTDOC_CSS.to_owned();
+    add_background_image_to_css(
+        cx,
+        &mut rustdoc_css,
+        "details.undocumented[open] > summary::before, \
+         details.rustdoc-toggle[open] > summary::before, \
+         details.rustdoc-toggle[open] > summary.hideme::before",
+        "toggle-minus.svg",
+    );
+    add_background_image_to_css(
+        cx,
+        &mut rustdoc_css,
+        "details.undocumented > summary::before, details.rustdoc-toggle > summary::before",
+        "toggle-plus.svg",
+    );
+    write_minify("rustdoc.css", &rustdoc_css)?;
+
     // Add all the static files. These may already exist, but we just
     // overwrite them anyway to make sure that they're fresh and up-to-date.
-    write_minify("rustdoc.css", static_files::RUSTDOC_CSS)?;
     write_minify("settings.css", static_files::SETTINGS_CSS)?;
     write_minify("noscript.css", static_files::NOSCRIPT_CSS)?;
 
@@ -217,6 +253,8 @@ pub(super) fn write_shared(
     write_toolchain("wheel.svg", static_files::WHEEL_SVG)?;
     write_toolchain("clipboard.svg", static_files::CLIPBOARD_SVG)?;
     write_toolchain("down-arrow.svg", static_files::DOWN_ARROW_SVG)?;
+    write_toolchain("toggle-minus.svg", static_files::TOGGLE_MINUS_PNG)?;
+    write_toolchain("toggle-plus.svg", static_files::TOGGLE_PLUS_PNG)?;
 
     let mut themes: Vec<&String> = themes.iter().collect();
     themes.sort();
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 91243a4086c..4e33eab5650 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1508,11 +1508,35 @@ details.rustdoc-toggle > summary.hideme > span {
 }
 
 details.rustdoc-toggle > summary::before {
-	content: "[+]";
-	font-weight: 300;
-	font-size: 0.8em;
-	letter-spacing: 1px;
+	content: "";
 	cursor: pointer;
+	width: 17px;
+	height: max(17px, 1.1em);
+	background-repeat: no-repeat;
+	background-position: top left;
+	display: inline-block;
+	vertical-align: middle;
+	opacity: .5;
+}
+
+/* Screen readers see the text version at the end the line.
+	Visual readers see the icon at the start of the line, but small and transparent. */
+details.rustdoc-toggle > summary::after {
+	content: "Expand";
+	overflow: hidden;
+	width: 0;
+	height: 0;
+	position: absolute;
+}
+
+details.rustdoc-toggle > summary.hideme::after {
+	/* "hideme" toggles already have a description when they're contracted */
+	content: "";
+}
+
+details.rustdoc-toggle > summary:focus::before,
+details.rustdoc-toggle > summary:hover::before {
+	opacity: 1;
 }
 
 details.rustdoc-toggle.top-doc > summary,
@@ -1560,20 +1584,44 @@ details.rustdoc-toggle[open] > summary.hideme > span {
 	display: none;
 }
 
-details.rustdoc-toggle[open] > summary::before {
-	content: "[−]";
-	display: inline;
+details.rustdoc-toggle[open] > summary::before,
+details.rustdoc-toggle[open] > summary.hideme::before {
+	width: 17px;
+	height: max(17px, 1.1em);
+	background-repeat: no-repeat;
+	background-position: top left;
+	display: inline-block;
+	content: "";
+}
+
+details.rustdoc-toggle[open] > summary::after,
+details.rustdoc-toggle[open] > summary.hideme::after {
+	content: "Collapse";
 }
 
 details.undocumented > summary::before {
-	content: "[+] Show hidden undocumented items";
+	padding-left: 17px;
+	height: max(17px, 1.1em);
+	background-repeat: no-repeat;
+	background-position: top left;
+	content: "Show hidden undocumented items";
 	cursor: pointer;
 	font-size: 16px;
 	font-weight: 300;
+	opacity: .5;
+}
+
+details.undocumented > summary:focus::before,
+details.undocumented > summary:hover::before {
+	opacity: 1;
 }
 
 details.undocumented[open] > summary::before {
-	content: "[−] Hide undocumented items";
+	padding-left: 17px;
+	height: max(17px, 1.1em);
+	background-repeat: no-repeat
+	background-position: top left;
+	content: "Hide undocumented items";
 }
 
 /* Media Queries */
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index df386fb66a3..849924ea550 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -229,6 +229,11 @@ details.undocumented > summary::before {
 	color: #999;
 }
 
+details.rustdoc-toggle > summary::before,
+details.undocumented > summary::before {
+	filter: invert(100%);
+}
+
 #crate-search {
 	color: #c5c5c5;
 	background-color: #141920;
diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css
index c8a5dbdc66a..c26122e4bff 100644
--- a/src/librustdoc/html/static/css/themes/dark.css
+++ b/src/librustdoc/html/static/css/themes/dark.css
@@ -194,6 +194,11 @@ details.undocumented > summary::before {
 	color: #999;
 }
 
+details.rustdoc-toggle > summary::before,
+details.undocumented > summary::before {
+	filter: invert(100%);
+}
+
 #crate-search {
 	color: #111;
 	background-color: #f0f0f0;
diff --git a/src/librustdoc/html/static/images/toggle-minus.svg b/src/librustdoc/html/static/images/toggle-minus.svg
new file mode 100644
index 00000000000..73154788a0e
--- /dev/null
+++ b/src/librustdoc/html/static/images/toggle-minus.svg
@@ -0,0 +1 @@
+<svg width="17" height="17" shape-rendering="crispEdges" stroke="#000" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5 2.5H2.5v12H5m7-12h2.5v12H12M5 8.5h7"/></svg>
\ No newline at end of file
diff --git a/src/librustdoc/html/static/images/toggle-plus.svg b/src/librustdoc/html/static/images/toggle-plus.svg
new file mode 100644
index 00000000000..08b17033e16
--- /dev/null
+++ b/src/librustdoc/html/static/images/toggle-plus.svg
@@ -0,0 +1 @@
+<svg width="17" height="17" shape-rendering="crispEdges" stroke="#000" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5 2.5H2.5v12H5m7-12h2.5v12H12M5 8.5h7M8.5 12V8.625v0V5"/></svg>
\ No newline at end of file
diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs
index 2ec7e66234d..6f3d08ea655 100644
--- a/src/librustdoc/html/static_files.rs
+++ b/src/librustdoc/html/static_files.rs
@@ -47,6 +47,12 @@ crate static CLIPBOARD_SVG: &[u8] = include_bytes!("static/images/clipboard.svg"
 /// The file contents of `down-arrow.svg`, the icon used for the crate choice combobox.
 crate static DOWN_ARROW_SVG: &[u8] = include_bytes!("static/images/down-arrow.svg");
 
+/// The file contents of `toggle-minus.svg`, the icon used for opened toggles.
+crate static TOGGLE_MINUS_PNG: &[u8] = include_bytes!("static/images/toggle-minus.svg");
+
+/// The file contents of `toggle-plus.svg`, the icon used for closed toggles.
+crate static TOGGLE_PLUS_PNG: &[u8] = include_bytes!("static/images/toggle-plus.svg");
+
 /// The contents of `COPYRIGHT.txt`, the license listing for files distributed with documentation
 /// output.
 crate static COPYRIGHT: &[u8] = include_bytes!("static/COPYRIGHT.txt");
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index ddb7b85d34a..b36be9541d2 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -293,7 +293,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
     ) -> Result<(Res, Option<String>), ErrorKind<'path>> {
         let tcx = self.cx.tcx;
         let no_res = || ResolutionFailure::NotResolved {
-            module_id: module_id.into(),
+            module_id: module_id,
             partial_res: None,
             unresolved: path_str.into(),
         };
@@ -521,7 +521,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                     // but the disambiguator logic expects the associated item.
                     // Store the kind in a side channel so that only the disambiguator logic looks at it.
                     if let Some((kind, id)) = side_channel {
-                        self.kind_side_channel.set(Some((kind, id.into())));
+                        self.kind_side_channel.set(Some((kind, id)));
                     }
                     Ok((res, Some(fragment)))
                 };
@@ -1268,7 +1268,7 @@ impl LinkCollector<'_, '_> {
                     // doesn't allow statements like `use str::trim;`, making this a (hopefully)
                     // valid omission. See https://github.com/rust-lang/rust/pull/80660#discussion_r551585677
                     // for discussion on the matter.
-                    verify(kind, id.into())?;
+                    verify(kind, id)?;
 
                     // FIXME: it would be nice to check that the feature gate was enabled in the original crate, not just ignore it altogether.
                     // However I'm not sure how to check that across crates.
@@ -1306,9 +1306,9 @@ impl LinkCollector<'_, '_> {
                 Some(ItemLink { link: ori_link.link, link_text, did: None, fragment })
             }
             Res::Def(kind, id) => {
-                verify(kind, id.into())?;
+                verify(kind, id)?;
                 let id = clean::register_res(self.cx, rustc_hir::def::Res::Def(kind, id));
-                Some(ItemLink { link: ori_link.link, link_text, did: Some(id.into()), fragment })
+                Some(ItemLink { link: ori_link.link, link_text, did: Some(id), fragment })
             }
         }
     }
@@ -1886,7 +1886,7 @@ fn resolution_failure(
                         name = start;
                         for ns in [TypeNS, ValueNS, MacroNS] {
                             if let Some(res) =
-                                collector.check_full_res(ns, &start, module_id.into(), &None)
+                                collector.check_full_res(ns, &start, module_id, &None)
                             {
                                 debug!("found partial_res={:?}", res);
                                 *partial_res = Some(res);
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs
index 91c495a2bbc..eefe50caa34 100644
--- a/src/librustdoc/passes/collect_trait_impls.rs
+++ b/src/librustdoc/passes/collect_trait_impls.rs
@@ -45,7 +45,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
 
                 // FIXME(eddyb) is this `doc(hidden)` check needed?
                 if !cx.tcx.get_attrs(def_id).lists(sym::doc).has_word(sym::hidden) {
-                    let impls = get_auto_trait_and_blanket_impls(cx, def_id.into());
+                    let impls = get_auto_trait_and_blanket_impls(cx, def_id);
                     new_items.extend(impls.filter(|i| cx.inlined.insert(i.def_id)));
                 }
             });
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index d74b3b46272..e2891035535 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -192,7 +192,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     } else {
                         // All items need to be handled here in case someone wishes to link
                         // to them with intra-doc links
-                        self.cx.cache.access_levels.map.insert(did.into(), AccessLevel::Public);
+                        self.cx.cache.access_levels.map.insert(did, AccessLevel::Public);
                     }
                 }
             }
@@ -204,7 +204,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             None => return false,
         };
 
-        let is_private = !self.cx.cache.access_levels.is_public(res_did.into());
+        let is_private = !self.cx.cache.access_levels.is_public(res_did);
         let is_hidden = inherits_doc_hidden(self.cx.tcx, res_hir_id);
 
         // Only inline if requested or if the item would otherwise be stripped.
diff --git a/src/test/ui/proc-macro/auxiliary/api/parse.rs b/src/test/ui/proc-macro/auxiliary/api/parse.rs
index a304c5e81a4..93551ebaf82 100644
--- a/src/test/ui/proc-macro/auxiliary/api/parse.rs
+++ b/src/test/ui/proc-macro/auxiliary/api/parse.rs
@@ -6,8 +6,8 @@ pub fn test() {
 }
 
 fn test_display_literal() {
-    assert_eq!(Literal::isize_unsuffixed(-10).to_string(), "- 10");
-    assert_eq!(Literal::isize_suffixed(-10).to_string(), "- 10isize");
+    assert_eq!(Literal::isize_unsuffixed(-10).to_string(), "-10");
+    assert_eq!(Literal::isize_suffixed(-10).to_string(), "-10isize");
 }
 
 fn test_parse_literal() {
@@ -18,7 +18,7 @@ fn test_parse_literal() {
     assert_eq!("b\"\"".parse::<Literal>().unwrap().to_string(), "b\"\"");
     assert_eq!("r##\"\"##".parse::<Literal>().unwrap().to_string(), "r##\"\"##");
     assert_eq!("10ulong".parse::<Literal>().unwrap().to_string(), "10ulong");
-    assert_eq!("-10ulong".parse::<Literal>().unwrap().to_string(), "- 10ulong");
+    assert_eq!("-10ulong".parse::<Literal>().unwrap().to_string(), "-10ulong");
 
     assert!("true".parse::<Literal>().is_err());
     assert!(".8".parse::<Literal>().is_err());
diff --git a/src/test/ui/union/union-drop.rs b/src/test/ui/union/union-drop.rs
index 9edf5827511..c3d7d41ca35 100644
--- a/src/test/ui/union/union-drop.rs
+++ b/src/test/ui/union/union-drop.rs
@@ -1,4 +1,7 @@
 // run-pass
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
 #![allow(dead_code)]
 #![allow(unused_variables)]
 
diff --git a/src/test/ui/union/union-drop.thirunsafeck.stderr b/src/test/ui/union/union-drop.thirunsafeck.stderr
deleted file mode 100644
index 9766ae4e435..00000000000
--- a/src/test/ui/union/union-drop.thirunsafeck.stderr
+++ /dev/null
@@ -1,22 +0,0 @@
-warning: unnecessary `unsafe` block
-  --> $DIR/union-drop.rs:27:9
-   |
-LL |         unsafe { CHECK += 1; }
-   |         ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: `#[warn(unused_unsafe)]` on by default
-
-warning: unnecessary `unsafe` block
-  --> $DIR/union-drop.rs:33:9
-   |
-LL |         unsafe { CHECK += 1; }
-   |         ^^^^^^ unnecessary `unsafe` block
-
-warning: unnecessary `unsafe` block
-  --> $DIR/union-drop.rs:40:5
-   |
-LL |     unsafe {
-   |     ^^^^^^ unnecessary `unsafe` block
-
-warning: 3 warnings emitted
-
diff --git a/src/test/ui/unsafe/union-assignop.mirunsafeck.stderr b/src/test/ui/unsafe/union-assignop.mirunsafeck.stderr
new file mode 100644
index 00000000000..cd338ac9e3a
--- /dev/null
+++ b/src/test/ui/unsafe/union-assignop.mirunsafeck.stderr
@@ -0,0 +1,59 @@
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union-assignop.rs:20:5
+   |
+LL |     foo.a += 5;
+   |     ^^^^^^^^^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union-assignop.rs:21:5
+   |
+LL |     foo.b += Dropping;
+   |     ^^^^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error[E0133]: assignment to union field that might need dropping is unsafe and requires unsafe function or block
+  --> $DIR/union-assignop.rs:22:5
+   |
+LL |     foo.b = Dropping;
+   |     ^^^^^^^^^^^^^^^^ assignment to union field that might need dropping
+   |
+   = note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized
+
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union-assignop.rs:23:5
+   |
+LL |     foo.a;
+   |     ^^^^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union-assignop.rs:25:5
+   |
+LL |     foo.b;
+   |     ^^^^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union-assignop.rs:27:13
+   |
+LL |     foo.b = foo.b;
+   |             ^^^^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error[E0133]: assignment to union field that might need dropping is unsafe and requires unsafe function or block
+  --> $DIR/union-assignop.rs:27:5
+   |
+LL |     foo.b = foo.b;
+   |     ^^^^^^^^^^^^^ assignment to union field that might need dropping
+   |
+   = note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/union-assignop.rs b/src/test/ui/unsafe/union-assignop.rs
new file mode 100644
index 00000000000..c4be20aa567
--- /dev/null
+++ b/src/test/ui/unsafe/union-assignop.rs
@@ -0,0 +1,30 @@
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
+#![feature(untagged_unions)]
+
+use std::ops::AddAssign;
+
+struct Dropping;
+impl AddAssign for Dropping {
+    fn add_assign(&mut self, _: Self) {}
+}
+
+union Foo {
+    a: u8, // non-dropping
+    b: Dropping, // treated as dropping
+}
+
+fn main() {
+    let mut foo = Foo { a: 42 };
+    foo.a += 5; //~ ERROR access to union field is unsafe
+    foo.b += Dropping; //~ ERROR access to union field is unsafe
+    foo.b = Dropping; //~ ERROR assignment to union field that might need dropping is unsafe
+    foo.a; //~ ERROR access to union field is unsafe
+    let foo = Foo { a: 42 };
+    foo.b; //~ ERROR access to union field is unsafe
+    let mut foo = Foo { a: 42 };
+    foo.b = foo.b;
+    //~^ ERROR access to union field is unsafe
+    //~| ERROR assignment to union field that might need dropping
+}
diff --git a/src/test/ui/unsafe/union-assignop.thirunsafeck.stderr b/src/test/ui/unsafe/union-assignop.thirunsafeck.stderr
new file mode 100644
index 00000000000..71de421a255
--- /dev/null
+++ b/src/test/ui/unsafe/union-assignop.thirunsafeck.stderr
@@ -0,0 +1,59 @@
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union-assignop.rs:20:5
+   |
+LL |     foo.a += 5;
+   |     ^^^^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union-assignop.rs:21:5
+   |
+LL |     foo.b += Dropping;
+   |     ^^^^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error[E0133]: assignment to union field that might need dropping is unsafe and requires unsafe function or block
+  --> $DIR/union-assignop.rs:22:5
+   |
+LL |     foo.b = Dropping;
+   |     ^^^^^^^^^^^^^^^^ assignment to union field that might need dropping
+   |
+   = note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized
+
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union-assignop.rs:23:5
+   |
+LL |     foo.a;
+   |     ^^^^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union-assignop.rs:25:5
+   |
+LL |     foo.b;
+   |     ^^^^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error[E0133]: assignment to union field that might need dropping is unsafe and requires unsafe function or block
+  --> $DIR/union-assignop.rs:27:5
+   |
+LL |     foo.b = foo.b;
+   |     ^^^^^^^^^^^^^ assignment to union field that might need dropping
+   |
+   = note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized
+
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union-assignop.rs:27:13
+   |
+LL |     foo.b = foo.b;
+   |             ^^^^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject d21c22870e58499d6c31f1bef3bf1255eb02166
+Subproject cc17afbb0067b1f57d8882640f63b2168d5b762