about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-04-30 19:01:01 +0000
committerbors <bors@rust-lang.org>2020-04-30 19:01:01 +0000
commit7ced01a730e8fc1bae2f8d4369c26812c0484da4 (patch)
tree5f972cddf361a86e359b3a523c5ac68110a151db /src
parentbe8589fc31162bb71b0f765beba6ce73ec8ba93a (diff)
parent97a8870022ec819c8b92b4c192242726c77e19f3 (diff)
downloadrust-7ced01a730e8fc1bae2f8d4369c26812c0484da4.tar.gz
rust-7ced01a730e8fc1bae2f8d4369c26812c0484da4.zip
Auto merge of #71717 - Dylan-DPC:rollup-av5vjor, r=Dylan-DPC
Rollup of 5 pull requests

Successful merges:

 - #70950 (extend NLL checker to understand `'empty` combined with universes)
 - #71433 (Add help message for missing right operand in condition)
 - #71449 (Move `{Free,}RegionRelations` and `FreeRegionMap` to `rustc_infer`)
 - #71559 (Detect git version before attempting to use --progress)
 - #71597 (Rename Unique::empty() -> Unique::dangling())

Failed merges:

r? @ghost
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/bootstrap.py26
-rw-r--r--src/liballoc/raw_vec.rs10
-rw-r--r--src/libcore/ptr/unique.rs3
-rw-r--r--src/librustc_data_structures/graph/scc/mod.rs5
-rw-r--r--src/librustc_infer/Cargo.toml1
-rw-r--r--src/librustc_infer/infer/free_regions.rs (renamed from src/librustc_middle/ty/free_region_map.rs)44
-rw-r--r--src/librustc_infer/infer/lexical_region_resolve/graphviz.rs2
-rw-r--r--src/librustc_infer/infer/lexical_region_resolve/mod.rs2
-rw-r--r--src/librustc_infer/infer/mod.rs7
-rw-r--r--src/librustc_infer/infer/outlives/env.rs2
-rw-r--r--src/librustc_middle/middle/free_region.rs44
-rw-r--r--src/librustc_middle/middle/mod.rs1
-rw-r--r--src/librustc_middle/ty/mod.rs1
-rw-r--r--src/librustc_mir/borrow_check/region_infer/mod.rs143
-rw-r--r--src/librustc_mir/borrow_check/type_check/constraint_conversion.rs8
-rw-r--r--src/librustc_mir/borrow_check/type_check/free_region_relations.rs2
-rw-r--r--src/librustc_mir/borrow_check/universal_regions.rs19
-rw-r--r--src/librustc_parse/parser/expr.rs5
-rw-r--r--src/librustc_trait_selection/opaque_types.rs2
-rw-r--r--src/test/mir-opt/nll/named-lifetimes-basic/rustc.use_x.nll.0.mir27
-rw-r--r--src/test/mir-opt/nll/region-subtyping-basic.rs4
-rw-r--r--src/test/mir-opt/nll/region-subtyping-basic/32bit/rustc.main.nll.0.mir143
-rw-r--r--src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir143
-rw-r--r--src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir11
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr4
-rw-r--r--src/test/ui/consts/const-ptr-unique-rpass.rs4
-rw-r--r--src/test/ui/hrtb/due-to-where-clause.nll.stderr2
-rw-r--r--src/test/ui/if/if-without-block.stderr2
-rw-r--r--src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr2
-rw-r--r--src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr2
-rw-r--r--src/test/ui/nll/issue-68550.rs15
-rw-r--r--src/test/ui/nll/issue-68550.stderr16
-rw-r--r--src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs36
-rw-r--r--src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr20
-rw-r--r--src/test/ui/nll/type-check-pointer-comparisons.rs8
-rw-r--r--src/test/ui/nll/type-check-pointer-comparisons.stderr14
36 files changed, 484 insertions, 296 deletions
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index d5efed61b54..2aa3f9c7ec0 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -2,6 +2,7 @@ from __future__ import absolute_import, division, print_function
 import argparse
 import contextlib
 import datetime
+import distutils.version
 import hashlib
 import os
 import re
@@ -331,6 +332,7 @@ class RustBuild(object):
         self.use_locked_deps = ''
         self.use_vendored_sources = ''
         self.verbose = False
