about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/doc/unstable-book/src/compiler-flags/src-hash-algorithm.md11
-rw-r--r--src/librustc_codegen_llvm/debuginfo/metadata.rs34
-rw-r--r--src/librustc_codegen_llvm/llvm/ffi.rs12
-rw-r--r--src/librustc_interface/util.rs8
-rw-r--r--src/librustc_middle/ich/impls_syntax.rs2
-rw-r--r--src/librustc_middle/ty/mod.rs48
-rw-r--r--src/librustc_session/config.rs30
-rw-r--r--src/librustc_session/options.rs15
-rw-r--r--src/librustc_session/session.rs56
-rw-r--r--src/librustc_span/Cargo.toml2
-rw-r--r--src/librustc_span/lib.rs89
-rw-r--r--src/librustc_span/source_map.rs19
-rw-r--r--src/librustc_typeck/check/wfcheck.rs108
-rw-r--r--src/librustc_typeck/collect/type_of.rs140
-rw-r--r--src/libserialize/serialize.rs24
-rw-r--r--src/libstd/sys/hermit/mod.rs4
-rw-r--r--src/libstd/sys/hermit/net.rs239
-rw-r--r--src/rustllvm/RustWrapper.cpp29
-rw-r--r--src/test/codegen/remap_path_prefix/main.rs4
-rw-r--r--src/test/codegen/remap_path_prefix/xcrate-generic.rs2
-rw-r--r--src/test/codegen/src-hash-algorithm/src-hash-algorithm-md5.rs6
-rw-r--r--src/test/codegen/src-hash-algorithm/src-hash-algorithm-sha1.rs6
-rw-r--r--src/test/ui/type-alias-impl-trait/bound_reduction2.rs5
-rw-r--r--src/test/ui/type-alias-impl-trait/bound_reduction2.stderr16
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs22
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr47
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr12
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs3
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr23
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr17
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs26
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr41
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60564.rs4
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60564.stderr31
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs4
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr16
-rw-r--r--src/test/ui/type-alias-impl-trait/not_a_defining_use.rs1
-rw-r--r--src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr19
-rw-r--r--src/tools/tidy/src/deps.rs11
41 files changed, 720 insertions, 470 deletions
diff --git a/src/doc/unstable-book/src/compiler-flags/src-hash-algorithm.md b/src/doc/unstable-book/src/compiler-flags/src-hash-algorithm.md
new file mode 100644
index 00000000000..5a7d0655a44
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/src-hash-algorithm.md
@@ -0,0 +1,11 @@
+# `src-hash-algorithm`
+
+The tracking issue for this feature is: [#70401](https://github.com/rust-lang/rust/issues/70401).
+
+------------------------
+
+The `-Z src-hash-algorithm` compiler flag controls which algorithm is used when hashing each source file. The hash is stored in the debug info and can be used by a debugger to verify the source code matches the executable.
+
+Supported hash algorithms are: `md5`, and `sha1`. Note that not all hash algorithms are supported by all debug info formats.
+
+By default, the compiler chooses the hash algorithm based on the target specification.
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index a9e21c056a3..700f25d35bc 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -41,7 +41,7 @@ use rustc_middle::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_session::config::{self, DebugInfo};
 use rustc_span::symbol::{Interner, Symbol};
-use rustc_span::{self, FileName, Span};
+use rustc_span::{self, FileName, SourceFileHash, Span};
 use rustc_target::abi::{Abi, Align, DiscriminantKind, HasDataLayout, Integer, LayoutOf};
 use rustc_target::abi::{Int, Pointer, F32, F64};
 use rustc_target::abi::{Primitive, Size, VariantIdx, Variants};
@@ -751,6 +751,14 @@ pub fn type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>, usage_site_span: Sp
     metadata
 }
 
+fn hex_encode(data: &[u8]) -> String {
+    let mut hex_string = String::with_capacity(data.len() * 2);
+    for byte in data.iter() {
+        write!(&mut hex_string, "{:02x}", byte).unwrap();
+    }
+    hex_string
+}
+
 pub fn file_metadata(
     cx: &CodegenCx<'ll, '_>,
     file_name: &FileName,
@@ -758,6 +766,8 @@ pub fn file_metadata(
 ) -> &'ll DIFile {
     debug!("file_metadata: file_name: {}, defining_crate: {}", file_name, defining_crate);
 
+    let source_file = cx.sess().source_map().get_source_file(file_name);
+    let hash = source_file.as_ref().map(|f| &f.src_hash);
     let file_name = Some(file_name.to_string());
     let directory = if defining_crate == LOCAL_CRATE {
         Some(cx.sess().working_dir.0.to_string_lossy().to_string())
@@ -766,17 +776,18 @@ pub fn file_metadata(
         // independent of the compiler's working directory one way or another.
         None
     };
-    file_metadata_raw(cx, file_name, directory)
+    file_metadata_raw(cx, file_name, directory, hash)
 }
 
 pub fn unknown_file_metadata(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
-    file_metadata_raw(cx, None, None)
+    file_metadata_raw(cx, None, None, None)
 }
 
 fn file_metadata_raw(
     cx: &CodegenCx<'ll, '_>,
     file_name: Option<String>,
     directory: Option<String>,
+    hash: Option<&SourceFileHash>,
 ) -> &'ll DIFile {
     let key = (file_name, directory);
 
@@ -789,6 +800,17 @@ fn file_metadata_raw(
             let file_name = file_name.as_deref().unwrap_or("<unknown>");
             let directory = directory.as_deref().unwrap_or("");
 
+            let (hash_kind, hash_value) = match hash {
+                Some(hash) => {
+                    let kind = match hash.kind {
+                        rustc_span::SourceFileHashAlgorithm::Md5 => llvm::ChecksumKind::MD5,
+                        rustc_span::SourceFileHashAlgorithm::Sha1 => llvm::ChecksumKind::SHA1,
+                    };
+                    (kind, hex_encode(hash.hash_bytes()))
+                }
+                None => (llvm::ChecksumKind::None, String::new()),
+            };
+
             let file_metadata = unsafe {
                 llvm::LLVMRustDIBuilderCreateFile(
                     DIB(cx),
@@ -796,6 +818,9 @@ fn file_metadata_raw(
                     file_name.len(),
                     directory.as_ptr().cast(),
                     directory.len(),
+                    hash_kind,
+                    hash_value.as_ptr().cast(),
+                    hash_value.len(),
                 )
             };
 
@@ -920,6 +945,9 @@ pub fn compile_unit_metadata(
             name_in_debuginfo.len(),
             work_dir.as_ptr().cast(),
             work_dir.len(),
+            llvm::ChecksumKind::None,
+            ptr::null(),
+            0,
         );
 
         let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index 1d61d95cc6b..aeb34e5c9c9 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -546,6 +546,15 @@ pub enum ThreadLocalMode {
     LocalExec,
 }
 
+/// LLVMRustChecksumKind
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub enum ChecksumKind {
+    None,
+    MD5,
+    SHA1,
+}
+
 extern "C" {
     type Opaque;
 }
@@ -1640,6 +1649,9 @@ extern "C" {
         FilenameLen: size_t,
         Directory: *const c_char,
         DirectoryLen: size_t,
+        CSKind: ChecksumKind,
+        Checksum: *const c_char,
+        ChecksumLen: size_t,
     ) -> &'a DIFile;
 
     pub fn LLVMRustDIBuilderCreateSubroutineType(
diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs
index a8cc34e1854..02bf1aded3b 100644
--- a/src/librustc_interface/util.rs
+++ b/src/librustc_interface/util.rs
@@ -22,7 +22,7 @@ use rustc_session::parse::CrateConfig;
 use rustc_session::CrateDisambiguator;
 use rustc_session::{config, early_error, filesearch, output, DiagnosticOutput, Session};
 use rustc_span::edition::Edition;
-use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMap};
+use rustc_span::source_map::{FileLoader, SourceMap};
 use rustc_span::symbol::{sym, Symbol};
 use smallvec::SmallVec;
 use std::env;
@@ -62,15 +62,13 @@ pub fn create_session(
     lint_caps: FxHashMap<lint::LintId, lint::Level>,
     descriptions: Registry,
 ) -> (Lrc<Session>, Lrc<Box<dyn CodegenBackend>>, Lrc<SourceMap>) {
-    let loader = file_loader.unwrap_or(box RealFileLoader);
-    let source_map = Lrc::new(SourceMap::with_file_loader(loader, sopts.file_path_mapping()));
-    let mut sess = session::build_session_with_source_map(
+    let (mut sess, source_map) = session::build_session_with_source_map(
         sopts,
         input_path,
         descriptions,
-        source_map.clone(),
         diagnostic_output,
         lint_caps,
+        file_loader,
     );
 
     let codegen_backend = get_codegen_backend(&sess);
diff --git a/src/librustc_middle/ich/impls_syntax.rs b/src/librustc_middle/ich/impls_syntax.rs
index c5a4b53b10d..300aac19e51 100644
--- a/src/librustc_middle/ich/impls_syntax.rs
+++ b/src/librustc_middle/ich/impls_syntax.rs
@@ -61,7 +61,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
             cnum,
             // Do not hash the source as it is not encoded
             src: _,
-            src_hash,
+            ref src_hash,
             external_src: _,
             start_pos,
             end_pos: _,
diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs
index 901365ef691..9b182333907 100644
--- a/src/librustc_middle/ty/mod.rs
+++ b/src/librustc_middle/ty/mod.rs
@@ -1077,48 +1077,42 @@ impl<'tcx> Generics {
         false
     }
 
+    pub fn param_at(&'tcx self, param_index: usize, tcx: TyCtxt<'tcx>) -> &'tcx GenericParamDef {
+        if let Some(index) = param_index.checked_sub(self.parent_count) {
+            &self.params[index]
+        } else {
+            tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
+                .param_at(param_index, tcx)
+        }
+    }
+
     pub fn region_param(
         &'tcx self,
         param: &EarlyBoundRegion,
         tcx: TyCtxt<'tcx>,
     ) -> &'tcx GenericParamDef {
-        if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
-            let param = &self.params[index as usize];
-            match param.kind {
-                GenericParamDefKind::Lifetime => param,
-                _ => bug!("expected lifetime parameter, but found another generic parameter"),
-            }
-        } else {
-            tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
-                .region_param(param, tcx)
+        let param = self.param_at(param.index as usize, tcx);
+        match param.kind {
+            GenericParamDefKind::Lifetime => param,
+            _ => bug!("expected lifetime parameter, but found another generic parameter"),
         }
     }
 
     /// Returns the `GenericParamDef` associated with this `ParamTy`.
     pub fn type_param(&'tcx self, param: &ParamTy, tcx: TyCtxt<'tcx>) -> &'tcx GenericParamDef {
-        if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
-            let param = &self.params[index as usize];
-            match param.kind {
-                GenericParamDefKind::Type { .. } => param,
-                _ => bug!("expected type parameter, but found another generic parameter"),
-            }
-        } else {
-            tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
-                .type_param(param, tcx)
+        let param = self.param_at(param.index as usize, tcx);
+        match param.kind {
+            GenericParamDefKind::Type { .. } => param,
+            _ => bug!("expected type parameter, but found another generic parameter"),
         }
     }
 
     /// Returns the `ConstParameterDef` associated with this `ParamConst`.
     pub fn const_param(&'tcx self, param: &ParamConst, tcx: TyCtxt<'tcx>) -> &GenericParamDef {
-        if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
-            let param = &self.params[index as usize];
-            match param.kind {
-                GenericParamDefKind::Const => param,
-                _ => bug!("expected const parameter, but found another generic parameter"),
-            }
-        } else {
-            tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
-                .const_param(param, tcx)
+        let param = self.param_at(param.index as usize, tcx);
+        match param.kind {
+            GenericParamDefKind::Const => param,
+            _ => bug!("expected const parameter, but found another generic parameter"),
         }
     }
 }
diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs
index 54481bd124d..58a03dbe388 100644
--- a/src/librustc_session/config.rs
+++ b/src/librustc_session/config.rs
@@ -18,9 +18,10 @@ use rustc_feature::UnstableFeatures;
 use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST};
 use rustc_span::source_map::{FileName, FilePathMapping};
 use rustc_span::symbol::{sym, Symbol};
+use rustc_span::SourceFileHashAlgorithm;
 
 use rustc_errors::emitter::HumanReadableErrorType;
-use rustc_errors::{ColorConfig, FatalError, Handler, HandlerFlags};
+use rustc_errors::{ColorConfig, HandlerFlags};
 
 use std::collections::btree_map::{
     Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter,
@@ -748,25 +749,30 @@ pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateCo
     user_cfg
 }
 
-pub fn build_target_config(opts: &Options, sp: &Handler) -> Config {
+pub fn build_target_config(opts: &Options, error_format: ErrorOutputType) -> Config {
     let target = Target::search(&opts.target_triple).unwrap_or_else(|e| {
-        sp.struct_fatal(&format!("Error loading target specification: {}", e))
-            .help("Use `--print target-list` for a list of built-in targets")
-            .emit();
-        FatalError.raise();
+        early_error(
+            error_format,
+            &format!(
+                "Error loading target specification: {}. \
+            Use `--print target-list` for a list of built-in targets",
+                e
+            ),
+        )
     });
 
     let ptr_width = match &target.target_pointer_width[..] {
         "16" => 16,
         "32" => 32,
         "64" => 64,
-        w => sp
-            .fatal(&format!(
+        w => early_error(
+            error_format,
+            &format!(
                 "target specification was invalid: \
              unrecognized target-pointer-width {}",
                 w
-            ))
-            .raise(),
+            ),
+        ),
     };
 
     Config { target, ptr_width }
@@ -1971,7 +1977,8 @@ impl PpMode {
 crate mod dep_tracking {
     use super::{
         CFGuard, CrateType, DebugInfo, ErrorOutputType, LinkerPluginLto, LtoCli, OptLevel,
-        OutputTypes, Passes, Sanitizer, SwitchWithOptPath, SymbolManglingVersion,
+        OutputTypes, Passes, Sanitizer, SourceFileHashAlgorithm, SwitchWithOptPath,
+        SymbolManglingVersion,
     };
     use crate::lint;
     use crate::utils::NativeLibraryKind;
@@ -2049,6 +2056,7 @@ crate mod dep_tracking {
     impl_dep_tracking_hash_via_hash!(LinkerPluginLto);
     impl_dep_tracking_hash_via_hash!(SwitchWithOptPath);
     impl_dep_tracking_hash_via_hash!(SymbolManglingVersion);
+    impl_dep_tracking_hash_via_hash!(Option<SourceFileHashAlgorithm>);
 
     impl_dep_tracking_hash_for_sortable_vec_of!(String);
     impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf);
diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs
index 432f1e17ab3..3962e30335d 100644
--- a/src/librustc_session/options.rs
+++ b/src/librustc_session/options.rs
@@ -10,6 +10,7 @@ use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel
 
 use rustc_feature::UnstableFeatures;
 use rustc_span::edition::Edition;
+use rustc_span::SourceFileHashAlgorithm;
 
 use std::collections::BTreeMap;
 
@@ -283,12 +284,14 @@ macro_rules! options {
             Some("one of: `disabled`, `trampolines`, or `aliases`");
         pub const parse_symbol_mangling_version: Option<&str> =
             Some("either `legacy` or `v0` (RFC 2603)");
+        pub const parse_src_file_hash: Option<&str> =
+            Some("either `md5`, or `sha1`");
     }
 
     #[allow(dead_code)]
     mod $mod_set {
         use super::{$struct_name, Passes, Sanitizer, LtoCli, LinkerPluginLto, SwitchWithOptPath,
-            SymbolManglingVersion, CFGuard};
+            SymbolManglingVersion, CFGuard, SourceFileHashAlgorithm};
         use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel};
         use std::path::PathBuf;
         use std::str::FromStr;
@@ -622,6 +625,14 @@ macro_rules! options {
             };
             true
         }
+
+        fn parse_src_file_hash(slot: &mut Option<SourceFileHashAlgorithm>, v: Option<&str>) -> bool {
+            match v.and_then(|s| SourceFileHashAlgorithm::from_str(s).ok()) {
+                Some(hash_kind) => *slot = Some(hash_kind),
+                _ => return false,
+            }
+            true
+        }
     }
 ) }
 
@@ -961,4 +972,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         "use new LLVM pass manager"),
     link_native_libraries: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
         "Link native libraries in the linker invocation."),
+    src_hash_algorithm: Option<SourceFileHashAlgorithm> = (None, parse_src_file_hash, [TRACKED],
+        "hash algorithm of source files in debug info (`md5`, or `sha1`)"),
 }
diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs
index 98d0fa74d62..1c5d19db49c 100644
--- a/src/librustc_session/session.rs
+++ b/src/librustc_session/session.rs
@@ -20,7 +20,8 @@ use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType};
 use rustc_errors::json::JsonEmitter;
 use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId, ErrorReported};
 use rustc_span::edition::Edition;
-use rustc_span::source_map::{self, MultiSpan, Span};
+use rustc_span::source_map::{self, FileLoader, MultiSpan, RealFileLoader, SourceMap, Span};
+use rustc_span::SourceFileHashAlgorithm;
 use rustc_target::spec::{PanicStrategy, RelroLevel, Target, TargetTriple};
 
 use std::cell::{self, RefCell};
