about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-02-27 02:18:11 +0000
committerbors <bors@rust-lang.org>2021-02-27 02:18:11 +0000
commit9fa580b1175018b0a276b0bc68f9827a106f7260 (patch)
tree59c6d8c32cb9915f5ef2e461cda52c68ad4d87ba /compiler
parent3da2dd3eae7b7cbf16960ab993de666470e43991 (diff)
parent95b31cf94964dcd082c32b41de112541873c2d8b (diff)
downloadrust-9fa580b1175018b0a276b0bc68f9827a106f7260.tar.gz
rust-9fa580b1175018b0a276b0bc68f9827a106f7260.zip
Auto merge of #82577 - Dylan-DPC:rollup-c3si8ju, r=Dylan-DPC
Rollup of 14 pull requests

Successful merges:

 - #81794 (update tracking issue for `relaxed_struct_unsize`)
 - #82057 (Replace const_cstr with cstr crate)
 - #82370 (Improve anonymous lifetime note to indicate the target span)
 - #82394 (:arrow_up: rust-analyzer)
 - #82396 (Add Future trait for doc_spotlight feature doc)
 - #82404 (Test hexagon-enum only when llvm target is present)
 - #82419 (expand: Preserve order of inert attributes during expansion)
 - #82420 (Enable API documentation for `std::os::wasi`.)
 - #82421 (Add a `size()` function to WASI's `MetadataExt`.)
 - #82442 (Skip emitting closure diagnostic when closure_kind_origins has no entry)
 - #82473 (Use libc::accept4 on Android instead of raw syscall.)
 - #82482 (Use small hash set in `mir_inliner_callees`)
 - #82490 (Update cargo)
 - #82494 (Substitute erased lifetimes on bad placeholder type)

Failed merges:

 - #82448 (Combine HasAttrs and HasTokens into AstLike)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_codegen_llvm/Cargo.toml1
-rw-r--r--compiler/rustc_codegen_llvm/src/abi.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs30
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs6
-rw-r--r--compiler/rustc_data_structures/src/const_cstr.rs30
-rw-r--r--compiler/rustc_data_structures/src/lib.rs1
-rw-r--r--compiler/rustc_expand/src/expand.rs23
-rw-r--r--compiler/rustc_feature/src/active.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs10
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs5
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs114
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs3
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs51
-rw-r--r--compiler/rustc_mir/src/transform/inline/cycle.rs11
-rw-r--r--compiler/rustc_typeck/src/collect.rs12
19 files changed, 157 insertions, 166 deletions
diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml
index ebbb852f21c..260edd9570b 100644
--- a/compiler/rustc_codegen_llvm/Cargo.toml
+++ b/compiler/rustc_codegen_llvm/Cargo.toml
@@ -10,6 +10,7 @@ doctest = false
 
 [dependencies]
 bitflags = "1.0"
+cstr = "0.2"
 libc = "0.2"
 measureme = "9.0.0"
 snap = "1"
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index a69241e456f..d714ff1fe9b 100644
--- a/compiler/rustc_codegen_llvm/src/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
@@ -554,7 +554,7 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
                 llvm::AddCallSiteAttrString(
                     callsite,
                     llvm::AttributePlace::Function,
-                    rustc_data_structures::const_cstr!("cmse_nonsecure_call"),
+                    cstr::cstr!("cmse_nonsecure_call"),
                 );
             }
         }
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index 26111729ba5..09ece6164eb 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -2,8 +2,8 @@
 
 use std::ffi::CString;
 
+use cstr::cstr;
 use rustc_codegen_ssa::traits::*;
-use rustc_data_structures::const_cstr;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::small_c_str::SmallCStr;
 use rustc_hir::def_id::DefId;
@@ -75,8 +75,8 @@ pub fn set_frame_pointer_elimination(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value)
         llvm::AddFunctionAttrStringValue(
             llfn,
             llvm::AttributePlace::Function,
-            const_cstr!("frame-pointer"),
-            const_cstr!("all"),
+            cstr!("frame-pointer"),
+            cstr!("all"),
         );
     }
 }
@@ -95,7 +95,7 @@ fn set_instrument_function(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
         llvm::AddFunctionAttrStringValue(
             llfn,
             llvm::AttributePlace::Function,
-            const_cstr!("instrument-function-entry-inlined"),
+            cstr!("instrument-function-entry-inlined"),
             &mcount_name,
         );
     }
