diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 51c012bc9c6e1..29421895a9482 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -297,6 +297,9 @@ jobs:
           - name: dist-powerpc64le-linux
             os: ubuntu-latest-xl
             env: {}
+          - name: dist-riscv64-linux
+            os: ubuntu-latest-xl
+            env: {}
           - name: dist-s390x-linux
             os: ubuntu-latest-xl
             env: {}
diff --git a/RELEASES.md b/RELEASES.md
index 977796c66132e..7bac14cb41534 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -82,6 +82,9 @@ Stabilized APIs
 Cargo
 -----
 
+- [Cargo uses the `embed-bitcode` flag to optimize disk usage and build
+  time.][cargo/8066]
+
 Misc
 ----
 - [Rustdoc now supports strikethrough text in Markdown.][71928] E.g.
@@ -97,12 +100,18 @@ Compatibility Notes
 - [Rustdoc's CLI's extra error exit codes have been removed.][71900] These were
   previously undocumented and not intended for public use. Rustdoc still provides
   a non-zero exit code on errors.
+- [Rustc's `lto` flag is incompatible with the new `embed-bitcode=no`.][71848]
+  This may cause issues if LTO is enabled through `RUSTFLAGS` or `cargo rustc`
+  flags while cargo is adding `embed-bitcode` itself. The recommended way to
+  control LTO is with Cargo profiles, either in `Cargo.toml` or `.cargo/config`,
+  or by setting `CARGO_PROFILE_<name>_LTO` in the environment.
 
 Internals Only
 --------------
 - [Make clippy a git subtree instead of a git submodule][70655]
 - [Unify the undo log of all snapshot types][69464]
 
+[71848]: https://github.com/rust-lang/rust/issues/71848/
 [73420]: https://github.com/rust-lang/rust/issues/73420/
 [72324]: https://github.com/rust-lang/rust/pull/72324/
 [71843]: https://github.com/rust-lang/rust/pull/71843/
@@ -129,6 +138,7 @@ Internals Only
 [69813]: https://github.com/rust-lang/rust/pull/69813/
 [69464]: https://github.com/rust-lang/rust/pull/69464/
 [68717]: https://github.com/rust-lang/rust/pull/68717/
+[cargo/8066]: https://github.com/rust-lang/cargo/pull/8066
 [`Arc::as_ptr`]: https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.as_ptr
 [`BTreeMap::remove_entry`]: https://doc.rust-lang.org/stable/std/collections/struct.BTreeMap.html#method.remove_entry
 [`Rc::as_ptr`]: https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.as_ptr
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index ca0b3ddc920ed..b7c527f6712e1 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -112,6 +112,15 @@ impl Step for Llvm {
     /// Compile LLVM for `target`.
     fn run(self, builder: &Builder<'_>) -> PathBuf {
         let target = self.target;
+        let target_native = if self.target.starts_with("riscv") {
+            // RISC-V target triples in Rust is not named the same as C compiler target triples.
+            // This converts Rust RISC-V target triples to C compiler triples.
+            let idx = target.find('-').unwrap();
+
+            format!("riscv{}{}", &target[5..7], &target[idx..])
+        } else {
+            target.to_string()
+        };
 
         let Meta { stamp, build_llvm_config, out_dir, root } =
             match prebuilt_llvm_config(builder, target) {
@@ -165,8 +174,8 @@ impl Step for Llvm {
             .define("LLVM_ENABLE_BINDINGS", "OFF")
             .define("LLVM_ENABLE_Z3_SOLVER", "OFF")
             .define("LLVM_PARALLEL_COMPILE_JOBS", builder.jobs().to_string())
-            .define("LLVM_TARGET_ARCH", target.split('-').next().unwrap())
-            .define("LLVM_DEFAULT_TARGET_TRIPLE", target);
+            .define("LLVM_TARGET_ARCH", target_native.split('-').next().unwrap())
+            .define("LLVM_DEFAULT_TARGET_TRIPLE", target_native);
 
         if !target.contains("netbsd") {
             cfg.define("LLVM_ENABLE_ZLIB", "ON");
@@ -213,6 +222,17 @@ impl Step for Llvm {
             }
         }
 
+        if target.starts_with("riscv") {
+            // In RISC-V, using C++ atomics require linking to `libatomic` but the LLVM build
+            // system check cannot detect this. Therefore it is set manually here.
+            if !builder.config.llvm_tools_enabled {
+                cfg.define("CMAKE_EXE_LINKER_FLAGS", "-latomic");
+            } else {
+                cfg.define("CMAKE_EXE_LINKER_FLAGS", "-latomic -static-libstdc++");
+            }
+            cfg.define("CMAKE_SHARED_LINKER_FLAGS", "-latomic");
+        }
+
         if target.contains("msvc") {
             cfg.define("LLVM_USE_CRT_DEBUG", "MT");
             cfg.define("LLVM_USE_CRT_RELEASE", "MT");
diff --git a/src/ci/azure-pipelines/auto.yml b/src/ci/azure-pipelines/auto.yml
index 0b460bbe865ee..1786baa0278b9 100644
--- a/src/ci/azure-pipelines/auto.yml
+++ b/src/ci/azure-pipelines/auto.yml
@@ -53,6 +53,7 @@ jobs:
       dist-powerpc-linux: {}
       dist-powerpc64-linux: {}
       dist-powerpc64le-linux: {}
+      dist-riscv64-linux: {}
       dist-s390x-linux: {}
       dist-x86_64-freebsd: {}
       dist-x86_64-illumos: {}
diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md
index 7e79cc8851369..ff28f4f603c9d 100644
--- a/src/ci/docker/README.md
+++ b/src/ci/docker/README.md
@@ -16,6 +16,11 @@ for example:
 
 Images will output artifacts in an `obj` dir at the root of a repository.
 
+To match conditions in rusts CI, also set the environment variable `DEPLOY=1`, e.g.:
+```
+DEPLOY=1 ./src/ci/docker/run.sh x86_64-gnu
+```
+
 **NOTE**: Re-using the same `obj` dir with different docker images with
 the same target triple (e.g. `dist-x86_64-linux` and `dist-various-1`)
 may result in strange linker errors, due shared library versions differing between platforms.
@@ -85,27 +90,44 @@ how to generate them, and how the existing ones were generated.
 
 ### Generating a `.config` file
 
+**NOTE:** Existing Dockerfiles can also be a good guide for the process and order
+of script execution.
+
 If you have a `linux-cross` image lying around you can use that and skip the
 next two steps.
 
-- First we spin up a container and copy `build_toolchain_root.sh` into it. All
+- First we spin up a container and copy all scripts into it. All
   these steps are outside the container:
 
 ```
-# Note: We use ubuntu:15.10 because that's the "base" of linux-cross Docker
-# image
-$ docker run -it ubuntu:15.10 bash
+# Note: We use ubuntu:16.04 because that's the "base" of linux-cross Docker
+# image, or simply run ./src/ci/docker/run.sh once, which will download the correct
+# one and you can check it out with `docker images`
+$ docker run -it ubuntu:16.04 bash
+# in another terminal:
 $ docker ps
 CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
-cfbec05ed730        ubuntu:15.10        "bash"              16 seconds ago      Up 15 seconds                           drunk_murdock
-$ docker cp build_toolchain_root.sh drunk_murdock:/
+cfbec05ed730        ubuntu:16.04        "bash"              16 seconds ago      Up 15 seconds                           drunk_murdock
+$ docker cp src/ci/docker/scripts drunk_murdock:/tmp/
 ```
 
 - Then inside the container we build crosstool-ng by simply calling the bash
   script we copied in the previous step:
 
 ```
-$ bash build_toolchain_root.sh
+$ cd /tmp/scripts
+# Download packages necessary for building
+$ bash ./cross-apt-packages.sh
+# Download and build crosstool-ng
+$ bash ./crosstool-ng.sh
+```
+
+- In case you want to adjust or start from an existing config, copy that
+  to the container. `crosstool-ng` will automatically load `./.config` if
+  present. Otherwise one can use the TUI to load any config-file.
+
+```
+$ docker cp arm-linux-gnueabi.config drunk_murdock:/tmp/.config
 ```
 
 - Now, inside the container run the following command to configure the
@@ -113,6 +135,7 @@ $ bash build_toolchain_root.sh
   section and come back.
 
 ```
+$ cd /tmp/
 $ ct-ng menuconfig
 ```
 
@@ -120,7 +143,7 @@ $ ct-ng menuconfig
   meaningful name. This is done outside the container.
 
 ```
-$ docker drunk_murdock:/.config arm-linux-gnueabi.config
+$ docker cp drunk_murdock:/tmp/.config arm-linux-gnueabi.config
 ```
 
 - Now you can shutdown the container or repeat the two last steps to generate a
diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile
new file mode 100644
index 0000000000000..dff7c475157a2
--- /dev/null
+++ b/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile
@@ -0,0 +1,31 @@
+FROM ubuntu:18.04
+
+COPY scripts/cross-apt-packages.sh /scripts/
+RUN sh /scripts/cross-apt-packages.sh
+
+COPY host-x86_64/dist-riscv64-linux/crosstool-ng.sh /scripts/
+RUN sh /scripts/crosstool-ng.sh
+
+COPY scripts/rustbuild-setup.sh /scripts/
+RUN sh /scripts/rustbuild-setup.sh
+USER rustbuild
+WORKDIR /tmp
+
+COPY host-x86_64/dist-riscv64-linux/build-toolchains.sh host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.config /tmp/
+RUN ./build-toolchains.sh
+
+USER root
+
+COPY scripts/sccache.sh /scripts/
+RUN sh /scripts/sccache.sh
+
+ENV PATH=$PATH:/x-tools/riscv64-unknown-linux-gnu/bin
+
+ENV CC_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-gcc \
+    AR_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-ar \
+    CXX_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-g++
+
+ENV HOSTS=riscv64gc-unknown-linux-gnu
+
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
+ENV SCRIPT python3 ../x.py dist --target $HOSTS --host $HOSTS
diff --git a/src/ci/docker/host-x86_64/dist-various-1/build-riscv-toolchain.sh b/src/ci/docker/host-x86_64/dist-riscv64-linux/build-toolchains.sh
similarity index 75%
rename from src/ci/docker/host-x86_64/dist-various-1/build-riscv-toolchain.sh
rename to src/ci/docker/host-x86_64/dist-riscv64-linux/build-toolchains.sh
index 9cb5700b3b6fb..6a7c022d01a5d 100755
--- a/src/ci/docker/host-x86_64/dist-various-1/build-riscv-toolchain.sh
+++ b/src/ci/docker/host-x86_64/dist-riscv64-linux/build-toolchains.sh
@@ -19,9 +19,9 @@ exit 1
   set -x
 }
 
-mkdir -p /tmp/build-riscv
-cp riscv64-unknown-linux-gnu.config /tmp/build-riscv/.config
-cd /tmp/build-riscv
+mkdir build
+cd build
+cp ../riscv64-unknown-linux-gnu.config .config
 hide_output ct-ng build
 cd ..
-rm -rf build-riscv
+rm -rf build
diff --git a/src/ci/docker/host-x86_64/dist-various-1/crosstool-ng.sh b/src/ci/docker/host-x86_64/dist-riscv64-linux/crosstool-ng.sh
old mode 100755
new mode 100644
similarity index 96%
rename from src/ci/docker/host-x86_64/dist-various-1/crosstool-ng.sh
rename to src/ci/docker/host-x86_64/dist-riscv64-linux/crosstool-ng.sh
index b01fdd0bf65e7..fb067a79a5c85
--- a/src/ci/docker/host-x86_64/dist-various-1/crosstool-ng.sh
+++ b/src/ci/docker/host-x86_64/dist-riscv64-linux/crosstool-ng.sh
@@ -1,4 +1,3 @@
-#!/bin/bash
 set -ex
 
 # Mirrored from https://github.com/crosstool-ng/crosstool-ng/archive/crosstool-ng-1.24.0.tar.gz
diff --git a/src/ci/docker/host-x86_64/dist-various-1/riscv64-unknown-linux-gnu.config b/src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.config
similarity index 99%
rename from src/ci/docker/host-x86_64/dist-various-1/riscv64-unknown-linux-gnu.config
rename to src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.config
index dd06065b19740..dbb4be550dd70 100644
--- a/src/ci/docker/host-x86_64/dist-various-1/riscv64-unknown-linux-gnu.config
+++ b/src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.config
@@ -17,8 +17,6 @@ CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y
 CT_CONFIGURE_has_python_3_4_or_newer=y
 CT_CONFIGURE_has_bison_2_7_or_newer=y
 CT_CONFIGURE_has_python=y
-CT_CONFIGURE_has_dtc=y
-CT_CONFIGURE_has_svn=y
 CT_CONFIGURE_has_git=y
 CT_CONFIGURE_has_md5sum=y
 CT_CONFIGURE_has_sha1sum=y
diff --git a/src/ci/docker/host-x86_64/dist-various-1/Dockerfile b/src/ci/docker/host-x86_64/dist-various-1/Dockerfile
index 87bab78f796c0..ac228cfe01d80 100644
--- a/src/ci/docker/host-x86_64/dist-various-1/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-various-1/Dockerfile
@@ -47,18 +47,6 @@ RUN add-apt-repository ppa:team-gcc-arm-embedded/ppa && \
     apt-get update && \
     apt-get install -y --no-install-recommends gcc-arm-embedded
 
-COPY scripts/rustbuild-setup.sh host-x86_64/dist-various-1/build-riscv-toolchain.sh host-x86_64/dist-various-1/riscv64-unknown-linux-gnu.config host-x86_64/dist-various-1/crosstool-ng.sh /build/
-RUN ./crosstool-ng.sh
-
-# Crosstool-ng will refuse to build as root
-RUN sh ./rustbuild-setup.sh
-USER rustbuild
-
-RUN ./build-riscv-toolchain.sh
-
-USER root
-ENV PATH=/x-tools/riscv64-unknown-linux-gnu/bin:$PATH
-
 COPY host-x86_64/dist-various-1/build-rumprun.sh /build
 RUN ./build-rumprun.sh
 
@@ -158,7 +146,6 @@ ENV TARGETS=$TARGETS,riscv32imc-unknown-none-elf
 ENV TARGETS=$TARGETS,riscv32imac-unknown-none-elf
 ENV TARGETS=$TARGETS,riscv64imac-unknown-none-elf
 ENV TARGETS=$TARGETS,riscv64gc-unknown-none-elf
-ENV TARGETS=$TARGETS,riscv64gc-unknown-linux-gnu
 ENV TARGETS=$TARGETS,armebv7r-none-eabi
 ENV TARGETS=$TARGETS,armebv7r-none-eabihf
 ENV TARGETS=$TARGETS,armv7r-none-eabi
@@ -186,9 +173,6 @@ ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \
     CFLAGS_aarch64_unknown_none_softfloat=-mstrict-align -march=armv8-a+nofp+nosimd \
     CC_aarch64_unknown_none=aarch64-none-elf-gcc \
     CFLAGS_aarch64_unknown_none=-mstrict-align -march=armv8-a+fp+simd \
-    CC_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-gcc \
-    AR_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-ar \
-    CXX_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-g++ \
     CC_riscv32i_unknown_none_elf=false \
     CC_riscv32imc_unknown_none_elf=false \
     CC_riscv32imac_unknown_none_elf=false \
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 6ab6a403c33dc..8545ec15d3280 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -341,6 +341,9 @@ jobs:
           - name: dist-powerpc64le-linux
             <<: *job-linux-xl
 
+          - name: dist-riscv64-linux
+            <<: *job-linux-xl
+
           - name: dist-s390x-linux
             <<: *job-linux-xl
 
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 6ddd41a26f122..56dddee7b7799 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -693,6 +693,7 @@ mod impls {
 pub trait DiscriminantKind {
     /// The type of the discriminant, which must satisfy the trait
     /// bounds required by `mem::Discriminant`.
+    #[cfg_attr(not(bootstrap), lang = "discriminant_type")]
     type Discriminant: Clone + Copy + Debug + Eq + PartialEq + Hash + Send + Sync + Unpin;
 }
 
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 7aca6af3de6f3..a27e8d2a72452 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -1681,6 +1681,7 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
 /// to allow `x?` (where `x` is an `Option<T>`) to be converted into your error type, you can
 /// implement `impl From<NoneError>` for `YourErrorType`. In that case, `x?` within a function that
 /// returns `Result<_, YourErrorType>` will translate a `None` value into an `Err` result.
+#[rustc_diagnostic_item = "none_error"]
 #[unstable(feature = "try_trait", issue = "42327")]
 #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
 pub struct NoneError;
diff --git a/src/librustc_error_codes/error_codes/E0715.md b/src/librustc_error_codes/error_codes/E0715.md
index 8f0022d942547..b27702b3c26e2 100644
--- a/src/librustc_error_codes/error_codes/E0715.md
+++ b/src/librustc_error_codes/error_codes/E0715.md
@@ -15,8 +15,7 @@ struct OverrideConst;
 impl Marker for OverrideConst { // error!
     const N: usize = 1;
 }
-
-fn main() {}
+# fn main() {}
 ```
 
 Because marker traits are allowed to have multiple implementations for the same
diff --git a/src/librustc_error_codes/error_codes/E0716.md b/src/librustc_error_codes/error_codes/E0716.md
index 25567c1d12810..c6d0337ddda56 100644
--- a/src/librustc_error_codes/error_codes/E0716.md
+++ b/src/librustc_error_codes/error_codes/E0716.md
@@ -1,5 +1,4 @@
-This error indicates that a temporary value is being dropped
-while a borrow is still in active use.
+A temporary value is being dropped while a borrow is still in active use.
 
 Erroneous code example:
 
@@ -11,12 +10,11 @@ let p = bar(&foo());
 let q = *p;
 ```
 
-Here, the expression `&foo()` is borrowing the expression
-`foo()`. As `foo()` is a call to a function, and not the name of
-a variable, this creates a **temporary** -- that temporary stores
-the return value from `foo()` so that it can be borrowed.
-You could imagine that `let p = bar(&foo());` is equivalent
-to this:
+Here, the expression `&foo()` is borrowing the expression `foo()`. As `foo()` is
+a call to a function, and not the name of a variable, this creates a
+**temporary** -- that temporary stores the return value from `foo()` so that it
+can be borrowed. You could imagine that `let p = bar(&foo());` is equivalent to
+this:
 
 ```compile_fail,E0597
 # fn foo() -> i32 { 22 }
@@ -28,16 +26,14 @@ let p = {
 let q = p;
 ```
 
-Whenever a temporary is created, it is automatically dropped (freed)
-according to fixed rules. Ordinarily, the temporary is dropped
-at the end of the enclosing statement -- in this case, after the `let`.
-This is illustrated in the example above by showing that `tmp` would
-be freed as we exit the block.
+Whenever a temporary is created, it is automatically dropped (freed) according
+to fixed rules. Ordinarily, the temporary is dropped at the end of the enclosing
+statement -- in this case, after the `let`. This is illustrated in the example
+above by showing that `tmp` would be freed as we exit the block.
 
-To fix this problem, you need to create a local variable
-to store the value in rather than relying on a temporary.
-For example, you might change the original program to
-the following:
+To fix this problem, you need to create a local variable to store the value in
+rather than relying on a temporary. For example, you might change the original
+program to the following:
 
 ```
 fn foo() -> i32 { 22 }
@@ -47,16 +43,15 @@ let p = bar(&value);
 let q = *p;
 ```
 
-By introducing the explicit `let value`, we allocate storage
-that will last until the end of the enclosing block (when `value`
-goes out of scope). When we borrow `&value`, we are borrowing a
-local variable that already exists, and hence no temporary is created.
+By introducing the explicit `let value`, we allocate storage that will last
+until the end of the enclosing block (when `value` goes out of scope). When we
+borrow `&value`, we are borrowing a local variable that already exists, and
+hence no temporary is created.
 
-Temporaries are not always dropped at the end of the enclosing
-statement. In simple cases where the `&` expression is immediately
-stored into a variable, the compiler will automatically extend
-the lifetime of the temporary until the end of the enclosing
-block. Therefore, an alternative way to fix the original
+Temporaries are not always dropped at the end of the enclosing statement. In
+simple cases where the `&` expression is immediately stored into a variable, the
+compiler will automatically extend the lifetime of the temporary until the end
+of the enclosing block. Therefore, an alternative way to fix the original
 program is to write `let tmp = &foo()` and not `let tmp = foo()`:
 
 ```
@@ -67,10 +62,10 @@ let p = bar(value);
 let q = *p;
 ```
 
-Here, we are still borrowing `foo()`, but as the borrow is assigned
-directly into a variable, the temporary will not be dropped until
-the end of the enclosing block. Similar rules apply when temporaries
-are stored into aggregate structures like a tuple or struct:
+Here, we are still borrowing `foo()`, but as the borrow is assigned directly
+into a variable, the temporary will not be dropped until the end of the
+enclosing block. Similar rules apply when temporaries are stored into aggregate
+structures like a tuple or struct:
 
 ```
 // Here, two temporaries are created, but
diff --git a/src/librustc_hir/lang_items.rs b/src/librustc_hir/lang_items.rs
index 1c8a56e5d80e7..88c97d874bed6 100644
--- a/src/librustc_hir/lang_items.rs
+++ b/src/librustc_hir/lang_items.rs
@@ -193,6 +193,9 @@ language_item_table! {
     CloneTraitLangItem,            sym::clone,              clone_trait,             Target::Trait;
     SyncTraitLangItem,             sym::sync,               sync_trait,              Target::Trait;
     DiscriminantKindTraitLangItem, sym::discriminant_kind,  discriminant_kind_trait, Target::Trait;
+    // The associated item of `trait DiscriminantKind`.
+    DiscriminantTypeLangItem,      sym::discriminant_type,  discriminant_type,       Target::AssocTy;
+
     FreezeTraitLangItem,           sym::freeze,             freeze_trait,            Target::Trait;
 
     DropTraitLangItem,             sym::drop,               drop_trait,              Target::Trait;
diff --git a/src/librustc_interface/lib.rs b/src/librustc_interface/lib.rs
index 0650d09003486..fe40c615f79c9 100644
--- a/src/librustc_interface/lib.rs
+++ b/src/librustc_interface/lib.rs
@@ -14,6 +14,7 @@ mod queries;
 pub mod util;
 
 pub use interface::{run_compiler, Config};
+pub use passes::{DEFAULT_EXTERN_QUERY_PROVIDERS, DEFAULT_QUERY_PROVIDERS};
 pub use queries::Queries;
 
 #[cfg(test)]
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 533d0a6d383c4..af4397075bb60 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -3,6 +3,7 @@ use crate::proc_macro_decls;
 use crate::util;
 
 use log::{info, log_enabled, warn};
+use once_cell::sync::Lazy;
 use rustc_ast::mut_visit::MutVisitor;
 use rustc_ast::{self, ast, visit};
 use rustc_codegen_ssa::back::link::emit_metadata;
@@ -19,6 +20,7 @@ use rustc_middle::arena::Arena;
 use rustc_middle::dep_graph::DepGraph;
 use rustc_middle::middle;
 use rustc_middle::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn};
+use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::steal::Steal;
 use rustc_middle::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt};
 use rustc_mir as mir;
@@ -719,7 +721,8 @@ pub fn prepare_outputs(
     Ok(outputs)
 }
 
-pub fn default_provide(providers: &mut ty::query::Providers) {
+pub static DEFAULT_QUERY_PROVIDERS: Lazy<Providers> = Lazy::new(|| {
+    let providers = &mut Providers::default();
     providers.analysis = analysis;
     proc_macro_decls::provide(providers);
     plugin::build::provide(providers);
@@ -738,12 +741,15 @@ pub fn default_provide(providers: &mut ty::query::Providers) {
     rustc_lint::provide(providers);
     rustc_symbol_mangling::provide(providers);
     rustc_codegen_ssa::provide(providers);
-}
+    *providers
+});
 
-pub fn default_provide_extern(providers: &mut ty::query::Providers) {
-    rustc_metadata::provide_extern(providers);
-    rustc_codegen_ssa::provide_extern(providers);
-}
+pub static DEFAULT_EXTERN_QUERY_PROVIDERS: Lazy<Providers> = Lazy::new(|| {
+    let mut extern_providers = *DEFAULT_QUERY_PROVIDERS;
+    rustc_metadata::provide_extern(&mut extern_providers);
+    rustc_codegen_ssa::provide_extern(&mut extern_providers);
+    extern_providers
+});
 
 pub struct QueryContext<'tcx>(&'tcx GlobalCtxt<'tcx>);
 
@@ -780,12 +786,11 @@ pub fn create_global_ctxt<'tcx>(
     let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess);
 
     let codegen_backend = compiler.codegen_backend();
-    let mut local_providers = ty::query::Providers::default();
-    default_provide(&mut local_providers);
+    let mut local_providers = *DEFAULT_QUERY_PROVIDERS;
     codegen_backend.provide(&mut local_providers);
 
-    let mut extern_providers = local_providers;
-    default_provide_extern(&mut extern_providers);
+    let mut extern_providers = *DEFAULT_EXTERN_QUERY_PROVIDERS;
+    codegen_backend.provide(&mut extern_providers);
     codegen_backend.provide_extern(&mut extern_providers);
 
     if let Some(callback) = compiler.override_queries {
diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs
index 4a41c3e97cafc..4265e6dca6a24 100644
--- a/src/librustc_interface/queries.rs
+++ b/src/librustc_interface/queries.rs
@@ -18,7 +18,6 @@ use rustc_session::{output::find_crate_name, Session};
 use rustc_span::symbol::sym;
 use std::any::Any;
 use std::cell::{Ref, RefCell, RefMut};
-use std::mem;
 use std::rc::Rc;
 
 /// Represent the result of a query.
@@ -395,37 +394,4 @@ impl Compiler {
 
         ret
     }
-
-    // This method is different to all the other methods in `Compiler` because
-    // it lacks a `Queries` entry. It's also not currently used. It does serve
-    // as an example of how `Compiler` can be used, with additional steps added
-    // between some passes. And see `rustc_driver::run_compiler` for a more
-    // complex example.
-    pub fn compile(&self) -> Result<()> {
-        let linker = self.enter(|queries| {
-            queries.prepare_outputs()?;
-
-            if self.session().opts.output_types.contains_key(&OutputType::DepInfo)
-                && self.session().opts.output_types.len() == 1
-            {
-                return Ok(None);
-            }
-
-            queries.global_ctxt()?;
-
-            // Drop AST after creating GlobalCtxt to free memory.
-            mem::drop(queries.expansion()?.take());
-
-            queries.ongoing_codegen()?;
-
-            let linker = queries.linker()?;
-            Ok(Some(linker))
-        })?;
-
-        if let Some(linker) = linker {
-            linker.link()?
-        }
-
-        Ok(())
-    }
 }
diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs
index d25f8bd1b8c58..5145b3b5e6fcc 100644
--- a/src/librustc_llvm/build.rs
+++ b/src/librustc_llvm/build.rs
@@ -275,6 +275,11 @@ fn main() {
         "stdc++"
     };
 
+    // RISC-V requires libatomic for sub-word atomic operations
+    if target.starts_with("riscv") {
+        println!("cargo:rustc-link-lib=atomic");
+    }
+
     // C++ runtime library
     if !target.contains("msvc") {
         if let Some(s) = llvm_static_stdcpp {
diff --git a/src/librustc_middle/dep_graph/dep_node.rs b/src/librustc_middle/dep_graph/dep_node.rs
index b14f17dee6060..98eed4045a34a 100644
--- a/src/librustc_middle/dep_graph/dep_node.rs
+++ b/src/librustc_middle/dep_graph/dep_node.rs
@@ -1,7 +1,9 @@
 //! This module defines the `DepNode` type which the compiler uses to represent
-//! nodes in the dependency graph. A `DepNode` consists of a `DepKind` (which
+//! nodes in the dependency graph.
+//!
+//! A `DepNode` consists of a `DepKind` (which
 //! specifies the kind of thing it represents, like a piece of HIR, MIR, etc)
-//! and a `Fingerprint`, a 128 bit hash value the exact meaning of which
+//! and a `Fingerprint`, a 128-bit hash value the exact meaning of which
 //! depends on the node's `DepKind`. Together, the kind and the fingerprint
 //! fully identify a dependency node, even across multiple compilation sessions.
 //! In other words, the value of the fingerprint does not depend on anything
@@ -11,9 +13,9 @@
 //! uniquely identify a given commit and has a few advantages:
 //!
 //! * A `DepNode` can simply be serialized to disk and loaded in another session
-//!   without the need to do any "rebasing (like we have to do for Spans and
-//!   NodeIds) or "retracing" like we had to do for `DefId` in earlier
-//!   implementations of the dependency graph.
+//!   without the need to do any "rebasing" (like we have to do for Spans and
+//!   NodeIds) or "retracing" (like we had to do for `DefId` in earlier
+//!   implementations of the dependency graph).
 //! * A `Fingerprint` is just a bunch of bits, which allows `DepNode` to
 //!   implement `Copy`, `Sync`, `Send`, `Freeze`, etc.
 //! * Since we just have a bit pattern, `DepNode` can be mapped from disk into
@@ -42,7 +44,7 @@
 //!   `DefId` it was computed from. In other cases, too much information gets
 //!   lost during fingerprint computation.
 //!
-//! The `DepConstructor` enum, together with `DepNode::new()` ensures that only
+//! The `DepConstructor` enum, together with `DepNode::new()`, ensures that only
 //! valid `DepNode` instances can be constructed. For example, the API does not
 //! allow for constructing parameterless `DepNode`s with anything other
 //! than a zeroed out fingerprint. More generally speaking, it relieves the
diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs
index 53f32b7c800bd..d04920de47f09 100644
--- a/src/librustc_parse/parser/stmt.rs
+++ b/src/librustc_parse/parser/stmt.rs
@@ -162,13 +162,19 @@ impl<'a> Parser<'a> {
             match self.parse_ty() {
                 Ok(ty) => (None, Some(ty)),
                 Err(mut err) => {
-                    // Rewind to before attempting to parse the type and continue parsing.
-                    let parser_snapshot_after_type =
-                        mem::replace(self, parser_snapshot_before_type);
                     if let Ok(snip) = self.span_to_snippet(pat.span) {
                         err.span_label(pat.span, format!("while parsing the type for `{}`", snip));
                     }
-                    (Some((parser_snapshot_after_type, colon_sp, err)), None)
+                    let err = if self.check(&token::Eq) {
+                        err.emit();
+                        None
+                    } else {
+                        // Rewind to before attempting to parse the type and continue parsing.
+                        let parser_snapshot_after_type =
+                            mem::replace(self, parser_snapshot_before_type);
+                        Some((parser_snapshot_after_type, colon_sp, err))
+                    };
+                    (err, None)
                 }
             }
         } else {
diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs
index 8b93b8a7aa74a..86b770104ea8e 100644
--- a/src/librustc_span/symbol.rs
+++ b/src/librustc_span/symbol.rs
@@ -327,6 +327,7 @@ symbols! {
         diagnostic,
         direct,
         discriminant_kind,
+        discriminant_type,
         discriminant_value,
         dispatch_from_dyn,
         div,
@@ -631,6 +632,7 @@ symbols! {
         nomem,
         non_ascii_idents,
         None,
+        none_error,
         non_exhaustive,
         no_niche,
         non_modrs_mods,
diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs
index 4ade1ce91632f..79d5c148ce4fe 100644
--- a/src/librustc_trait_selection/traits/error_reporting/mod.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs
@@ -26,6 +26,7 @@ use rustc_middle::ty::{
     TypeFoldable, WithConstness,
 };
 use rustc_session::DiagnosticMessageId;
+use rustc_span::symbol::sym;
 use rustc_span::{ExpnKind, MultiSpan, Span, DUMMY_SP};
 use std::fmt;
 
@@ -283,8 +284,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                             .span_to_snippet(span)
                             .map(|s| &s == "?")
                             .unwrap_or(false);
-                        let is_from = format!("{}", trait_ref.print_only_trait_path())
-                            .starts_with("std::convert::From<");
+                        let is_from = self.tcx.get_diagnostic_item(sym::from_trait)
+                            == Some(trait_ref.def_id());
                         let is_unsize =
                             { Some(trait_ref.def_id()) == self.tcx.lang_items().unsize_trait() };
                         let (message, note) = if is_try && is_from {
@@ -315,12 +316,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                             ))
                         );
 
-                        let should_convert_option_to_result =
-                            format!("{}", trait_ref.print_only_trait_path())
-                                .starts_with("std::convert::From<std::option::NoneError");
-                        let should_convert_result_to_option = format!("{}", trait_ref)
-                            .starts_with("<std::option::NoneError as std::convert::From<");
                         if is_try && is_from {
+                            let none_error = self
+                                .tcx
+                                .get_diagnostic_item(sym::none_error)
+                                .map(|def_id| tcx.type_of(def_id));
+                            let should_convert_option_to_result =
+                                Some(trait_ref.skip_binder().substs.type_at(1)) == none_error;
+                            let should_convert_result_to_option =
+                                Some(trait_ref.self_ty().skip_binder()) == none_error;
                             if should_convert_option_to_result {
                                 err.span_suggestion_verbose(
                                     span.shrink_to_lo(),
diff --git a/src/librustc_trait_selection/traits/project.rs b/src/librustc_trait_selection/traits/project.rs
index bd86109e5a491..c08198ec373b8 100644
--- a/src/librustc_trait_selection/traits/project.rs
+++ b/src/librustc_trait_selection/traits/project.rs
@@ -23,11 +23,12 @@ use crate::traits::error_reporting::InferCtxtExt;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::ErrorReported;
 use rustc_hir::def_id::DefId;
-use rustc_hir::lang_items::{FnOnceOutputLangItem, FnOnceTraitLangItem, GeneratorTraitLangItem};
+use rustc_hir::lang_items::{
+    DiscriminantTypeLangItem, FnOnceOutputLangItem, FnOnceTraitLangItem, GeneratorTraitLangItem,
+};
 use rustc_infer::infer::resolve::OpportunisticRegionResolver;
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
 use rustc_middle::ty::subst::Subst;
-use rustc_middle::ty::util::IntTypeExt;
 use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness};
 use rustc_span::symbol::sym;
 use rustc_span::DUMMY_SP;
@@ -1324,22 +1325,11 @@ fn confirm_discriminant_kind_candidate<'cx, 'tcx>(
     let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
     let substs = tcx.mk_substs([self_ty.into()].iter());
 
-    let assoc_items = tcx.associated_items(tcx.lang_items().discriminant_kind_trait().unwrap());
-    // FIXME: emit an error if the trait definition is wrong
-    let discriminant_def_id = assoc_items.in_definition_order().next().unwrap().def_id;
-
-    let discriminant_ty = match self_ty.kind {
-        // Use the discriminant type for enums.
-        ty::Adt(adt, _) if adt.is_enum() => adt.repr.discr_type().to_ty(tcx),
-        // Default to `i32` for generators.
-        ty::Generator(..) => tcx.types.i32,
-        // Use `u8` for all other types.
-        _ => tcx.types.u8,
-    };
+    let discriminant_def_id = tcx.require_lang_item(DiscriminantTypeLangItem, None);
 
     let predicate = ty::ProjectionPredicate {
         projection_ty: ty::ProjectionTy { substs, item_def_id: discriminant_def_id },
-        ty: discriminant_ty,
+        ty: self_ty.discriminant_ty(tcx),
     };
 
     confirm_param_env_candidate(selcx, obligation, ty::Binder::bind(predicate))
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 8fa581180ef60..9fa3f6cc39610 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1322,8 +1322,9 @@ fn settings(root_path: &str, suffix: &str) -> String {
             .into(),
         ("auto-hide-attributes", "Auto-hide item attributes.", true).into(),
         ("auto-hide-method-docs", "Auto-hide item methods' documentation", false).into(),
-        ("auto-hide-trait-implementations", "Auto-hide trait implementations documentation", true)
+        ("auto-hide-trait-implementations", "Auto-hide trait implementation documentation", true)
             .into(),
+        ("auto-collapse-implementors", "Auto-hide implementors of a trait", true).into(),
         ("go-to-only-result", "Directly go to item in search if there is only one result", false)
             .into(),
         ("line-numbers", "Show line numbers on code examples", false).into(),
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 69e2bacc21882..336c691ac1c24 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -2243,8 +2243,7 @@ function defocusSearchBar() {
                 relatedDoc = relatedDoc.nextElementSibling;
             }
 
-            if ((!relatedDoc && hasClass(docblock, "docblock") === false) ||
-                (pageId && document.getElementById(pageId))) {
+            if (!relatedDoc && hasClass(docblock, "docblock") === false) {
                 return;
             }
 
@@ -2364,6 +2363,7 @@ function defocusSearchBar() {
     (function() {
         var toggle = createSimpleToggle(false);
         var hideMethodDocs = getCurrentValue("rustdoc-auto-hide-method-docs") === "true";
+        var hideImplementors = getCurrentValue("rustdoc-auto-collapse-implementors") !== "false";
         var pageId = getPageId();
 
         var func = function(e) {
@@ -2393,7 +2393,13 @@ function defocusSearchBar() {
             if (hasClass(e, "impl") &&
                 (next.getElementsByClassName("method").length > 0 ||
                  next.getElementsByClassName("associatedconstant").length > 0)) {
-                insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]);
+                var newToggle = toggle.cloneNode(true);
+                insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]);
+                // In case the option "auto-collapse implementors" is not set to false, we collapse
+                // all implementors.
+                if (hideImplementors === true && e.parentNode.id === "implementors-list") {
+                    collapseDocs(newToggle, "hide", pageId);
+                }
             }
         };
 
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index a3f4dc55fe757..15a0c76ceeafb 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -364,6 +364,7 @@ nav.sub {
 #results > table {
 	width: 100%;
 	table-layout: fixed;
+	margin-bottom: 40px;
 }
 
 .content pre.line-numbers {
diff --git a/src/libstd/sys/unix/process/process_fuchsia.rs b/src/libstd/sys/unix/process/process_fuchsia.rs
index f0bd1cdfed52f..6daf2885baed0 100644
--- a/src/libstd/sys/unix/process/process_fuchsia.rs
+++ b/src/libstd/sys/unix/process/process_fuchsia.rs
@@ -246,6 +246,7 @@ impl ExitStatus {
     }
 }
 
+/// Converts a raw `c_int` to a type-safe `ExitStatus` by wrapping it without copying.
 impl From<c_int> for ExitStatus {
     fn from(a: c_int) -> ExitStatus {
         ExitStatus(a as i64)
diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs
index de35fe0521d03..371291b9f76ab 100644
--- a/src/libstd/sys/unix/process/process_unix.rs
+++ b/src/libstd/sys/unix/process/process_unix.rs
@@ -479,6 +479,7 @@ impl ExitStatus {
     }
 }
 
+/// Converts a raw `c_int` to a type-safe `ExitStatus` by wrapping it without copying.
 impl From<c_int> for ExitStatus {
     fn from(a: c_int) -> ExitStatus {
         ExitStatus(a)
diff --git a/src/libstd/sys/vxworks/process/process_common.rs b/src/libstd/sys/vxworks/process/process_common.rs
index 78b6e9a4db785..bbbd5eda77314 100644
--- a/src/libstd/sys/vxworks/process/process_common.rs
+++ b/src/libstd/sys/vxworks/process/process_common.rs
@@ -376,6 +376,7 @@ impl ExitStatus {
     }
 }
 
+/// Converts a raw `c_int` to a type-safe `ExitStatus` by wrapping it without copying.
 impl From<c_int> for ExitStatus {
     fn from(a: c_int) -> ExitStatus {
         ExitStatus(a)
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index 77f9a5c9dc7b9..7d6d4775eec8a 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -378,6 +378,7 @@ impl ExitStatus {
     }
 }
 
+/// Converts a raw `c::DWORD` to a type-safe `ExitStatus` by wrapping it without copying.
 impl From<c::DWORD> for ExitStatus {
     fn from(u: c::DWORD) -> ExitStatus {
         ExitStatus(u)
diff --git a/src/test/ui/generator/discriminant.rs b/src/test/ui/generator/discriminant.rs
index 3d0930da42243..195e77022992d 100644
--- a/src/test/ui/generator/discriminant.rs
+++ b/src/test/ui/generator/discriminant.rs
@@ -66,8 +66,8 @@ macro_rules! yield250 {
 }
 
 fn cycle(
-    gen: impl Generator<()> + Unpin + DiscriminantKind<Discriminant = i32>,
-    expected_max_discr: i32
+    gen: impl Generator<()> + Unpin + DiscriminantKind<Discriminant = u32>,
+    expected_max_discr: u32
 ) {
     let mut gen = Box::pin(gen);
     let mut max_discr = 0;
diff --git a/src/test/ui/issues/issue-34334.rs b/src/test/ui/issues/issue-34334.rs
index afe4d42edd8c8..97905e2f8fa43 100644
--- a/src/test/ui/issues/issue-34334.rs
+++ b/src/test/ui/issues/issue-34334.rs
@@ -1,11 +1,6 @@
 fn main () {
     let sr: Vec<(u32, _, _) = vec![];
     //~^ ERROR expected one of `,` or `>`, found `=`
-    //~| ERROR expected value, found struct `Vec`
-    //~| ERROR mismatched types
-    //~| ERROR invalid left-hand side of assignment
-    //~| ERROR expected expression, found reserved identifier `_`
-    //~| ERROR expected expression, found reserved identifier `_`
     let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
-    //~^ ERROR no method named `iter` found
+    //~^ ERROR a value of type `std::vec::Vec<(u32, _, _)>` cannot be built
 }
diff --git a/src/test/ui/issues/issue-34334.stderr b/src/test/ui/issues/issue-34334.stderr
index 5f157f6e3c089..364f8264db463 100644
--- a/src/test/ui/issues/issue-34334.stderr
+++ b/src/test/ui/issues/issue-34334.stderr
@@ -1,55 +1,19 @@
-error: expected expression, found reserved identifier `_`
-  --> $DIR/issue-34334.rs:2:23
-   |
-LL |     let sr: Vec<(u32, _, _) = vec![];
-   |                       ^ expected expression
-
-error: expected expression, found reserved identifier `_`
-  --> $DIR/issue-34334.rs:2:26
-   |
-LL |     let sr: Vec<(u32, _, _) = vec![];
-   |                          ^ expected expression
-
 error: expected one of `,` or `>`, found `=`
   --> $DIR/issue-34334.rs:2:29
    |
 LL |     let sr: Vec<(u32, _, _) = vec![];
-   |         ---                 ^ expected one of `,` or `>`
-   |         | |
-   |         | help: use `=` if you meant to assign
+   |         --                  ^ expected one of `,` or `>`
+   |         |
    |         while parsing the type for `sr`
 
-error[E0423]: expected value, found struct `Vec`
-  --> $DIR/issue-34334.rs:2:13
-   |
-LL |     let sr: Vec<(u32, _, _) = vec![];
-   |             ^^^ help: use struct literal syntax instead: `Vec { buf: val, len: val }`
-
-error[E0308]: mismatched types
-  --> $DIR/issue-34334.rs:2:31
-   |
-LL |     let sr: Vec<(u32, _, _) = vec![];
-   |                               ^^^^^^ expected `bool`, found struct `std::vec::Vec`
-   |
-   = note: expected type `bool`
-            found struct `std::vec::Vec<_>`
-   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error[E0070]: invalid left-hand side of assignment
-  --> $DIR/issue-34334.rs:2:29
-   |
-LL |     let sr: Vec<(u32, _, _) = vec![];
-   |             --------------- ^
-   |             |
-   |             cannot assign to this expression
-
-error[E0599]: no method named `iter` found for unit type `()` in the current scope
-  --> $DIR/issue-34334.rs:9:36
+error[E0277]: a value of type `std::vec::Vec<(u32, _, _)>` cannot be built from an iterator over elements of type `()`
+  --> $DIR/issue-34334.rs:4:87
    |
 LL |     let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
-   |                                    ^^^^ method not found in `()`
+   |                                                                                       ^^^^^^^ value of type `std::vec::Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator<Item=()>`
+   |
+   = help: the trait `std::iter::FromIterator<()>` is not implemented for `std::vec::Vec<(u32, _, _)>`
 
-error: aborting due to 7 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0070, E0308, E0423, E0599.
-For more information about an error, try `rustc --explain E0070`.
+For more information about this error, try `rustc --explain E0277`.