@@ -870,16 +871,15 @@ pub fn build_session(
     local_crate_source_file: Option<PathBuf>,
     registry: rustc_errors::registry::Registry,
 ) -> Session {
-    let file_path_mapping = sopts.file_path_mapping();
-
     build_session_with_source_map(
         sopts,
         local_crate_source_file,
         registry,
-        Lrc::new(source_map::SourceMap::new(file_path_mapping)),
         DiagnosticOutput::Default,
         Default::default(),
+        None,
     )
+    .0
 }
 
 fn default_emitter(
@@ -956,10 +956,10 @@ pub fn build_session_with_source_map(
     sopts: config::Options,
     local_crate_source_file: Option<PathBuf>,
     registry: rustc_errors::registry::Registry,
-    source_map: Lrc<source_map::SourceMap>,
     diagnostics_output: DiagnosticOutput,
-    lint_caps: FxHashMap<lint::LintId, lint::Level>,
-) -> Session {
+    driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
+    file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
+) -> (Session, Lrc<SourceMap>) {
     // FIXME: This is not general enough to make the warning lint completely override
     // normal diagnostic warnings, since the warning lint can also be denied and changed
     // later via the source code.
@@ -977,23 +977,33 @@ pub fn build_session_with_source_map(
         DiagnosticOutput::Default => None,
         DiagnosticOutput::Raw(write) => Some(write),
     };
+
+    let target_cfg = config::build_target_config(&sopts, sopts.error_format);
+    let host_triple = TargetTriple::from_triple(config::host_triple());
+    let host = Target::search(&host_triple).unwrap_or_else(|e| {
+        early_error(sopts.error_format, &format!("Error loading host specification: {}", e))
+    });
+
+    let loader = file_loader.unwrap_or(Box::new(RealFileLoader));
+    let hash_kind = sopts.debugging_opts.src_hash_algorithm.unwrap_or_else(|| {
+        if target_cfg.target.options.is_like_msvc {
+            SourceFileHashAlgorithm::Sha1
+        } else {
+            SourceFileHashAlgorithm::Md5
+        }
+    });
+    let source_map = Lrc::new(SourceMap::with_file_loader_and_hash_kind(
+        loader,
+        sopts.file_path_mapping(),
+        hash_kind,
+    ));
     let emitter = default_emitter(&sopts, registry, &source_map, write_dest);
 
-    let diagnostic_handler = rustc_errors::Handler::with_emitter_and_flags(
+    let span_diagnostic = rustc_errors::Handler::with_emitter_and_flags(
         emitter,
         sopts.debugging_opts.diagnostic_handler_flags(can_emit_warnings),
     );
 
-    build_session_(sopts, local_crate_source_file, diagnostic_handler, source_map, lint_caps)
-}
-
-fn build_session_(
-    sopts: config::Options,
-    local_crate_source_file: Option<PathBuf>,
-    span_diagnostic: rustc_errors::Handler,
-    source_map: Lrc<source_map::SourceMap>,
-    driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
-) -> Session {
     let self_profiler = if let SwitchWithOptPath::Enabled(ref d) = sopts.debugging_opts.self_profile
     {
         let directory =
@@ -1015,13 +1025,7 @@ fn build_session_(
         None
     };
 
-    let host_triple = TargetTriple::from_triple(config::host_triple());
-    let host = Target::search(&host_triple).unwrap_or_else(|e| {
-        span_diagnostic.fatal(&format!("Error loading host specification: {}", e)).raise()
-    });
-    let target_cfg = config::build_target_config(&sopts, &span_diagnostic);
-
-    let parse_sess = ParseSess::with_span_handler(span_diagnostic, source_map);
+    let parse_sess = ParseSess::with_span_handler(span_diagnostic, source_map.clone());
     let sysroot = match &sopts.maybe_sysroot {
         Some(sysroot) => sysroot.clone(),
         None => filesearch::get_or_default_sysroot(),
@@ -1135,7 +1139,7 @@ fn build_session_(
 
     validate_commandline_args_with_session_available(&sess);
 
-    sess
+    (sess, source_map)
 }
 
 // If it is useful to have a Session available already for validating a
diff --git a/src/librustc_span/Cargo.toml b/src/librustc_span/Cargo.toml
index c3fa2331d2b..1c2721260d6 100644
--- a/src/librustc_span/Cargo.toml
+++ b/src/librustc_span/Cargo.toml
@@ -19,3 +19,5 @@ scoped-tls = "1.0"
 unicode-width = "0.1.4"
 cfg-if = "0.1.2"
 log = "0.4"
+sha-1 = "0.8"
+md-5 = "0.8"
diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs
index 3bcc20d36e7..0d9f3f214fb 100644
--- a/src/librustc_span/lib.rs
+++ b/src/librustc_span/lib.rs
@@ -47,9 +47,14 @@ use std::borrow::Cow;
 use std::cell::RefCell;
 use std::cmp::{self, Ordering};
 use std::fmt;
-use std::hash::{Hash, Hasher};
+use std::hash::Hash;
 use std::ops::{Add, Sub};
 use std::path::PathBuf;
+use std::str::FromStr;
+
+use md5::Md5;
+use sha1::Digest;
+use sha1::Sha1;
 
 #[cfg(test)]
 mod tests;
@@ -874,6 +879,70 @@ impl ExternalSource {
 #[derive(Debug)]
 pub struct OffsetOverflowError;
 
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+pub enum SourceFileHashAlgorithm {
+    Md5,
+    Sha1,
+}
+
+impl FromStr for SourceFileHashAlgorithm {
+    type Err = ();
+
+    fn from_str(s: &str) -> Result<SourceFileHashAlgorithm, ()> {
+        match s {
+            "md5" => Ok(SourceFileHashAlgorithm::Md5),
+            "sha1" => Ok(SourceFileHashAlgorithm::Sha1),
+            _ => Err(()),
+        }
+    }
+}
+
+rustc_data_structures::impl_stable_hash_via_hash!(SourceFileHashAlgorithm);
+
+/// The hash of the on-disk source file used for debug info.
+#[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
+#[derive(HashStable_Generic)]
+pub struct SourceFileHash {
+    pub kind: SourceFileHashAlgorithm,
+    value: [u8; 20],
+}
+
+impl SourceFileHash {
+    pub fn new(kind: SourceFileHashAlgorithm, src: &str) -> SourceFileHash {
+        let mut hash = SourceFileHash { kind, value: Default::default() };
+        let len = hash.hash_len();
+        let value = &mut hash.value[..len];
+        let data = src.as_bytes();
+        match kind {
+            SourceFileHashAlgorithm::Md5 => {
+                value.copy_from_slice(&Md5::digest(data));
+            }
+            SourceFileHashAlgorithm::Sha1 => {
+                value.copy_from_slice(&Sha1::digest(data));
+            }
+        }
+        hash
+    }
+
+    /// Check if the stored hash matches the hash of the string.
+    pub fn matches(&self, src: &str) -> bool {
+        Self::new(self.kind, src) == *self
+    }
+
+    /// The bytes of the hash.
+    pub fn hash_bytes(&self) -> &[u8] {
+        let len = self.hash_len();
+        &self.value[..len]
+    }
+
+    fn hash_len(&self) -> usize {
+        match self.kind {
+            SourceFileHashAlgorithm::Md5 => 16,
+            SourceFileHashAlgorithm::Sha1 => 20,
+        }
+    }
+}
+
 /// A single source in the `SourceMap`.
 #[derive(Clone)]
 pub struct SourceFile {
@@ -889,7 +958,7 @@ pub struct SourceFile {
     /// The complete source code.
     pub src: Option<Lrc<String>>,
     /// The source code's hash.
-    pub src_hash: u128,
+    pub src_hash: SourceFileHash,
     /// The external source code (used for external crates, which will have a `None`
     /// value as `self.src`.
     pub external_src: Lock<ExternalSource>,
@@ -987,7 +1056,8 @@ impl Decodable for SourceFile {
             let name: FileName = d.read_struct_field("name", 0, |d| Decodable::decode(d))?;
             let name_was_remapped: bool =
                 d.read_struct_field("name_was_remapped", 1, |d| Decodable::decode(d))?;
-            let src_hash: u128 = d.read_struct_field("src_hash", 2, |d| Decodable::decode(d))?;
+            let src_hash: SourceFileHash =
+                d.read_struct_field("src_hash", 2, |d| Decodable::decode(d))?;
             let start_pos: BytePos =
                 d.read_struct_field("start_pos", 3, |d| Decodable::decode(d))?;
             let end_pos: BytePos = d.read_struct_field("end_pos", 4, |d| Decodable::decode(d))?;
@@ -1062,14 +1132,12 @@ impl SourceFile {
         unmapped_path: FileName,
         mut src: String,
         start_pos: BytePos,
+        hash_kind: SourceFileHashAlgorithm,
     ) -> Self {
+        // Compute the file hash before any normalization.
+        let src_hash = SourceFileHash::new(hash_kind, &src);
         let normalized_pos = normalize_src(&mut src, start_pos);
 
-        let src_hash = {
-            let mut hasher: StableHasher = StableHasher::new();
-            hasher.write(src.as_bytes());
-            hasher.finish::<u128>()
-        };
         let name_hash = {
             let mut hasher: StableHasher = StableHasher::new();
             name.hash(&mut hasher);
@@ -1125,10 +1193,7 @@ impl SourceFile {
             } = &mut *external_src
             {
                 if let Some(src) = src {
-                    let mut hasher: StableHasher = StableHasher::new();
-                    hasher.write(src.as_bytes());
-
-                    if hasher.finish::<u128>() == self.src_hash {
+                    if self.src_hash.matches(&src) {
                         *src_kind = ExternalSourceKind::Present(Lrc::new(src));
                         return true;
                     }
diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs
index 57e68320f3f..49e2144b3e3 100644
--- a/src/librustc_span/source_map.rs
+++ b/src/librustc_span/source_map.rs
@@ -141,27 +141,31 @@ pub struct SourceMap {
     // This is used to apply the file path remapping as specified via
     // `--remap-path-prefix` to all `SourceFile`s allocated within this `SourceMap`.
     path_mapping: FilePathMapping,
+
+    /// The algorithm used for hashing the contents of each source file.
+    hash_kind: SourceFileHashAlgorithm,
 }
 
 impl SourceMap {
     pub fn new(path_mapping: FilePathMapping) -> SourceMap {
-        SourceMap {
-            used_address_space: AtomicU32::new(0),
-            files: Default::default(),
-            file_loader: Box::new(RealFileLoader),
+        Self::with_file_loader_and_hash_kind(
+            Box::new(RealFileLoader),
             path_mapping,
-        }
+            SourceFileHashAlgorithm::Md5,
+        )
     }
 
-    pub fn with_file_loader(
+    pub fn with_file_loader_and_hash_kind(
         file_loader: Box<dyn FileLoader + Sync + Send>,
         path_mapping: FilePathMapping,
+        hash_kind: SourceFileHashAlgorithm,
     ) -> SourceMap {
         SourceMap {
             used_address_space: AtomicU32::new(0),
             files: Default::default(),
             file_loader,
             path_mapping,
+            hash_kind,
         }
     }
 
@@ -275,6 +279,7 @@ impl SourceMap {
                     unmapped_path,
                     src,
                     Pos::from_usize(start_pos),
+                    self.hash_kind,
                 ));
 
                 let mut files = self.files.borrow_mut();
@@ -296,7 +301,7 @@ impl SourceMap {
         &self,
         filename: FileName,
         name_was_remapped: bool,
-        src_hash: u128,
+        src_hash: SourceFileHash,
         name_hash: u128,
         source_len: usize,
         cnum: CrateNum,
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 30a53cbc397..b0ff17ad56d 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -9,7 +9,7 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::itemlikevisit::ParItemLikeVisitor;
 use rustc_hir::lang_items;
 use rustc_hir::ItemKind;
-use rustc_middle::ty::subst::{InternalSubsts, Subst};
+use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
 use rustc_middle::ty::trait_def::TraitSpecializationKind;
 use rustc_middle::ty::{
     self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
@@ -864,87 +864,77 @@ fn check_opaque_types<'fcx, 'tcx>(
                 trace!("check_opaque_types: opaque_ty, {:?}, {:?}", def_id, substs);
                 let generics = tcx.generics_of(def_id);
                 // Only check named `impl Trait` types defined in this crate.
+                // FIXME(eddyb) is  `generics.parent.is_none()` correct? It seems
+                // potentially risky wrt associated types in `impl`s.
                 if generics.parent.is_none() && def_id.is_local() {
                     let opaque_hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
                     if may_define_opaque_type(tcx, fn_def_id, opaque_hir_id) {
                         trace!("check_opaque_types: may define, generics={:#?}", generics);
-                        let mut seen: FxHashMap<_, Vec<_>> = FxHashMap::default();
-                        for (subst, param) in substs.iter().zip(&generics.params) {
-                            match subst.unpack() {
-                                ty::subst::GenericArgKind::Type(ty) => match ty.kind {
-                                    ty::Param(..) => {}
-                                    // Prevent `fn foo() -> Foo<u32>` from being defining.
-                                    _ => {
-                                        tcx.sess
-                                            .struct_span_err(
-                                                span,
-                                                "non-defining opaque type use \
-                                                 in defining scope",
-                                            )
-                                            .span_note(
-                                                tcx.def_span(param.def_id),
-                                                &format!(
-                                                    "used non-generic type {} for \
-                                                     generic parameter",
-                                                    ty,
-                                                ),
-                                            )
-                                            .emit();
-                                    }
-                                },
+                        let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default();
+                        for (i, &arg) in substs.iter().enumerate() {
+                            let arg_is_param = match arg.unpack() {
+                                GenericArgKind::Type(ty) => matches!(ty.kind, ty::Param(_)),
 
-                                ty::subst::GenericArgKind::Lifetime(region) => {
-                                    let param_span = tcx.def_span(param.def_id);
+                                GenericArgKind::Lifetime(region) => {
                                     if let ty::ReStatic = region {
                                         tcx.sess
                                             .struct_span_err(
                                                 span,
-                                                "non-defining opaque type use \
-                                                 in defining scope",
+                                                "non-defining opaque type use in defining scope",
                                             )
                                             .span_label(
-                                                param_span,
+                                                tcx.def_span(generics.param_at(i, tcx).def_id),
                                                 "cannot use static lifetime; use a bound lifetime \
                                                  instead or remove the lifetime parameter from the \
                                                  opaque type",
                                             )
                                             .emit();
-                                    } else {
-                                        seen.entry(region).or_default().push(param_span);
+                                        continue;
                                     }
+
+                                    true
                                 }
 
-                                ty::subst::GenericArgKind::Const(ct) => match ct.val {
-                                    ty::ConstKind::Param(_) => {}
-                                    _ => {
-                                        tcx.sess
-                                            .struct_span_err(
-                                                span,
-                                                "non-defining opaque type use \
-                                                 in defining scope",
-                                            )
-                                            .span_note(
-                                                tcx.def_span(param.def_id),
-                                                &format!(
-                                                    "used non-generic const {} for \
-                                                     generic parameter",
-                                                    ty,
-                                                ),
-                                            )
-                                            .emit();
-                                    }
-                                },
-                            } // match subst
-                        } // for (subst, param)
-                        for (_, spans) in seen {
-                            if spans.len() > 1 {
+                                GenericArgKind::Const(ct) => {
+                                    matches!(ct.val, ty::ConstKind::Param(_))
+                                }
+                            };
+
+                            if arg_is_param {
+                                seen_params.entry(arg).or_default().push(i);
+                            } else {
+                                // Prevent `fn foo() -> Foo<u32>` from being defining.
+                                let opaque_param = generics.param_at(i, tcx);
+                                tcx.sess
+                                    .struct_span_err(
+                                        span,
+                                        "non-defining opaque type use in defining scope",
+                                    )
+                                    .span_note(
+                                        tcx.def_span(opaque_param.def_id),
+                                        &format!(
+                                            "used non-generic {} `{}` for generic parameter",
+                                            opaque_param.kind.descr(),
+                                            arg,
+                                        ),
+                                    )
+                                    .emit();
+                            }
+                        } // for (arg, param)
+
+                        for (_, indices) in seen_params {
+                            if indices.len() > 1 {
+                                let descr = generics.param_at(indices[0], tcx).kind.descr();
+                                let spans: Vec<_> = indices
+                                    .into_iter()
+                                    .map(|i| tcx.def_span(generics.param_at(i, tcx).def_id))
+                                    .collect();
                                 tcx.sess
                                     .struct_span_err(
                                         span,
-                                        "non-defining opaque type use \
-                                         in defining scope",
+                                        "non-defining opaque type use in defining scope",
                                     )
-                                    .span_note(spans, "lifetime used multiple times")
+                                    .span_note(spans, &format!("{} used multiple times", descr))
                                     .emit();
                             }
                         }
diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs
index e6099b98dc8..d45c8270068 100644
--- a/src/librustc_typeck/collect/type_of.rs
+++ b/src/librustc_typeck/collect/type_of.rs
@@ -1,4 +1,4 @@
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{struct_span_err, Applicability, StashKey};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -7,7 +7,7 @@ use rustc_hir::intravisit;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::Node;
 use rustc_middle::hir::map::Map;
-use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
+use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
 use rustc_middle::ty::util::IntTypeExt;
 use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable};
 use rustc_session::parse::feature_err;
@@ -369,13 +369,8 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
     struct ConstraintLocator<'tcx> {
         tcx: TyCtxt<'tcx>,
         def_id: DefId,
-        // (first found type span, actual type, mapping from the opaque type's generic
-        // parameters to the concrete type's generic parameters)
-        //
-        // The mapping is an index for each use site of a generic parameter in the concrete type
-        //
-        // The indices index into the generic parameters on the opaque type.
-        found: Option<(Span, Ty<'tcx>, Vec<usize>)>,
+        // (first found type span, actual type)
+        found: Option<(Span, Ty<'tcx>)>,
     }
 
     impl ConstraintLocator<'_> {
@@ -407,83 +402,51 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
 
                 // FIXME(oli-obk): trace the actual span from inference to improve errors.
                 let span = self.tcx.def_span(def_id);
-                // used to quickly look up the position of a generic parameter
-                let mut index_map: FxHashMap<ty::ParamTy, usize> = FxHashMap::default();
-                // Skipping binder is ok, since we only use this to find generic parameters and
-                // their positions.
-                for (idx, subst) in substs.iter().enumerate() {
-                    if let GenericArgKind::Type(ty) = subst.unpack() {
-                        if let ty::Param(p) = ty.kind {
-                            if index_map.insert(p, idx).is_some() {
-                                // There was already an entry for `p`, meaning a generic parameter
-                                // was used twice.
-                                self.tcx.sess.span_err(
-                                    span,
-                                    &format!(
-                                        "defining opaque type use restricts opaque \
-                                         type by using the generic parameter `{}` twice",
-                                        p,
-                                    ),
-                                );
-                                return;
-                            }
-                        } else {
+
+                // HACK(eddyb) this check shouldn't be needed, as `wfcheck`
+                // performs the same checks, in theory, but I've kept it here
+                // using `delay_span_bug`, just in case `wfcheck` slips up.
+                let opaque_generics = self.tcx.generics_of(self.def_id);
+                let mut used_params: FxHashSet<_> = FxHashSet::default();
+                for (i, arg) in substs.iter().enumerate() {
+                    let arg_is_param = match arg.unpack() {
+                        GenericArgKind::Type(ty) => matches!(ty.kind, ty::Param(_)),
+                        GenericArgKind::Lifetime(lt) => {
+                            matches!(lt, ty::ReEarlyBound(_) | ty::ReFree(_))
+                        }
+                        GenericArgKind::Const(ct) => matches!(ct.val, ty::ConstKind::Param(_)),
+                    };
+
+                    if arg_is_param {
+                        if !used_params.insert(arg) {
+                            // There was already an entry for `arg`, meaning a generic parameter
+                            // was used twice.
                             self.tcx.sess.delay_span_bug(
                                 span,
                                 &format!(
-                                    "non-defining opaque ty use in defining scope: {:?}, {:?}",
-                                    concrete_type, substs,
+                                    "defining opaque type use restricts opaque \
+                                     type by using the generic parameter `{}` twice",
+                                    arg,
                                 ),
                             );
                         }
-                    }
-                }
-                // Compute the index within the opaque type for each generic parameter used in
-                // the concrete type.
-                let indices = concrete_type
-                    .subst(self.tcx, substs)
-                    .walk()
-                    .filter_map(|t| match &t.kind {
-                        ty::Param(p) => Some(*index_map.get(p).unwrap()),
-                        _ => None,
-                    })
-                    .collect();
-                let is_param = |ty: Ty<'_>| match ty.kind {
-                    ty::Param(_) => true,
-                    _ => false,
-                };
-                let bad_substs: Vec<_> = substs
-                    .iter()
-                    .enumerate()
-                    .filter_map(|(i, k)| {
-                        if let GenericArgKind::Type(ty) = k.unpack() { Some((i, ty)) } else { None }
-                    })
-                    .filter(|(_, ty)| !is_param(ty))
-                    .collect();
-                if !bad_substs.is_empty() {
-                    let identity_substs = InternalSubsts::identity_for_item(self.tcx, self.def_id);
-                    for (i, bad_subst) in bad_substs {
-                        self.tcx.sess.span_err(
+                    } else {
+                        let param = opaque_generics.param_at(i, self.tcx);
+                        self.tcx.sess.delay_span_bug(
                             span,
                             &format!(
                                 "defining opaque type use does not fully define opaque type: \
-                            generic parameter `{}` is specified as concrete type `{}`",
-                                identity_substs.type_at(i),
-                                bad_subst
+                                 generic parameter `{}` is specified as concrete {} `{}`",
+                                param.name,
+                                param.kind.descr(),
+                                arg,
                             ),
                         );
                     }
-                } else if let Some((prev_span, prev_ty, ref prev_indices)) = self.found {
-                    let mut ty = concrete_type.walk().fuse();
-                    let mut p_ty = prev_ty.walk().fuse();
-                    let iter_eq = (&mut ty).zip(&mut p_ty).all(|(t, p)| match (&t.kind, &p.kind) {
-                        // Type parameters are equal to any other type parameter for the purpose of
-                        // concrete type equality, as it is possible to obtain the same type just
-                        // by passing matching parameters to a function.
-                        (ty::Param(_), ty::Param(_)) => true,
-                        _ => t == p,
-                    });
-                    if !iter_eq || ty.next().is_some() || p_ty.next().is_some() {
+                }
+
+                if let Some((prev_span, prev_ty)) = self.found {
+                    if *concrete_type != prev_ty {
                         debug!("find_opaque_ty_constraints: span={:?}", span);
                         // Found different concrete types for the opaque type.
                         let mut err = self.tcx.sess.struct_span_err(
@@ -496,34 +459,9 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                         );
                         err.span_note(prev_span, "previous use here");
                         err.emit();
-                    } else if indices != *prev_indices {
-                        // Found "same" concrete types, but the generic parameter order differs.
-                        let mut err = self.tcx.sess.struct_span_err(
-                            span,
-                            "concrete type's generic parameters differ from previous defining use",
-                        );
-                        use std::fmt::Write;
-                        let mut s = String::new();
-                        write!(s, "expected [").unwrap();
-                        let list = |s: &mut String, indices: &Vec<usize>| {
-                            let mut indices = indices.iter().cloned();
-                            if let Some(first) = indices.next() {
-                                write!(s, "`{}`", substs[first]).unwrap();
-                                for i in indices {
-                                    write!(s, ", `{}`", substs[i]).unwrap();
-                                }
-                            }
-                        };
-                        list(&mut s, prev_indices);
-                        write!(s, "], got [").unwrap();
-                        list(&mut s, &indices);
-                        write!(s, "]").unwrap();
-                        err.span_label(span, s);
-                        err.span_note(prev_span, "previous use here");
-                        err.emit();
                     }
                 } else {
-                    self.found = Some((span, concrete_type, indices));
+                    self.found = Some((span, concrete_type));
                 }
             } else {
                 debug!(
@@ -606,7 +544,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
     }
 
     match locator.found {
-        Some((_, ty, _)) => ty,
+        Some((_, ty)) => ty,
         None => {
             let span = tcx.def_span(def_id);
             tcx.sess.span_err(span, "could not find defining uses");
diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs
index 8c6548cd3c5..e80d16bb0c7 100644
--- a/src/libserialize/serialize.rs
+++ b/src/libserialize/serialize.rs
@@ -706,6 +706,30 @@ impl<T: Decodable> Decodable for Vec<T> {
     }
 }
 
+impl Encodable for [u8; 20] {
+    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+        s.emit_seq(self.len(), |s| {
+            for (i, e) in self.iter().enumerate() {
+                s.emit_seq_elt(i, |s| e.encode(s))?
+            }
+            Ok(())
+        })
+    }
+}
+
+impl Decodable for [u8; 20] {
+    fn decode<D: Decoder>(d: &mut D) -> Result<[u8; 20], D::Error> {
+        d.read_seq(|d, len| {
+            assert!(len == 20);
+            let mut v = [0u8; 20];
+            for i in 0..len {
+                v[i] = d.read_seq_elt(i, |d| Decodable::decode(d))?;
+            }
+            Ok(v)
+        })
+    }
+}
+
 impl<'a, T: Encodable> Encodable for Cow<'a, [T]>
 where
     [T]: ToOwned<Owned = Vec<T>>,
diff --git a/src/libstd/sys/hermit/mod.rs b/src/libstd/sys/hermit/mod.rs
index 1e4a53abdc7..958532b8fc4 100644
--- a/src/libstd/sys/hermit/mod.rs
+++ b/src/libstd/sys/hermit/mod.rs
@@ -93,9 +93,7 @@ pub unsafe extern "C" fn __rust_abort() {
 
 #[cfg(not(test))]
 pub fn init() {
-    unsafe {
-        let _ = net::init();
-    }
+    let _ = net::init();
 }
 
 #[cfg(not(test))]
diff --git a/src/libstd/sys/hermit/net.rs b/src/libstd/sys/hermit/net.rs
index 82917e71be1..377c3132c5a 100644
--- a/src/libstd/sys/hermit/net.rs
+++ b/src/libstd/sys/hermit/net.rs
@@ -1,291 +1,362 @@
 use crate::convert::TryFrom;
 use crate::fmt;
-use crate::io::{self, IoSlice, IoSliceMut};
+use crate::io::{self, ErrorKind, IoSlice, IoSliceMut};
 use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
 use crate::str;
+use crate::sys::hermit::abi;
 use crate::sys::{unsupported, Void};
 use crate::time::Duration;
 
-//// Iinitializes HermitCore's network stack
-pub unsafe fn init() -> io::Result<()> {
+/// Checks whether the HermitCore's socket interface has been started already, and
+/// if not, starts it.
+pub fn init() -> io::Result<()> {
+    if abi::network_init() < 0 {
+        return Err(io::Error::new(ErrorKind::Other, "Unable to initialize network interface"));
+    }
+
     Ok(())
 }
 
-pub struct TcpStream(Void);
+pub struct TcpStream(abi::Handle);
 
 impl TcpStream {
-    pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
-        unsupported()
+    pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
+        let addr = addr?;
+
+        match abi::tcpstream::connect(addr.ip().to_string().as_bytes(), addr.port(), None) {
+            Ok(handle) => Ok(TcpStream(handle)),
+            _ => {
+                Err(io::Error::new(ErrorKind::Other, "Unable to initiate a connection on a socket"))
+            }
+        }
     }
 
-    pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
-        unsupported()
+    pub fn connect_timeout(saddr: &SocketAddr, duration: Duration) -> io::Result<TcpStream> {
+        match abi::tcpstream::connect(
+            saddr.ip().to_string().as_bytes(),
+            saddr.port(),
+            Some(duration.as_millis() as u64),
+        ) {
+            Ok(handle) => Ok(TcpStream(handle)),
+            _ => {
+                Err(io::Error::new(ErrorKind::Other, "Unable to initiate a connection on a socket"))
+            }
+        }
     }
 
-    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-        match self.0 {}
+    pub fn set_read_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
+        abi::tcpstream::set_read_timeout(self.0, duration.map(|d| d.as_millis() as u64))
+            .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to set timeout value"))
     }
 
-    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-        match self.0 {}
+    pub fn set_write_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
+        abi::tcpstream::set_write_timeout(self.0, duration.map(|d| d.as_millis() as u64))
+            .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to set timeout value"))
     }
 
     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
-        match self.0 {}
+        let duration = abi::tcpstream::get_read_timeout(self.0)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to determine timeout value"))?;
+
+        Ok(duration.map(|d| Duration::from_millis(d)))
     }
 
     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
-        match self.0 {}
+        let duration = abi::tcpstream::get_write_timeout(self.0)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to determine timeout value"))?;
+
+        Ok(duration.map(|d| Duration::from_millis(d)))
     }
 
-    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
-        match self.0 {}
+    pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
+        abi::tcpstream::peek(self.0, buf)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "set_nodelay failed"))
     }
 
-    pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
-        match self.0 {}
+    pub fn read(&self, buffer: &mut [u8]) -> io::Result<usize> {
+        self.read_vectored(&mut [IoSliceMut::new(buffer)])
     }
 
-    pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        match self.0 {}
+    pub fn read_vectored(&self, ioslice: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        let mut size: usize = 0;
+
+        for i in ioslice.iter_mut() {
+            let mut pos: usize = 0;
+
+            while pos < i.len() {
+                let ret = abi::tcpstream::read(self.0, &mut i[pos..])
+                    .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to read on socket"))?;
+
+                if ret == 0 {
+                    return Ok(size);
+                } else {
+                    size += ret;
+                    pos += ret;
+                }
+            }
+        }
+
+        Ok(size)
     }
 
-    pub fn write(&self, _: &[u8]) -> io::Result<usize> {
-        match self.0 {}
+    pub fn write(&self, buffer: &[u8]) -> io::Result<usize> {
+        self.write_vectored(&[IoSlice::new(buffer)])
     }
 
-    pub fn write_vectored(&self, _: &[IoSlice<'_>]) -> io::Result<usize> {
-        match self.0 {}
+    pub fn write_vectored(&self, ioslice: &[IoSlice<'_>]) -> io::Result<usize> {
+        let mut size: usize = 0;
+
+        for i in ioslice.iter() {
+            size += abi::tcpstream::write(self.0, i)
+                .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to write on socket"))?;
+        }
+
+        Ok(size)
     }
 
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "peer_addr isn't supported"))
     }
 
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "socket_addr isn't supported"))
     }
 
-    pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
-        match self.0 {}
+    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
+        abi::tcpstream::shutdown(self.0, how as i32)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "unable to shutdown socket"))
     }
 
     pub fn duplicate(&self) -> io::Result<TcpStream> {
-        match self.0 {}
+        let handle = abi::tcpstream::duplicate(self.0)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "unable to duplicate stream"))?;
+
+        Ok(TcpStream(handle))
     }
 
-    pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+    pub fn set_nodelay(&self, mode: bool) -> io::Result<()> {
+        abi::tcpstream::set_nodelay(self.0, mode)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "set_nodelay failed"))
     }
 
     pub fn nodelay(&self) -> io::Result<bool> {
-        match self.0 {}
+        abi::tcpstream::nodelay(self.0)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "nodelay failed"))
     }
 
-    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
-        match self.0 {}
+    pub fn set_ttl(&self, tll: u32) -> io::Result<()> {
+        abi::tcpstream::set_tll(self.0, tll)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "unable to set TTL"))
     }
 
     pub fn ttl(&self) -> io::Result<u32> {
-        match self.0 {}
+        abi::tcpstream::get_tll(self.0)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "unable to get TTL"))
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "take_error isn't supported"))
     }
 
-    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+    pub fn set_nonblocking(&self, mode: bool) -> io::Result<()> {
+        abi::tcpstream::set_nonblocking(self.0, mode)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "unable to set blocking mode"))
+    }
+}
+
+impl Drop for TcpStream {
+    fn drop(&mut self) {
+        let _ = abi::tcpstream::close(self.0);
     }
 }
 
 impl fmt::Debug for TcpStream {
     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.0 {}
+        Ok(())
     }
 }
 
-pub struct TcpListener(Void);
+pub struct TcpListener(abi::Handle);
 
 impl TcpListener {
     pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
-        unsupported()
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn duplicate(&self) -> io::Result<TcpListener> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_ttl(&self, _: u32) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn ttl(&self) -> io::Result<u32> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn only_v6(&self) -> io::Result<bool> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 }
 
 impl fmt::Debug for TcpListener {
     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.0 {}
+        Ok(())
     }
 }
 