+        self.git_version = None
 
     def download_stage0(self):
         """Fetch the build system for Rust, written in Rust
@@ -743,15 +745,13 @@ class RustBuild(object):
 
         run(["git", "submodule", "-q", "sync", module],
             cwd=self.rust_root, verbose=self.verbose)
-        try:
-            run(["git", "submodule", "update",
-                 "--init", "--recursive", "--progress", module],
-                cwd=self.rust_root, verbose=self.verbose, exception=True)
-        except RuntimeError:
-            # Some versions of git don't support --progress.
-            run(["git", "submodule", "update",
-                 "--init", "--recursive", module],
-                cwd=self.rust_root, verbose=self.verbose)
+
+        update_args = ["git", "submodule", "update", "--init", "--recursive"]
+        if self.git_version >= distutils.version.LooseVersion("2.11.0"):
+            update_args.append("--progress")
+        update_args.append(module)
+        run(update_args, cwd=self.rust_root, verbose=self.verbose, exception=True)
+
         run(["git", "reset", "-q", "--hard"],
             cwd=module_path, verbose=self.verbose)
         run(["git", "clean", "-qdfx"],
@@ -763,9 +763,13 @@ class RustBuild(object):
                 self.get_toml('submodules') == "false":
             return
 
-        # check the existence of 'git' command
+        default_encoding = sys.getdefaultencoding()
+
+        # check the existence and version of 'git' command
         try:
-            subprocess.check_output(['git', '--version'])
+            git_version_output = subprocess.check_output(['git', '--version'])
+            git_version_str = git_version_output.strip().split()[2].decode(default_encoding)
+            self.git_version = distutils.version.LooseVersion(git_version_str)
         except (subprocess.CalledProcessError, OSError):
             print("error: `git` is not found, please make sure it's installed and in the path.")
             sys.exit(1)
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index ca165b61e26..a8e19c9cbaa 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -25,9 +25,9 @@ mod tests;
 /// involved. This type is excellent for building your own data structures like Vec and VecDeque.
 /// In particular:
 ///
-/// * Produces `Unique::empty()` on zero-sized types.
-/// * Produces `Unique::empty()` on zero-length allocations.
-/// * Avoids freeing `Unique::empty()`.
+/// * Produces `Unique::dangling()` on zero-sized types.
+/// * Produces `Unique::dangling()` on zero-length allocations.
+/// * Avoids freeing `Unique::dangling()`.
 /// * Catches all overflows in capacity computations (promotes them to "capacity overflow" panics).
 /// * Guards against 32-bit systems allocating more than isize::MAX bytes.
 /// * Guards against overflowing your length.
@@ -125,7 +125,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
     /// the returned `RawVec`.
     pub const fn new_in(alloc: A) -> Self {
         // `cap: 0` means "unallocated". zero-sized types are ignored.
-        Self { ptr: Unique::empty(), cap: 0, alloc }
+        Self { ptr: Unique::dangling(), cap: 0, alloc }
     }
 
     /// Like `with_capacity`, but parameterized over the choice of
@@ -172,7 +172,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
     }
 
     /// Gets a raw pointer to the start of the allocation. Note that this is
-    /// `Unique::empty()` if `capacity == 0` or `T` is zero-sized. In the former case, you must
+    /// `Unique::dangling()` if `capacity == 0` or `T` is zero-sized. In the former case, you must
     /// be careful.
     pub fn ptr(&self) -> *mut T {
         self.ptr.as_ptr()
diff --git a/src/libcore/ptr/unique.rs b/src/libcore/ptr/unique.rs
index f5a5baceacc..f58d35f0613 100644
--- a/src/libcore/ptr/unique.rs
+++ b/src/libcore/ptr/unique.rs
@@ -70,9 +70,8 @@ impl<T: Sized> Unique<T> {
     /// a `T`, which means this must not be used as a "not yet initialized"
     /// sentinel value. Types that lazily allocate must track initialization by
     /// some other means.
-    // FIXME: rename to dangling() to match NonNull?
     #[inline]
-    pub const fn empty() -> Self {
+    pub const fn dangling() -> Self {
         // SAFETY: mem::align_of() returns a valid, non-null pointer. The
         // conditions to call new_unchecked() are thus respected.
         unsafe { Unique::new_unchecked(mem::align_of::<T>() as *mut T) }
diff --git a/src/librustc_data_structures/graph/scc/mod.rs b/src/librustc_data_structures/graph/scc/mod.rs
index 7ecf3e3cb8d..57eaf56f268 100644
--- a/src/librustc_data_structures/graph/scc/mod.rs
+++ b/src/librustc_data_structures/graph/scc/mod.rs
@@ -47,6 +47,11 @@ impl<N: Idx, S: Idx> Sccs<N, S> {
     }
 
     /// Returns an iterator over the SCCs in the graph.
+    ///
+    /// The SCCs will be iterated in **dependency order** (or **post order**),
+    /// meaning that if `S1 -> S2`, we will visit `S2` first and `S1` after.
+    /// This is convenient when the edges represent dependencies: when you visit
+    /// `S1`, the value for `S2` will already have been computed.
     pub fn all_sccs(&self) -> impl Iterator<Item = S> {
         (0..self.scc_data.len()).map(S::new)
     }
diff --git a/src/librustc_infer/Cargo.toml b/src/librustc_infer/Cargo.toml
index bc4080ac6c8..fa8e5a2ab78 100644
--- a/src/librustc_infer/Cargo.toml
+++ b/src/librustc_infer/Cargo.toml
@@ -19,6 +19,7 @@ rustc_hir = { path = "../librustc_hir" }
 rustc_index = { path = "../librustc_index" }
 rustc_macros = { path = "../librustc_macros" }
 rustc_session = { path = "../librustc_session" }
+rustc_serialize = { path = "../libserialize", package = "serialize" }
 rustc_span = { path = "../librustc_span" }
 rustc_target = { path = "../librustc_target" }
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_middle/ty/free_region_map.rs b/src/librustc_infer/infer/free_regions.rs
index 2ab12a4acbf..e31c524c197 100644
--- a/src/librustc_middle/ty/free_region_map.rs
+++ b/src/librustc_infer/infer/free_regions.rs
@@ -1,5 +1,47 @@
-use crate::ty::{self, Lift, Region, TyCtxt};
+//! This module handles the relationships between "free regions", i.e., lifetime parameters.
+//! Ordinarily, free regions are unrelated to one another, but they can be related via implied
+//! or explicit bounds. In that case, we track the bounds using the `TransitiveRelation` type,
+//! and use that to decide when one free region outlives another, and so forth.
+
 use rustc_data_structures::transitive_relation::TransitiveRelation;
+use rustc_hir::def_id::DefId;
+use rustc_middle::middle::region;
+use rustc_middle::ty::{self, Lift, Region, TyCtxt};
+
+/// Combines a `region::ScopeTree` (which governs relationships between
+/// scopes) and a `FreeRegionMap` (which governs relationships between
+/// free regions) to yield a complete relation between concrete
+/// regions.
+///
+/// This stuff is a bit convoluted and should be refactored, but as we
+/// transition to NLL, it'll all go away anyhow.
+pub struct RegionRelations<'a, 'tcx> {
+    pub tcx: TyCtxt<'tcx>,
+
+    /// The context used to fetch the region maps.
+    pub context: DefId,
+
+    /// The region maps for the given context.
+    pub region_scope_tree: &'a region::ScopeTree,
+
+    /// Free-region relationships.
+    pub free_regions: &'a FreeRegionMap<'tcx>,
+}
+
+impl<'a, 'tcx> RegionRelations<'a, 'tcx> {
+    pub fn new(
+        tcx: TyCtxt<'tcx>,
+        context: DefId,
+        region_scope_tree: &'a region::ScopeTree,
+        free_regions: &'a FreeRegionMap<'tcx>,
+    ) -> Self {
+        Self { tcx, context, region_scope_tree, free_regions }
+    }
+
+    pub fn lub_free_regions(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> Region<'tcx> {
+        self.free_regions.lub_free_regions(self.tcx, r_a, r_b)
+    }
+}
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default, HashStable)]
 pub struct FreeRegionMap<'tcx> {
diff --git a/src/librustc_infer/infer/lexical_region_resolve/graphviz.rs b/src/librustc_infer/infer/lexical_region_resolve/graphviz.rs
index 141424fc0c7..5d3e8f440d6 100644
--- a/src/librustc_infer/infer/lexical_region_resolve/graphviz.rs
+++ b/src/librustc_infer/infer/lexical_region_resolve/graphviz.rs
@@ -10,10 +10,10 @@ use graphviz as dot;
 
 use super::Constraint;
 use crate::infer::region_constraints::RegionConstraintData;
+use crate::infer::RegionRelations;
 use crate::infer::SubregionOrigin;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir::def_id::DefIndex;
-use rustc_middle::middle::free_region::RegionRelations;
 use rustc_middle::middle::region;
 use rustc_middle::ty;
 
diff --git a/src/librustc_infer/infer/lexical_region_resolve/mod.rs b/src/librustc_infer/infer/lexical_region_resolve/mod.rs
index c8d35774978..3ff0e26a4dc 100644
--- a/src/librustc_infer/infer/lexical_region_resolve/mod.rs
+++ b/src/librustc_infer/infer/lexical_region_resolve/mod.rs
@@ -6,6 +6,7 @@ use crate::infer::region_constraints::MemberConstraint;
 use crate::infer::region_constraints::RegionConstraintData;
 use crate::infer::region_constraints::VarInfos;
 use crate::infer::region_constraints::VerifyBound;
+use crate::infer::RegionRelations;
 use crate::infer::RegionVariableOrigin;
 use crate::infer::RegionckMode;
 use crate::infer::SubregionOrigin;
@@ -14,7 +15,6 @@ use rustc_data_structures::graph::implementation::{
     Direction, Graph, NodeIndex, INCOMING, OUTGOING,
 };
 use rustc_index::vec::{Idx, IndexVec};
-use rustc_middle::middle::free_region::RegionRelations;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::ty::{ReEarlyBound, ReEmpty, ReErased, ReFree, ReStatic};
diff --git a/src/librustc_infer/infer/mod.rs b/src/librustc_infer/infer/mod.rs
index edaa7a04b34..267f1e7e2dc 100644
--- a/src/librustc_infer/infer/mod.rs
+++ b/src/librustc_infer/infer/mod.rs
@@ -18,7 +18,6 @@ use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
 use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
 use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
-use rustc_middle::middle::free_region::RegionRelations;
 use rustc_middle::middle::region;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::ConstEvalResult;
@@ -39,6 +38,7 @@ use std::collections::BTreeMap;
 use std::fmt;
 
 use self::combine::CombineFields;
+use self::free_regions::RegionRelations;
 use self::lexical_region_resolve::LexicalRegionResolutions;
 use self::outlives::env::OutlivesEnvironment;
 use self::region_constraints::{GenericKind, RegionConstraintData, VarInfos, VerifyBound};
@@ -50,6 +50,7 @@ pub mod canonical;
 mod combine;
 mod equate;
 pub mod error_reporting;
+pub mod free_regions;
 mod freshen;
 mod fudge;
 mod glb;
@@ -472,6 +473,9 @@ pub enum NLLRegionVariableOrigin {
     /// from a `for<'a> T` binder). Meant to represent "any region".
     Placeholder(ty::PlaceholderRegion),
 
+    /// The variable we create to represent `'empty(U0)`.
+    RootEmptyRegion,
+
     Existential {
         /// If this is true, then this variable was created to represent a lifetime
         /// bound in a `for` binder. For example, it might have been created to
@@ -493,6 +497,7 @@ impl NLLRegionVariableOrigin {
             NLLRegionVariableOrigin::FreeRegion => true,
             NLLRegionVariableOrigin::Placeholder(..) => true,
             NLLRegionVariableOrigin::Existential { .. } => false,
+            NLLRegionVariableOrigin::RootEmptyRegion => false,
         }
     }
 
diff --git a/src/librustc_infer/infer/outlives/env.rs b/src/librustc_infer/infer/outlives/env.rs
index 06a23269389..1a9e20e79fe 100644
--- a/src/librustc_infer/infer/outlives/env.rs
+++ b/src/librustc_infer/infer/outlives/env.rs
@@ -1,9 +1,9 @@
+use crate::infer::free_regions::FreeRegionMap;
 use crate::infer::{GenericKind, InferCtxt};
 use crate::traits::query::OutlivesBound;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
 use rustc_middle::ty;
-use rustc_middle::ty::free_region_map::FreeRegionMap;
 
 use super::explicit_outlives_bounds;
 
diff --git a/src/librustc_middle/middle/free_region.rs b/src/librustc_middle/middle/free_region.rs
deleted file mode 100644
index 62ccd946744..00000000000
--- a/src/librustc_middle/middle/free_region.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-//! This module handles the relationships between "free regions", i.e., lifetime parameters.
-//! Ordinarily, free regions are unrelated to one another, but they can be related via implied
-//! or explicit bounds. In that case, we track the bounds using the `TransitiveRelation` type,
-//! and use that to decide when one free region outlives another, and so forth.
-
-use crate::middle::region;
-use crate::ty::free_region_map::FreeRegionMap;
-use crate::ty::{Region, TyCtxt};
-use rustc_hir::def_id::DefId;
-
-/// Combines a `region::ScopeTree` (which governs relationships between
-/// scopes) and a `FreeRegionMap` (which governs relationships between
-/// free regions) to yield a complete relation between concrete
-/// regions.
-///
-/// This stuff is a bit convoluted and should be refactored, but as we
-/// transition to NLL, it'll all go away anyhow.
-pub struct RegionRelations<'a, 'tcx> {
-    pub tcx: TyCtxt<'tcx>,
-
-    /// The context used to fetch the region maps.
-    pub context: DefId,
-
-    /// The region maps for the given context.
-    pub region_scope_tree: &'a region::ScopeTree,
-
-    /// Free-region relationships.
-    pub free_regions: &'a FreeRegionMap<'tcx>,
-}
-
-impl<'a, 'tcx> RegionRelations<'a, 'tcx> {
-    pub fn new(
-        tcx: TyCtxt<'tcx>,
-        context: DefId,
-        region_scope_tree: &'a region::ScopeTree,
-        free_regions: &'a FreeRegionMap<'tcx>,
-    ) -> Self {
-        Self { tcx, context, region_scope_tree, free_regions }
-    }
-
-    pub fn lub_free_regions(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> Region<'tcx> {
-        self.free_regions.lub_free_regions(self.tcx, r_a, r_b)
-    }
-}
diff --git a/src/librustc_middle/middle/mod.rs b/src/librustc_middle/middle/mod.rs
index 464488964af..9bc9ca6707a 100644
--- a/src/librustc_middle/middle/mod.rs
+++ b/src/librustc_middle/middle/mod.rs
@@ -2,7 +2,6 @@ pub mod codegen_fn_attrs;
 pub mod cstore;
 pub mod dependency_format;
 pub mod exported_symbols;
-pub mod free_region;
 pub mod lang_items;
 pub mod lib_features {
     use rustc_data_structures::fx::{FxHashMap, FxHashSet};
diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs
index 0abe44b3106..af278f9000e 100644
--- a/src/librustc_middle/ty/mod.rs
+++ b/src/librustc_middle/ty/mod.rs
@@ -96,7 +96,6 @@ pub mod error;
 pub mod fast_reject;
 pub mod flags;
 pub mod fold;
-pub mod free_region_map;
 pub mod inhabitedness;
 pub mod layout;
 pub mod normalize_erasing_regions;
diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs
index 832f4278149..fe113843800 100644
--- a/src/librustc_mir/borrow_check/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/region_infer/mod.rs
@@ -6,7 +6,6 @@ use rustc_data_structures::frozen::Frozen;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::graph::scc::Sccs;
 use rustc_hir::def_id::DefId;
-use rustc_index::bit_set::BitSet;
 use rustc_index::vec::IndexVec;
 use rustc_infer::infer::canonical::QueryOutlivesConstraint;
 use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound};
@@ -315,16 +314,81 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// SCC could have as well. This implies that the SCC must have
     /// the minimum, or narrowest, universe.
     fn compute_scc_universes(
-        constraints_scc: &Sccs<RegionVid, ConstraintSccIndex>,
+        constraint_sccs: &Sccs<RegionVid, ConstraintSccIndex>,
         definitions: &IndexVec<RegionVid, RegionDefinition<'tcx>>,
     ) -> IndexVec<ConstraintSccIndex, ty::UniverseIndex> {
-        let num_sccs = constraints_scc.num_sccs();
+        let num_sccs = constraint_sccs.num_sccs();
         let mut scc_universes = IndexVec::from_elem_n(ty::UniverseIndex::MAX, num_sccs);
 
+        debug!("compute_scc_universes()");
+
+        // For each region R in universe U, ensure that the universe for the SCC
+        // that contains R is "no bigger" than U. This effectively sets the universe
+        // for each SCC to be the minimum of the regions within.
         for (region_vid, region_definition) in definitions.iter_enumerated() {
-            let scc = constraints_scc.scc(region_vid);
+            let scc = constraint_sccs.scc(region_vid);
             let scc_universe = &mut scc_universes[scc];
-            *scc_universe = ::std::cmp::min(*scc_universe, region_definition.universe);
+            let scc_min = std::cmp::min(region_definition.universe, *scc_universe);
+            if scc_min != *scc_universe {
+                *scc_universe = scc_min;
+                debug!(
+                    "compute_scc_universes: lowered universe of {scc:?} to {scc_min:?} \
+                    because it contains {region_vid:?} in {region_universe:?}",
+                    scc = scc,
+                    scc_min = scc_min,
+                    region_vid = region_vid,
+                    region_universe = region_definition.universe,
+                );
+            }
+        }
+
+        // Walk each SCC `A` and `B` such that `A: B`
+        // and ensure that universe(A) can see universe(B).
+        //
+        // This serves to enforce the 'empty/placeholder' hierarchy
+        // (described in more detail on `RegionKind`):
+        //
+        // ```
+        // static -----+
+        //   |         |
+        // empty(U0) placeholder(U1)
+        //   |      /
+        // empty(U1)
+        // ```
+        //
+        // In particular, imagine we have variables R0 in U0 and R1
+        // created in U1, and constraints like this;
+        //
+        // ```
+        // R1: !1 // R1 outlives the placeholder in U1
+        // R1: R0 // R1 outlives R0
+        // ```
+        //
+        // Here, we wish for R1 to be `'static`, because it
+        // cannot outlive `placeholder(U1)` and `empty(U0)` any other way.
+        //
+        // Thanks to this loop, what happens is that the `R1: R0`
+        // constraint lowers the universe of `R1` to `U0`, which in turn
+        // means that the `R1: !1` constraint will (later) cause
+        // `R1` to become `'static`.
+        for scc_a in constraint_sccs.all_sccs() {
+            for &scc_b in constraint_sccs.successors(scc_a) {
+                let scc_universe_a = scc_universes[scc_a];
+                let scc_universe_b = scc_universes[scc_b];
+                let scc_universe_min = std::cmp::min(scc_universe_a, scc_universe_b);
+                if scc_universe_a != scc_universe_min {
+                    scc_universes[scc_a] = scc_universe_min;
+
+                    debug!(
+                        "compute_scc_universes: lowered universe of {scc_a:?} to {scc_universe_min:?} \
+                        because {scc_a:?}: {scc_b:?} and {scc_b:?} is in universe {scc_universe_b:?}",
+                        scc_a = scc_a,
+                        scc_b = scc_b,
+                        scc_universe_min = scc_universe_min,
+                        scc_universe_b = scc_universe_b
+                    );
+                }
+            }
         }
 
         debug!("compute_scc_universes: scc_universe = {:#?}", scc_universes);
@@ -416,7 +480,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                     }
                 }
 
-                NLLRegionVariableOrigin::Existential { .. } => {
+                NLLRegionVariableOrigin::RootEmptyRegion
+                | NLLRegionVariableOrigin::Existential { .. } => {
                     // For existential, regions, nothing to do.
                 }
             }
@@ -550,9 +615,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         // SCC. For each SCC, we visit its successors and compute
         // their values, then we union all those values to get our
         // own.
-        let visited = &mut BitSet::new_empty(self.constraint_sccs.num_sccs());
-        for scc_index in self.constraint_sccs.all_sccs() {
-            self.propagate_constraint_sccs_if_new(scc_index, visited);
+        let constraint_sccs = self.constraint_sccs.clone();
+        for scc in constraint_sccs.all_sccs() {
+            self.compute_value_for_scc(scc);
         }
 
         // Sort the applied member constraints so we can binary search
@@ -560,37 +625,17 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         self.member_constraints_applied.sort_by_key(|applied| applied.member_region_scc);
     }
 
-    /// Computes the value of the SCC `scc_a` if it has not already
-    /// been computed. The `visited` parameter is a bitset
-    #[inline]
-    fn propagate_constraint_sccs_if_new(
-        &mut self,
-        scc_a: ConstraintSccIndex,
-        visited: &mut BitSet<ConstraintSccIndex>,
-    ) {
-        if visited.insert(scc_a) {
-            self.propagate_constraint_sccs_new(scc_a, visited);
-        }
-    }
-
     /// Computes the value of the SCC `scc_a`, which has not yet been
-    /// computed. This works by first computing all successors of the
-    /// SCC (if they haven't been computed already) and then unioning
-    /// together their elements.
-    fn propagate_constraint_sccs_new(
-        &mut self,
-        scc_a: ConstraintSccIndex,
-        visited: &mut BitSet<ConstraintSccIndex>,
-    ) {
+    /// computed, by unioning the values of its successors.
+    /// Assumes that all successors have been computed already
+    /// (which is assured by iterating over SCCs in dependency order).
+    fn compute_value_for_scc(&mut self, scc_a: ConstraintSccIndex) {
         let constraint_sccs = self.constraint_sccs.clone();
 
         // Walk each SCC `B` such that `A: B`...
         for &scc_b in constraint_sccs.successors(scc_a) {
             debug!("propagate_constraint_sccs: scc_a = {:?} scc_b = {:?}", scc_a, scc_b);
 
-            // ...compute the value of `B`...
-            self.propagate_constraint_sccs_if_new(scc_b, visited);
-
             // ...and add elements from `B` into `A`. One complication
             // arises because of universes: If `B` contains something
             // that `A` cannot name, then `A` can only contain `B` if
@@ -1258,7 +1303,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                     self.check_bound_universal_region(fr, placeholder, errors_buffer);
                 }
 
-                NLLRegionVariableOrigin::Existential { .. } => {
+                NLLRegionVariableOrigin::RootEmptyRegion
+                | NLLRegionVariableOrigin::Existential { .. } => {
                     // nothing to check here
                 }
             }
@@ -1360,7 +1406,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                     self.check_bound_universal_region(fr, placeholder, errors_buffer);
                 }
 
-                NLLRegionVariableOrigin::Existential { .. } => {
+                NLLRegionVariableOrigin::RootEmptyRegion
+                | NLLRegionVariableOrigin::Existential { .. } => {
                     // nothing to check here
                 }
             }
@@ -1633,9 +1680,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 universe1.cannot_name(placeholder.universe)
             }
 
-            NLLRegionVariableOrigin::FreeRegion | NLLRegionVariableOrigin::Existential { .. } => {
-                false
-            }
+            NLLRegionVariableOrigin::RootEmptyRegion
+            | NLLRegionVariableOrigin::FreeRegion
+            | NLLRegionVariableOrigin::Existential { .. } => false,
         }
     }
 
@@ -1773,6 +1820,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// Finds some region R such that `fr1: R` and `R` is live at `elem`.
     crate fn find_sub_region_live_at(&self, fr1: RegionVid, elem: Location) -> RegionVid {
         debug!("find_sub_region_live_at(fr1={:?}, elem={:?})", fr1, elem);
+        debug!("find_sub_region_live_at: {:?} is in scc {:?}", fr1, self.constraint_sccs.scc(fr1));
+        debug!(
+            "find_sub_region_live_at: {:?} is in universe {:?}",
+            fr1,
+            self.scc_universes[self.constraint_sccs.scc(fr1)]
+        );
         self.find_constraint_paths_between_regions(fr1, |r| {
             // First look for some `r` such that `fr1: r` and `r` is live at `elem`
             debug!(
@@ -1794,13 +1847,16 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         .or_else(|| {
             // If we fail to find THAT, it may be that `fr1` is a
             // placeholder that cannot "fit" into its SCC. In that
-            // case, there should be some `r` where `fr1: r`, both
-            // `fr1` and `r` are in the same SCC, and `fr1` is a
+            // case, there should be some `r` where `fr1: r` and `fr1` is a
             // placeholder that `r` cannot name. We can blame that
             // edge.
+            //
+            // Remember that if `R1: R2`, then the universe of R1
+            // must be able to name the universe of R2, because R2 will
+            // be at least `'empty(Universe(R2))`, and `R1` must be at
+            // larger than that.
             self.find_constraint_paths_between_regions(fr1, |r| {
-                self.constraint_sccs.scc(fr1) == self.constraint_sccs.scc(r)
-                    && self.cannot_name_placeholder(r, fr1)
+                self.cannot_name_placeholder(r, fr1)
             })
         })
         .map(|(_path, r)| r)
@@ -1944,7 +2000,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         let blame_source = match from_region_origin {
             NLLRegionVariableOrigin::FreeRegion
             | NLLRegionVariableOrigin::Existential { from_forall: false } => true,
-            NLLRegionVariableOrigin::Placeholder(_)
+            NLLRegionVariableOrigin::RootEmptyRegion
+            | NLLRegionVariableOrigin::Placeholder(_)
             | NLLRegionVariableOrigin::Existential { from_forall: true } => false,
         };
 
diff --git a/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs b/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs
index 8e4f44e8195..711271a63fb 100644
--- a/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs
+++ b/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs
@@ -160,10 +160,6 @@ impl<'a, 'b, 'tcx> TypeOutlivesDelegate<'tcx> for &'a mut ConstraintConversion<'
         a: ty::Region<'tcx>,
         b: ty::Region<'tcx>,
     ) {
-        // FIXME -- this is not the fix I would prefer
-        if let ty::ReEmpty(ty::UniverseIndex::ROOT) = a {
-            return;
-        }
         let b = self.to_region_vid(b);
         let a = self.to_region_vid(a);
         self.add_outlives(b, a);
@@ -176,10 +172,6 @@ impl<'a, 'b, 'tcx> TypeOutlivesDelegate<'tcx> for &'a mut ConstraintConversion<'
         a: ty::Region<'tcx>,
         bound: VerifyBound<'tcx>,
     ) {
-        // FIXME: I'd prefer if NLL had a notion of empty
-        if let ty::ReEmpty(ty::UniverseIndex::ROOT) = a {
-            return;
-        }
         let type_test = self.verify_to_type_test(kind, a, bound);
         self.add_type_test(type_test);
     }
diff --git a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs
index 0583295bfca..f97dff14645 100644
--- a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs
+++ b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs
@@ -1,12 +1,12 @@
 use rustc_data_structures::frozen::Frozen;
 use rustc_data_structures::transitive_relation::TransitiveRelation;
 use rustc_infer::infer::canonical::QueryRegionConstraints;
+use rustc_infer::infer::free_regions::FreeRegionRelations;
 use rustc_infer::infer::outlives;
 use rustc_infer::infer::region_constraints::GenericKind;
 use rustc_infer::infer::InferCtxt;
 use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::traits::query::OutlivesBound;
-use rustc_middle::ty::free_region_map::FreeRegionRelations;
 use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
 use rustc_span::DUMMY_SP;
 use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
diff --git a/src/librustc_mir/borrow_check/universal_regions.rs b/src/librustc_mir/borrow_check/universal_regions.rs
index d70ee8f9d5e..3003f4639d9 100644
--- a/src/librustc_mir/borrow_check/universal_regions.rs
+++ b/src/librustc_mir/borrow_check/universal_regions.rs
@@ -54,6 +54,13 @@ pub struct UniversalRegions<'tcx> {
     /// The total number of universal region variables instantiated.
     num_universals: usize,
 
+    /// A special region variable created for the `'empty(U0)` region.
+    /// Note that this is **not** a "universal" region, as it doesn't
+    /// represent a universally bound placeholder or any such thing.
+    /// But we do create it here in this type because it's a useful region
+    /// to have around in a few limited cases.
+    pub root_empty: RegionVid,
+
     /// The "defining" type for this function, with all universal
     /// regions instantiated. For a closure or generator, this is the
     /// closure type, but for a top-level function it's the `FnDef`.
@@ -317,7 +324,11 @@ impl<'tcx> UniversalRegions<'tcx> {
 
     /// See `UniversalRegionIndices::to_region_vid`.
     pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
-        self.indices.to_region_vid(r)
+        if let ty::ReEmpty(ty::UniverseIndex::ROOT) = r {
+            self.root_empty
+        } else {
+            self.indices.to_region_vid(r)
+        }
     }
 
     /// As part of the NLL unit tests, you can annotate a function with
@@ -473,10 +484,16 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
             _ => None,
         };
 
+        let root_empty = self
+            .infcx
+            .next_nll_region_var(NLLRegionVariableOrigin::RootEmptyRegion)
+            .to_region_vid();
+
         UniversalRegions {
             indices,
             fr_static,
             fr_fn_body,
+            root_empty,
             first_extern_index,
             first_local_index,
             num_universals,
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index 3f08fb79790..55c9f26999b 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -1549,6 +1549,11 @@ impl<'a> Parser<'a> {
             let block = self.parse_block().map_err(|mut err| {
                 if not_block {
                     err.span_label(lo, "this `if` expression has a condition, but no block");
+                    if let ExprKind::Binary(_, _, ref right) = cond.kind {
+                        if let ExprKind::Block(_, _) = right.kind {
+                            err.help("maybe you forgot the right operand of the condition?");
+                        }
+                    }
                 }
                 err
             })?;
diff --git a/src/librustc_trait_selection/opaque_types.rs b/src/librustc_trait_selection/opaque_types.rs
index e208698e962..4f8075b0171 100644
--- a/src/librustc_trait_selection/opaque_types.rs
+++ b/src/librustc_trait_selection/opaque_types.rs
@@ -6,10 +6,10 @@ use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
 use rustc_hir::Node;
 use rustc_infer::infer::error_reporting::unexpected_hidden_region_diagnostic;
+use rustc_infer::infer::free_regions::FreeRegionRelations;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::{self, InferCtxt, InferOk};
 use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor};
-use rustc_middle::ty::free_region_map::FreeRegionRelations;
 use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef};
 use rustc_middle::ty::{self, GenericParamDefKind, Ty, TyCtxt};
 use rustc_session::config::nightly_options;
diff --git a/src/test/mir-opt/nll/named-lifetimes-basic/rustc.use_x.nll.0.mir b/src/test/mir-opt/nll/named-lifetimes-basic/rustc.use_x.nll.0.mir
index a486af608ef..dcfb069b84a 100644
--- a/src/test/mir-opt/nll/named-lifetimes-basic/rustc.use_x.nll.0.mir
+++ b/src/test/mir-opt/nll/named-lifetimes-basic/rustc.use_x.nll.0.mir
@@ -13,10 +13,11 @@
 | '_#2r | U0 | {bb0[0..=1], '_#2r}
 | '_#3r | U0 | {bb0[0..=1], '_#3r}
 | '_#4r | U0 | {bb0[0..=1], '_#4r}
-| '_#5r | U0 | {bb0[0..=1], '_#1r}
-| '_#6r | U0 | {bb0[0..=1], '_#2r}
-| '_#7r | U0 | {bb0[0..=1], '_#1r}
-| '_#8r | U0 | {bb0[0..=1], '_#3r}
+| '_#5r | U0 | {}
+| '_#6r | U0 | {bb0[0..=1], '_#1r}
+| '_#7r | U0 | {bb0[0..=1], '_#2r}
+| '_#8r | U0 | {bb0[0..=1], '_#1r}
+| '_#9r | U0 | {bb0[0..=1], '_#3r}
 |
 | Inference Constraints
 | '_#0r live at {bb0[0..=1]}
@@ -24,16 +25,16 @@
 | '_#2r live at {bb0[0..=1]}
 | '_#3r live at {bb0[0..=1]}
 | '_#4r live at {bb0[0..=1]}
-| '_#1r: '_#5r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27)
-| '_#1r: '_#7r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55)
-| '_#2r: '_#6r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43)
-| '_#3r: '_#8r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67)
-| '_#5r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27)
-| '_#6r: '_#2r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43)
-| '_#7r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55)
-| '_#8r: '_#3r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67)
+| '_#1r: '_#6r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27)
+| '_#1r: '_#8r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55)
+| '_#2r: '_#7r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43)
+| '_#3r: '_#9r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67)
+| '_#6r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27)
+| '_#7r: '_#2r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43)
+| '_#8r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55)
+| '_#9r: '_#3r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67)
 |
-fn use_x(_1: &'_#5r mut i32, _2: &'_#6r u32, _3: &'_#7r u32, _4: &'_#8r u32) -> bool {
+fn use_x(_1: &'_#6r mut i32, _2: &'_#7r u32, _3: &'_#8r u32, _4: &'_#9r u32) -> bool {
     debug w => _1;                       // in scope 0 at $DIR/named-lifetimes-basic.rs:12:26: 12:27
     debug x => _2;                       // in scope 0 at $DIR/named-lifetimes-basic.rs:12:42: 12:43
     debug y => _3;                       // in scope 0 at $DIR/named-lifetimes-basic.rs:12:54: 12:55
diff --git a/src/test/mir-opt/nll/region-subtyping-basic.rs b/src/test/mir-opt/nll/region-subtyping-basic.rs
index 740cb1c5e96..66d7cda2b85 100644
--- a/src/test/mir-opt/nll/region-subtyping-basic.rs
+++ b/src/test/mir-opt/nll/region-subtyping-basic.rs
@@ -7,7 +7,9 @@
 
 #![allow(warnings)]
 
-fn use_x(_: usize) -> bool { true }
+fn use_x(_: usize) -> bool {
+    true
+}
 
 // EMIT_MIR_FOR_EACH_BIT_WIDTH
 // EMIT_MIR rustc.main.nll.0.mir
diff --git a/src/test/mir-opt/nll/region-subtyping-basic/32bit/rustc.main.nll.0.mir b/src/test/mir-opt/nll/region-subtyping-basic/32bit/rustc.main.nll.0.mir
index 7d396c3f1fb..3e0867d9b09 100644
--- a/src/test/mir-opt/nll/region-subtyping-basic/32bit/rustc.main.nll.0.mir
+++ b/src/test/mir-opt/nll/region-subtyping-basic/32bit/rustc.main.nll.0.mir
@@ -7,164 +7,165 @@
 | Inferred Region Values
 | '_#0r | U0 | {bb0[0..=8], bb1[0], bb2[0..=8], bb3[0], bb4[0..=1], bb5[0..=3], bb6[0..=3], bb7[0..=2], bb8[0..=5], '_#0r, '_#1r}
 | '_#1r | U0 | {bb0[0..=8], bb1[0], bb2[0..=8], bb3[0], bb4[0..=1], bb5[0..=3], bb6[0..=3], bb7[0..=2], bb8[0..=5], '_#1r}
-| '_#2r | U0 | {bb2[0..=8], bb3[0], bb5[0..=2]}
-| '_#3r | U0 | {bb2[1..=8], bb3[0], bb5[0..=2]}
-| '_#4r | U0 | {bb2[4..=8], bb3[0], bb5[0..=2]}
+| '_#2r | U0 | {}
+| '_#3r | U0 | {bb2[0..=8], bb3[0], bb5[0..=2]}
+| '_#4r | U0 | {bb2[1..=8], bb3[0], bb5[0..=2]}
+| '_#5r | U0 | {bb2[4..=8], bb3[0], bb5[0..=2]}
 |
 | Inference Constraints
 | '_#0r live at {bb0[0..=8], bb1[0], bb2[0..=8], bb3[0], bb4[0..=1], bb5[0..=3], bb6[0..=3], bb7[0..=2], bb8[0..=5]}
 | '_#1r live at {bb0[0..=8], bb1[0], bb2[0..=8], bb3[0], bb4[0..=1], bb5[0..=3], bb6[0..=3], bb7[0..=2], bb8[0..=5]}
-| '_#2r live at {bb2[0]}
-| '_#3r live at {bb2[1..=3]}
-| '_#4r live at {bb2[4..=8], bb3[0], bb5[0..=2]}
-| '_#2r: '_#3r due to Assignment at Single(bb2[0])
-| '_#3r: '_#4r due to Assignment at Single(bb2[3])
+| '_#3r live at {bb2[0]}
+| '_#4r live at {bb2[1..=3]}
+| '_#5r live at {bb2[4..=8], bb3[0], bb5[0..=2]}
+| '_#3r: '_#4r due to Assignment at Single(bb2[0])
+| '_#4r: '_#5r due to Assignment at Single(bb2[3])
 |
 fn main() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/region-subtyping-basic.rs:14:11: 14:11
-    let mut _1: [usize; Const { ty: usize, val: Value(Scalar(0x00000003)) }]; // in scope 0 at $DIR/region-subtyping-basic.rs:15:9: 15:14
-    let _3: usize;                       // in scope 0 at $DIR/region-subtyping-basic.rs:16:16: 16:17
-    let mut _4: usize;                   // in scope 0 at $DIR/region-subtyping-basic.rs:16:14: 16:18
-    let mut _5: bool;                    // in scope 0 at $DIR/region-subtyping-basic.rs:16:14: 16:18
-    let mut _7: bool;                    // in scope 0 at $DIR/region-subtyping-basic.rs:18:8: 18:12
-    let _8: bool;                        // in scope 0 at $DIR/region-subtyping-basic.rs:19:9: 19:18
-    let mut _9: usize;                   // in scope 0 at $DIR/region-subtyping-basic.rs:19:15: 19:17
-    let _10: bool;                       // in scope 0 at $DIR/region-subtyping-basic.rs:21:9: 21:18
+    let mut _0: ();                      // return place in scope 0 at $DIR/region-subtyping-basic.rs:16:11: 16:11
+    let mut _1: [usize; Const { ty: usize, val: Value(Scalar(0x00000003)) }]; // in scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14
+    let _3: usize;                       // in scope 0 at $DIR/region-subtyping-basic.rs:18:16: 18:17
+    let mut _4: usize;                   // in scope 0 at $DIR/region-subtyping-basic.rs:18:14: 18:18
+    let mut _5: bool;                    // in scope 0 at $DIR/region-subtyping-basic.rs:18:14: 18:18
+    let mut _7: bool;                    // in scope 0 at $DIR/region-subtyping-basic.rs:20:8: 20:12
+    let _8: bool;                        // in scope 0 at $DIR/region-subtyping-basic.rs:21:9: 21:18
+    let mut _9: usize;                   // in scope 0 at $DIR/region-subtyping-basic.rs:21:15: 21:17
+    let _10: bool;                       // in scope 0 at $DIR/region-subtyping-basic.rs:23:9: 23:18
     scope 1 {
-        debug v => _1;                   // in scope 1 at $DIR/region-subtyping-basic.rs:15:9: 15:14
-        let _2: &'_#3r usize;            // in scope 1 at $DIR/region-subtyping-basic.rs:16:9: 16:10
+        debug v => _1;                   // in scope 1 at $DIR/region-subtyping-basic.rs:17:9: 17:14
+        let _2: &'_#4r usize;            // in scope 1 at $DIR/region-subtyping-basic.rs:18:9: 18:10
         scope 2 {
-            debug p => _2;               // in scope 2 at $DIR/region-subtyping-basic.rs:16:9: 16:10
-            let _6: &'_#4r usize;        // in scope 2 at $DIR/region-subtyping-basic.rs:17:9: 17:10
+            debug p => _2;               // in scope 2 at $DIR/region-subtyping-basic.rs:18:9: 18:10
+            let _6: &'_#5r usize;        // in scope 2 at $DIR/region-subtyping-basic.rs:19:9: 19:10
             scope 3 {
-                debug q => _6;           // in scope 3 at $DIR/region-subtyping-basic.rs:17:9: 17:10
+                debug q => _6;           // in scope 3 at $DIR/region-subtyping-basic.rs:19:9: 19:10
             }
         }
     }
 
     bb0: {
-        StorageLive(_1);                 // bb0[0]: scope 0 at $DIR/region-subtyping-basic.rs:15:9: 15:14
-        _1 = [const Const(Value(Scalar(0x00000001)): usize), const Const(Value(Scalar(0x00000002)): usize), const Const(Value(Scalar(0x00000003)): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:15:17: 15:26
+        StorageLive(_1);                 // bb0[0]: scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14
+        _1 = [const Const(Value(Scalar(0x00000001)): usize), const Const(Value(Scalar(0x00000002)): usize), const Const(Value(Scalar(0x00000003)): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:17:17: 17:26
                                          // ty::Const
                                          // + ty: usize
                                          // + val: Value(Scalar(0x00000001))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:15:18: 15:19
+                                         // + span: $DIR/region-subtyping-basic.rs:17:18: 17:19
                                          // + literal: Const { ty: usize, val: Value(Scalar(0x00000001)) }
                                          // ty::Const
                                          // + ty: usize
                                          // + val: Value(Scalar(0x00000002))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:15:21: 15:22
+                                         // + span: $DIR/region-subtyping-basic.rs:17:21: 17:22
                                          // + literal: Const { ty: usize, val: Value(Scalar(0x00000002)) }
                                          // ty::Const
                                          // + ty: usize
                                          // + val: Value(Scalar(0x00000003))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:15:24: 15:25
+                                         // + span: $DIR/region-subtyping-basic.rs:17:24: 17:25
                                          // + literal: Const { ty: usize, val: Value(Scalar(0x00000003)) }
-        FakeRead(ForLet, _1);            // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:15:9: 15:14
-        StorageLive(_2);                 // bb0[3]: scope 1 at $DIR/region-subtyping-basic.rs:16:9: 16:10
-        StorageLive(_3);                 // bb0[4]: scope 1 at $DIR/region-subtyping-basic.rs:16:16: 16:17
-        _3 = const Const(Value(Scalar(0x00000000)): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:16:16: 16:17
+        FakeRead(ForLet, _1);            // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14
+        StorageLive(_2);                 // bb0[3]: scope 1 at $DIR/region-subtyping-basic.rs:18:9: 18:10
+        StorageLive(_3);                 // bb0[4]: scope 1 at $DIR/region-subtyping-basic.rs:18:16: 18:17
+        _3 = const Const(Value(Scalar(0x00000000)): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:18:16: 18:17
                                          // ty::Const
                                          // + ty: usize
                                          // + val: Value(Scalar(0x00000000))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:16:16: 16:17
+                                         // + span: $DIR/region-subtyping-basic.rs:18:16: 18:17
                                          // + literal: Const { ty: usize, val: Value(Scalar(0x00000000)) }
-        _4 = Len(_1);                    // bb0[6]: scope 1 at $DIR/region-subtyping-basic.rs:16:14: 16:18
-        _5 = Lt(_3, _4);                 // bb0[7]: scope 1 at $DIR/region-subtyping-basic.rs:16:14: 16:18
-        assert(move _5, "index out of bounds: the len is {} but the index is {}", move _4, _3) -> [success: bb2, unwind: bb1]; // bb0[8]: scope 1 at $DIR/region-subtyping-basic.rs:16:14: 16:18
+        _4 = Len(_1);                    // bb0[6]: scope 1 at $DIR/region-subtyping-basic.rs:18:14: 18:18
+        _5 = Lt(_3, _4);                 // bb0[7]: scope 1 at $DIR/region-subtyping-basic.rs:18:14: 18:18
+        assert(move _5, "index out of bounds: the len is {} but the index is {}", move _4, _3) -> [success: bb2, unwind: bb1]; // bb0[8]: scope 1 at $DIR/region-subtyping-basic.rs:18:14: 18:18
     }
 
     bb1 (cleanup): {
-        resume;                          // bb1[0]: scope 0 at $DIR/region-subtyping-basic.rs:14:1: 23:2
+        resume;                          // bb1[0]: scope 0 at $DIR/region-subtyping-basic.rs:16:1: 25:2
     }
 
     bb2: {
-        _2 = &'_#2r _1[_3];              // bb2[0]: scope 1 at $DIR/region-subtyping-basic.rs:16:13: 16:18
-        FakeRead(ForLet, _2);            // bb2[1]: scope 1 at $DIR/region-subtyping-basic.rs:16:9: 16:10
-        StorageLive(_6);                 // bb2[2]: scope 2 at $DIR/region-subtyping-basic.rs:17:9: 17:10
-        _6 = _2;                         // bb2[3]: scope 2 at $DIR/region-subtyping-basic.rs:17:13: 17:14
-        FakeRead(ForLet, _6);            // bb2[4]: scope 2 at $DIR/region-subtyping-basic.rs:17:9: 17:10
-        StorageLive(_7);                 // bb2[5]: scope 3 at $DIR/region-subtyping-basic.rs:18:8: 18:12
-        _7 = const Const(Value(Scalar(0x01)): bool); // bb2[6]: scope 3 at $DIR/region-subtyping-basic.rs:18:8: 18:12
+        _2 = &'_#3r _1[_3];              // bb2[0]: scope 1 at $DIR/region-subtyping-basic.rs:18:13: 18:18
+        FakeRead(ForLet, _2);            // bb2[1]: scope 1 at $DIR/region-subtyping-basic.rs:18:9: 18:10
+        StorageLive(_6);                 // bb2[2]: scope 2 at $DIR/region-subtyping-basic.rs:19:9: 19:10
+        _6 = _2;                         // bb2[3]: scope 2 at $DIR/region-subtyping-basic.rs:19:13: 19:14
+        FakeRead(ForLet, _6);            // bb2[4]: scope 2 at $DIR/region-subtyping-basic.rs:19:9: 19:10
+        StorageLive(_7);                 // bb2[5]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12
+        _7 = const Const(Value(Scalar(0x01)): bool); // bb2[6]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12
                                          // ty::Const
                                          // + ty: bool
                                          // + val: Value(Scalar(0x01))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:18:8: 18:12
+                                         // + span: $DIR/region-subtyping-basic.rs:20:8: 20:12
                                          // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
-        FakeRead(ForMatchedPlace, _7);   // bb2[7]: scope 3 at $DIR/region-subtyping-basic.rs:18:8: 18:12
-        switchInt(_7) -> [Const(Value(Scalar(0x00)): bool): bb4, otherwise: bb3]; // bb2[8]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6
+        FakeRead(ForMatchedPlace, _7);   // bb2[7]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12
+        switchInt(_7) -> [Const(Value(Scalar(0x00)): bool): bb4, otherwise: bb3]; // bb2[8]: scope 3 at $DIR/region-subtyping-basic.rs:20:5: 24:6
     }
 
     bb3: {
-        falseEdges -> [real: bb5, imaginary: bb4]; // bb3[0]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6
+        falseEdges -> [real: bb5, imaginary: bb4]; // bb3[0]: scope 3 at $DIR/region-subtyping-basic.rs:20:5: 24:6
     }
 
     bb4: {
-        StorageLive(_10);                // bb4[0]: scope 3 at $DIR/region-subtyping-basic.rs:21:9: 21:18
-        _10 = const Const(Value(Scalar(<ZST>)): fn(usize) -> bool {use_x})(const Const(Value(Scalar(0x00000016)): usize)) -> [return: bb7, unwind: bb1]; // bb4[1]: scope 3 at $DIR/region-subtyping-basic.rs:21:9: 21:18
+        StorageLive(_10);                // bb4[0]: scope 3 at $DIR/region-subtyping-basic.rs:23:9: 23:18
+        _10 = const Const(Value(Scalar(<ZST>)): fn(usize) -> bool {use_x})(const Const(Value(Scalar(0x00000016)): usize)) -> [return: bb7, unwind: bb1]; // bb4[1]: scope 3 at $DIR/region-subtyping-basic.rs:23:9: 23:18
                                          // ty::Const
                                          // + ty: fn(usize) -> bool {use_x}
                                          // + val: Value(Scalar(<ZST>))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:21:9: 21:14
+                                         // + span: $DIR/region-subtyping-basic.rs:23:9: 23:14
                                          // + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(Scalar(<ZST>)) }
                                          // ty::Const
                                          // + ty: usize
                                          // + val: Value(Scalar(0x00000016))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:21:15: 21:17
+                                         // + span: $DIR/region-subtyping-basic.rs:23:15: 23:17
                                          // + literal: Const { ty: usize, val: Value(Scalar(0x00000016)) }
     }
 
     bb5: {
-        StorageLive(_8);                 // bb5[0]: scope 3 at $DIR/region-subtyping-basic.rs:19:9: 19:18
-        StorageLive(_9);                 // bb5[1]: scope 3 at $DIR/region-subtyping-basic.rs:19:15: 19:17
-        _9 = (*_6);                      // bb5[2]: scope 3 at $DIR/region-subtyping-basic.rs:19:15: 19:17
-        _8 = const Const(Value(Scalar(<ZST>)): fn(usize) -> bool {use_x})(move _9) -> [return: bb6, unwind: bb1]; // bb5[3]: scope 3 at $DIR/region-subtyping-basic.rs:19:9: 19:18
+        StorageLive(_8);                 // bb5[0]: scope 3 at $DIR/region-subtyping-basic.rs:21:9: 21:18
+        StorageLive(_9);                 // bb5[1]: scope 3 at $DIR/region-subtyping-basic.rs:21:15: 21:17
+        _9 = (*_6);                      // bb5[2]: scope 3 at $DIR/region-subtyping-basic.rs:21:15: 21:17
+        _8 = const Const(Value(Scalar(<ZST>)): fn(usize) -> bool {use_x})(move _9) -> [return: bb6, unwind: bb1]; // bb5[3]: scope 3 at $DIR/region-subtyping-basic.rs:21:9: 21:18
                                          // ty::Const
                                          // + ty: fn(usize) -> bool {use_x}
                                          // + val: Value(Scalar(<ZST>))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:19:9: 19:14
+                                         // + span: $DIR/region-subtyping-basic.rs:21:9: 21:14
                                          // + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(Scalar(<ZST>)) }
     }
 
     bb6: {
-        StorageDead(_9);                 // bb6[0]: scope 3 at $DIR/region-subtyping-basic.rs:19:17: 19:18
-        StorageDead(_8);                 // bb6[1]: scope 3 at $DIR/region-subtyping-basic.rs:19:18: 19:19
-        _0 = const Const(Value(Scalar(<ZST>)): ()); // bb6[2]: scope 3 at $DIR/region-subtyping-basic.rs:18:13: 20:6
+        StorageDead(_9);                 // bb6[0]: scope 3 at $DIR/region-subtyping-basic.rs:21:17: 21:18
+        StorageDead(_8);                 // bb6[1]: scope 3 at $DIR/region-subtyping-basic.rs:21:18: 21:19
+        _0 = const Const(Value(Scalar(<ZST>)): ()); // bb6[2]: scope 3 at $DIR/region-subtyping-basic.rs:20:13: 22:6
                                          // ty::Const
                                          // + ty: ()
                                          // + val: Value(Scalar(<ZST>))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:18:13: 20:6
+                                         // + span: $DIR/region-subtyping-basic.rs:20:13: 22:6
                                          // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
-        goto -> bb8;                     // bb6[3]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6
+        goto -> bb8;                     // bb6[3]: scope 3 at $DIR/region-subtyping-basic.rs:20:5: 24:6
     }
 
     bb7: {
-        StorageDead(_10);                // bb7[0]: scope 3 at $DIR/region-subtyping-basic.rs:21:18: 21:19
-        _0 = const Const(Value(Scalar(<ZST>)): ()); // bb7[1]: scope 3 at $DIR/region-subtyping-basic.rs:20:12: 22:6
+        StorageDead(_10);                // bb7[0]: scope 3 at $DIR/region-subtyping-basic.rs:23:18: 23:19
+        _0 = const Const(Value(Scalar(<ZST>)): ()); // bb7[1]: scope 3 at $DIR/region-subtyping-basic.rs:22:12: 24:6
                                          // ty::Const
                                          // + ty: ()
                                          // + val: Value(Scalar(<ZST>))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:20:12: 22:6
+                                         // + span: $DIR/region-subtyping-basic.rs:22:12: 24:6
                                          // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
-        goto -> bb8;                     // bb7[2]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6
+        goto -> bb8;                     // bb7[2]: scope 3 at $DIR/region-subtyping-basic.rs:20:5: 24:6
     }
 
     bb8: {
-        StorageDead(_6);                 // bb8[0]: scope 2 at $DIR/region-subtyping-basic.rs:23:1: 23:2
-        StorageDead(_3);                 // bb8[1]: scope 1 at $DIR/region-subtyping-basic.rs:23:1: 23:2
-        StorageDead(_2);                 // bb8[2]: scope 1 at $DIR/region-subtyping-basic.rs:23:1: 23:2
-        StorageDead(_1);                 // bb8[3]: scope 0 at $DIR/region-subtyping-basic.rs:23:1: 23:2
-        StorageDead(_7);                 // bb8[4]: scope 0 at $DIR/region-subtyping-basic.rs:23:1: 23:2
-        return;                          // bb8[5]: scope 0 at $DIR/region-subtyping-basic.rs:23:2: 23:2
+        StorageDead(_6);                 // bb8[0]: scope 2 at $DIR/region-subtyping-basic.rs:25:1: 25:2
+        StorageDead(_3);                 // bb8[1]: scope 1 at $DIR/region-subtyping-basic.rs:25:1: 25:2
+        StorageDead(_2);                 // bb8[2]: scope 1 at $DIR/region-subtyping-basic.rs:25:1: 25:2
+        StorageDead(_1);                 // bb8[3]: scope 0 at $DIR/region-subtyping-basic.rs:25:1: 25:2
+        StorageDead(_7);                 // bb8[4]: scope 0 at $DIR/region-subtyping-basic.rs:25:1: 25:2
+        return;                          // bb8[5]: scope 0 at $DIR/region-subtyping-basic.rs:25:2: 25:2
     }
 }
diff --git a/src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir b/src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir
index 4a285d035be..61db4dba586 100644
--- a/src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir
+++ b/src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir
@@ -7,164 +7,165 @@
 | Inferred Region Values
 | '_#0r | U0 | {bb0[0..=8], bb1[0], bb2[0..=8], bb3[0], bb4[0..=1], bb5[0..=3], bb6[0..=3], bb7[0..=2], bb8[0..=5], '_#0r, '_#1r}
 | '_#1r | U0 | {bb0[0..=8], bb1[0], bb2[0..=8], bb3[0], bb4[0..=1], bb5[0..=3], bb6[0..=3], bb7[0..=2], bb8[0..=5], '_#1r}
-| '_#2r | U0 | {bb2[0..=8], bb3[0], bb5[0..=2]}
-| '_#3r | U0 | {bb2[1..=8], bb3[0], bb5[0..=2]}
-| '_#4r | U0 | {bb2[4..=8], bb3[0], bb5[0..=2]}
+| '_#2r | U0 | {}
+| '_#3r | U0 | {bb2[0..=8], bb3[0], bb5[0..=2]}
+| '_#4r | U0 | {bb2[1..=8], bb3[0], bb5[0..=2]}
+| '_#5r | U0 | {bb2[4..=8], bb3[0], bb5[0..=2]}
 |
 | Inference Constraints
 | '_#0r live at {bb0[0..=8], bb1[0], bb2[0..=8], bb3[0], bb4[0..=1], bb5[0..=3], bb6[0..=3], bb7[0..=2], bb8[0..=5]}
 | '_#1r live at {bb0[0..=8], bb1[0], bb2[0..=8], bb3[0], bb4[0..=1], bb5[0..=3], bb6[0..=3], bb7[0..=2], bb8[0..=5]}
-| '_#2r live at {bb2[0]}
-| '_#3r live at {bb2[1..=3]}
-| '_#4r live at {bb2[4..=8], bb3[0], bb5[0..=2]}
-| '_#2r: '_#3r due to Assignment at Single(bb2[0])
-| '_#3r: '_#4r due to Assignment at Single(bb2[3])
+| '_#3r live at {bb2[0]}
+| '_#4r live at {bb2[1..=3]}
+| '_#5r live at {bb2[4..=8], bb3[0], bb5[0..=2]}
+| '_#3r: '_#4r due to Assignment at Single(bb2[0])
+| '_#4r: '_#5r due to Assignment at Single(bb2[3])
 |
 fn main() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/region-subtyping-basic.rs:14:11: 14:11
-    let mut _1: [usize; Const { ty: usize, val: Value(Scalar(0x0000000000000003)) }]; // in scope 0 at $DIR/region-subtyping-basic.rs:15:9: 15:14
-    let _3: usize;                       // in scope 0 at $DIR/region-subtyping-basic.rs:16:16: 16:17
-    let mut _4: usize;                   // in scope 0 at $DIR/region-subtyping-basic.rs:16:14: 16:18
-    let mut _5: bool;                    // in scope 0 at $DIR/region-subtyping-basic.rs:16:14: 16:18
-    let mut _7: bool;                    // in scope 0 at $DIR/region-subtyping-basic.rs:18:8: 18:12
-    let _8: bool;                        // in scope 0 at $DIR/region-subtyping-basic.rs:19:9: 19:18
-    let mut _9: usize;                   // in scope 0 at $DIR/region-subtyping-basic.rs:19:15: 19:17
-    let _10: bool;                       // in scope 0 at $DIR/region-subtyping-basic.rs:21:9: 21:18
+    let mut _0: ();                      // return place in scope 0 at $DIR/region-subtyping-basic.rs:16:11: 16:11
+    let mut _1: [usize; Const { ty: usize, val: Value(Scalar(0x0000000000000003)) }]; // in scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14
+    let _3: usize;                       // in scope 0 at $DIR/region-subtyping-basic.rs:18:16: 18:17
+    let mut _4: usize;                   // in scope 0 at $DIR/region-subtyping-basic.rs:18:14: 18:18
+    let mut _5: bool;                    // in scope 0 at $DIR/region-subtyping-basic.rs:18:14: 18:18
+    let mut _7: bool;                    // in scope 0 at $DIR/region-subtyping-basic.rs:20:8: 20:12
+    let _8: bool;                        // in scope 0 at $DIR/region-subtyping-basic.rs:21:9: 21:18
+    let mut _9: usize;                   // in scope 0 at $DIR/region-subtyping-basic.rs:21:15: 21:17
+    let _10: bool;                       // in scope 0 at $DIR/region-subtyping-basic.rs:23:9: 23:18
     scope 1 {
-        debug v => _1;                   // in scope 1 at $DIR/region-subtyping-basic.rs:15:9: 15:14
-        let _2: &'_#3r usize;            // in scope 1 at $DIR/region-subtyping-basic.rs:16:9: 16:10
+        debug v => _1;                   // in scope 1 at $DIR/region-subtyping-basic.rs:17:9: 17:14
+        let _2: &'_#4r usize;            // in scope 1 at $DIR/region-subtyping-basic.rs:18:9: 18:10
         scope 2 {
-            debug p => _2;               // in scope 2 at $DIR/region-subtyping-basic.rs:16:9: 16:10
-            let _6: &'_#4r usize;        // in scope 2 at $DIR/region-subtyping-basic.rs:17:9: 17:10
+            debug p => _2;               // in scope 2 at $DIR/region-subtyping-basic.rs:18:9: 18:10
+            let _6: &'_#5r usize;        // in scope 2 at $DIR/region-subtyping-basic.rs:19:9: 19:10
             scope 3 {
-                debug q => _6;           // in scope 3 at $DIR/region-subtyping-basic.rs:17:9: 17:10
+                debug q => _6;           // in scope 3 at $DIR/region-subtyping-basic.rs:19:9: 19:10
             }
         }
     }
 
     bb0: {
-        StorageLive(_1);                 // bb0[0]: scope 0 at $DIR/region-subtyping-basic.rs:15:9: 15:14
-        _1 = [const Const(Value(Scalar(0x0000000000000001)): usize), const Const(Value(Scalar(0x0000000000000002)): usize), const Const(Value(Scalar(0x0000000000000003)): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:15:17: 15:26
+        StorageLive(_1);                 // bb0[0]: scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14
+        _1 = [const Const(Value(Scalar(0x0000000000000001)): usize), const Const(Value(Scalar(0x0000000000000002)): usize), const Const(Value(Scalar(0x0000000000000003)): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:17:17: 17:26
                                          // ty::Const
                                          // + ty: usize
                                          // + val: Value(Scalar(0x0000000000000001))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:15:18: 15:19
+                                         // + span: $DIR/region-subtyping-basic.rs:17:18: 17:19
                                          // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000001)) }
                                          // ty::Const
                                          // + ty: usize
                                          // + val: Value(Scalar(0x0000000000000002))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:15:21: 15:22
+                                         // + span: $DIR/region-subtyping-basic.rs:17:21: 17:22
                                          // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000002)) }
                                          // ty::Const
                                          // + ty: usize
                                          // + val: Value(Scalar(0x0000000000000003))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:15:24: 15:25
+                                         // + span: $DIR/region-subtyping-basic.rs:17:24: 17:25
                                          // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000003)) }
-        FakeRead(ForLet, _1);            // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:15:9: 15:14
-        StorageLive(_2);                 // bb0[3]: scope 1 at $DIR/region-subtyping-basic.rs:16:9: 16:10
-        StorageLive(_3);                 // bb0[4]: scope 1 at $DIR/region-subtyping-basic.rs:16:16: 16:17
-        _3 = const Const(Value(Scalar(0x0000000000000000)): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:16:16: 16:17
+        FakeRead(ForLet, _1);            // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14
+        StorageLive(_2);                 // bb0[3]: scope 1 at $DIR/region-subtyping-basic.rs:18:9: 18:10
+        StorageLive(_3);                 // bb0[4]: scope 1 at $DIR/region-subtyping-basic.rs:18:16: 18:17
+        _3 = const Const(Value(Scalar(0x0000000000000000)): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:18:16: 18:17
                                          // ty::Const
                                          // + ty: usize
                                          // + val: Value(Scalar(0x0000000000000000))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:16:16: 16:17
+                                         // + span: $DIR/region-subtyping-basic.rs:18:16: 18:17
                                          // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) }
-        _4 = Len(_1);                    // bb0[6]: scope 1 at $DIR/region-subtyping-basic.rs:16:14: 16:18
-        _5 = Lt(_3, _4);                 // bb0[7]: scope 1 at $DIR/region-subtyping-basic.rs:16:14: 16:18
-        assert(move _5, "index out of bounds: the len is {} but the index is {}", move _4, _3) -> [success: bb2, unwind: bb1]; // bb0[8]: scope 1 at $DIR/region-subtyping-basic.rs:16:14: 16:18
+        _4 = Len(_1);                    // bb0[6]: scope 1 at $DIR/region-subtyping-basic.rs:18:14: 18:18
+        _5 = Lt(_3, _4);                 // bb0[7]: scope 1 at $DIR/region-subtyping-basic.rs:18:14: 18:18
+        assert(move _5, "index out of bounds: the len is {} but the index is {}", move _4, _3) -> [success: bb2, unwind: bb1]; // bb0[8]: scope 1 at $DIR/region-subtyping-basic.rs:18:14: 18:18
     }
 
     bb1 (cleanup): {
-        resume;                          // bb1[0]: scope 0 at $DIR/region-subtyping-basic.rs:14:1: 23:2
+        resume;                          // bb1[0]: scope 0 at $DIR/region-subtyping-basic.rs:16:1: 25:2
     }
 
     bb2: {
-        _2 = &'_#2r _1[_3];              // bb2[0]: scope 1 at $DIR/region-subtyping-basic.rs:16:13: 16:18
-        FakeRead(ForLet, _2);            // bb2[1]: scope 1 at $DIR/region-subtyping-basic.rs:16:9: 16:10
-        StorageLive(_6);                 // bb2[2]: scope 2 at $DIR/region-subtyping-basic.rs:17:9: 17:10
-        _6 = _2;                         // bb2[3]: scope 2 at $DIR/region-subtyping-basic.rs:17:13: 17:14
-        FakeRead(ForLet, _6);            // bb2[4]: scope 2 at $DIR/region-subtyping-basic.rs:17:9: 17:10
-        StorageLive(_7);                 // bb2[5]: scope 3 at $DIR/region-subtyping-basic.rs:18:8: 18:12
-        _7 = const Const(Value(Scalar(0x01)): bool); // bb2[6]: scope 3 at $DIR/region-subtyping-basic.rs:18:8: 18:12
+        _2 = &'_#3r _1[_3];              // bb2[0]: scope 1 at $DIR/region-subtyping-basic.rs:18:13: 18:18
+        FakeRead(ForLet, _2);            // bb2[1]: scope 1 at $DIR/region-subtyping-basic.rs:18:9: 18:10
+        StorageLive(_6);                 // bb2[2]: scope 2 at $DIR/region-subtyping-basic.rs:19:9: 19:10
+        _6 = _2;                         // bb2[3]: scope 2 at $DIR/region-subtyping-basic.rs:19:13: 19:14
+        FakeRead(ForLet, _6);            // bb2[4]: scope 2 at $DIR/region-subtyping-basic.rs:19:9: 19:10
+        StorageLive(_7);                 // bb2[5]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12
+        _7 = const Const(Value(Scalar(0x01)): bool); // bb2[6]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12
                                          // ty::Const
                                          // + ty: bool
                                          // + val: Value(Scalar(0x01))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:18:8: 18:12
+                                         // + span: $DIR/region-subtyping-basic.rs:20:8: 20:12
                                          // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
-        FakeRead(ForMatchedPlace, _7);   // bb2[7]: scope 3 at $DIR/region-subtyping-basic.rs:18:8: 18:12
-        switchInt(_7) -> [Const(Value(Scalar(0x00)): bool): bb4, otherwise: bb3]; // bb2[8]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6
+        FakeRead(ForMatchedPlace, _7);   // bb2[7]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12
+        switchInt(_7) -> [Const(Value(Scalar(0x00)): bool): bb4, otherwise: bb3]; // bb2[8]: scope 3 at $DIR/region-subtyping-basic.rs:20:5: 24:6
     }
 
     bb3: {
-        falseEdges -> [real: bb5, imaginary: bb4]; // bb3[0]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6
+        falseEdges -> [real: bb5, imaginary: bb4]; // bb3[0]: scope 3 at $DIR/region-subtyping-basic.rs:20:5: 24:6
     }
 
     bb4: {
-        StorageLive(_10);                // bb4[0]: scope 3 at $DIR/region-subtyping-basic.rs:21:9: 21:18
-        _10 = const Const(Value(Scalar(<ZST>)): fn(usize) -> bool {use_x})(const Const(Value(Scalar(0x0000000000000016)): usize)) -> [return: bb7, unwind: bb1]; // bb4[1]: scope 3 at $DIR/region-subtyping-basic.rs:21:9: 21:18
+        StorageLive(_10);                // bb4[0]: scope 3 at $DIR/region-subtyping-basic.rs:23:9: 23:18
+        _10 = const Const(Value(Scalar(<ZST>)): fn(usize) -> bool {use_x})(const Const(Value(Scalar(0x0000000000000016)): usize)) -> [return: bb7, unwind: bb1]; // bb4[1]: scope 3 at $DIR/region-subtyping-basic.rs:23:9: 23:18
                                          // ty::Const
                                          // + ty: fn(usize) -> bool {use_x}
                                          // + val: Value(Scalar(<ZST>))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:21:9: 21:14
+                                         // + span: $DIR/region-subtyping-basic.rs:23:9: 23:14
                                          // + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(Scalar(<ZST>)) }
                                          // ty::Const
                                          // + ty: usize
                                          // + val: Value(Scalar(0x0000000000000016))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:21:15: 21:17
+                                         // + span: $DIR/region-subtyping-basic.rs:23:15: 23:17
                                          // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000016)) }
     }
 
     bb5: {
-        StorageLive(_8);                 // bb5[0]: scope 3 at $DIR/region-subtyping-basic.rs:19:9: 19:18
-        StorageLive(_9);                 // bb5[1]: scope 3 at $DIR/region-subtyping-basic.rs:19:15: 19:17
-        _9 = (*_6);                      // bb5[2]: scope 3 at $DIR/region-subtyping-basic.rs:19:15: 19:17
-        _8 = const Const(Value(Scalar(<ZST>)): fn(usize) -> bool {use_x})(move _9) -> [return: bb6, unwind: bb1]; // bb5[3]: scope 3 at $DIR/region-subtyping-basic.rs:19:9: 19:18
+        StorageLive(_8);                 // bb5[0]: scope 3 at $DIR/region-subtyping-basic.rs:21:9: 21:18
+        StorageLive(_9);                 // bb5[1]: scope 3 at $DIR/region-subtyping-basic.rs:21:15: 21:17
+        _9 = (*_6);                      // bb5[2]: scope 3 at $DIR/region-subtyping-basic.rs:21:15: 21:17
+        _8 = const Const(Value(Scalar(<ZST>)): fn(usize) -> bool {use_x})(move _9) -> [return: bb6, unwind: bb1]; // bb5[3]: scope 3 at $DIR/region-subtyping-basic.rs:21:9: 21:18
                                          // ty::Const
                                          // + ty: fn(usize) -> bool {use_x}
                                          // + val: Value(Scalar(<ZST>))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:19:9: 19:14
+                                         // + span: $DIR/region-subtyping-basic.rs:21:9: 21:14
                                          // + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(Scalar(<ZST>)) }
     }
 
     bb6: {
-        StorageDead(_9);                 // bb6[0]: scope 3 at $DIR/region-subtyping-basic.rs:19:17: 19:18
-        StorageDead(_8);                 // bb6[1]: scope 3 at $DIR/region-subtyping-basic.rs:19:18: 19:19
-        _0 = const Const(Value(Scalar(<ZST>)): ()); // bb6[2]: scope 3 at $DIR/region-subtyping-basic.rs:18:13: 20:6
+        StorageDead(_9);                 // bb6[0]: scope 3 at $DIR/region-subtyping-basic.rs:21:17: 21:18
+        StorageDead(_8);                 // bb6[1]: scope 3 at $DIR/region-subtyping-basic.rs:21:18: 21:19
+        _0 = const Const(Value(Scalar(<ZST>)): ()); // bb6[2]: scope 3 at $DIR/region-subtyping-basic.rs:20:13: 22:6
                                          // ty::Const
                                          // + ty: ()
                                          // + val: Value(Scalar(<ZST>))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:18:13: 20:6
+                                         // + span: $DIR/region-subtyping-basic.rs:20:13: 22:6
                                          // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
-        goto -> bb8;                     // bb6[3]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6
+        goto -> bb8;                     // bb6[3]: scope 3 at $DIR/region-subtyping-basic.rs:20:5: 24:6
     }
 
     bb7: {
-        StorageDead(_10);                // bb7[0]: scope 3 at $DIR/region-subtyping-basic.rs:21:18: 21:19
-        _0 = const Const(Value(Scalar(<ZST>)): ()); // bb7[1]: scope 3 at $DIR/region-subtyping-basic.rs:20:12: 22:6
+        StorageDead(_10);                // bb7[0]: scope 3 at $DIR/region-subtyping-basic.rs:23:18: 23:19
+        _0 = const Const(Value(Scalar(<ZST>)): ()); // bb7[1]: scope 3 at $DIR/region-subtyping-basic.rs:22:12: 24:6
                                          // ty::Const
                                          // + ty: ()
                                          // + val: Value(Scalar(<ZST>))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:20:12: 22:6
+                                         // + span: $DIR/region-subtyping-basic.rs:22:12: 24:6
                                          // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
-        goto -> bb8;                     // bb7[2]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6
+        goto -> bb8;                     // bb7[2]: scope 3 at $DIR/region-subtyping-basic.rs:20:5: 24:6
     }
 
     bb8: {
-        StorageDead(_6);                 // bb8[0]: scope 2 at $DIR/region-subtyping-basic.rs:23:1: 23:2
-        StorageDead(_3);                 // bb8[1]: scope 1 at $DIR/region-subtyping-basic.rs:23:1: 23:2
-        StorageDead(_2);                 // bb8[2]: scope 1 at $DIR/region-subtyping-basic.rs:23:1: 23:2
-        StorageDead(_1);                 // bb8[3]: scope 0 at $DIR/region-subtyping-basic.rs:23:1: 23:2
-        StorageDead(_7);                 // bb8[4]: scope 0 at $DIR/region-subtyping-basic.rs:23:1: 23:2
-        return;                          // bb8[5]: scope 0 at $DIR/region-subtyping-basic.rs:23:2: 23:2
+        StorageDead(_6);                 // bb8[0]: scope 2 at $DIR/region-subtyping-basic.rs:25:1: 25:2
+        StorageDead(_3);                 // bb8[1]: scope 1 at $DIR/region-subtyping-basic.rs:25:1: 25:2
+        StorageDead(_2);                 // bb8[2]: scope 1 at $DIR/region-subtyping-basic.rs:25:1: 25:2
+        StorageDead(_1);                 // bb8[3]: scope 0 at $DIR/region-subtyping-basic.rs:25:1: 25:2
+        StorageDead(_7);                 // bb8[4]: scope 0 at $DIR/region-subtyping-basic.rs:25:1: 25:2
+        return;                          // bb8[5]: scope 0 at $DIR/region-subtyping-basic.rs:25:2: 25:2
     }
 }
diff --git a/src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir b/src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir
index 5ffc83158ea..7799f20d974 100644
--- a/src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir
+++ b/src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir
@@ -7,15 +7,16 @@
 | Inferred Region Values
 | '_#0r | U0 | {bb0[0..=22], '_#0r, '_#1r}
 | '_#1r | U0 | {bb0[0..=22], '_#1r}
-| '_#2r | U0 | {bb0[10..=11]}
-| '_#3r | U0 | {bb0[11]}
+| '_#2r | U0 | {}
+| '_#3r | U0 | {bb0[10..=11]}
+| '_#4r | U0 | {bb0[11]}
 |
 | Inference Constraints
 | '_#0r live at {bb0[0..=22]}
 | '_#1r live at {bb0[0..=22]}
-| '_#2r live at {bb0[10]}
-| '_#3r live at {bb0[11]}
-| '_#2r: '_#3r due to Assignment at Single(bb0[10])
+| '_#3r live at {bb0[10]}
+| '_#4r live at {bb0[11]}
+| '_#3r: '_#4r due to Assignment at Single(bb0[10])
 |
 fn main() -> () {
     let mut _0: ();                      // return place in scope 0 at $DIR/storage_ranges.rs:3:11: 3:11
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr
index c69595a3f4d..da584e8ad4e 100644
--- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr
+++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr
@@ -34,7 +34,7 @@ LL | |     (a, b)
 LL | | }
    | |_^
    |
-   = note: hidden type `(&u8, &u8)` captures lifetime '_#4r
+   = note: hidden type `(&u8, &u8)` captures lifetime '_#5r
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
   --> $DIR/ret-impl-trait-no-fg.rs:9:1
@@ -48,7 +48,7 @@ LL | |     (a, b)
 LL | | }
    | |_^
    |
-   = note: hidden type `(&u8, &u8)` captures lifetime '_#5r
+   = note: hidden type `(&u8, &u8)` captures lifetime '_#6r
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/consts/const-ptr-unique-rpass.rs b/src/test/ui/consts/const-ptr-unique-rpass.rs
index e8735e1a32c..fc13bb98bd2 100644
--- a/src/test/ui/consts/const-ptr-unique-rpass.rs
+++ b/src/test/ui/consts/const-ptr-unique-rpass.rs
@@ -8,9 +8,9 @@ use test::black_box as b; // prevent promotion of the argument and const-propaga
 use std::ptr::Unique;
 
 
-const PTR: *mut u32 = Unique::empty().as_ptr();
+const PTR: *mut u32 = Unique::dangling().as_ptr();
 
 pub fn main() {
     // Be super-extra paranoid and cast the fn items to fn pointers before blackboxing them.
-    assert_eq!(PTR, b::<fn() -> _>(Unique::<u32>::empty)().as_ptr());
+    assert_eq!(PTR, b::<fn() -> _>(Unique::<u32>::dangling)().as_ptr());
 }
diff --git a/src/test/ui/hrtb/due-to-where-clause.nll.stderr b/src/test/ui/hrtb/due-to-where-clause.nll.stderr
index e476047a7a6..90803a0adb0 100644
--- a/src/test/ui/hrtb/due-to-where-clause.nll.stderr
+++ b/src/test/ui/hrtb/due-to-where-clause.nll.stderr
@@ -2,7 +2,7 @@ error: higher-ranked subtype error
   --> $DIR/due-to-where-clause.rs:2:5
    |
 LL |     test::<FooS>(&mut 42);
-   |     ^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/if/if-without-block.stderr b/src/test/ui/if/if-without-block.stderr
index 34df8e3d779..ee2bb62e2bb 100644
--- a/src/test/ui/if/if-without-block.stderr
+++ b/src/test/ui/if/if-without-block.stderr
@@ -6,6 +6,8 @@ LL |     if 5 == {
 ...
 LL | }
    | ^ expected `{`
+   |
+   = help: maybe you forgot the right operand of the condition?
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr
index 5bfc446f6a5..129af80ce4a 100644
--- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr
+++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr
@@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
    |                                                                          ^^^^^^^^^^^^^^^^^^
    |
-   = note: hidden type `Ordinary<'_>` captures lifetime '_#8r
+   = note: hidden type `Ordinary<'_>` captures lifetime '_#9r
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr
index 7291eee7b9e..de6d5edcae5 100644
--- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr
+++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr
@@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
    |                                                              ^^^^^^^^^^^^^^^^^^
    |
-   = note: hidden type `Ordinary<'_>` captures lifetime '_#5r
+   = note: hidden type `Ordinary<'_>` captures lifetime '_#6r
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/issue-68550.rs b/src/test/ui/nll/issue-68550.rs
new file mode 100644
index 00000000000..6bfd18de18c
--- /dev/null
+++ b/src/test/ui/nll/issue-68550.rs
@@ -0,0 +1,15 @@
+// Regression test for issue #68550.
+//
+// The `&'static A:` where clause was triggering
+// ICEs because it wound up being compiled to reference
+// the `'empty(U0)` region.
+
+fn run<'a, A>(x: A)
+where
+    A: 'static,
+    &'static A: ,
+{
+    let _: &'a A = &x; //~ ERROR `x` does not live long enough
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/issue-68550.stderr b/src/test/ui/nll/issue-68550.stderr
new file mode 100644
index 00000000000..e234ebb04e1
--- /dev/null
+++ b/src/test/ui/nll/issue-68550.stderr
@@ -0,0 +1,16 @@
+error[E0597]: `x` does not live long enough
+  --> $DIR/issue-68550.rs:12:20
+   |
+LL | fn run<'a, A>(x: A)
+   |        -- lifetime `'a` defined here
+...
+LL |     let _: &'a A = &x;
+   |            -----   ^^ borrowed value does not live long enough
+   |            |
+   |            type annotation requires that `x` is borrowed for `'a`
+LL | }
+   | - `x` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs b/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs
new file mode 100644
index 00000000000..d3964a7f515
--- /dev/null
+++ b/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs
@@ -0,0 +1,36 @@
+// Test that the NLL solver cannot find a solution
+// for `exists<R1> { forall<R1> { R2: R1 } }`.
+//
+// In this test, the impl should match `fn(T)` for some `T`,
+// but we ask it to match `for<'a> fn(&'a ())`. Due to argument
+// contravariance, this effectively requires a `T = &'b ()` where
+// `forall<'a> { 'a: 'b }`. Therefore, we get an error.
+//
+// Note the use of `-Zno-leak-check` and `feature(nll)` here. These
+// are presently required in order to skip the leak-check errors.
+//
+// c.f. Issue #57642.
+//
+// compile-flags:-Zno-leak-check
+
+#![feature(nll)]
+
+trait Y {
+    type F;
+    fn make_f() -> Self::F;
+}
+
+impl<T> Y for fn(T) {
+    type F = fn(T);
+
+    fn make_f() -> Self::F {
+        |_| {}
+    }
+}
+
+fn main() {
+    let _x = <fn(&())>::make_f();
+    //~^ higher-ranked subtype error
+    //~| higher-ranked subtype error
+    //~| higher-ranked subtype error
+}
diff --git a/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr b/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr
new file mode 100644
index 00000000000..70fb877d716
--- /dev/null
+++ b/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr
@@ -0,0 +1,20 @@
+error: higher-ranked subtype error
+  --> $DIR/impl-fn-ignore-binder-via-bottom.rs:32:14
+   |
+LL |     let _x = <fn(&())>::make_f();
+   |              ^^^^^^^^^^^^^^^^^^^
+
+error: higher-ranked subtype error
+  --> $DIR/impl-fn-ignore-binder-via-bottom.rs:32:14
+   |
+LL |     let _x = <fn(&())>::make_f();
+   |              ^^^^^^^^^^^^^^^^^^^
+
+error: higher-ranked subtype error
+  --> $DIR/impl-fn-ignore-binder-via-bottom.rs:32:14
+   |
+LL |     let _x = <fn(&())>::make_f();
+   |              ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/nll/type-check-pointer-comparisons.rs b/src/test/ui/nll/type-check-pointer-comparisons.rs
index 3c900356fab..298a6ef7ab3 100644
--- a/src/test/ui/nll/type-check-pointer-comparisons.rs
+++ b/src/test/ui/nll/type-check-pointer-comparisons.rs
@@ -21,13 +21,13 @@ fn compare_fn_ptr<'a, 'b, 'c>(f: fn(&'c mut &'a i32), g: fn(&'c mut &'b i32)) {
 }
 
 fn compare_hr_fn_ptr<'a>(f: fn(&'a i32), g: fn(&i32)) {
-    // Ideally this should compile with the operands swapped as well, but HIR
-    // type checking prevents it (and stops compilation) for now.
-    f == g; // OK
+    f == g;
+    //~^ ERROR higher-ranked subtype error
 }
 
 fn compare_const_fn_ptr<'a>(f: *const fn(&'a i32), g: *const fn(&i32)) {
-    f == g; // OK
+    f == g;
+    //~^ ERROR higher-ranked subtype error
 }
 
 fn main() {}
diff --git a/src/test/ui/nll/type-check-pointer-comparisons.stderr b/src/test/ui/nll/type-check-pointer-comparisons.stderr
index f350b861eb6..0fc7480260f 100644
--- a/src/test/ui/nll/type-check-pointer-comparisons.stderr
+++ b/src/test/ui/nll/type-check-pointer-comparisons.stderr
@@ -76,5 +76,17 @@ LL |     f == g;
 
 help: `'a` and `'b` must be the same: replace one with the other
 
-error: aborting due to 6 previous errors
+error: higher-ranked subtype error
+  --> $DIR/type-check-pointer-comparisons.rs:24:5
+   |
+LL |     f == g;
+   |     ^^^^^^
+
+error: higher-ranked subtype error
+  --> $DIR/type-check-pointer-comparisons.rs:29:5
+   |
+LL |     f == g;
+   |     ^^^^^^
+
+error: aborting due to 8 previous errors