@@ -129,16 +129,16 @@ fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
         StackProbeType::None => None,
         // Request LLVM to generate the probes inline. If the given LLVM version does not support
         // this, no probe is generated at all (even if the attribute is specified).
-        StackProbeType::Inline => Some(const_cstr!("inline-asm")),
+        StackProbeType::Inline => Some(cstr!("inline-asm")),
         // Flag our internal `__rust_probestack` function as the stack probe symbol.
         // This is defined in the `compiler-builtins` crate for each architecture.
-        StackProbeType::Call => Some(const_cstr!("__rust_probestack")),
+        StackProbeType::Call => Some(cstr!("__rust_probestack")),
         // Pick from the two above based on the LLVM version.
         StackProbeType::InlineOrCall { min_llvm_version_for_inline } => {
             if llvm_util::get_version() < min_llvm_version_for_inline {
-                Some(const_cstr!("__rust_probestack"))
+                Some(cstr!("__rust_probestack"))
             } else {
-                Some(const_cstr!("inline-asm"))
+                Some(cstr!("inline-asm"))
             }
         }
     };
@@ -146,7 +146,7 @@ fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
         llvm::AddFunctionAttrStringValue(
             llfn,
             llvm::AttributePlace::Function,
-            const_cstr!("probe-stack"),
+            cstr!("probe-stack"),
             attr_value,
         );
     }
@@ -169,7 +169,7 @@ pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
     llvm::AddFunctionAttrStringValue(
         llfn,
         llvm::AttributePlace::Function,
-        const_cstr!("target-cpu"),
+        cstr!("target-cpu"),
         target_cpu.as_c_str(),
     );
 }
@@ -180,7 +180,7 @@ pub fn apply_tune_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
         llvm::AddFunctionAttrStringValue(
             llfn,
             llvm::AttributePlace::Function,
-            const_cstr!("tune-cpu"),
+            cstr!("tune-cpu"),
             tune_cpu.as_c_str(),
         );
     }
@@ -289,7 +289,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::
         Attribute::NoAlias.apply_llfn(llvm::AttributePlace::ReturnValue, llfn);
     }
     if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::CMSE_NONSECURE_ENTRY) {
-        llvm::AddFunctionAttrString(llfn, Function, const_cstr!("cmse_nonsecure_entry"));
+        llvm::AddFunctionAttrString(llfn, Function, cstr!("cmse_nonsecure_entry"));
     }
     sanitize(cx, codegen_fn_attrs.no_sanitize, llfn);
 
@@ -319,7 +319,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::
         llvm::AddFunctionAttrStringValue(
             llfn,
             llvm::AttributePlace::Function,
-            const_cstr!("target-features"),
+            cstr!("target-features"),
             &val,
         );
     }
@@ -332,7 +332,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::
             llvm::AddFunctionAttrStringValue(
                 llfn,
                 llvm::AttributePlace::Function,
-                const_cstr!("wasm-import-module"),
+                cstr!("wasm-import-module"),
                 &module,
             );
 
@@ -342,7 +342,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::
             llvm::AddFunctionAttrStringValue(
                 llfn,
                 llvm::AttributePlace::Function,
-                const_cstr!("wasm-import-name"),
+                cstr!("wasm-import-name"),
                 &name,
             );
         }
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index d2f4d3edc22..f4852c91e53 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -5,13 +5,13 @@ use crate::llvm::{AtomicOrdering, AtomicRmwBinOp, SynchronizationScope};
 use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
+use cstr::cstr;
 use libc::{c_char, c_uint};
 use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, TypeKind};
 use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
 use rustc_codegen_ssa::mir::place::PlaceRef;
 use rustc_codegen_ssa::traits::*;
 use rustc_codegen_ssa::MemFlags;
-use rustc_data_structures::const_cstr;
 use rustc_data_structures::small_c_str::SmallCStr;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::layout::TyAndLayout;
@@ -979,7 +979,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
     }
 
     fn cleanup_pad(&mut self, parent: Option<&'ll Value>, args: &[&'ll Value]) -> Funclet<'ll> {
-        let name = const_cstr!("cleanuppad");
+        let name = cstr!("cleanuppad");
         let ret = unsafe {
             llvm::LLVMRustBuildCleanupPad(
                 self.llbuilder,
@@ -1003,7 +1003,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
     }
 
     fn catch_pad(&mut self, parent: &'ll Value, args: &[&'ll Value]) -> Funclet<'ll> {