-pub struct UdpSocket(Void);
+pub struct UdpSocket(abi::Handle);
 
 impl UdpSocket {
     pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
-        unsupported()
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn duplicate(&self) -> io::Result<UdpSocket> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn broadcast(&self) -> io::Result<bool> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn multicast_loop_v4(&self) -> io::Result<bool> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn multicast_loop_v6(&self) -> io::Result<bool> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_ttl(&self, _: u32) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn ttl(&self) -> io::Result<u32> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn send(&self, _: &[u8]) -> io::Result<usize> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 }
 
 impl fmt::Debug for UdpSocket {
     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.0 {}
+        Ok(())
     }
 }
 
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index 799adb41882..21094b32520 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -640,6 +640,25 @@ static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind)
   }
 }
 
+enum class LLVMRustChecksumKind {
+  None,
+  MD5,
+  SHA1,
+};
+
+static Optional<DIFile::ChecksumKind> fromRust(LLVMRustChecksumKind Kind) {
+  switch (Kind) {
+  case LLVMRustChecksumKind::None:
+    return None;
+  case LLVMRustChecksumKind::MD5:
+    return DIFile::ChecksumKind::CSK_MD5;
+  case LLVMRustChecksumKind::SHA1:
+    return DIFile::ChecksumKind::CSK_SHA1;
+  default:
+    report_fatal_error("bad ChecksumKind.");
+  }
+}
+
 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
   return DEBUG_METADATA_VERSION;
 }
