about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-06-28 16:44:29 +0000
committerbors <bors@rust-lang.org>2020-06-28 16:44:29 +0000
commit2f517ce6f28b5d638cce4c1eccdbe63255b11420 (patch)
tree32d461aeb5d988a76a319c6cec6c1d663c282446
parent25687caa2e4e35b31c29e28998710670e9d54ee9 (diff)
parent117b734ad6af4f646d47256c97d3e0cc95e6ab90 (diff)
downloadrust-2f517ce6f28b5d638cce4c1eccdbe63255b11420.tar.gz
rust-2f517ce6f28b5d638cce4c1eccdbe63255b11420.zip
Auto merge of #73838 - Manishearth:rollup-jj57e84, r=Manishearth
Rollup of 9 pull requests

Successful merges:

 - #73577 (Add partition_point)
 - #73757 (Const prop: erase all block-only locals at the end of every block)
 - #73774 (Make liveness more precise for assignments to fields)
 - #73795 (Add some `const_compare_raw_pointers`-related regression tests)
 - #73800 (Forward Hash::write_iN to Hash::write_uN)
 - #73813 (Rename two `Resolver` traits)
 - #73817 (Rename clashing_extern_decl to clashing_extern_declarations.)
 - #73826 (Fix docstring typo)
 - #73833 (Remove GlobalCtxt::enter_local)

Failed merges:

r? @ghost
-rw-r--r--src/libcore/hash/mod.rs10
-rw-r--r--src/libcore/lib.rs4
-rw-r--r--src/libcore/slice/mod.rs54
-rw-r--r--src/libcore/tests/lib.rs1
-rw-r--r--src/libcore/tests/slice.rs40
-rw-r--r--src/librustc_ast_lowering/lib.rs6
-rw-r--r--src/librustc_builtin_macros/lib.rs4
-rw-r--r--src/librustc_builtin_macros/proc_macro_harness.rs4
-rw-r--r--src/librustc_builtin_macros/standard_library_imports.rs4
-rw-r--r--src/librustc_builtin_macros/test_harness.rs6
-rw-r--r--src/librustc_expand/base.rs6
-rw-r--r--src/librustc_infer/infer/mod.rs36
-rw-r--r--src/librustc_lint/builtin.rs18
-rw-r--r--src/librustc_lint/lib.rs2
-rw-r--r--src/librustc_middle/ty/context.rs32
-rw-r--r--src/librustc_mir/dataflow/impls/liveness.rs27
-rw-r--r--src/librustc_mir/interpret/eval_context.rs7
-rw-r--r--src/librustc_mir/interpret/machine.rs19
-rw-r--r--src/librustc_mir/interpret/operand.rs6
-rw-r--r--src/librustc_mir/interpret/place.rs6
-rw-r--r--src/librustc_mir/transform/const_prop.rs68
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs2
-rw-r--r--src/librustc_resolve/check_unused.rs2
-rw-r--r--src/librustc_resolve/def_collector.rs2
-rw-r--r--src/librustc_resolve/imports.rs2
-rw-r--r--src/librustc_resolve/late.rs2
-rw-r--r--src/librustc_resolve/lib.rs2
-rw-r--r--src/librustc_resolve/macros.rs7
-rw-r--r--src/libstd/io/buffered.rs2
-rw-r--r--src/libstd/sys/unix/args.rs4
-rw-r--r--src/test/ui/const-generics/issues/issue-71381.rs33
-rw-r--r--src/test/ui/const-generics/issues/issue-71381.stderr14
-rw-r--r--src/test/ui/const-generics/issues/issue-71382.rs24
-rw-r--r--src/test/ui/const-generics/issues/issue-71382.stderr8
-rw-r--r--src/test/ui/const-generics/issues/issue-71611.rs9
-rw-r--r--src/test/ui/const-generics/issues/issue-71611.stderr8
-rw-r--r--src/test/ui/const-generics/issues/issue-72352.rs21
-rw-r--r--src/test/ui/const-generics/issues/issue-72352.stderr8
-rw-r--r--src/test/ui/issues/issue-1866.rs2
-rw-r--r--src/test/ui/issues/issue-1866.stderr4
-rw-r--r--src/test/ui/issues/issue-5791.rs2
-rw-r--r--src/test/ui/issues/issue-5791.stderr4
-rw-r--r--src/test/ui/lint/clashing-extern-fn.rs87
-rw-r--r--src/test/ui/lint/clashing-extern-fn.stderr24
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-3.rs2
-rw-r--r--src/test/ui/mir-dataflow/liveness-projection.rs32
-rw-r--r--src/test/ui/mir-dataflow/liveness-projection.stderr16
-rw-r--r--src/test/ui/parser/extern-abi-from-mac-literal-frag.rs2
48 files changed, 526 insertions, 159 deletions
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index d80101753cb..6abe19dc155 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -333,31 +333,31 @@ pub trait Hasher {
     #[inline]
     #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_i16(&mut self, i: i16) {
-        self.write(&i.to_ne_bytes())
+        self.write_u16(i as u16)
     }
     /// Writes a single `i32` into this hasher.
     #[inline]
     #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_i32(&mut self, i: i32) {
-        self.write(&i.to_ne_bytes())
+        self.write_u32(i as u32)
     }
     /// Writes a single `i64` into this hasher.
     #[inline]
     #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_i64(&mut self, i: i64) {
-        self.write(&i.to_ne_bytes())
+        self.write_u64(i as u64)
     }
     /// Writes a single `i128` into this hasher.
     #[inline]
     #[stable(feature = "i128", since = "1.26.0")]
     fn write_i128(&mut self, i: i128) {
-        self.write(&i.to_ne_bytes())
+        self.write_u128(i as u128)
     }
     /// Writes a single `isize` into this hasher.
     #[inline]
     #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_isize(&mut self, i: isize) {
-        self.write(&i.to_ne_bytes())
+        self.write_usize(i as usize)
     }
 }
 
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 2b26e5303a8..15466ce94a8 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -279,9 +279,9 @@ pub mod primitive;
 // crate uses the this crate as its libcore.
 #[path = "../stdarch/crates/core_arch/src/mod.rs"]
 #[allow(missing_docs, missing_debug_implementations, dead_code, unused_imports)]
-// FIXME: This annotation should be moved into rust-lang/stdarch after clashing_extern_decl is
+// FIXME: This annotation should be moved into rust-lang/stdarch after clashing_extern_declarations is
 // merged. It currently cannot because bootstrap fails as the lint hasn't been defined yet.
-#[cfg_attr(not(bootstrap), allow(clashing_extern_decl))]
+#[cfg_attr(not(bootstrap), allow(clashing_extern_declarations))]
 #[unstable(feature = "stdsimd", issue = "48556")]
 mod core_arch;
 
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index 57bacdd99ef..6a50cdbc1d9 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -2663,6 +2663,60 @@ impl<T> [T] {
     {
         self.iter().is_sorted_by_key(f)
     }
+
+    /// Returns the index of the partition point according to the given predicate
+    /// (the index of the first element of the second partition).
+    ///
+    /// The slice is assumed to be partitioned according to the given predicate.
+    /// This means that all elements for which the predicate returns true are at the start of the slice
+    /// and all elements for which the predicate returns false are at the end.
+    /// For example, [7, 15, 3, 5, 4, 12, 6] is a partitioned under the predicate x % 2 != 0
+    /// (all odd numbers are at the start, all even at the end).
+    ///
+    /// If this slice is not partitioned, the returned result is unspecified and meaningless,
+    /// as this method performs a kind of binary search.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(partition_point)]
+    ///
+    /// let v = [1, 2, 3, 3, 5, 6, 7];
+    /// let i = v.partition_point(|&x| x < 5);
+    ///
+    /// assert_eq!(i, 4);
+    /// assert!(v[..i].iter().all(|&x| x < 5));
+    /// assert!(v[i..].iter().all(|&x| !(x < 5)));
+    /// ```
+    #[unstable(feature = "partition_point", reason = "new API", issue = "73831")]
+    pub fn partition_point<P>(&self, mut pred: P) -> usize
+    where
+        P: FnMut(&T) -> bool,
+    {
+        let mut left = 0;
+        let mut right = self.len();
+
+        while left != right {
+            let mid = left + (right - left) / 2;
+            // SAFETY:
+            // When left < right, left <= mid < right.
+            // Therefore left always increases and right always decreases,
+            // and eigher of them is selected.
+            // In both cases left <= right is satisfied.
+            // Therefore if left < right in a step,
+            // left <= right is satisfied in the next step.
+            // Therefore as long as left != right, 0 <= left < right <= len is satisfied
+            // and if this case 0 <= mid < len is satisfied too.
+            let value = unsafe { self.get_unchecked(mid) };
+            if pred(value) {
+                left = mid + 1;
+            } else {
+                right = mid;
+            }
+        }
+
+        left
+    }
 }
 
 #[lang = "slice_u8"]
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 4e55452a4c3..524c38a7ab4 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -44,6 +44,7 @@
 #![feature(const_forget)]
 #![feature(option_unwrap_none)]
 #![feature(peekable_next_if)]