-        let name = const_cstr!("catchpad");
+        let name = cstr!("catchpad");
         let ret = unsafe {
             llvm::LLVMRustBuildCatchPad(
                 self.llbuilder,
@@ -1022,7 +1022,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         unwind: Option<&'ll BasicBlock>,
         num_handlers: usize,
     ) -> &'ll Value {
-        let name = const_cstr!("catchswitch");
+        let name = cstr!("catchswitch");
         let ret = unsafe {
             llvm::LLVMRustBuildCatchSwitch(
                 self.llbuilder,
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index 16e1a8a1242..99046839973 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -5,9 +5,9 @@ use crate::llvm::{self, True};
 use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
+use cstr::cstr;
 use libc::c_uint;
 use rustc_codegen_ssa::traits::*;
-use rustc_data_structures::const_cstr;
 use rustc_hir::def_id::DefId;
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
 use rustc_middle::mir::interpret::{
@@ -419,9 +419,9 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
                             .all(|&byte| byte == 0);
 
                     let sect_name = if all_bytes_are_zero {
-                        const_cstr!("__DATA,__thread_bss")
+                        cstr!("__DATA,__thread_bss")
                     } else {
-                        const_cstr!("__DATA,__thread_data")
+                        cstr!("__DATA,__thread_data")
                     };
                     llvm::LLVMSetSection(g, sect_name.as_ptr());
                 }
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index ee099f93258..3ddc7424202 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -7,10 +7,10 @@ use crate::llvm_util;
 use crate::type_::Type;
 use crate::value::Value;
 
+use cstr::cstr;
 use rustc_codegen_ssa::base::wants_msvc_seh;
 use rustc_codegen_ssa::traits::*;
 use rustc_data_structures::base_n;
-use rustc_data_structures::const_cstr;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::small_c_str::SmallCStr;
 use rustc_middle::bug;
@@ -414,8 +414,8 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
     }
 
     fn create_used_variable(&self) {
-        let name = const_cstr!("llvm.used");
-        let section = const_cstr!("llvm.metadata");
+        let name = cstr!("llvm.used");
+        let section = cstr!("llvm.metadata");
         let array =
             self.const_array(&self.type_ptr_to(self.type_i8()), &*self.used_statics.borrow());
 
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 1464784ae28..85d1b702399 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -18,8 +18,8 @@ use crate::llvm::debuginfo::{
 };
 use crate::value::Value;
 
+use cstr::cstr;
 use rustc_codegen_ssa::traits::*;
-use rustc_data_structures::const_cstr;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -1075,7 +1075,7 @@ pub fn compile_unit_metadata(
                 gcov_cu_info.len() as c_uint,
             );
 
-            let llvm_gcov_ident = const_cstr!("llvm.gcov");
+            let llvm_gcov_ident = cstr!("llvm.gcov");
             llvm::LLVMAddNamedMetadataOperand(
                 debug_context.llmod,
                 llvm_gcov_ident.as_ptr(),
@@ -1093,7 +1093,7 @@ pub fn compile_unit_metadata(
             );
             llvm::LLVMAddNamedMetadataOperand(
                 debug_context.llmod,
-                const_cstr!("llvm.ident").as_ptr(),
+                cstr!("llvm.ident").as_ptr(),
                 llvm::LLVMMDNodeInContext(debug_context.llcontext, &name_metadata, 1),
             );
         }
diff --git a/compiler/rustc_data_structures/src/const_cstr.rs b/compiler/rustc_data_structures/src/const_cstr.rs
deleted file mode 100644
index 1ebcb87818e..00000000000
--- a/compiler/rustc_data_structures/src/const_cstr.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-/// This macro creates a zero-overhead &CStr by adding a NUL terminator to
-/// the string literal passed into it at compile-time. Use it like:
-///
-/// ```
-///     let some_const_cstr = const_cstr!("abc");
-/// ```
-///
-/// The above is roughly equivalent to:
-///
-/// ```
-///     let some_const_cstr = CStr::from_bytes_with_nul(b"abc\0").unwrap()
-/// ```
-///
-/// Note that macro only checks the string literal for internal NULs if
-/// debug-assertions are enabled in order to avoid runtime overhead in release
-/// builds.
-#[macro_export]
-macro_rules! const_cstr {
-    ($s:expr) => {{
-        use std::ffi::CStr;
-
-        let str_plus_nul = concat!($s, "\0");
-
-        if cfg!(debug_assertions) {
-            CStr::from_bytes_with_nul(str_plus_nul.as_bytes()).unwrap()
-        } else {
-            unsafe { CStr::from_bytes_with_nul_unchecked(str_plus_nul.as_bytes()) }
-        }
-    }};
-}
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 4ab493d3cc9..fcb2bca7b4c 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -69,7 +69,6 @@ pub mod base_n;
 pub mod binary_search_util;
 pub mod box_region;
 pub mod captures;
-pub mod const_cstr;
 pub mod flock;
 pub mod functor;
 pub mod fx;
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 5a4737842f0..10c19ea105e 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -301,6 +301,8 @@ pub enum InvocationKind {
     },
     Attr {
         attr: ast::Attribute,
+        // Re-insertion position for inert attributes.
+        pos: usize,
         item: Annotatable,
         // Required for resolving derive helper attributes.
         derives: Vec<Path>,
@@ -690,7 +692,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 }
                 _ => unreachable!(),
             },
-            InvocationKind::Attr { attr, mut item, derives } => match ext {
+            InvocationKind::Attr { attr, pos, mut item, derives } => match ext {
                 SyntaxExtensionKind::Attr(expander) => {
                     self.gate_proc_macro_input(&item);
                     self.gate_proc_macro_attr_item(span, &item);
@@ -721,7 +723,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                                 ExpandResult::Retry(item) => {
                                     // Reassemble the original invocation for retrying.
                                     return ExpandResult::Retry(Invocation {
-                                        kind: InvocationKind::Attr { attr, item, derives },
+                                        kind: InvocationKind::Attr { attr, pos, item, derives },
                                         ..invoc
                                     });
                                 }
@@ -739,7 +741,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                     if *mark_used {
                         self.cx.sess.mark_attr_used(&attr);
                     }
-                    item.visit_attrs(|attrs| attrs.push(attr));
+                    item.visit_attrs(|attrs| attrs.insert(pos, attr));
                     fragment_kind.expect_from_annotatables(iter::once(item))
                 }
                 _ => unreachable!(),
@@ -1000,17 +1002,20 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
 
     fn collect_attr(
         &mut self,
-        (attr, derives): (ast::Attribute, Vec<Path>),
+        (attr, pos, derives): (ast::Attribute, usize, Vec<Path>),
         item: Annotatable,
         kind: AstFragmentKind,
     ) -> AstFragment {
-        self.collect(kind, InvocationKind::Attr { attr, item, derives })
+        self.collect(kind, InvocationKind::Attr { attr, pos, item, derives })
     }
 
     /// If `item` is an attribute invocation, remove the attribute and return it together with
-    /// derives following it. We have to collect the derives in order to resolve legacy derive
-    /// helpers (helpers written before derives that introduce them).
-    fn take_first_attr(&mut self, item: &mut impl HasAttrs) -> Option<(ast::Attribute, Vec<Path>)> {
+    /// its position and derives following it. We have to collect the derives in order to resolve
+    /// legacy derive helpers (helpers written before derives that introduce them).
+    fn take_first_attr(
+        &mut self,
+        item: &mut impl HasAttrs,
+    ) -> Option<(ast::Attribute, usize, Vec<Path>)> {
         let mut attr = None;
 
         item.visit_attrs(|attrs| {
@@ -1033,7 +1038,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
                         })
                         .collect();
 
-                    (attr, following_derives)
+                    (attr, attr_pos, following_derives)
                 })
         });
 
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 3f484ab5686..6960b735f33 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -633,7 +633,7 @@ declare_features! (
     (active, abi_c_cmse_nonsecure_call, "1.51.0", Some(81391), None),
 
     /// Lessens the requirements for structs to implement `Unsize`.
-    (active, relaxed_struct_unsize, "1.51.0", Some(1), None),
+    (active, relaxed_struct_unsize, "1.51.0", Some(81793), None),
 
     /// Allows macro attributes to observe output of `#[derive]`.
     (active, macro_attributes_in_derive_output, "1.51.0", Some(81119), None),
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 2d5f43e5890..eeff48a6395 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -50,6 +50,7 @@ use super::region_constraints::GenericKind;
 use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs};
 
 use crate::infer;
+use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
 use crate::traits::error_reporting::report_object_safety_error;
 use crate::traits::{
     IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
@@ -179,7 +180,14 @@ fn msg_span_from_early_bound_and_free_regions(
         }
         ty::ReFree(ref fr) => match fr.bound_region {
             ty::BrAnon(idx) => {
-                (format!("the anonymous lifetime #{} defined on", idx + 1), tcx.hir().span(node))
+                if let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region) {
+                    ("the anonymous lifetime defined on".to_string(), ty.span)
+                } else {
+                    (
+                        format!("the anonymous lifetime #{} defined on", idx + 1),
+                        tcx.hir().span(node),
+                    )
+                }
             }
             _ => (
                 format!("the lifetime `{}` as defined on", region),
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs
index cdd68d83f22..1b35c4032f4 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs
@@ -1,6 +1,7 @@
 //! Error Reporting for Anonymous Region Lifetime Errors
 //! where both the regions are anonymous.
 
+use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
 use crate::infer::error_reporting::nice_region_error::util::AnonymousParamInfo;
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
 use crate::infer::lexical_region_resolve::RegionResolutionError;
@@ -66,9 +67,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
         let scope_def_id_sub = anon_reg_sub.def_id;
         let bregion_sub = anon_reg_sub.boundregion;
 
-        let ty_sup = self.find_anon_type(sup, &bregion_sup)?;
+        let ty_sup = find_anon_type(self.tcx(), sup, &bregion_sup)?;
 
-        let ty_sub = self.find_anon_type(sub, &bregion_sub)?;
+        let ty_sub = find_anon_type(self.tcx(), sub, &bregion_sub)?;
 
         debug!(
             "try_report_anon_anon_conflict: found_param1={:?} sup={:?} br1={:?}",
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs
index b014b9832e7..ffdaedf8666 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs
@@ -1,4 +1,3 @@
-use crate::infer::error_reporting::nice_region_error::NiceRegionError;
 use rustc_hir as hir;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::Node;
@@ -6,67 +5,64 @@ use rustc_middle::hir::map::Map;
 use rustc_middle::middle::resolve_lifetime as rl;
 use rustc_middle::ty::{self, Region, TyCtxt};
 
-impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
-    /// This function calls the `visit_ty` method for the parameters
-    /// corresponding to the anonymous regions. The `nested_visitor.found_type`
-    /// contains the anonymous type.
-    ///
-    /// # Arguments
-    /// region - the anonymous region corresponding to the anon_anon conflict
-    /// br - the bound region corresponding to the above region which is of type `BrAnon(_)`
-    ///
-    /// # Example
-    /// ```
-    /// fn foo(x: &mut Vec<&u8>, y: &u8)
-    ///    { x.push(y); }
-    /// ```
-    /// The function returns the nested type corresponding to the anonymous region
-    /// for e.g., `&u8` and Vec<`&u8`.
-    pub(super) fn find_anon_type(
-        &self,
-        region: Region<'tcx>,
-        br: &ty::BoundRegionKind,
-    ) -> Option<(&hir::Ty<'tcx>, &hir::FnDecl<'tcx>)> {
-        if let Some(anon_reg) = self.tcx().is_suitable_region(region) {
-            let hir_id = self.tcx().hir().local_def_id_to_hir_id(anon_reg.def_id);
-            let fndecl = match self.tcx().hir().get(hir_id) {
-                Node::Item(&hir::Item { kind: hir::ItemKind::Fn(ref m, ..), .. })
-                | Node::TraitItem(&hir::TraitItem {
-                    kind: hir::TraitItemKind::Fn(ref m, ..),
-                    ..
-                })
-                | Node::ImplItem(&hir::ImplItem {
-                    kind: hir::ImplItemKind::Fn(ref m, ..), ..
-                }) => &m.decl,
-                _ => return None,
-            };
+/// This function calls the `visit_ty` method for the parameters
+/// corresponding to the anonymous regions. The `nested_visitor.found_type`
+/// contains the anonymous type.
+///
+/// # Arguments
+/// region - the anonymous region corresponding to the anon_anon conflict
+/// br - the bound region corresponding to the above region which is of type `BrAnon(_)`
+///
+/// # Example
+/// ```
+/// fn foo(x: &mut Vec<&u8>, y: &u8)
+///    { x.push(y); }
+/// ```
+/// The function returns the nested type corresponding to the anonymous region
+/// for e.g., `&u8` and Vec<`&u8`.
+pub(crate) fn find_anon_type(
+    tcx: TyCtxt<'tcx>,
+    region: Region<'tcx>,
+    br: &ty::BoundRegionKind,
+) -> Option<(&'tcx hir::Ty<'tcx>, &'tcx hir::FnDecl<'tcx>)> {
+    if let Some(anon_reg) = tcx.is_suitable_region(region) {
+        let hir_id = tcx.hir().local_def_id_to_hir_id(anon_reg.def_id);
+        let fndecl = match tcx.hir().get(hir_id) {
+            Node::Item(&hir::Item { kind: hir::ItemKind::Fn(ref m, ..), .. })
+            | Node::TraitItem(&hir::TraitItem {
+                kind: hir::TraitItemKind::Fn(ref m, ..), ..
+            })
+            | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(ref m, ..), .. }) => {
+                &m.decl
+            }
+            _ => return None,
+        };
 
-            fndecl
-                .inputs
-                .iter()
-                .find_map(|arg| self.find_component_for_bound_region(arg, br))
-                .map(|ty| (ty, &**fndecl))
-        } else {
-            None
-        }
+        fndecl
+            .inputs
+            .iter()
+            .find_map(|arg| find_component_for_bound_region(tcx, arg, br))
+            .map(|ty| (ty, &**fndecl))
+    } else {
+        None
     }
+}
 
-    // This method creates a FindNestedTypeVisitor which returns the type corresponding
-    // to the anonymous region.
-    fn find_component_for_bound_region(
-        &self,
-        arg: &'tcx hir::Ty<'tcx>,
-        br: &ty::BoundRegionKind,
-    ) -> Option<&'tcx hir::Ty<'tcx>> {
-        let mut nested_visitor = FindNestedTypeVisitor {
-            tcx: self.tcx(),
-            bound_region: *br,
-            found_type: None,
-            current_index: ty::INNERMOST,
-        };
-        nested_visitor.visit_ty(arg);
-        nested_visitor.found_type
-    }
+// This method creates a FindNestedTypeVisitor which returns the type corresponding
+// to the anonymous region.
+fn find_component_for_bound_region(
+    tcx: TyCtxt<'tcx>,
+    arg: &'tcx hir::Ty<'tcx>,
+    br: &ty::BoundRegionKind,
+) -> Option<&'tcx hir::Ty<'tcx>> {
+    let mut nested_visitor = FindNestedTypeVisitor {
+        tcx,
+        bound_region: *br,
+        found_type: None,
+        current_index: ty::INNERMOST,
+    };
+    nested_visitor.visit_ty(arg);
+    nested_visitor.found_type
 }
 
 // The FindNestedTypeVisitor captures the corresponding `hir::Ty` of the
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs
index 0599c78ebfd..e20436690b3 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs
@@ -6,7 +6,7 @@ use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::source_map::Span;
 
 mod different_lifetimes;
-mod find_anon_type;
+pub mod find_anon_type;
 mod named_anon_conflict;
 mod placeholder_error;
 mod static_impl_trait;
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
index 2f622231a08..2f3c0d6957a 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
@@ -1,5 +1,6 @@
 //! Error Reporting for Anonymous Region Lifetime Errors
 //! where one region is named and the other is anonymous.
+use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
 use rustc_hir::intravisit::Visitor;
@@ -74,7 +75,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
             return None;
         }
 
-        if let Some((_, fndecl)) = self.find_anon_type(anon, &br) {
+        if let Some((_, fndecl)) = find_anon_type(self.tcx(), anon, &br) {
             if self.is_self_anon(is_first, scope_def_id) {
                 return None;
             }
diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs
index 0400431a542..2f40a90fb55 100644
--- a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs
@@ -513,32 +513,33 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         let id = id.expect_local();
         let tables = tcx.typeck(id);
         let hir_id = tcx.hir().local_def_id_to_hir_id(id);
-        let (span, place) = &tables.closure_kind_origins()[hir_id];
-        let reason = if let PlaceBase::Upvar(upvar_id) = place.base {
-            let upvar = ty::place_to_string_for_capture(tcx, place);
-            match tables.upvar_capture(upvar_id) {
-                ty::UpvarCapture::ByRef(ty::UpvarBorrow {
-                    kind: ty::BorrowKind::MutBorrow | ty::BorrowKind::UniqueImmBorrow,
-                    ..
-                }) => {
-                    format!("mutable borrow of `{}`", upvar)
-                }
-                ty::UpvarCapture::ByValue(_) => {
-                    format!("possible mutation of `{}`", upvar)
+        if let Some((span, place)) = tables.closure_kind_origins().get(hir_id) {
+            let reason = if let PlaceBase::Upvar(upvar_id) = place.base {
+                let upvar = ty::place_to_string_for_capture(tcx, place);
+                match tables.upvar_capture(upvar_id) {
+                    ty::UpvarCapture::ByRef(ty::UpvarBorrow {
+                        kind: ty::BorrowKind::MutBorrow | ty::BorrowKind::UniqueImmBorrow,
+                        ..
+                    }) => {
+                        format!("mutable borrow of `{}`", upvar)
+                    }
+                    ty::UpvarCapture::ByValue(_) => {
+                        format!("possible mutation of `{}`", upvar)
+                    }
+                    val => bug!("upvar `{}` borrowed, but not mutably: {:?}", upvar, val),
                 }
-                val => bug!("upvar `{}` borrowed, but not mutably: {:?}", upvar, val),
-            }
-        } else {
-            bug!("not an upvar")
-        };
-        err.span_label(
-            *span,
-            format!(
-                "calling `{}` requires mutable binding due to {}",
-                self.describe_place(the_place_err).unwrap(),
-                reason
-            ),
-        );
+            } else {
+                bug!("not an upvar")
+            };
+            err.span_label(
+                *span,
+                format!(
+                    "calling `{}` requires mutable binding due to {}",
+                    self.describe_place(the_place_err).unwrap(),
+                    reason
+                ),
+            );
+        }
     }
 
     // Attempt to search similar mutable associated items for suggestion.
diff --git a/compiler/rustc_mir/src/transform/inline/cycle.rs b/compiler/rustc_mir/src/transform/inline/cycle.rs
index 4c24bec0ce3..295f3ec70dc 100644
--- a/compiler/rustc_mir/src/transform/inline/cycle.rs
+++ b/compiler/rustc_mir/src/transform/inline/cycle.rs
@@ -1,4 +1,5 @@
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::sso::SsoHashSet;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::mir::TerminatorKind;
@@ -140,7 +141,7 @@ crate fn mir_inliner_callees<'tcx>(
         // Functions from other crates and MIR shims
         _ => tcx.instance_mir(instance),
     };
-    let mut calls = Vec::new();
+    let mut calls = SsoHashSet::new();
     for bb_data in body.basic_blocks() {
         let terminator = bb_data.terminator();
         if let TerminatorKind::Call { func, .. } = &terminator.kind {
@@ -149,12 +150,8 @@ crate fn mir_inliner_callees<'tcx>(
                 ty::FnDef(def_id, substs) => (*def_id, *substs),
                 _ => continue,
             };
-            // We've seen this before
-            if calls.contains(&call) {
-                continue;
-            }
-            calls.push(call);
+            calls.insert(call);
         }
     }
-    tcx.arena.alloc_slice(&calls)
+    tcx.arena.alloc_from_iter(calls.iter().copied())
 }
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 9fbc56f051b..3881d55ef91 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -371,6 +371,11 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
         span: Span,
     ) -> &'tcx Const<'tcx> {
         bad_placeholder_type(self.tcx(), vec![span]).emit();
+        // Typeck doesn't expect erased regions to be returned from `type_of`.
+        let ty = self.tcx.fold_regions(ty, &mut false, |r, _| match r {
+            ty::ReErased => self.tcx.lifetimes.re_static,
+            _ => r,
+        });
         self.tcx().const_error(ty)
     }
 
@@ -1647,6 +1652,12 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
             match get_infer_ret_ty(&sig.decl.output) {
                 Some(ty) => {
                     let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id];
+                    // Typeck doesn't expect erased regions to be returned from `type_of`.
+                    let fn_sig = tcx.fold_regions(fn_sig, &mut false, |r, _| match r {
+                        ty::ReErased => tcx.lifetimes.re_static,
+                        _ => r,
+                    });
+
                     let mut visitor = PlaceholderHirTyCollector::default();
                     visitor.visit_ty(ty);
                     let mut diag = bad_placeholder_type(tcx, visitor.0);
@@ -1675,6 +1686,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
                         }
                     }
                     diag.emit();
+
                     ty::Binder::bind(fn_sig)
                 }
                 None => AstConv::ty_of_fn(