@@ -686,9 +705,15 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(
     LLVMRustDIBuilderRef Builder,
     const char *Filename, size_t FilenameLen,
-    const char *Directory, size_t DirectoryLen) {
+    const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind,
+    const char *Checksum, size_t ChecksumLen) {
+  Optional<DIFile::ChecksumKind> llvmCSKind = fromRust(CSKind);
+  Optional<DIFile::ChecksumInfo<StringRef>> CSInfo{};
+  if (llvmCSKind)
+    CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen});
   return wrap(Builder->createFile(StringRef(Filename, FilenameLen),
-                                  StringRef(Directory, DirectoryLen)));
+                                  StringRef(Directory, DirectoryLen),
+                                  CSInfo));
 }
 
 extern "C" LLVMMetadataRef
diff --git a/src/test/codegen/remap_path_prefix/main.rs b/src/test/codegen/remap_path_prefix/main.rs
index 4724dc3c3e5..20475bab0fc 100644
--- a/src/test/codegen/remap_path_prefix/main.rs
+++ b/src/test/codegen/remap_path_prefix/main.rs
@@ -22,7 +22,7 @@ fn main() {
 }
 
 // Here we check that local debuginfo is mapped correctly.
-// CHECK: !DIFile(filename: "/the/src/remap_path_prefix/main.rs", directory: "/the/cwd/")
+// CHECK: !DIFile(filename: "/the/src/remap_path_prefix/main.rs", directory: "/the/cwd/"
 
 // And here that debuginfo from other crates are expanded to absolute paths.