+#![feature(partition_point)]
 
 extern crate test;
 
diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs
index cd46117f763..fba73be92be 100644
--- a/src/libcore/tests/slice.rs
+++ b/src/libcore/tests/slice.rs
@@ -82,6 +82,46 @@ fn test_binary_search_implementation_details() {
 }
 
 #[test]
+fn test_partition_point() {
+    let b: [i32; 0] = [];
+    assert_eq!(b.partition_point(|&x| x < 5), 0);
+
+    let b = [4];
+    assert_eq!(b.partition_point(|&x| x < 3), 0);
+    assert_eq!(b.partition_point(|&x| x < 4), 0);
+    assert_eq!(b.partition_point(|&x| x < 5), 1);
+
+    let b = [1, 2, 4, 6, 8, 9];
+    assert_eq!(b.partition_point(|&x| x < 5), 3);
+    assert_eq!(b.partition_point(|&x| x < 6), 3);
+    assert_eq!(b.partition_point(|&x| x < 7), 4);
+    assert_eq!(b.partition_point(|&x| x < 8), 4);
+
+    let b = [1, 2, 4, 5, 6, 8];
+    assert_eq!(b.partition_point(|&x| x < 9), 6);
+
+    let b = [1, 2, 4, 6, 7, 8, 9];
+    assert_eq!(b.partition_point(|&x| x < 6), 3);
+    assert_eq!(b.partition_point(|&x| x < 5), 3);
+    assert_eq!(b.partition_point(|&x| x < 8), 5);
+
+    let b = [1, 2, 4, 5, 6, 8, 9];
+    assert_eq!(b.partition_point(|&x| x < 7), 5);
+    assert_eq!(b.partition_point(|&x| x < 0), 0);
+
+    let b = [1, 3, 3, 3, 7];
+    assert_eq!(b.partition_point(|&x| x < 0), 0);
+    assert_eq!(b.partition_point(|&x| x < 1), 0);
+    assert_eq!(b.partition_point(|&x| x < 2), 1);
+    assert_eq!(b.partition_point(|&x| x < 3), 1);
+    assert_eq!(b.partition_point(|&x| x < 4), 4);
+    assert_eq!(b.partition_point(|&x| x < 5), 4);
+    assert_eq!(b.partition_point(|&x| x < 6), 4);
+    assert_eq!(b.partition_point(|&x| x < 7), 4);
+    assert_eq!(b.partition_point(|&x| x < 8), 5);
+}
+
+#[test]
 fn test_iterator_nth() {
     let v: &[_] = &[0, 1, 2, 3, 4];
     for i in 0..v.len() {
diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs
index 863f525bdc8..bc0980f041b 100644
--- a/src/librustc_ast_lowering/lib.rs
+++ b/src/librustc_ast_lowering/lib.rs
@@ -91,7 +91,7 @@ struct LoweringContext<'a, 'hir: 'a> {
     /// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.
     sess: &'a Session,
 
-    resolver: &'a mut dyn Resolver,
+    resolver: &'a mut dyn ResolverAstLowering,
 
     /// HACK(Centril): there is a cyclic dependency between the parser and lowering
     /// if we don't have this function pointer. To avoid that dependency so that
@@ -172,7 +172,7 @@ struct LoweringContext<'a, 'hir: 'a> {
     allow_gen_future: Option<Lrc<[Symbol]>>,
 }
 
-pub trait Resolver {
+pub trait ResolverAstLowering {
     fn def_key(&mut self, id: DefId) -> DefKey;
 
     fn item_generics_num_lifetimes(&self, def: DefId, sess: &Session) -> usize;
@@ -299,7 +299,7 @@ impl<'a> ImplTraitContext<'_, 'a> {
 pub fn lower_crate<'a, 'hir>(
     sess: &'a Session,
     krate: &'a Crate,
-    resolver: &'a mut dyn Resolver,
+    resolver: &'a mut dyn ResolverAstLowering,
     nt_to_tokenstream: NtToTokenstream,
     arena: &'hir Arena<'hir>,
 ) -> hir::Crate<'hir> {
diff --git a/src/librustc_builtin_macros/lib.rs b/src/librustc_builtin_macros/lib.rs
index f56d8a372a7..173a823dc7d 100644
--- a/src/librustc_builtin_macros/lib.rs
+++ b/src/librustc_builtin_macros/lib.rs
@@ -15,7 +15,7 @@ extern crate proc_macro;
 
 use crate::deriving::*;
 
-use rustc_expand::base::{MacroExpanderFn, Resolver, SyntaxExtension, SyntaxExtensionKind};
+use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtension, SyntaxExtensionKind};
 use rustc_expand::proc_macro::BangProcMacro;
 use rustc_span::edition::Edition;
 use rustc_span::symbol::{sym, Ident};
@@ -45,7 +45,7 @@ pub mod proc_macro_harness;
 pub mod standard_library_imports;
 pub mod test_harness;
 
-pub fn register_builtin_macros(resolver: &mut dyn Resolver, edition: Edition) {
+pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand, edition: Edition) {
     let mut register = |name, kind| {
         resolver.register_builtin_macro(
             Ident::with_dummy_span(name),
diff --git a/src/librustc_builtin_macros/proc_macro_harness.rs b/src/librustc_builtin_macros/proc_macro_harness.rs
index adaf5f03079..7cc9c1f7663 100644
--- a/src/librustc_builtin_macros/proc_macro_harness.rs
+++ b/src/librustc_builtin_macros/proc_macro_harness.rs
@@ -6,7 +6,7 @@ use rustc_ast::expand::is_proc_macro_attr;
 use rustc_ast::ptr::P;
 use rustc_ast::visit::{self, Visitor};
 use rustc_ast_pretty::pprust;
-use rustc_expand::base::{ExtCtxt, Resolver};
+use rustc_expand::base::{ExtCtxt, ResolverExpand};
 use rustc_expand::expand::{AstFragment, ExpansionConfig};
 use rustc_session::parse::ParseSess;
 use rustc_span::hygiene::AstPass;
@@ -52,7 +52,7 @@ struct CollectProcMacros<'a> {
 
 pub fn inject(
     sess: &ParseSess,
-    resolver: &mut dyn Resolver,
+    resolver: &mut dyn ResolverExpand,
     mut krate: ast::Crate,
     is_proc_macro_crate: bool,
     has_proc_macro_decls: bool,
diff --git a/src/librustc_builtin_macros/standard_library_imports.rs b/src/librustc_builtin_macros/standard_library_imports.rs
index cd3773c76c4..671ff8ce54f 100644
--- a/src/librustc_builtin_macros/standard_library_imports.rs
+++ b/src/librustc_builtin_macros/standard_library_imports.rs
@@ -1,6 +1,6 @@
 use rustc_ast::ptr::P;
 use rustc_ast::{ast, attr};
-use rustc_expand::base::{ExtCtxt, Resolver};
+use rustc_expand::base::{ExtCtxt, ResolverExpand};
 use rustc_expand::expand::ExpansionConfig;
 use rustc_session::parse::ParseSess;
 use rustc_span::edition::Edition;
@@ -10,7 +10,7 @@ use rustc_span::DUMMY_SP;
 
 pub fn inject(
     mut krate: ast::Crate,
-    resolver: &mut dyn Resolver,
+    resolver: &mut dyn ResolverExpand,
     sess: &ParseSess,
     alt_std_name: Option<Symbol>,
 ) -> (ast::Crate, Option<Symbol>) {
diff --git a/src/librustc_builtin_macros/test_harness.rs b/src/librustc_builtin_macros/test_harness.rs
index 34ed4c800e0..da8bf2b8b51 100644
--- a/src/librustc_builtin_macros/test_harness.rs
+++ b/src/librustc_builtin_macros/test_harness.rs
@@ -6,7 +6,7 @@ use rustc_ast::attr;
 use rustc_ast::entry::{self, EntryPointType};
 use rustc_ast::mut_visit::{ExpectOne, *};
 use rustc_ast::ptr::P;
-use rustc_expand::base::{ExtCtxt, Resolver};
+use rustc_expand::base::{ExtCtxt, ResolverExpand};
 use rustc_expand::expand::{AstFragment, ExpansionConfig};
 use rustc_feature::Features;
 use rustc_session::parse::ParseSess;
@@ -37,7 +37,7 @@ struct TestCtxt<'a> {
 // existing main functions, and synthesizing a main test harness
 pub fn inject(
     sess: &ParseSess,
-    resolver: &mut dyn Resolver,
+    resolver: &mut dyn ResolverExpand,
     should_test: bool,
     krate: &mut ast::Crate,
     span_diagnostic: &rustc_errors::Handler,
@@ -192,7 +192,7 @@ impl MutVisitor for EntryPointCleaner {
 /// Crawl over the crate, inserting test reexports and the test main function
 fn generate_test_harness(
     sess: &ParseSess,
-    resolver: &mut dyn Resolver,
+    resolver: &mut dyn ResolverExpand,
     reexport_test_harness_main: Option<Symbol>,
     krate: &mut ast::Crate,
     features: &Features,
diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs
index d4c756c9ec7..757eee8bb46 100644
--- a/src/librustc_expand/base.rs
+++ b/src/librustc_expand/base.rs
@@ -889,7 +889,7 @@ pub enum InvocationRes {
 /// Error type that denotes indeterminacy.
 pub struct Indeterminate;
 
-pub trait Resolver {
+pub trait ResolverExpand {
     fn next_node_id(&mut self) -> NodeId;
 
     fn resolve_dollar_crates(&mut self);
@@ -946,7 +946,7 @@ pub struct ExtCtxt<'a> {
     pub ecfg: expand::ExpansionConfig<'a>,
     pub reduced_recursion_limit: Option<Limit>,
     pub root_path: PathBuf,
-    pub resolver: &'a mut dyn Resolver,
+    pub resolver: &'a mut dyn ResolverExpand,
     pub current_expansion: ExpansionData,
     pub expansions: FxHashMap<Span, Vec<String>>,
     /// Called directly after having parsed an external `mod foo;` in expansion.
@@ -957,7 +957,7 @@ impl<'a> ExtCtxt<'a> {
     pub fn new(
         parse_sess: &'a ParseSess,
         ecfg: expand::ExpansionConfig<'a>,
-        resolver: &'a mut dyn Resolver,
+        resolver: &'a mut dyn ResolverExpand,
         extern_mod_loaded: Option<&'a dyn Fn(&ast::Crate)>,
     ) -> ExtCtxt<'a> {
         ExtCtxt {
diff --git a/src/librustc_infer/infer/mod.rs b/src/librustc_infer/infer/mod.rs
index 8f8ce03d638..76ac61c0672 100644
--- a/src/librustc_infer/infer/mod.rs
+++ b/src/librustc_infer/infer/mod.rs
@@ -570,7 +570,7 @@ impl<'tcx> fmt::Display for FixupError<'tcx> {
 /// Necessary because we can't write the following bound:
 /// `F: for<'b, 'tcx> where 'tcx FnOnce(InferCtxt<'b, 'tcx>)`.
 pub struct InferCtxtBuilder<'tcx> {
-    global_tcx: TyCtxt<'tcx>,
+    tcx: TyCtxt<'tcx>,
     fresh_tables: Option<RefCell<ty::TypeckTables<'tcx>>>,
 }
 
@@ -580,7 +580,7 @@ pub trait TyCtxtInferExt<'tcx> {
 
 impl TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
     fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
-        InferCtxtBuilder { global_tcx: self, fresh_tables: None }
+        InferCtxtBuilder { tcx: self, fresh_tables: None }
     }
 }
 
@@ -616,24 +616,22 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
     }
 
     pub fn enter<R>(&mut self, f: impl for<'a> FnOnce(InferCtxt<'a, 'tcx>) -> R) -> R {
-        let InferCtxtBuilder { global_tcx, ref fresh_tables } = *self;
+        let InferCtxtBuilder { tcx, ref fresh_tables } = *self;
         let in_progress_tables = fresh_tables.as_ref();
-        global_tcx.enter_local(|tcx| {
-            f(InferCtxt {
-                tcx,
-                in_progress_tables,
-                inner: RefCell::new(InferCtxtInner::new()),
-                lexical_region_resolutions: RefCell::new(None),
-                selection_cache: Default::default(),
-                evaluation_cache: Default::default(),
-                reported_trait_errors: Default::default(),
-                reported_closure_mismatch: Default::default(),
-                tainted_by_errors_flag: Cell::new(false),
-                err_count_on_creation: tcx.sess.err_count(),
-                in_snapshot: Cell::new(false),
-                skip_leak_check: Cell::new(false),
-                universe: Cell::new(ty::UniverseIndex::ROOT),
-            })
+        f(InferCtxt {
+            tcx,
+            in_progress_tables,
+            inner: RefCell::new(InferCtxtInner::new()),
+            lexical_region_resolutions: RefCell::new(None),
+            selection_cache: Default::default(),
+            evaluation_cache: Default::default(),
+            reported_trait_errors: Default::default(),
+            reported_closure_mismatch: Default::default(),
+            tainted_by_errors_flag: Cell::new(false),
+            err_count_on_creation: tcx.sess.err_count(),
+            in_snapshot: Cell::new(false),
+            skip_leak_check: Cell::new(false),
+            universe: Cell::new(ty::UniverseIndex::ROOT),
         })
     }
 }
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index d8f3caa2c44..36d2954ac6e 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -2055,12 +2055,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue {
 }
 
 declare_lint! {
-    pub CLASHING_EXTERN_DECL,
+    pub CLASHING_EXTERN_DECLARATIONS,
     Warn,
     "detects when an extern fn has been declared with the same name but different types"
 }
 
-pub struct ClashingExternDecl {
+pub struct ClashingExternDeclarations {
     seen_decls: FxHashMap<Symbol, HirId>,
 }
 
@@ -2083,9 +2083,9 @@ impl SymbolName {
     }
 }
 
-impl ClashingExternDecl {
+impl ClashingExternDeclarations {
     crate fn new() -> Self {
-        ClashingExternDecl { seen_decls: FxHashMap::default() }
+        ClashingExternDeclarations { seen_decls: FxHashMap::default() }
     }
     /// Insert a new foreign item into the seen set. If a symbol with the same name already exists
     /// for the item, return its HirId without updating the set.
@@ -2211,18 +2211,18 @@ impl ClashingExternDecl {
     }
 }
 
-impl_lint_pass!(ClashingExternDecl => [CLASHING_EXTERN_DECL]);
+impl_lint_pass!(ClashingExternDeclarations => [CLASHING_EXTERN_DECLARATIONS]);
 
-impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ClashingExternDecl {
+impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ClashingExternDeclarations {
     fn check_foreign_item(&mut self, cx: &LateContext<'a, 'tcx>, this_fi: &hir::ForeignItem<'_>) {
-        trace!("ClashingExternDecl: check_foreign_item: {:?}", this_fi);
+        trace!("ClashingExternDeclarations: check_foreign_item: {:?}", this_fi);
         if let ForeignItemKind::Fn(..) = this_fi.kind {
             let tcx = *&cx.tcx;
             if let Some(existing_hid) = self.insert(tcx, this_fi) {
                 let existing_decl_ty = tcx.type_of(tcx.hir().local_def_id(existing_hid));
                 let this_decl_ty = tcx.type_of(tcx.hir().local_def_id(this_fi.hir_id));
                 debug!(
-                    "ClashingExternDecl: Comparing existing {:?}: {:?} to this {:?}: {:?}",
+                    "ClashingExternDeclarations: Comparing existing {:?}: {:?} to this {:?}: {:?}",
                     existing_hid, existing_decl_ty, this_fi.hir_id, this_decl_ty
                 );
                 // Check that the declarations match.
@@ -2239,7 +2239,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ClashingExternDecl {
                         };
                     // Finally, emit the diagnostic.
                     tcx.struct_span_lint_hir(
-                        CLASHING_EXTERN_DECL,
+                        CLASHING_EXTERN_DECLARATIONS,
                         this_fi.hir_id,
                         get_relevant_span(this_fi),
                         |lint| {
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index b39abe7b411..4da98d20159 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -155,7 +155,7 @@ macro_rules! late_lint_passes {
                 // and change this to a module lint pass
                 MissingDebugImplementations: MissingDebugImplementations::default(),
                 ArrayIntoIter: ArrayIntoIter,
-                ClashingExternDecl: ClashingExternDecl::new(),
+                ClashingExternDeclarations: ClashingExternDeclarations::new(),
             ]
         );
     };
diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs
index 44c8c1f6fdb..e2f601371b1 100644
--- a/src/librustc_middle/ty/context.rs
+++ b/src/librustc_middle/ty/context.rs
@@ -1560,28 +1560,6 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 }
 
-impl<'tcx> GlobalCtxt<'tcx> {
-    /// Calls the closure with a local `TyCtxt` using the given arena.
-    /// `interners` is a slot passed so we can create a CtxtInterners
-    /// with the same lifetime as `arena`.
-    pub fn enter_local<F, R>(&'tcx self, f: F) -> R
-    where
-        F: FnOnce(TyCtxt<'tcx>) -> R,
-    {
-        let tcx = TyCtxt { gcx: self };
-        ty::tls::with_related_context(tcx, |icx| {
-            let new_icx = ty::tls::ImplicitCtxt {
-                tcx,
-                query: icx.query,
-                diagnostics: icx.diagnostics,
-                layout_depth: icx.layout_depth,
-                task_deps: icx.task_deps,
-            };
-            ty::tls::enter_context(&new_icx, |_| f(tcx))
-        })
-    }
-}
-
 /// A trait implemented for all `X<'a>` types that can be safely and
 /// efficiently converted to `X<'tcx>` as long as they are part of the
 /// provided `TyCtxt<'tcx>`.
@@ -1818,11 +1796,11 @@ pub mod tls {
         with_context_opt(|opt_context| f(opt_context.expect("no ImplicitCtxt stored in tls")))
     }
 
-    /// Allows access to the current `ImplicitCtxt` whose tcx field has the same global
-    /// interner as the tcx argument passed in. This means the closure is given an `ImplicitCtxt`
-    /// with the same `'tcx` lifetime as the `TyCtxt` passed in.
-    /// This will panic if you pass it a `TyCtxt` which has a different global interner from
-    /// the current `ImplicitCtxt`'s `tcx` field.
+    /// Allows access to the current `ImplicitCtxt` whose tcx field is the same as the tcx argument
+    /// passed in. This means the closure is given an `ImplicitCtxt` with the same `'tcx` lifetime
+    /// as the `TyCtxt` passed in.
+    /// This will panic if you pass it a `TyCtxt` which is different from the current
+    /// `ImplicitCtxt`'s `tcx` field.
     #[inline]
     pub fn with_related_context<'tcx, F, R>(tcx: TyCtxt<'tcx>, f: F) -> R
     where
diff --git a/src/librustc_mir/dataflow/impls/liveness.rs b/src/librustc_mir/dataflow/impls/liveness.rs
index d24faacd377..784b0bd9293 100644
--- a/src/librustc_mir/dataflow/impls/liveness.rs
+++ b/src/librustc_mir/dataflow/impls/liveness.rs
@@ -92,7 +92,27 @@ impl<'tcx, T> Visitor<'tcx> for TransferFunction<'_, T>
 where
     T: GenKill<Local>,
 {
+    fn visit_place(&mut self, place: &mir::Place<'tcx>, context: PlaceContext, location: Location) {
+        let mir::Place { projection, local } = *place;
+
+        // We purposefully do not call `super_place` here to avoid calling `visit_local` for this
+        // place with one of the `Projection` variants of `PlaceContext`.
+        self.visit_projection(local, projection, context, location);
+
+        match DefUse::for_place(context) {
+            // Treat derefs as a use of the base local. `*p = 4` is not a def of `p` but a use.
+            Some(_) if place.is_indirect() => self.0.gen(local),
+
+            Some(DefUse::Def) if projection.is_empty() => self.0.kill(local),
+            Some(DefUse::Use) => self.0.gen(local),
+            _ => {}
+        }
+    }
+
     fn visit_local(&mut self, &local: &Local, context: PlaceContext, _: Location) {
+        // Because we do not call `super_place` above, `visit_local` is only called for locals that
+        // do not appear as part of  a `Place` in the MIR. This handles cases like the implicit use
+        // of the return place in a `Return` terminator or the index in an `Index` projection.
         match DefUse::for_place(context) {
             Some(DefUse::Def) => self.0.kill(local),
             Some(DefUse::Use) => self.0.gen(local),
@@ -126,7 +146,6 @@ impl DefUse {
                 | MutatingUseContext::AsmOutput
                 | MutatingUseContext::Borrow
                 | MutatingUseContext::Drop
-                | MutatingUseContext::Projection
                 | MutatingUseContext::Retag,
             )
             | PlaceContext::NonMutatingUse(
@@ -134,11 +153,15 @@ impl DefUse {
                 | NonMutatingUseContext::Copy
                 | NonMutatingUseContext::Inspect
                 | NonMutatingUseContext::Move
-                | NonMutatingUseContext::Projection
                 | NonMutatingUseContext::ShallowBorrow
                 | NonMutatingUseContext::SharedBorrow
                 | NonMutatingUseContext::UniqueBorrow,
             ) => Some(DefUse::Use),
+
+            PlaceContext::MutatingUse(MutatingUseContext::Projection)
+            | PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) => {
+                unreachable!("A projection could be a def or a use and must be handled separately")
+            }
         }
     }
 }
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 9c72a18c6d4..602876e3de1 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -132,6 +132,10 @@ pub enum LocalValue<Tag = ()> {
 }
 
 impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> {
+    /// Read the local's value or error if the local is not yet live or not live anymore.
+    ///
+    /// Note: This may only be invoked from the `Machine::access_local` hook and not from
+    /// anywhere else. You may be invalidating machine invariants if you do!
     pub fn access(&self) -> InterpResult<'tcx, Operand<Tag>> {
         match self.value {
             LocalValue::Dead => throw_ub!(DeadLocal),
@@ -144,6 +148,9 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> {
 
     /// Overwrite the local.  If the local can be overwritten in place, return a reference
     /// to do so; otherwise return the `MemPlace` to consult instead.
+    ///
+    /// Note: This may only be invoked from the `Machine::access_local_mut` hook and not from
+    /// anywhere else. You may be invalidating machine invariants if you do!
     pub fn access_mut(
         &mut self,
     ) -> InterpResult<'tcx, Result<&mut LocalValue<Tag>, MemPlace<Tag>>> {
diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs
index b5dc40d9551..ec1c93c8165 100644
--- a/src/librustc_mir/interpret/machine.rs
+++ b/src/librustc_mir/interpret/machine.rs
@@ -11,7 +11,7 @@ use rustc_span::def_id::DefId;
 
 use super::{
     AllocId, Allocation, AllocationExtra, CheckInAllocMsg, Frame, ImmTy, InterpCx, InterpResult,
-    Memory, MemoryKind, OpTy, Operand, PlaceTy, Pointer, Scalar,
+    LocalValue, MemPlace, Memory, MemoryKind, OpTy, Operand, PlaceTy, Pointer, Scalar,
 };
 
 /// Data returned by Machine::stack_pop,
@@ -192,6 +192,8 @@ pub trait Machine<'mir, 'tcx>: Sized {
     ) -> InterpResult<'tcx>;
 
     /// Called to read the specified `local` from the `frame`.
+    /// Since reading a ZST is not actually accessing memory or locals, this is never invoked
+    /// for ZST reads.
     #[inline]
     fn access_local(
         _ecx: &InterpCx<'mir, 'tcx, Self>,
@@ -201,6 +203,21 @@ pub trait Machine<'mir, 'tcx>: Sized {
         frame.locals[local].access()
     }
 
+    /// Called to write the specified `local` from the `frame`.
+    /// Since writing a ZST is not actually accessing memory or locals, this is never invoked
+    /// for ZST reads.
+    #[inline]
+    fn access_local_mut<'a>(
+        ecx: &'a mut InterpCx<'mir, 'tcx, Self>,
+        frame: usize,
+        local: mir::Local,
+    ) -> InterpResult<'tcx, Result<&'a mut LocalValue<Self::PointerTag>, MemPlace<Self::PointerTag>>>
+    where
+        'tcx: 'mir,
+    {
+        ecx.stack_mut()[frame].locals[local].access_mut()
+    }
+
     /// Called before a basic block terminator is executed.
     /// You can use this to detect endlessly running programs.
     #[inline]
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index fd55deaf83b..b02b5219ba1 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -432,7 +432,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         })
     }
 
-    /// This is used by [priroda](https://github.com/oli-obk/priroda) to get an OpTy from a local
+    /// Read from a local. Will not actually access the local if reading from a ZST.
+    /// Will not access memory, instead an indirect `Operand` is returned.
+    ///
+    /// This is public because it is used by [priroda](https://github.com/oli-obk/priroda) to get an
+    /// OpTy from a local
     pub fn access_local(
         &self,
         frame: &super::Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>,
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 98a1cea97e2..3868150c6bd 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -741,7 +741,7 @@ where
         // but not factored as a separate function.
         let mplace = match dest.place {
             Place::Local { frame, local } => {
-                match self.stack_mut()[frame].locals[local].access_mut()? {
+                match M::access_local_mut(self, frame, local)? {
                     Ok(local) => {
                         // Local can be updated in-place.
                         *local = LocalValue::Live(Operand::Immediate(src));
@@ -974,7 +974,7 @@ where
     ) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::PointerTag>, Option<Size>)> {
         let (mplace, size) = match place.place {
             Place::Local { frame, local } => {
-                match self.stack_mut()[frame].locals[local].access_mut()? {
+                match M::access_local_mut(self, frame, local)? {
                     Ok(&mut local_val) => {
                         // We need to make an allocation.
 
@@ -998,7 +998,7 @@ where
                         }
                         // Now we can call `access_mut` again, asserting it goes well,
                         // and actually overwrite things.
-                        *self.stack_mut()[frame].locals[local].access_mut().unwrap().unwrap() =
+                        *M::access_local_mut(self, frame, local).unwrap().unwrap() =
                             LocalValue::Live(Operand::Indirect(mplace));
                         (mplace, Some(size))
                     }
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index a891f12c8e1..841f1c2b647 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -4,6 +4,7 @@
 use std::cell::Cell;
 
 use rustc_ast::ast::Mutability;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def::DefKind;
 use rustc_hir::HirId;
 use rustc_index::bit_set::BitSet;
@@ -28,7 +29,7 @@ use rustc_trait_selection::traits;
 use crate::const_eval::error_to_const_error;
 use crate::interpret::{
     self, compile_time_machine, AllocId, Allocation, Frame, ImmTy, Immediate, InterpCx, LocalState,
-    LocalValue, Memory, MemoryKind, OpTy, Operand as InterpOperand, PlaceTy, Pointer,
+    LocalValue, MemPlace, Memory, MemoryKind, OpTy, Operand as InterpOperand, PlaceTy, Pointer,
     ScalarMaybeUninit, StackPopCleanup,
 };
 use crate::transform::{MirPass, MirSource};
@@ -151,11 +152,19 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
 struct ConstPropMachine<'mir, 'tcx> {
     /// The virtual call stack.
     stack: Vec<Frame<'mir, 'tcx, (), ()>>,
+    /// `OnlyInsideOwnBlock` locals that were written in the current block get erased at the end.
+    written_only_inside_own_block_locals: FxHashSet<Local>,
+    /// Locals that need to be cleared after every block terminates.
+    only_propagate_inside_block_locals: BitSet<Local>,
 }
 
 impl<'mir, 'tcx> ConstPropMachine<'mir, 'tcx> {
-    fn new() -> Self {
-        Self { stack: Vec::new() }
+    fn new(only_propagate_inside_block_locals: BitSet<Local>) -> Self {
+        Self {
+            stack: Vec::new(),
+            written_only_inside_own_block_locals: Default::default(),
+            only_propagate_inside_block_locals,
+        }
     }
 }
 
@@ -227,6 +236,18 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
         l.access()
     }
 
+    fn access_local_mut<'a>(
+        ecx: &'a mut InterpCx<'mir, 'tcx, Self>,
+        frame: usize,
+        local: Local,
+    ) -> InterpResult<'tcx, Result<&'a mut LocalValue<Self::PointerTag>, MemPlace<Self::PointerTag>>>
+    {
+        if frame == 0 && ecx.machine.only_propagate_inside_block_locals.contains(local) {
+            ecx.machine.written_only_inside_own_block_locals.insert(local);
+        }
+        ecx.machine.stack[frame].locals[local].access_mut()
+    }
+
     fn before_access_global(
         _memory_extra: &(),
         _alloc_id: AllocId,
@@ -274,8 +295,6 @@ struct ConstPropagator<'mir, 'tcx> {
     // Because we have `MutVisitor` we can't obtain the `SourceInfo` from a `Location`. So we store
     // the last known `SourceInfo` here and just keep revisiting it.
     source_info: Option<SourceInfo>,
-    // Locals we need to forget at the end of the current block
-    locals_of_current_block: BitSet<Local>,
 }
 
 impl<'mir, 'tcx> LayoutOf for ConstPropagator<'mir, 'tcx> {
@@ -313,8 +332,20 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         let param_env = tcx.param_env(def_id).with_reveal_all();
 
         let span = tcx.def_span(def_id);
-        let mut ecx = InterpCx::new(tcx, span, param_env, ConstPropMachine::new(), ());
         let can_const_prop = CanConstProp::check(body);
+        let mut only_propagate_inside_block_locals = BitSet::new_empty(can_const_prop.len());
+        for (l, mode) in can_const_prop.iter_enumerated() {
+            if *mode == ConstPropMode::OnlyInsideOwnBlock {
+                only_propagate_inside_block_locals.insert(l);
+            }
+        }
+        let mut ecx = InterpCx::new(
+            tcx,
+            span,
+            param_env,
+            ConstPropMachine::new(only_propagate_inside_block_locals),
+            (),
+        );
 
         let ret = ecx
             .layout_of(body.return_ty().subst(tcx, substs))
@@ -345,7 +376,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             //FIXME(wesleywiser) we can't steal this because `Visitor::super_visit_body()` needs it
             local_decls: body.local_decls.clone(),
             source_info: None,
-            locals_of_current_block: BitSet::new_empty(body.local_decls.len()),
         }
     }
 
@@ -900,7 +930,6 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
                                 Will remove it from const-prop after block is finished. Local: {:?}",
                                 place.local
                             );
-                            self.locals_of_current_block.insert(place.local);
                         }
                         ConstPropMode::OnlyPropagateInto | ConstPropMode::NoPropagation => {
                             trace!("can't propagate into {:?}", place);
@@ -1089,10 +1118,27 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
                 }
             }
         }
-        // We remove all Locals which are restricted in propagation to their containing blocks.
-        for local in self.locals_of_current_block.iter() {
+
+        // We remove all Locals which are restricted in propagation to their containing blocks and
+        // which were modified in the current block.
+        // Take it out of the ecx so we can get a mutable reference to the ecx for `remove_const`
+        let mut locals = std::mem::take(&mut self.ecx.machine.written_only_inside_own_block_locals);
+        for &local in locals.iter() {
             Self::remove_const(&mut self.ecx, local);
         }
-        self.locals_of_current_block.clear();
+        locals.clear();
+        // Put it back so we reuse the heap of the storage
+        self.ecx.machine.written_only_inside_own_block_locals = locals;
+        if cfg!(debug_assertions) {
+            // Ensure we are correctly erasing locals with the non-debug-assert logic.
+            for local in self.ecx.machine.only_propagate_inside_block_locals.iter() {
+                assert!(
+                    self.get_const(local.into()).is_none()
+                        || self
+                            .layout_of(self.local_decls[local].ty)
+                            .map_or(true, |layout| layout.is_zst())
+                )
+            }
+        }
     }
 }
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 72faa68d0b2..a92d451dfd0 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -19,7 +19,7 @@ use rustc_ast::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind,
 use rustc_ast::ast::{AssocItem, AssocItemKind, MetaItemKind, StmtKind};
 use rustc_ast::token::{self, Token};
 use rustc_ast::visit::{self, AssocCtxt, Visitor};
-use rustc_ast_lowering::Resolver as ResolverAstLowering;
+use rustc_ast_lowering::ResolverAstLowering;
 use rustc_attr as attr;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{struct_span_err, Applicability};
diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs
index 0ca01a384e7..1f36e1ed83d 100644
--- a/src/librustc_resolve/check_unused.rs
+++ b/src/librustc_resolve/check_unused.rs
@@ -29,7 +29,7 @@ use crate::Resolver;
 use rustc_ast::ast;
 use rustc_ast::node_id::NodeMap;
 use rustc_ast::visit::{self, Visitor};
-use rustc_ast_lowering::Resolver as ResolverAstLowering;
+use rustc_ast_lowering::ResolverAstLowering;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::pluralize;
 use rustc_middle::ty;
diff --git a/src/librustc_resolve/def_collector.rs b/src/librustc_resolve/def_collector.rs
index dc8d1a8d3fd..c25a20210e0 100644
--- a/src/librustc_resolve/def_collector.rs
+++ b/src/librustc_resolve/def_collector.rs
@@ -4,7 +4,7 @@ use rustc_ast::ast::*;
 use rustc_ast::token::{self, Token};
 use rustc_ast::visit::{self, FnKind};
 use rustc_ast::walk_list;
-use rustc_ast_lowering::Resolver as ResolverAstLowering;
+use rustc_ast_lowering::ResolverAstLowering;
 use rustc_expand::expand::AstFragment;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::definitions::*;
diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs
index 8a6541b399e..ded0ee8a966 100644
--- a/src/librustc_resolve/imports.rs
+++ b/src/librustc_resolve/imports.rs
@@ -12,7 +12,7 @@ use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBindin
 use rustc_ast::ast::NodeId;
 use rustc_ast::unwrap_or;
 use rustc_ast::util::lev_distance::find_best_match_for_name;
-use rustc_ast_lowering::Resolver as ResolverAstLowering;
+use rustc_ast_lowering::ResolverAstLowering;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::ptr_key::PtrKey;
 use rustc_errors::{pluralize, struct_span_err, Applicability};
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index b8fb813ea15..84ba9094ea1 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -16,7 +16,7 @@ use rustc_ast::ptr::P;
 use rustc_ast::util::lev_distance::find_best_match_for_name;
 use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
 use rustc_ast::{unwrap_or, walk_list};
-use rustc_ast_lowering::Resolver as ResolverAstLowering;
+use rustc_ast_lowering::ResolverAstLowering;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::DiagnosticId;
 use rustc_hir::def::Namespace::{self, *};
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 9ddcf9e1de7..dccaf76723a 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -27,7 +27,7 @@ use rustc_ast::attr;
 use rustc_ast::node_id::NodeMap;
 use rustc_ast::unwrap_or;
 use rustc_ast::visit::{self, Visitor};
-use rustc_ast_lowering::Resolver as ResolverAstLowering;
+use rustc_ast_lowering::ResolverAstLowering;
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
 use rustc_data_structures::ptr_key::PtrKey;
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 398b0e92d9d..3976e501c16 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -7,12 +7,11 @@ use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy};
 use crate::{CrateLint, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Weak};
 use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding};
 use rustc_ast::ast::{self, NodeId};
-use rustc_ast_lowering::Resolver as ResolverAstLowering;
+use rustc_ast_lowering::ResolverAstLowering;
 use rustc_ast_pretty::pprust;
 use rustc_attr::{self as attr, StabilityLevel};
 use rustc_data_structures::fx::FxHashSet;
-use rustc_expand::base::SyntaxExtension;
-use rustc_expand::base::{self, Indeterminate, InvocationRes};
+use rustc_expand::base::{Indeterminate, InvocationRes, ResolverExpand, SyntaxExtension};
 use rustc_expand::compile_declarative_macro;
 use rustc_expand::expand::{AstFragment, AstFragmentKind, Invocation, InvocationKind};
 use rustc_feature::is_builtin_attr_name;
@@ -141,7 +140,7 @@ crate fn registered_attrs_and_tools(
     (registered_attrs, registered_tools)
 }
 
-impl<'a> base::Resolver for Resolver<'a> {
+impl<'a> ResolverExpand for Resolver<'a> {
     fn next_node_id(&mut self) -> NodeId {
         self.next_node_id()
     }
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 0737008a94c..b4c91cced43 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -400,7 +400,7 @@ impl<R: Seek> Seek for BufReader<R> {
 /// in memory, like a `Vec<u8>`.
 ///
 /// It is critical to call [`flush`] before `BufWriter<W>` is dropped. Though
-/// dropping will attempt to flush the the contents of the buffer, any errors
+/// dropping will attempt to flush the contents of the buffer, any errors
 /// that happen in the process of dropping will be ignored. Calling [`flush`]
 /// ensures that the buffer is empty and thus dropping will not even attempt
 /// file operations.
diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs
index 1d1cdda1257..773fab36be2 100644
--- a/src/libstd/sys/unix/args.rs
+++ b/src/libstd/sys/unix/args.rs
@@ -205,7 +205,7 @@ mod imp {
         #[cfg(target_arch = "aarch64")]
         extern "C" {
             fn objc_msgSend(obj: NsId, sel: Sel) -> NsId;
-            #[cfg_attr(not(bootstrap), allow(clashing_extern_decl))]
+            #[cfg_attr(not(bootstrap), allow(clashing_extern_declarations))]
             #[link_name = "objc_msgSend"]
             fn objc_msgSend_ul(obj: NsId, sel: Sel, i: libc::c_ulong) -> NsId;
         }
@@ -213,7 +213,7 @@ mod imp {
         #[cfg(not(target_arch = "aarch64"))]
         extern "C" {
             fn objc_msgSend(obj: NsId, sel: Sel, ...) -> NsId;
-            #[cfg_attr(not(bootstrap), allow(clashing_extern_decl))]
+            #[cfg_attr(not(bootstrap), allow(clashing_extern_declarations))]
             #[link_name = "objc_msgSend"]
             fn objc_msgSend_ul(obj: NsId, sel: Sel, ...) -> NsId;
         }
diff --git a/src/test/ui/const-generics/issues/issue-71381.rs b/src/test/ui/const-generics/issues/issue-71381.rs
new file mode 100644
index 00000000000..c32bd2847f8
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-71381.rs
@@ -0,0 +1,33 @@
+#![feature(const_generics)]
+#![allow(incomplete_features)]
+
+struct Test(*const usize);
+
+type PassArg = ();
+
+unsafe extern "C" fn pass(args: PassArg) {
+    println!("Hello, world!");
+}
+
+impl Test {
+    pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
+        //~^ ERROR: using function pointers as const generic parameters is forbidden
+        self.0 = Self::trampiline::<Args, IDX, FN> as _
+    }
+
+    unsafe extern "C" fn trampiline<
+        Args: Sized,
+        const IDX: usize,
+        const FN: unsafe extern "C" fn(Args),
+        //~^ ERROR: using function pointers as const generic parameters is forbidden
+    >(
+        args: Args,
+    ) {
+        FN(args)
+    }
+}
+
+fn main() {
+    let x = Test();
+    x.call_me::<PassArg, 30, pass>()
+}
diff --git a/src/test/ui/const-generics/issues/issue-71381.stderr b/src/test/ui/const-generics/issues/issue-71381.stderr
new file mode 100644
index 00000000000..6bb776fcfc0
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-71381.stderr
@@ -0,0 +1,14 @@
+error: using function pointers as const generic parameters is forbidden
+  --> $DIR/issue-71381.rs:13:61
+   |
+LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
+   |                                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: using function pointers as const generic parameters is forbidden
+  --> $DIR/issue-71381.rs:21:19
+   |
+LL |         const FN: unsafe extern "C" fn(Args),
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/const-generics/issues/issue-71382.rs b/src/test/ui/const-generics/issues/issue-71382.rs
new file mode 100644
index 00000000000..e0cf9812d95
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-71382.rs
@@ -0,0 +1,24 @@
+#![feature(const_generics)]
+#![allow(incomplete_features)]
+
+struct Test();
+
+fn pass() {
+    println!("Hello, world!");
+}
+
+impl Test {
+    pub fn call_me(&self) {
+        self.test::<pass>();
+    }
+
+    fn test<const FN: fn()>(&self) {
+        //~^ ERROR: using function pointers as const generic parameters is forbidden
+        FN();
+    }
+}
+
+fn main() {
+    let x = Test();
+    x.call_me()
+}
diff --git a/src/test/ui/const-generics/issues/issue-71382.stderr b/src/test/ui/const-generics/issues/issue-71382.stderr
new file mode 100644
index 00000000000..1652b0bdfa8
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-71382.stderr
@@ -0,0 +1,8 @@
+error: using function pointers as const generic parameters is forbidden
+  --> $DIR/issue-71382.rs:15:23
+   |
+LL |     fn test<const FN: fn()>(&self) {
+   |                       ^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-71611.rs b/src/test/ui/const-generics/issues/issue-71611.rs
new file mode 100644
index 00000000000..64a049e743f
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-71611.rs
@@ -0,0 +1,9 @@
+#![feature(const_generics)]
+#![allow(incomplete_features)]
+
+fn func<A, const F: fn(inner: A)>(outer: A) {
+    //~^ ERROR: using function pointers as const generic parameters is forbidden
+    F(outer);
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-71611.stderr b/src/test/ui/const-generics/issues/issue-71611.stderr
new file mode 100644
index 00000000000..9a7bf1c0a88
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-71611.stderr
@@ -0,0 +1,8 @@
+error: using function pointers as const generic parameters is forbidden
+  --> $DIR/issue-71611.rs:4:21
+   |
+LL | fn func<A, const F: fn(inner: A)>(outer: A) {
+   |                     ^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-72352.rs b/src/test/ui/const-generics/issues/issue-72352.rs
new file mode 100644
index 00000000000..e977af8deb7
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-72352.rs
@@ -0,0 +1,21 @@
+#![feature(const_generics)]
+#![allow(incomplete_features)]
+
+use std::ffi::{CStr, CString};
+
+unsafe fn unsafely_do_the_thing<const F: fn(&CStr) -> usize>(ptr: *const i8) -> usize {
+    //~^ ERROR: using function pointers as const generic parameters is forbidden
+    F(CStr::from_ptr(ptr))
+}
+
+fn safely_do_the_thing(s: &CStr) -> usize {
+    s.to_bytes().len()
+}
+
+fn main() {
+    let baguette = CString::new("baguette").unwrap();
+    let ptr = baguette.as_ptr();
+    println!("{}", unsafe {
+        unsafely_do_the_thing::<safely_do_the_thing>(ptr)
+    });
+}
diff --git a/src/test/ui/const-generics/issues/issue-72352.stderr b/src/test/ui/const-generics/issues/issue-72352.stderr
new file mode 100644
index 00000000000..bc48da10393
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-72352.stderr
@@ -0,0 +1,8 @@
+error: using function pointers as const generic parameters is forbidden
+  --> $DIR/issue-72352.rs:6:42
+   |
+LL | unsafe fn unsafely_do_the_thing<const F: fn(&CStr) -> usize>(ptr: *const i8) -> usize {
+   |                                          ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/issues/issue-1866.rs b/src/test/ui/issues/issue-1866.rs
index 668baefa5e4..9f8a3a82624 100644
--- a/src/test/ui/issues/issue-1866.rs
+++ b/src/test/ui/issues/issue-1866.rs
@@ -1,7 +1,7 @@
 // build-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
-#![warn(clashing_extern_decl)]
+#![warn(clashing_extern_declarations)]
 
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-1866.stderr b/src/test/ui/issues/issue-1866.stderr
index 13c08ebd373..5edae48a10f 100644
--- a/src/test/ui/issues/issue-1866.stderr
+++ b/src/test/ui/issues/issue-1866.stderr
@@ -10,8 +10,8 @@ LL |             pub fn rust_task_is_unwinding(rt: *const rust_task) -> bool;
 note: the lint level is defined here
   --> $DIR/issue-1866.rs:4:9
    |
-LL | #![warn(clashing_extern_decl)]
-   |         ^^^^^^^^^^^^^^^^^^^^
+LL | #![warn(clashing_extern_declarations)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: expected `unsafe extern "C" fn(*const usize) -> bool`
               found `unsafe extern "C" fn(*const bool) -> bool`
 
diff --git a/src/test/ui/issues/issue-5791.rs b/src/test/ui/issues/issue-5791.rs
index fda72a1b20e..d9be27250cd 100644
--- a/src/test/ui/issues/issue-5791.rs
+++ b/src/test/ui/issues/issue-5791.rs
@@ -1,6 +1,6 @@
 // run-pass
 #![allow(dead_code)]
-#![warn(clashing_extern_decl)]
+#![warn(clashing_extern_declarations)]
 // pretty-expanded FIXME #23616
 
 extern {
diff --git a/src/test/ui/issues/issue-5791.stderr b/src/test/ui/issues/issue-5791.stderr
index 7ae83c43f13..cf60e609deb 100644
--- a/src/test/ui/issues/issue-5791.stderr
+++ b/src/test/ui/issues/issue-5791.stderr
@@ -12,8 +12,8 @@ LL | |     fn malloc2(len: i32, foo: i32) -> *const u8;
 note: the lint level is defined here
   --> $DIR/issue-5791.rs:3:9
    |
-LL | #![warn(clashing_extern_decl)]
-   |         ^^^^^^^^^^^^^^^^^^^^
+LL | #![warn(clashing_extern_declarations)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: expected `unsafe extern "C" fn(i32) -> *const u8`
               found `unsafe extern "C" fn(i32, i32) -> *const u8`
 
diff --git a/src/test/ui/lint/clashing-extern-fn.rs b/src/test/ui/lint/clashing-extern-fn.rs
index 32f3a78f4e9..544614100ba 100644
--- a/src/test/ui/lint/clashing-extern-fn.rs
+++ b/src/test/ui/lint/clashing-extern-fn.rs
@@ -1,17 +1,17 @@
 // check-pass
 // aux-build:external_extern_fn.rs
 #![crate_type = "lib"]
-#![warn(clashing_extern_decl)]
+#![warn(clashing_extern_declarations)]
 
 extern crate external_extern_fn;
 
-extern {
+extern "C" {
     fn clash(x: u8);
     fn no_clash(x: u8);
 }
 
 fn redeclared_different_signature() {
-    extern {
+    extern "C" {
         fn clash(x: u64); //~ WARN `clash` redeclared with a different signature
     }
 
@@ -22,7 +22,7 @@ fn redeclared_different_signature() {
 }
 
 fn redeclared_same_signature() {
-    extern {
+    extern "C" {
         fn no_clash(x: u8);
     }
     unsafe {
@@ -30,12 +30,12 @@ fn redeclared_same_signature() {
     }
 }
 
-extern {
+extern "C" {
     fn extern_fn(x: u64);
 }
 
 fn extern_clash() {
-    extern {
+    extern "C" {
         fn extern_fn(x: u32); //~ WARN `extern_fn` redeclared with a different signature
     }
     unsafe {
@@ -49,7 +49,7 @@ fn extern_no_clash() {
         crate::extern_fn(123);
     }
 }
-extern {
+extern "C" {
     fn some_other_new_name(x: i16);
 
     #[link_name = "extern_link_name"]
@@ -60,7 +60,7 @@ extern {
 }
 
 fn link_name_clash() {
-    extern {
+    extern "C" {
         fn extern_link_name(x: u32);
         //~^ WARN `extern_link_name` redeclared with a different signature
 
@@ -75,85 +75,112 @@ fn link_name_clash() {
 }
 
 mod a {
-    extern {
+    extern "C" {
         fn different_mod(x: u8);
     }
 }
 mod b {
-    extern {
+    extern "C" {
         fn different_mod(x: u64); //~ WARN `different_mod` redeclared with a different signature
     }
 }
 
-extern {
+extern "C" {
     fn variadic_decl(x: u8, ...);
 }
 
 fn variadic_clash() {
-    extern {
+    extern "C" {
         fn variadic_decl(x: u8); //~ WARN `variadic_decl` redeclared with a different signature
     }
 }
 
 #[no_mangle]
-fn no_mangle_name(x: u8) { }
+fn no_mangle_name(x: u8) {}
 
-extern {
+extern "C" {
     #[link_name = "unique_link_name"]
     fn link_name_specified(x: u8);
 }
 
 fn tricky_no_clash() {
-    extern {
+    extern "C" {
         // Shouldn't warn, because the declaration above actually declares a different symbol (and
         // Rust's name resolution rules around shadowing will handle this gracefully).
         fn link_name_specified() -> u32;
 
         // The case of a no_mangle name colliding with an extern decl (see #28179) is related but
-        // shouldn't be reported by ClashingExternDecl, because this is an example of unmangled
-        // name clash causing bad behaviour in functions with a defined body.
+        // shouldn't be reported by ClashingExternDeclarations, because this is an example of
+        // unmangled name clash causing bad behaviour in functions with a defined body.
         fn no_mangle_name() -> u32;
     }
 }
 
 mod banana {
     mod one {
-        #[repr(C)] struct Banana { weight: u32, length: u16 }
-        extern "C" { fn weigh_banana(count: *const Banana) -> u64; }
+        #[repr(C)]
+        struct Banana {
+            weight: u32,
+            length: u16,
+        }
+        extern "C" {
+            fn weigh_banana(count: *const Banana) -> u64;
+        }
     }
 
     mod two {
-        #[repr(C)] struct Banana { weight: u32, length: u16 } // note: distinct type
-        // This should not trigger the lint because two::Banana is structurally equivalent to
-        // one::Banana.
-        extern "C" { fn weigh_banana(count: *const Banana) -> u64; }
+        #[repr(C)]
+        struct Banana {
+            weight: u32,
+            length: u16,
+        } // note: distinct type
+        extern "C" {
+          // This should not trigger the lint because two::Banana is structurally equivalent to
+          // one::Banana.
+            fn weigh_banana(count: *const Banana) -> u64;
+        }
     }
 
     mod three {
         // This _should_ trigger the lint, because repr(packed) should generate a struct that has a
         // different layout.
-        #[repr(packed)] struct Banana { weight: u32, length: u16 }
+        #[repr(packed)]
+        struct Banana {
+            weight: u32,
+            length: u16,
+        }
         #[allow(improper_ctypes)]
-        extern "C" { fn weigh_banana(count: *const Banana) -> u64; }
-        //~^ WARN `weigh_banana` redeclared with a different signature
+        extern "C" {
+            fn weigh_banana(count: *const Banana) -> u64;
+            //~^ WARN `weigh_banana` redeclared with a different signature
+        }
     }
 }
 
 mod sameish_members {
     mod a {
         #[repr(C)]
-        struct Point { x: i16, y: i16 }
+        struct Point {
+            x: i16,
+            y: i16,
+        }
 
-        extern "C" { fn draw_point(p: Point); }
+        extern "C" {
+            fn draw_point(p: Point);
+        }
     }
     mod b {
         #[repr(C)]
-        struct Point { coordinates: [i16; 2] }
+        struct Point {
+            coordinates: [i16; 2],
+        }
 
         // It's possible we are overconservative for this case, as accessing the elements of the
         // coordinates array might end up correctly accessing `.x` and `.y`. However, this may not
         // always be the case, for every architecture and situation. This is also a really odd
         // thing to do anyway.
-        extern "C" { fn draw_point(p: Point); } //~ WARN `draw_point` redeclared with a different
+        extern "C" {
+            fn draw_point(p: Point); //~ WARN `draw_point` redeclared with a different
+        }
     }
 }
diff --git a/src/test/ui/lint/clashing-extern-fn.stderr b/src/test/ui/lint/clashing-extern-fn.stderr
index fb7bf135f53..96e51ab5a3e 100644
--- a/src/test/ui/lint/clashing-extern-fn.stderr
+++ b/src/test/ui/lint/clashing-extern-fn.stderr
@@ -10,8 +10,8 @@ LL |         fn clash(x: u64);
 note: the lint level is defined here
   --> $DIR/clashing-extern-fn.rs:4:9
    |
-LL | #![warn(clashing_extern_decl)]
-   |         ^^^^^^^^^^^^^^^^^^^^
+LL | #![warn(clashing_extern_declarations)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: expected `unsafe extern "C" fn(u8)`
               found `unsafe extern "C" fn(u64)`
 
@@ -94,25 +94,25 @@ LL |         fn variadic_decl(x: u8);
               found `unsafe extern "C" fn(u8)`
 
 warning: `weigh_banana` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:137:22
+  --> $DIR/clashing-extern-fn.rs:154:13
    |
-LL |         extern "C" { fn weigh_banana(count: *const Banana) -> u64; }
-   |                      --------------------------------------------- `weigh_banana` previously declared here
+LL |             fn weigh_banana(count: *const Banana) -> u64;
+   |             --------------------------------------------- `weigh_banana` previously declared here
 ...
-LL |         extern "C" { fn weigh_banana(count: *const Banana) -> u64; }
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+LL |             fn weigh_banana(count: *const Banana) -> u64;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
    |
    = note: expected `unsafe extern "C" fn(*const banana::one::Banana) -> u64`
               found `unsafe extern "C" fn(*const banana::three::Banana) -> u64`
 
 warning: `draw_point` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:157:22
+  --> $DIR/clashing-extern-fn.rs:183:13
    |
-LL |         extern "C" { fn draw_point(p: Point); }
-   |                      ------------------------ `draw_point` previously declared here
+LL |             fn draw_point(p: Point);
+   |             ------------------------ `draw_point` previously declared here
 ...
-LL |         extern "C" { fn draw_point(p: Point); }
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+LL |             fn draw_point(p: Point);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
    |
    = note: expected `unsafe extern "C" fn(sameish_members::a::Point)`
               found `unsafe extern "C" fn(sameish_members::b::Point)`
diff --git a/src/test/ui/lint/dead-code/lint-dead-code-3.rs b/src/test/ui/lint/dead-code/lint-dead-code-3.rs
index ff33abfa645..fe3c392ccf1 100644
--- a/src/test/ui/lint/dead-code/lint-dead-code-3.rs
+++ b/src/test/ui/lint/dead-code/lint-dead-code-3.rs
@@ -1,6 +1,6 @@
 #![allow(unused_variables)]
 #![allow(non_camel_case_types)]
-#![allow(clashing_extern_decl)]
+#![allow(clashing_extern_declarations)]
 #![deny(dead_code)]
 
 #![crate_type="lib"]
diff --git a/src/test/ui/mir-dataflow/liveness-projection.rs b/src/test/ui/mir-dataflow/liveness-projection.rs
new file mode 100644
index 00000000000..486f31b635d
--- /dev/null
+++ b/src/test/ui/mir-dataflow/liveness-projection.rs
@@ -0,0 +1,32 @@
+#![feature(core_intrinsics, rustc_attrs)]
+
+use std::intrinsics::rustc_peek;
+
+#[rustc_mir(rustc_peek_liveness, stop_after_dataflow)]
+fn foo() {
+    {
+        let mut x: (i32, i32) = (42, 0);
+
+        // Assignment to a projection does not cause `x` to become live
+        unsafe { rustc_peek(x); } //~ ERROR bit not set
+        x.1 = 42;
+
+        x = (0, 42);
+
+        // ...but a read from a projection does.
+        unsafe { rustc_peek(x); }
+        println!("{}", x.1);
+    }
+
+    {
+        let mut x = 42;
+
+        // Derefs are treated like a read of a local even if they are on the LHS of an assignment.
+        let p = &mut x;
+        unsafe { rustc_peek(&p); }
+        *p = 24;
+        unsafe { rustc_peek(&p); } //~ ERROR bit not set
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/mir-dataflow/liveness-projection.stderr b/src/test/ui/mir-dataflow/liveness-projection.stderr
new file mode 100644
index 00000000000..f9480c88090
--- /dev/null
+++ b/src/test/ui/mir-dataflow/liveness-projection.stderr
@@ -0,0 +1,16 @@
+error: rustc_peek: bit not set
+  --> $DIR/liveness-projection.rs:11:18
+   |
+LL |         unsafe { rustc_peek(x); }
+   |                  ^^^^^^^^^^^^^
+
+error: rustc_peek: bit not set
+  --> $DIR/liveness-projection.rs:28:18
+   |
+LL |         unsafe { rustc_peek(&p); }
+   |                  ^^^^^^^^^^^^^^
+
+error: stop_after_dataflow ended compilation
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/extern-abi-from-mac-literal-frag.rs b/src/test/ui/parser/extern-abi-from-mac-literal-frag.rs
index a516aa44c65..8f5d7f4f7f8 100644
--- a/src/test/ui/parser/extern-abi-from-mac-literal-frag.rs
+++ b/src/test/ui/parser/extern-abi-from-mac-literal-frag.rs
@@ -1,4 +1,4 @@
-#![allow(clashing_extern_decl)]
+#![allow(clashing_extern_declarations)]
 // check-pass
 
 // In this test we check that the parser accepts an ABI string when it