-// CHECK: !DIFile(filename: "/the/aux-src/remap_path_prefix_aux.rs", directory: "")
+// CHECK: !DIFile(filename: "/the/aux-src/remap_path_prefix_aux.rs", directory: ""
diff --git a/src/test/codegen/remap_path_prefix/xcrate-generic.rs b/src/test/codegen/remap_path_prefix/xcrate-generic.rs
index 30d6112fd02..7a9d2ca9b6b 100644
--- a/src/test/codegen/remap_path_prefix/xcrate-generic.rs
+++ b/src/test/codegen/remap_path_prefix/xcrate-generic.rs
@@ -11,4 +11,4 @@ pub fn foo() {
 }
 
 // Here we check that local debuginfo is mapped correctly.
-// CHECK: !DIFile(filename: "/the/aux-src/xcrate-generic.rs", directory: "")
+// CHECK: !DIFile(filename: "/the/aux-src/xcrate-generic.rs", directory: ""
diff --git a/src/test/codegen/src-hash-algorithm/src-hash-algorithm-md5.rs b/src/test/codegen/src-hash-algorithm/src-hash-algorithm-md5.rs
new file mode 100644
index 00000000000..64be1127786
--- /dev/null
+++ b/src/test/codegen/src-hash-algorithm/src-hash-algorithm-md5.rs
@@ -0,0 +1,6 @@
+// compile-flags: -g -Z src-hash-algorithm=md5
+
+#![crate_type = "lib"]
+
+pub fn test() {}
+// CHECK: checksumkind: CSK_MD5
diff --git a/src/test/codegen/src-hash-algorithm/src-hash-algorithm-sha1.rs b/src/test/codegen/src-hash-algorithm/src-hash-algorithm-sha1.rs
new file mode 100644
index 00000000000..54e07152142
--- /dev/null
+++ b/src/test/codegen/src-hash-algorithm/src-hash-algorithm-sha1.rs
@@ -0,0 +1,6 @@
+// compile-flags: -g -Z src-hash-algorithm=sha1
+
+#![crate_type = "lib"]
+
+pub fn test() {}
+// CHECK: checksumkind: CSK_SHA1
diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction2.rs b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs
index 1becb1e83a5..0a4cc9b7fe8 100644
--- a/src/test/ui/type-alias-impl-trait/bound_reduction2.rs
+++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs
@@ -8,13 +8,12 @@ trait TraitWithAssoc {
 }
 
 type Foo<V> = impl Trait<V>;
-//~^ ERROR could not find defining uses
-//~| ERROR the trait bound `T: TraitWithAssoc` is not satisfied
+//~^ ERROR the trait bound `T: TraitWithAssoc` is not satisfied
 
 trait Trait<U> {}
 
 impl<W> Trait<W> for () {}
 
-fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> { //~ ERROR does not fully define
+fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
     ()
 }
diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr
index aff558569ea..b871f79aa1d 100644
--- a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr
+++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr
@@ -9,20 +9,6 @@ help: consider further restricting this bound
 LL | fn foo_desugared<T: TraitWithAssoc + TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
    |                                    ^^^^^^^^^^^^^^^^
 
-error: defining opaque type use does not fully define opaque type: generic parameter `V` is specified as concrete type `<T as TraitWithAssoc>::Assoc`
-  --> $DIR/bound_reduction2.rs:18:1
-   |
-LL | / fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
-LL | |     ()
-LL | | }
-   | |_^
-
-error: could not find defining uses
-  --> $DIR/bound_reduction2.rs:10:1
-   |
-LL | type Foo<V> = impl Trait<V>;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs
index 165e320be5e..4503607a836 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs
@@ -1,14 +1,26 @@
-#![feature(type_alias_impl_trait)]
+#![feature(type_alias_impl_trait, const_generics)]
+#![allow(incomplete_features)]
 
 use std::fmt::Debug;
 
 fn main() {}
 
 // test that unused generic parameters are ok
-type Two<T, U> = impl Debug;
-//~^ could not find defining uses
+type TwoTys<T, U> = impl Debug;
+type TwoLifetimes<'a, 'b> = impl Debug;
+type TwoConsts<const X: usize, const Y: usize> = impl Debug;
 
-fn one<T: Debug>(t: T) -> Two<T, T> {
-//~^ ERROR defining opaque type use restricts opaque type
+fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> {
+//~^ ERROR non-defining opaque type use in defining scope
+    t
+}
+
+fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> {
+//~^ ERROR non-defining opaque type use in defining scope
+    t
+}
+
+fn one_const<const N: usize>(t: *mut [u8; N]) -> TwoConsts<N, N> {
+//~^ ERROR non-defining opaque type use in defining scope
     t
 }
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr
index e1794034e20..b4757e2763d 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr
@@ -1,17 +1,38 @@
-error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
-  --> $DIR/generic_duplicate_param_use.rs:11:1
-   |
-LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
-LL | |
-LL | |     t
-LL | | }
-   | |_^
+error: non-defining opaque type use in defining scope
+  --> $DIR/generic_duplicate_param_use.rs:13:30
+   |
+LL | fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> {
+   |                              ^^^^^^^^^^^^
+   |
+note: type used multiple times
+  --> $DIR/generic_duplicate_param_use.rs:9:13
+   |
+LL | type TwoTys<T, U> = impl Debug;
+   |             ^  ^
 
-error: could not find defining uses
-  --> $DIR/generic_duplicate_param_use.rs:8:1
+error: non-defining opaque type use in defining scope
+  --> $DIR/generic_duplicate_param_use.rs:18:36
+   |
+LL | fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> {
+   |                                    ^^^^^^^^^^^^^^^^^^^^
+   |
+note: lifetime used multiple times
+  --> $DIR/generic_duplicate_param_use.rs:10:19
+   |
+LL | type TwoLifetimes<'a, 'b> = impl Debug;
+   |                   ^^  ^^
+
+error: non-defining opaque type use in defining scope
+  --> $DIR/generic_duplicate_param_use.rs:23:50
+   |
+LL | fn one_const<const N: usize>(t: *mut [u8; N]) -> TwoConsts<N, N> {
+   |                                                  ^^^^^^^^^^^^^^^
+   |
+note: constant used multiple times
+  --> $DIR/generic_duplicate_param_use.rs:11:22
    |
-LL | type Two<T, U> = impl Debug;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | type TwoConsts<const X: usize, const Y: usize> = impl Debug;
+   |                      ^               ^
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs
index 0adce817c5c..2b98d8fc63a 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs
@@ -8,10 +8,10 @@ fn main() {}
 type Two<T, U> = impl Debug;
 
 fn one<T: Debug>(t: T) -> Two<T, T> {
-//~^ defining opaque type use restricts opaque type
     t
 }
 
 fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
+//~^ ERROR concrete type differs from previous defining opaque type use
     t
 }
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr
index a9a51fa0b4b..8170c671f68 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr
@@ -1,8 +1,16 @@
-error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/generic_duplicate_param_use2.rs:14:1
+   |
+LL | / fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
+LL | |
+LL | |     t
+LL | | }
+   | |_^ expected `U`, got `T`
+   |
+note: previous use here
   --> $DIR/generic_duplicate_param_use2.rs:10:1
    |
 LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
-LL | |
 LL | |     t
 LL | | }
    | |_^
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs
index 8d3e7f9f424..d9133fd11f7 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs
@@ -8,15 +8,14 @@ fn main() {}
 type Two<T, U> = impl Debug;
 
 fn one<T: Debug>(t: T) -> Two<T, T> {
-//~^ defining opaque type use restricts opaque type
     t
 }
 
 fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
+//~^ ERROR concrete type differs from previous defining opaque type use
     t
 }
 
 fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
-//~^ concrete type's generic parameters differ from previous defining use
     u
 }
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr
index 04dcdc295f9..86dd3368400 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr
@@ -1,28 +1,19 @@
-error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
-  --> $DIR/generic_duplicate_param_use3.rs:10:1
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/generic_duplicate_param_use3.rs:14:1
    |
-LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
+LL | / fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
 LL | |
 LL | |     t
 LL | | }
-   | |_^
-
-error: concrete type's generic parameters differ from previous defining use
-  --> $DIR/generic_duplicate_param_use3.rs:19:1
-   |
-LL | / fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
-LL | |
-LL | |     u
-LL | | }
-   | |_^ expected [`T`], got [`U`]
+   | |_^ expected `U`, got `T`
    |
 note: previous use here
-  --> $DIR/generic_duplicate_param_use3.rs:15:1
+  --> $DIR/generic_duplicate_param_use3.rs:10:1
    |
-LL | / fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
+LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
 LL | |     t
 LL | | }
    | |_^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs
index 65f7d7f485d..40388c3b6c8 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs
@@ -8,7 +8,7 @@ fn main() {}
 type Two<T, U> = impl Debug;
 
 fn one<T: Debug>(t: T) -> Two<T, T> {
-//~^ ERROR defining opaque type use restricts opaque type
+//~^ ERROR non-defining opaque type use in defining scope
     t
 }
 
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr
index 082177b8212..fcf01f5164a 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr
@@ -1,11 +1,14 @@
-error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
-  --> $DIR/generic_duplicate_param_use4.rs:10:1
+error: non-defining opaque type use in defining scope
+  --> $DIR/generic_duplicate_param_use4.rs:10:27
    |
-LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
-LL | |
-LL | |     t
-LL | | }
-   | |_^
+LL | fn one<T: Debug>(t: T) -> Two<T, T> {
+   |                           ^^^^^^^^^
+   |
+note: type used multiple times
+  --> $DIR/generic_duplicate_param_use4.rs:8:10
+   |
+LL | type Two<T, U> = impl Debug;
+   |          ^  ^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs
index 60106eba175..b1782120f84 100644
--- a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs
+++ b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs
@@ -1,13 +1,27 @@
-#![feature(type_alias_impl_trait)]
+#![feature(type_alias_impl_trait, const_generics)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
 
 fn main() {}
 
-type Cmp<T> = impl 'static;
-//~^ ERROR could not find defining uses
-//~^^ ERROR: at least one trait must be specified
+type OneTy<T> = impl Debug;
+type OneLifetime<'a> = impl Debug;
+type OneConst<const X: usize> = impl Debug;
 
+// Not defining uses, because they doesn't define *all* possible generics.
 
-// not a defining use, because it doesn't define *all* possible generics
-fn cmp() -> Cmp<u32> { //~ ERROR defining opaque type use does not fully define
+fn concrete_ty() -> OneTy<u32> {
+//~^ ERROR non-defining opaque type use in defining scope
     5u32
 }
+
+fn concrete_lifetime() -> OneLifetime<'static> {
+//~^ ERROR non-defining opaque type use in defining scope
+    6u32
+}
+
+fn concrete_const() -> OneConst<{123}> {
+//~^ ERROR non-defining opaque type use in defining scope
+    7u32
+}
diff --git a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr
index b952aaa79cc..b0ffc4a5ef6 100644
--- a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr
@@ -1,22 +1,35 @@
-error: at least one trait must be specified
-  --> $DIR/generic_nondefining_use.rs:5:15
+error: non-defining opaque type use in defining scope
+  --> $DIR/generic_nondefining_use.rs:14:21
    |
-LL | type Cmp<T> = impl 'static;
-   |               ^^^^^^^^^^^^
+LL | fn concrete_ty() -> OneTy<u32> {
+   |                     ^^^^^^^^^^
+   |
+note: used non-generic type `u32` for generic parameter
+  --> $DIR/generic_nondefining_use.rs:8:12
+   |
+LL | type OneTy<T> = impl Debug;
+   |            ^
 
-error: defining opaque type use does not fully define opaque type: generic parameter `T` is specified as concrete type `u32`
-  --> $DIR/generic_nondefining_use.rs:11:1
+error: non-defining opaque type use in defining scope
+  --> $DIR/generic_nondefining_use.rs:19:27
    |
-LL | / fn cmp() -> Cmp<u32> {
-LL | |     5u32
-LL | | }
-   | |_^
+LL | type OneLifetime<'a> = impl Debug;
+   |                  -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
+...
+LL | fn concrete_lifetime() -> OneLifetime<'static> {
+   |                           ^^^^^^^^^^^^^^^^^^^^
 
-error: could not find defining uses
-  --> $DIR/generic_nondefining_use.rs:5:1
+error: non-defining opaque type use in defining scope
+  --> $DIR/generic_nondefining_use.rs:24:24
+   |
+LL | fn concrete_const() -> OneConst<{123}> {
+   |                        ^^^^^^^^^^^^^^^
+   |
+note: used non-generic constant `123usize` for generic parameter
+  --> $DIR/generic_nondefining_use.rs:10:21
    |
-LL | type Cmp<T> = impl 'static;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | type OneConst<const X: usize> = impl Debug;
+   |                     ^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.rs b/src/test/ui/type-alias-impl-trait/issue-60564.rs
index 73acc92172b..4eb7f7836d8 100644
--- a/src/test/ui/type-alias-impl-trait/issue-60564.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-60564.rs
@@ -6,7 +6,6 @@ trait IterBits {
 }
 
 type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
-//~^ ERROR could not find defining uses
 
 impl<T: Copy, E> IterBits for T
 where
@@ -18,7 +17,8 @@ where
 {
     type BitsIter = IterBitsIter<T, E, u8>;
     fn iter_bits(self, n: u8) -> Self::BitsIter {
-    //~^ ERROR defining opaque type use does not fully define opaque type
+    //~^ ERROR non-defining opaque type use in defining scope
+    //~| ERROR non-defining opaque type use in defining scope
         (0u8..n)
             .rev()
             .map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.stderr b/src/test/ui/type-alias-impl-trait/issue-60564.stderr
index 9de3e759e15..55984609437 100644
--- a/src/test/ui/type-alias-impl-trait/issue-60564.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-60564.stderr
@@ -1,19 +1,26 @@
-error: defining opaque type use does not fully define opaque type: generic parameter `I` is specified as concrete type `u8`
-  --> $DIR/issue-60564.rs:20:5
+error: non-defining opaque type use in defining scope
+  --> $DIR/issue-60564.rs:19:34
    |
-LL | /     fn iter_bits(self, n: u8) -> Self::BitsIter {
-LL | |
-LL | |         (0u8..n)
-LL | |             .rev()
-LL | |             .map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
-LL | |     }
-   | |_____^
+LL |     fn iter_bits(self, n: u8) -> Self::BitsIter {
+   |                                  ^^^^^^^^^^^^^^
+   |
+note: used non-generic type `_` for generic parameter
+  --> $DIR/issue-60564.rs:8:22
+   |
+LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
+   |                      ^
 
-error: could not find defining uses
-  --> $DIR/issue-60564.rs:8:1
+error: non-defining opaque type use in defining scope
+  --> $DIR/issue-60564.rs:19:34
+   |
+LL |     fn iter_bits(self, n: u8) -> Self::BitsIter {
+   |                                  ^^^^^^^^^^^^^^
+   |
+note: used non-generic type `u8` for generic parameter
+  --> $DIR/issue-60564.rs:8:25
    |
 LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                         ^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs
index d00f8d7a901..3b6decbe9c6 100644
--- a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs
@@ -4,9 +4,9 @@
 
 #![feature(type_alias_impl_trait)]
 trait Trait<T> {}
-type Alias<'a, U> = impl Trait<U>; //~ ERROR could not find defining uses
+type Alias<'a, U> = impl Trait<U>;
 fn f<'a>() -> Alias<'a, ()> {}
-//~^ ERROR defining opaque type use does not fully define opaque type: generic parameter `U`
+//~^ ERROR non-defining opaque type use in defining scope
 
 fn main() {}
 
diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr
index b585942406f..c2fa54f50f8 100644
--- a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr
@@ -1,14 +1,14 @@
-error: defining opaque type use does not fully define opaque type: generic parameter `U` is specified as concrete type `()`
-  --> $DIR/issue-68368-non-defining-use.rs:8:1
+error: non-defining opaque type use in defining scope
+  --> $DIR/issue-68368-non-defining-use.rs:8:15
    |
 LL | fn f<'a>() -> Alias<'a, ()> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: could not find defining uses
-  --> $DIR/issue-68368-non-defining-use.rs:7:1
+   |               ^^^^^^^^^^^^^
+   |
+note: used non-generic type `()` for generic parameter
+  --> $DIR/issue-68368-non-defining-use.rs:7:16
    |
 LL | type Alias<'a, U> = impl Trait<U>;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
diff --git a/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs b/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs
index ca00e582d34..02485b24e7b 100644
--- a/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs
+++ b/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs
@@ -7,7 +7,6 @@ fn main() {}
 type Two<T, U> = impl Debug;
 
 fn two<T: Debug>(t: T) -> Two<T, u32> {
-    //~^ ERROR defining opaque type use does not fully define opaque type
     (t, 4i8)
 }
 
diff --git a/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr
index d68f1bd30a0..cce861b76c9 100644
--- a/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr
+++ b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr
@@ -1,14 +1,5 @@
-error: defining opaque type use does not fully define opaque type: generic parameter `U` is specified as concrete type `u32`
-  --> $DIR/not_a_defining_use.rs:9:1
-   |
-LL | / fn two<T: Debug>(t: T) -> Two<T, u32> {
-LL | |
-LL | |     (t, 4i8)
-LL | | }
-   | |_^
-
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/not_a_defining_use.rs:30:1
+  --> $DIR/not_a_defining_use.rs:29:1
    |
 LL | / fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> {
 LL | |     (t, <U as Bar>::FOO)
@@ -16,12 +7,12 @@ LL | | }
    | |_^ expected `(T, i8)`, got `(T, <U as Bar>::Blub)`
    |
 note: previous use here
-  --> $DIR/not_a_defining_use.rs:14:1
+  --> $DIR/not_a_defining_use.rs:9:1
    |
-LL | / fn three<T: Debug, U>(t: T) -> Two<T, U> {
-LL | |     (t, 5i8)
+LL | / fn two<T: Debug>(t: T) -> Two<T, u32> {
+LL | |     (t, 4i8)
 LL | | }
    | |_^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index a221184fab0..62dc965b55f 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -26,7 +26,6 @@ const LICENSES: &[&str] = &[
 const EXCEPTIONS: &[(&str, &str)] = &[
     ("mdbook", "MPL-2.0"),                  // mdbook
     ("openssl", "Apache-2.0"),              // cargo, mdbook
-    ("arrayref", "BSD-2-Clause"),           // mdbook via handlebars via pest
     ("toml-query", "MPL-2.0"),              // mdbook
     ("toml-query_derive", "MPL-2.0"),       // mdbook
     ("is-match", "MPL-2.0"),                // mdbook
@@ -74,6 +73,9 @@ const WHITELIST: &[&str] = &[
     "backtrace",
     "backtrace-sys",
     "bitflags",
+    "block-buffer",
+    "block-padding",
+    "byte-tools",
     "byteorder",
     "c2-chacha",
     "cc",
@@ -87,15 +89,18 @@ const WHITELIST: &[&str] = &[
     "crossbeam-queue",
     "crossbeam-utils",
     "datafrog",
+    "digest",
     "dlmalloc",
     "either",
     "ena",
     "env_logger",
+    "fake-simd",
     "filetime",
     "flate2",
     "fortanix-sgx-abi",
     "fuchsia-zircon",
     "fuchsia-zircon-sys",
+    "generic-array",
     "getopts",
     "getrandom",
     "hashbrown",
@@ -111,6 +116,7 @@ const WHITELIST: &[&str] = &[
     "lock_api",
     "log",
     "log_settings",
+    "md-5",
     "measureme",
     "memchr",
     "memmap",
@@ -118,6 +124,7 @@ const WHITELIST: &[&str] = &[
     "miniz_oxide",
     "nodrop",
     "num_cpus",
+    "opaque-debug",
     "parking_lot",
     "parking_lot_core",
     "pkg-config",
@@ -150,6 +157,7 @@ const WHITELIST: &[&str] = &[
     "semver-parser",
     "serde",
     "serde_derive",
+    "sha-1",
     "smallvec",
     "stable_deref_trait",
     "syn",
@@ -159,6 +167,7 @@ const WHITELIST: &[&str] = &[
     "termion",
     "termize",
     "thread_local",
+    "typenum",
     "ucd-util",
     "unicode-normalization",
     "unicode-script",