about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2020-03-18 18:03:35 +0100
committerGitHub <noreply@github.com>2020-03-18 18:03:35 +0100
commit3f583fc27079fbc0983635f3fd40b47b89ed2f80 (patch)
tree4fd0e81ac0ae7afc0114fe89673033a192b0b479
parent8188b2163dfe3de7b8e3b52ee86c9c2eac78ffa1 (diff)
parent1ee5829575e73f217674f0a4e271c2e4246546e1 (diff)
downloadrust-3f583fc27079fbc0983635f3fd40b47b89ed2f80.tar.gz
rust-3f583fc27079fbc0983635f3fd40b47b89ed2f80.zip
Rollup merge of #69189 - matthewjasper:erase-the-world, r=nikomatsakis
Erase regions in writeback

Regions in `TypeckTables` (except canonicalized user annotations) are now erased. Further, we no longer do lexical region solving on item bodies with `-Zborrowck=mir`.

cc #68261
r? @nikomatsakis
-rw-r--r--src/librustc/ty/context.rs9
-rw-r--r--src/librustc_infer/infer/error_reporting/mod.rs13
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs11
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs19
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/util.rs78
-rw-r--r--src/librustc_infer/infer/lexical_region_resolve/mod.rs35
-rw-r--r--src/librustc_infer/infer/mod.rs62
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/region_errors.rs3
-rw-r--r--src/librustc_trait_selection/traits/mod.rs4
-rw-r--r--src/librustc_typeck/check/dropck.rs4
-rw-r--r--src/librustc_typeck/check/regionck.rs21
-rw-r--r--src/librustc_typeck/check/writeback.rs33
-rw-r--r--src/librustc_typeck/coherence/builtin.rs6
-rw-r--r--src/librustc_typeck/impl_wf_check/min_specialization.rs4
-rw-r--r--src/test/incremental/hashes/closure_expressions.rs4
-rw-r--r--src/test/incremental/hashes/inherent_impls.rs2
-rw-r--r--src/test/incremental/hashes/unary_and_binary_exprs.rs2
-rw-r--r--src/test/mir-opt/const-promotion-extern-static.rs20
-rw-r--r--src/test/mir-opt/no-drop-for-inactive-variant.rs2
-rw-r--r--src/test/mir-opt/remove_fake_borrows.rs10
-rw-r--r--src/test/mir-opt/storage_live_dead_in_statics.rs12
-rw-r--r--src/test/pretty/issue-4264.pp44
-rw-r--r--src/test/ui/consts/transmute-size-mismatch-before-typeck.stderr2
-rw-r--r--src/test/ui/error-codes/E0121.stderr2
-rw-r--r--src/test/ui/issues/issue-21174.stderr4
-rw-r--r--src/test/ui/lint/uninitialized-zeroed.stderr16
-rw-r--r--src/test/ui/pattern/usefulness/always-inhabited-union-ref.rs2
-rw-r--r--src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr2
-rw-r--r--src/test/ui/regions/regions-free-region-ordering-caller.migrate.stderr58
-rw-r--r--src/test/ui/regions/regions-free-region-ordering-caller.rs6
-rw-r--r--src/test/ui/suggestions/const-no-type.rs2
-rw-r--r--src/test/ui/suggestions/const-no-type.stderr2
-rw-r--r--src/test/ui/transmute/main.stderr3
-rw-r--r--src/test/ui/typeck/typeck_type_placeholder_item.stderr4
34 files changed, 264 insertions, 237 deletions
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index d6f6788697c..d7a259cc870 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -23,7 +23,6 @@ use crate::mir::{
 };
 use crate::traits;
 use crate::traits::{Clause, Clauses, Goal, GoalKind, Goals};
-use crate::ty::free_region_map::FreeRegionMap;
 use crate::ty::layout::{LayoutDetails, TargetDataLayout, VariantIdx};
 use crate::ty::query;
 use crate::ty::steal::Steal;
@@ -416,11 +415,6 @@ pub struct TypeckTables<'tcx> {
     /// this field will be set to `true`.
     pub tainted_by_errors: bool,
 
-    /// Stores the free-region relationships that were deduced from
-    /// its where-clauses and parameter types. These are then
-    /// read-again by borrowck.
-    pub free_region_map: FreeRegionMap<'tcx>,
-
     /// All the opaque types that are restricted to concrete types
     /// by this function.
     pub concrete_opaque_types: FxHashMap<DefId, ResolvedOpaqueTy<'tcx>>,
@@ -456,7 +450,6 @@ impl<'tcx> TypeckTables<'tcx> {
             coercion_casts: Default::default(),
             used_trait_imports: Lrc::new(Default::default()),
             tainted_by_errors: false,
-            free_region_map: Default::default(),
             concrete_opaque_types: Default::default(),
             upvar_list: Default::default(),
             generator_interior_types: Default::default(),
@@ -719,7 +712,6 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
 
             ref used_trait_imports,
             tainted_by_errors,
-            ref free_region_map,
             ref concrete_opaque_types,
             ref upvar_list,
             ref generator_interior_types,
@@ -757,7 +749,6 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
             coercion_casts.hash_stable(hcx, hasher);
             used_trait_imports.hash_stable(hcx, hasher);
             tainted_by_errors.hash_stable(hcx, hasher);
-            free_region_map.hash_stable(hcx, hasher);
             concrete_opaque_types.hash_stable(hcx, hasher);
             upvar_list.hash_stable(hcx, hasher);
             generator_interior_types.hash_stable(hcx, hasher);
diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs
index a544381f33d..ebbfcb28db2 100644
--- a/src/librustc_infer/infer/error_reporting/mod.rs
+++ b/src/librustc_infer/infer/error_reporting/mod.rs
@@ -49,7 +49,7 @@ use super::lexical_region_resolve::RegionResolutionError;
 use super::region_constraints::GenericKind;
 use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs};
 
-use crate::infer::{self, SuppressRegionErrors};
+use crate::infer;
 use crate::traits::error_reporting::report_object_safety_error;
 use crate::traits::{
     IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
@@ -372,17 +372,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         &self,
         region_scope_tree: &region::ScopeTree,
         errors: &Vec<RegionResolutionError<'tcx>>,
-        suppress: SuppressRegionErrors,
     ) {
-        debug!(
-            "report_region_errors(): {} errors to start, suppress = {:?}",
-            errors.len(),
-            suppress
-        );
-
-        if suppress.suppressed() {
-            return;
-        }
+        debug!("report_region_errors(): {} errors to start", errors.len());
 
         // try to pre-process the errors, which will group some of them
         // together into a `ProcessedErrors` group:
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs
index 1a09729ef64..50b324c7227 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs
@@ -3,6 +3,8 @@
 
 use crate::infer::error_reporting::nice_region_error::util::AnonymousParamInfo;
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
+use crate::infer::lexical_region_resolve::RegionResolutionError;
+use crate::infer::SubregionOrigin;
 use rustc::util::common::ErrorReported;
 
 use rustc_errors::struct_span_err;
@@ -47,6 +49,15 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     pub(super) fn try_report_anon_anon_conflict(&self) -> Option<ErrorReported> {
         let (span, sub, sup) = self.regions()?;
 
+        if let Some(RegionResolutionError::ConcreteFailure(
+            SubregionOrigin::ReferenceOutlivesReferent(..),
+            ..,
+        )) = self.error
+        {
+            // This error doesn't make much sense in this case.
+            return None;
+        }
+
         // Determine whether the sub and sup consist of both anonymous (elided) regions.
         let anon_reg_sup = self.tcx().is_suitable_region(sup)?;
 
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs
index d8c314a0d2f..2357ee689d5 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs
@@ -17,12 +17,7 @@ mod util;
 
 impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
     pub fn try_report_nice_region_error(&self, error: &RegionResolutionError<'tcx>) -> bool {
-        if let Some(tables) = self.in_progress_tables {
-            let tables = tables.borrow();
-            NiceRegionError::new(self, error.clone(), Some(&tables)).try_report().is_some()
-        } else {
-            NiceRegionError::new(self, error.clone(), None).try_report().is_some()
-        }
+        NiceRegionError::new(self, error.clone()).try_report().is_some()
     }
 }
 
@@ -30,16 +25,11 @@ pub struct NiceRegionError<'cx, 'tcx> {
     infcx: &'cx InferCtxt<'cx, 'tcx>,
     error: Option<RegionResolutionError<'tcx>>,
     regions: Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)>,
-    tables: Option<&'cx ty::TypeckTables<'tcx>>,
 }
 
 impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
-    pub fn new(
-        infcx: &'cx InferCtxt<'cx, 'tcx>,
-        error: RegionResolutionError<'tcx>,
-        tables: Option<&'cx ty::TypeckTables<'tcx>>,
-    ) -> Self {
-        Self { infcx, error: Some(error), regions: None, tables }
+    pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>, error: RegionResolutionError<'tcx>) -> Self {
+        Self { infcx, error: Some(error), regions: None }
     }
 
     pub fn new_from_span(
@@ -47,9 +37,8 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
         span: Span,
         sub: ty::Region<'tcx>,
         sup: ty::Region<'tcx>,
-        tables: Option<&'cx ty::TypeckTables<'tcx>>,
     ) -> Self {
-        Self { infcx, error: None, regions: Some((span, sub, sup)), tables }
+        Self { infcx, error: None, regions: Some((span, sub, sup)) }
     }
 
     fn tcx(&self) -> TyCtxt<'tcx> {
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs
index cab632935fd..de72c276595 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs
@@ -51,52 +51,44 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
         };
 
         let hir = &self.tcx().hir();
-        if let Some(hir_id) = hir.as_local_hir_id(id) {
-            if let Some(body_id) = hir.maybe_body_owned_by(hir_id) {
-                let body = hir.body(body_id);
-                let owner_id = hir.body_owner(body_id);
-                let fn_decl = hir.fn_decl_by_hir_id(owner_id).unwrap();
-                if let Some(tables) = self.tables {
-                    body.params
-                        .iter()
-                        .enumerate()
-                        .filter_map(|(index, param)| {
-                            // May return None; sometimes the tables are not yet populated.
-                            let ty_hir_id = fn_decl.inputs[index].hir_id;
-                            let param_ty_span = hir.span(ty_hir_id);
-                            let ty = tables.node_type_opt(param.hir_id)?;
-                            let mut found_anon_region = false;
-                            let new_param_ty = self.tcx().fold_regions(&ty, &mut false, |r, _| {
-                                if *r == *anon_region {
-                                    found_anon_region = true;
-                                    replace_region
-                                } else {
-                                    r
-                                }
-                            });
-                            if found_anon_region {
-                                let is_first = index == 0;
-                                Some(AnonymousParamInfo {
-                                    param,
-                                    param_ty: new_param_ty,
-                                    param_ty_span,
-                                    bound_region,
-                                    is_first,
-                                })
-                            } else {
-                                None
-                            }
-                        })
-                        .next()
+        let hir_id = hir.as_local_hir_id(id)?;
+        let body_id = hir.maybe_body_owned_by(hir_id)?;
+        let body = hir.body(body_id);
+        let owner_id = hir.body_owner(body_id);
+        let fn_decl = hir.fn_decl_by_hir_id(owner_id).unwrap();
+        let poly_fn_sig = self.tcx().fn_sig(id);
+        let fn_sig = self.tcx().liberate_late_bound_regions(id, &poly_fn_sig);
+        body.params
+            .iter()
+            .enumerate()
+            .filter_map(|(index, param)| {
+                // May return None; sometimes the tables are not yet populated.
+                let ty = fn_sig.inputs()[index];
+                let mut found_anon_region = false;
+                let new_param_ty = self.tcx().fold_regions(&ty, &mut false, |r, _| {
+                    if *r == *anon_region {
+                        found_anon_region = true;
+                        replace_region
+                    } else {
+                        r
+                    }
+                });
+                if found_anon_region {
+                    let ty_hir_id = fn_decl.inputs[index].hir_id;
+                    let param_ty_span = hir.span(ty_hir_id);
+                    let is_first = index == 0;
+                    Some(AnonymousParamInfo {
+                        param,
+                        param_ty: new_param_ty,
+                        param_ty_span,
+                        bound_region,
+                        is_first,
+                    })
                 } else {
                     None
                 }
-            } else {
-                None
-            }
-        } else {
-            None
-        }
+            })
+            .next()
     }
 
     // Here, we check for the case where the anonymous region
diff --git a/src/librustc_infer/infer/lexical_region_resolve/mod.rs b/src/librustc_infer/infer/lexical_region_resolve/mod.rs
index b7278ecd5e4..3af10e850d5 100644
--- a/src/librustc_infer/infer/lexical_region_resolve/mod.rs
+++ b/src/librustc_infer/infer/lexical_region_resolve/mod.rs
@@ -7,6 +7,7 @@ use crate::infer::region_constraints::RegionConstraintData;
 use crate::infer::region_constraints::VarInfos;
 use crate::infer::region_constraints::VerifyBound;
 use crate::infer::RegionVariableOrigin;
+use crate::infer::RegionckMode;
 use crate::infer::SubregionOrigin;
 use rustc::middle::free_region::RegionRelations;
 use rustc::ty::fold::TypeFoldable;
@@ -33,12 +34,29 @@ pub fn resolve<'tcx>(
     region_rels: &RegionRelations<'_, 'tcx>,
     var_infos: VarInfos,
     data: RegionConstraintData<'tcx>,
+    mode: RegionckMode,
 ) -> (LexicalRegionResolutions<'tcx>, Vec<RegionResolutionError<'tcx>>) {
     debug!("RegionConstraintData: resolve_regions()");
     let mut errors = vec![];
     let mut resolver = LexicalResolver { region_rels, var_infos, data };
-    let values = resolver.infer_variable_values(&mut errors);
-    (values, errors)
+    match mode {
+        RegionckMode::Solve => {
+            let values = resolver.infer_variable_values(&mut errors);
+            (values, errors)
+        }
+        RegionckMode::Erase { suppress_errors: false } => {
+            // Do real inference to get errors, then erase the results.
+            let mut values = resolver.infer_variable_values(&mut errors);
+            let re_erased = region_rels.tcx.lifetimes.re_erased;
+
+            values.values.iter_mut().for_each(|v| *v = VarValue::Value(re_erased));
+            (values, errors)
+        }
+        RegionckMode::Erase { suppress_errors: true } => {
+            // Skip region inference entirely.
+            (resolver.erased_data(region_rels.tcx), Vec::new())
+        }
+    }
 }
 
 /// Contains the result of lexical region resolution. Offers methods
@@ -163,6 +181,19 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
         }
     }
 
+    /// An erased version of the lexical region resolutions. Used when we're
+    /// erasing regions and suppressing errors: in item bodies with
+    /// `-Zborrowck=mir`.
+    fn erased_data(&self, tcx: TyCtxt<'tcx>) -> LexicalRegionResolutions<'tcx> {
+        LexicalRegionResolutions {
+            error_region: tcx.lifetimes.re_static,
+            values: IndexVec::from_elem_n(
+                VarValue::Value(tcx.lifetimes.re_erased),
+                self.num_vars(),
+            ),
+        }
+    }
+
     fn dump_constraints(&self, free_regions: &RegionRelations<'_, 'tcx>) {
         debug!("----() Start constraint listing (context={:?}) ()----", free_regions.context);
         for (idx, (constraint, _)) in self.data.constraints.iter().enumerate() {
diff --git a/src/librustc_infer/infer/mod.rs b/src/librustc_infer/infer/mod.rs
index 9ae131c568d..c5f06d53b8f 100644
--- a/src/librustc_infer/infer/mod.rs
+++ b/src/librustc_infer/infer/mod.rs
@@ -79,31 +79,50 @@ pub type Bound<T> = Option<T>;
 pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
 pub type FixupResult<'tcx, T> = Result<T, FixupError<'tcx>>; // "fixup result"
 
-/// A flag that is used to suppress region errors. This is normally
-/// false, but sometimes -- when we are doing region checks that the
-/// NLL borrow checker will also do -- it might be set to true.
-#[derive(Copy, Clone, Default, Debug)]
-pub struct SuppressRegionErrors {
-    suppressed: bool,
+/// How we should handle region solving.
+///
+/// This is used so that the region values inferred by HIR region solving are
+/// not exposed, and so that we can avoid doing work in HIR typeck that MIR
+/// typeck will also do.
+#[derive(Copy, Clone, Debug)]
+pub enum RegionckMode {
+    /// The default mode: report region errors, don't erase regions.
+    Solve,
+    /// Erase the results of region after solving.
+    Erase {
+        /// A flag that is used to suppress region errors, when we are doing
+        /// region checks that the NLL borrow checker will also do -- it might
+        /// be set to true.
+        suppress_errors: bool,
+    },
+}
+
+impl Default for RegionckMode {
+    fn default() -> Self {
+        RegionckMode::Solve
+    }
 }
 
-impl SuppressRegionErrors {
+impl RegionckMode {
     pub fn suppressed(self) -> bool {
-        self.suppressed
+        match self {
+            Self::Solve => false,
+            Self::Erase { suppress_errors } => suppress_errors,
+        }
     }
 
     /// Indicates that the MIR borrowck will repeat these region
     /// checks, so we should ignore errors if NLL is (unconditionally)
     /// enabled.
-    pub fn when_nll_is_enabled(tcx: TyCtxt<'_>) -> Self {
+    pub fn for_item_body(tcx: TyCtxt<'_>) -> Self {
         // FIXME(Centril): Once we actually remove `::Migrate` also make
         // this always `true` and then proceed to eliminate the dead code.
         match tcx.borrowck_mode() {
             // If we're on Migrate mode, report AST region errors
-            BorrowckMode::Migrate => SuppressRegionErrors { suppressed: false },
+            BorrowckMode::Migrate => RegionckMode::Erase { suppress_errors: false },
 
             // If we're on MIR, don't report AST region errors as they should be reported by NLL
-            BorrowckMode::Mir => SuppressRegionErrors { suppressed: true },
+            BorrowckMode::Mir => RegionckMode::Erase { suppress_errors: true },
         }
     }
 }
@@ -1207,20 +1226,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         region_context: DefId,
         region_map: &region::ScopeTree,
         outlives_env: &OutlivesEnvironment<'tcx>,
-        suppress: SuppressRegionErrors,
+        mode: RegionckMode,
     ) {
         assert!(
             self.is_tainted_by_errors() || self.inner.borrow().region_obligations.is_empty(),
             "region_obligations not empty: {:#?}",
             self.inner.borrow().region_obligations
         );
-
-        let region_rels = &RegionRelations::new(
-            self.tcx,
-            region_context,
-            region_map,
-            outlives_env.free_region_map(),
-        );
         let (var_infos, data) = self
             .inner
             .borrow_mut()
@@ -1228,8 +1240,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             .take()
             .expect("regions already resolved")
             .into_infos_and_data();
+
+        let region_rels = &RegionRelations::new(
+            self.tcx,
+            region_context,
+            region_map,
+            outlives_env.free_region_map(),
+        );
+
         let (lexical_region_resolutions, errors) =
-            lexical_region_resolve::resolve(region_rels, var_infos, data);
+            lexical_region_resolve::resolve(region_rels, var_infos, data, mode);
 
         let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions));
         assert!(old_value.is_none());
@@ -1240,7 +1260,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             // this infcx was in use.  This is totally hokey but
             // otherwise we have a hard time separating legit region
             // errors from silly ones.
-            self.report_region_errors(region_map, &errors, suppress);
+            self.report_region_errors(region_map, &errors);
         }
     }
 
diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs
index f751a16cfce..494b6421fd5 100644
--- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs
@@ -284,8 +284,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         debug!("report_region_error: category={:?} {:?}", category, span);
         // Check if we can use one of the "nice region errors".
         if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) {
-            let tables = self.infcx.tcx.typeck_tables_of(self.mir_def_id);
-            let nice = NiceRegionError::new_from_span(self.infcx, span, o, f, Some(tables));
+            let nice = NiceRegionError::new_from_span(self.infcx, span, o, f);
             if let Some(diag) = nice.try_report_from_nll() {
                 diag.buffer(&mut self.errors_buffer);
                 return;
diff --git a/src/librustc_trait_selection/traits/mod.rs b/src/librustc_trait_selection/traits/mod.rs
index 7b93982db97..43a90c4a6c1 100644
--- a/src/librustc_trait_selection/traits/mod.rs
+++ b/src/librustc_trait_selection/traits/mod.rs
@@ -21,7 +21,7 @@ mod util;
 pub mod wf;
 
 use crate::infer::outlives::env::OutlivesEnvironment;
-use crate::infer::{InferCtxt, SuppressRegionErrors, TyCtxtInferExt};
+use crate::infer::{InferCtxt, RegionckMode, TyCtxtInferExt};
 use crate::traits::error_reporting::InferCtxtExt as _;
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc::middle::region;
@@ -244,7 +244,7 @@ fn do_normalize_predicates<'tcx>(
             region_context,
             &region_scope_tree,
             &outlives_env,
-            SuppressRegionErrors::default(),
+            RegionckMode::default(),
         );
 
         let predicates = match infcx.fully_resolve(&predicates) {
diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs
index dca4f9e7cbe..e48ebbbb235 100644
--- a/src/librustc_typeck/check/dropck.rs
+++ b/src/librustc_typeck/check/dropck.rs
@@ -9,7 +9,7 @@ use rustc::ty::subst::{Subst, SubstsRef};
 use rustc::ty::{self, Predicate, Ty, TyCtxt};
 use rustc_errors::struct_span_err;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
-use rustc_infer::infer::{InferOk, SuppressRegionErrors, TyCtxtInferExt};
+use rustc_infer::infer::{InferOk, RegionckMode, TyCtxtInferExt};
 use rustc_infer::traits::TraitEngineExt as _;
 use rustc_span::Span;
 use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
@@ -139,7 +139,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
             drop_impl_did,
             &region_scope_tree,
             &outlives_env,
-            SuppressRegionErrors::default(),
+            RegionckMode::default(),
         );
         Ok(())
     })
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index 975c6e101a6..b6d6d3a7a87 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -85,7 +85,7 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::PatKind;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
-use rustc_infer::infer::{self, RegionObligation, SuppressRegionErrors};
+use rustc_infer::infer::{self, RegionObligation, RegionckMode};
 use rustc_span::Span;
 use rustc_trait_selection::infer::OutlivesEnvironmentExt;
 use rustc_trait_selection::opaque_types::InferCtxtExt;
@@ -124,10 +124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             rcx.visit_body(body);
             rcx.visit_region_obligations(id);
         }
-        rcx.resolve_regions_and_report_errors(SuppressRegionErrors::when_nll_is_enabled(self.tcx));
-
-        assert!(self.tables.borrow().free_region_map.is_empty());
-        self.tables.borrow_mut().free_region_map = rcx.outlives_environment.into_free_region_map();
+        rcx.resolve_regions_and_report_errors(RegionckMode::for_item_body(self.tcx));
     }
 
     /// Region checking during the WF phase for items. `wf_tys` are the
@@ -145,7 +142,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         rcx.outlives_environment.add_implied_bounds(self, wf_tys, item_id, span);
         rcx.outlives_environment.save_implied_bounds(item_id);
         rcx.visit_region_obligations(item_id);
-        rcx.resolve_regions_and_report_errors(SuppressRegionErrors::default());
+        rcx.resolve_regions_and_report_errors(RegionckMode::default());
     }
 
     /// Region check a function body. Not invoked on closures, but
@@ -168,13 +165,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             rcx.visit_fn_body(fn_id, body, self.tcx.hir().span(fn_id));
         }
 
-        rcx.resolve_regions_and_report_errors(SuppressRegionErrors::when_nll_is_enabled(self.tcx));
-
-        // In this mode, we also copy the free-region-map into the
-        // tables of the enclosing fcx. In the other regionck modes
-        // (e.g., `regionck_item`), we don't have an enclosing tables.
-        assert!(self.tables.borrow().free_region_map.is_empty());
-        self.tables.borrow_mut().free_region_map = rcx.outlives_environment.into_free_region_map();
+        rcx.resolve_regions_and_report_errors(RegionckMode::for_item_body(self.tcx));
     }
 }
 
@@ -355,7 +346,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
         self.select_all_obligations_or_error();
     }
 
-    fn resolve_regions_and_report_errors(&self, suppress: SuppressRegionErrors) {
+    fn resolve_regions_and_report_errors(&self, mode: RegionckMode) {
         self.infcx.process_registered_region_obligations(
             self.outlives_environment.region_bound_pairs_map(),
             self.implicit_region_bound,
@@ -366,7 +357,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
             self.subject_def_id,
             &self.region_scope_tree,
             &self.outlives_environment,
-            suppress,
+            mode,
         );
     }
 
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index b8f8030e3cd..8ed6cc3a943 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -62,7 +62,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         wbcx.visit_fru_field_types();
         wbcx.visit_opaque_types(body.value.span);
         wbcx.visit_coercion_casts();
-        wbcx.visit_free_region_map();
         wbcx.visit_user_provided_tys();
         wbcx.visit_user_provided_sigs();
         wbcx.visit_generator_interior_types();
@@ -125,7 +124,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
 
     fn write_ty_to_tables(&mut self, hir_id: hir::HirId, ty: Ty<'tcx>) {
         debug!("write_ty_to_tables({:?}, {:?})", hir_id, ty);
-        assert!(!ty.needs_infer() && !ty.has_placeholders());
+        assert!(!ty.needs_infer() && !ty.has_placeholders() && !ty.has_free_regions());
         self.tables.node_types_mut().insert(hir_id, ty);
     }
 
@@ -327,9 +326,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
             let new_upvar_capture = match *upvar_capture {
                 ty::UpvarCapture::ByValue => ty::UpvarCapture::ByValue,
                 ty::UpvarCapture::ByRef(ref upvar_borrow) => {
-                    let r = upvar_borrow.region;
-                    let r = self.resolve(&r, &upvar_id.var_path.hir_id);
-                    ty::UpvarCapture::ByRef(ty::UpvarBorrow { kind: upvar_borrow.kind, region: r })
+                    ty::UpvarCapture::ByRef(ty::UpvarBorrow {
+                        kind: upvar_borrow.kind,
+                        region: self.tcx().lifetimes.re_erased,
+                    })
                 }
             };
             debug!("Upvar capture for {:?} resolved to {:?}", upvar_id, new_upvar_capture);
@@ -358,11 +358,6 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         }
     }
 
-    fn visit_free_region_map(&mut self) {
-        self.tables.free_region_map = self.fcx.tables.borrow().free_region_map.clone();
-        debug_assert!(!self.tables.free_region_map.elements().any(|r| r.has_local_value()));
-    }
-
     fn visit_user_provided_tys(&mut self) {
         let fcx_tables = self.fcx.tables.borrow();
         debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root);
@@ -427,8 +422,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
     fn visit_opaque_types(&mut self, span: Span) {
         for (&def_id, opaque_defn) in self.fcx.opaque_types.borrow().iter() {
             let hir_id = self.tcx().hir().as_local_hir_id(def_id).unwrap();
-            let instantiated_ty =
-                self.tcx().erase_regions(&self.resolve(&opaque_defn.concrete_ty, &hir_id));
+            let instantiated_ty = self.resolve(&opaque_defn.concrete_ty, &hir_id);
 
             debug_assert!(!instantiated_ty.has_escaping_bound_vars());
 
@@ -617,10 +611,8 @@ impl Locatable for hir::HirId {
     }
 }
 
-///////////////////////////////////////////////////////////////////////////
-// The Resolver. This is the type folding engine that detects
-// unresolved types and so forth.
-
+/// The Resolver. This is the type folding engine that detects
+/// unresolved types and so forth.
 struct Resolver<'cx, 'tcx> {
     tcx: TyCtxt<'tcx>,
     infcx: &'cx InferCtxt<'cx, 'tcx>,
@@ -653,7 +645,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
 
     fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
         match self.infcx.fully_resolve(&t) {
-            Ok(t) => t,
+            Ok(t) => self.infcx.tcx.erase_regions(&t),
             Err(_) => {
                 debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
                 self.report_error(t);
@@ -662,15 +654,14 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
         }
     }
 
-    // FIXME This should be carefully checked
-    // We could use `self.report_error` but it doesn't accept a ty::Region, right now.
     fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
-        self.infcx.fully_resolve(&r).unwrap_or(self.tcx.lifetimes.re_static)
+        debug_assert!(!r.is_late_bound(), "Should not be resolving bound region.");
+        self.tcx.lifetimes.re_erased
     }
 
     fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
         match self.infcx.fully_resolve(&ct) {
-            Ok(ct) => ct,
+            Ok(ct) => self.infcx.tcx.erase_regions(&ct),
             Err(_) => {
                 debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
                 // FIXME: we'd like to use `self.report_error`, but it doesn't yet
diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs
index 2ea7601ae65..e24d9bebf65 100644
--- a/src/librustc_typeck/coherence/builtin.rs
+++ b/src/librustc_typeck/coherence/builtin.rs
@@ -12,7 +12,7 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::ItemKind;
 use rustc_infer::infer;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
-use rustc_infer::infer::{SuppressRegionErrors, TyCtxtInferExt};
+use rustc_infer::infer::{RegionckMode, TyCtxtInferExt};
 use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
 use rustc_trait_selection::traits::misc::{can_type_implement_copy, CopyImplementationError};
 use rustc_trait_selection::traits::predicate_for_trait_def;
@@ -307,7 +307,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: DefId) {
                             impl_did,
                             &region_scope_tree,
                             &outlives_env,
-                            SuppressRegionErrors::default(),
+                            RegionckMode::default(),
                         );
                     }
                 }
@@ -568,7 +568,7 @@ pub fn coerce_unsized_info(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUnsizedI
             impl_did,
             &region_scope_tree,
             &outlives_env,
-            SuppressRegionErrors::default(),
+            RegionckMode::default(),
         );
 
         CoerceUnsizedInfo { custom_kind: kind }
diff --git a/src/librustc_typeck/impl_wf_check/min_specialization.rs b/src/librustc_typeck/impl_wf_check/min_specialization.rs
index e96a8c454b8..cae88376118 100644
--- a/src/librustc_typeck/impl_wf_check/min_specialization.rs
+++ b/src/librustc_typeck/impl_wf_check/min_specialization.rs
@@ -75,7 +75,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
-use rustc_infer::infer::{InferCtxt, SuppressRegionErrors, TyCtxtInferExt};
+use rustc_infer::infer::{InferCtxt, RegionckMode, TyCtxtInferExt};
 use rustc_infer::traits::specialization_graph::Node;
 use rustc_span::Span;
 use rustc_trait_selection::traits::{self, translate_substs, wf};
@@ -162,7 +162,7 @@ fn get_impl_substs<'tcx>(
         impl1_def_id,
         &ScopeTree::default(),
         &outlives_env,
-        SuppressRegionErrors::default(),
+        RegionckMode::default(),
     );
     let impl2_substs = match infcx.fully_resolve(&impl2_substs) {
         Ok(s) => s,
diff --git a/src/test/incremental/hashes/closure_expressions.rs b/src/test/incremental/hashes/closure_expressions.rs
index 3d9db340f63..8edece2c8d3 100644
--- a/src/test/incremental/hashes/closure_expressions.rs
+++ b/src/test/incremental/hashes/closure_expressions.rs
@@ -84,8 +84,8 @@ pub fn add_type_ascription_to_parameter() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="hir_owner_items, mir_built, typeck_tables_of")]
-#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg = "cfail2", except = "hir_owner_items, typeck_tables_of")]
+#[rustc_clean(cfg = "cfail3")]
 pub fn add_type_ascription_to_parameter() {
     let closure = |x: u32| x + 1u32;
     let _: u32 = closure(1);
diff --git a/src/test/incremental/hashes/inherent_impls.rs b/src/test/incremental/hashes/inherent_impls.rs
index c0b80a92df6..139c265164b 100644
--- a/src/test/incremental/hashes/inherent_impls.rs
+++ b/src/test/incremental/hashes/inherent_impls.rs
@@ -360,7 +360,7 @@ impl Foo {
 impl Foo {
     #[rustc_clean(
         cfg="cfail2",
-        except="hir_owner,hir_owner_items,generics_of,predicates_of,type_of,typeck_tables_of"
+        except="hir_owner,hir_owner_items,generics_of,predicates_of,type_of"
     )]
     #[rustc_clean(cfg="cfail3")]
     pub fn add_lifetime_bound_to_lifetime_param_of_method<'a, 'b: 'a>(&self) { }
diff --git a/src/test/incremental/hashes/unary_and_binary_exprs.rs b/src/test/incremental/hashes/unary_and_binary_exprs.rs
index 9b63003482f..89aa0b1a58b 100644
--- a/src/test/incremental/hashes/unary_and_binary_exprs.rs
+++ b/src/test/incremental/hashes/unary_and_binary_exprs.rs
@@ -81,7 +81,7 @@ pub fn var_deref(x: &i32, y: &i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="hir_owner_items,optimized_mir,mir_built,typeck_tables_of", cfg="cfail2")]
+#[rustc_clean(except="hir_owner_items,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn var_deref(x: &i32, y: &i32) -> i32 {
     *y
diff --git a/src/test/mir-opt/const-promotion-extern-static.rs b/src/test/mir-opt/const-promotion-extern-static.rs
index 0d4a6d1bafd..c858a4c5ee7 100644
--- a/src/test/mir-opt/const-promotion-extern-static.rs
+++ b/src/test/mir-opt/const-promotion-extern-static.rs
@@ -4,9 +4,9 @@ extern "C" {
 
 static Y: i32 = 42;
 
-static mut BAR: *const &'static i32 = [&Y].as_ptr();
+static mut BAR: *const &i32 = [&Y].as_ptr();
 
-static mut FOO: *const &'static i32 = [unsafe { &X }].as_ptr();
+static mut FOO: *const &i32 = [unsafe { &X }].as_ptr();
 
 fn main() {}
 
@@ -18,8 +18,8 @@ fn main() {}
 //     _4 = &(*_5);
 //     _3 = [move _4];
 //     _2 = &_3;
-//     _1 = move _2 as &[&'static i32] (Pointer(Unsize));
-//     _0 = const core::slice::<impl [&'static i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
+//     _1 = move _2 as &[&i32] (Pointer(Unsize));
+//     _0 = const core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
 // }
 // ...
 // bb2: {
@@ -35,8 +35,8 @@ fn main() {}
 //     _4 = &(*_5);
 //     _3 = [move _4];
 //     _2 = &_3;
-//     _1 = move _2 as &[&'static i32] (Pointer(Unsize));
-//     _0 = const core::slice::<impl [&'static i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
+//     _1 = move _2 as &[&i32] (Pointer(Unsize));
+//     _0 = const core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
 // }
 // ...
 // bb2: {
@@ -50,8 +50,8 @@ fn main() {}
 // ...
 //     _6 = const BAR::promoted[0];
 //     _2 = &(*_6);
-//     _1 = move _2 as &[&'static i32] (Pointer(Unsize));
-//     _0 = const core::slice::<impl [&'static i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
+//     _1 = move _2 as &[&i32] (Pointer(Unsize));
+//     _0 = const core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
 // }
 // ...
 // bb2: {
@@ -63,8 +63,8 @@ fn main() {}
 // ...
 //     _6 = const FOO::promoted[0];
 //     _2 = &(*_6);
-//     _1 = move _2 as &[&'static i32] (Pointer(Unsize));
-//     _0 = const core::slice::<impl [&'static i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
+//     _1 = move _2 as &[&i32] (Pointer(Unsize));
+//     _0 = const core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
 // }
 // ...
 // bb2: {
diff --git a/src/test/mir-opt/no-drop-for-inactive-variant.rs b/src/test/mir-opt/no-drop-for-inactive-variant.rs
index f9067616845..74a606af28f 100644
--- a/src/test/mir-opt/no-drop-for-inactive-variant.rs
+++ b/src/test/mir-opt/no-drop-for-inactive-variant.rs
@@ -27,7 +27,7 @@ fn main() {
 //     }
 //     bb2: {
 //         ...
-//         const std::rt::begin_panic::<&'static str>(const "explicit panic") -> bb5;
+//         const std::rt::begin_panic::<&str>(const "explicit panic") -> bb5;
 //     }
 //     bb3: {
 //         unreachable;
diff --git a/src/test/mir-opt/remove_fake_borrows.rs b/src/test/mir-opt/remove_fake_borrows.rs
index 294fe247c38..ea106eaf595 100644
--- a/src/test/mir-opt/remove_fake_borrows.rs
+++ b/src/test/mir-opt/remove_fake_borrows.rs
@@ -26,16 +26,16 @@ fn main() {
 //     goto -> bb7;
 // }
 // bb2: {
-//     switchInt((*(*((_1 as Some).0: &'<empty> &'<empty> i32)))) -> [0i32: bb3, otherwise: bb1];
+//     switchInt((*(*((_1 as Some).0: &&i32)))) -> [0i32: bb3, otherwise: bb1];
 // }
 // bb3: {
 //     goto -> bb4;
 // }
 // bb4: {
 //     _4 = &shallow _1;
-//     _5 = &shallow ((_1 as Some).0: &'<empty> &'<empty> i32);
-//     _6 = &shallow (*((_1 as Some).0: &'<empty> &'<empty> i32));
-//     _7 = &shallow (*(*((_1 as Some).0: &'<empty> &'<empty> i32)));
+//     _5 = &shallow ((_1 as Some).0: &&i32);
+//     _6 = &shallow (*((_1 as Some).0: &&i32));
+//     _7 = &shallow (*(*((_1 as Some).0: &&i32)));
 //     StorageLive(_8);
 //     _8 = _2;
 //     switchInt(move _8) -> [false: bb6, otherwise: bb5];
@@ -72,7 +72,7 @@ fn main() {
 //     goto -> bb7;
 // }
 // bb2: {
-//     switchInt((*(*((_1 as Some).0: &'<empty> &'<empty> i32)))) -> [0i32: bb3, otherwise: bb1];
+//     switchInt((*(*((_1 as Some).0: &&i32)))) -> [0i32: bb3, otherwise: bb1];
 // }
 // bb3: {
 //     goto -> bb4;
diff --git a/src/test/mir-opt/storage_live_dead_in_statics.rs b/src/test/mir-opt/storage_live_dead_in_statics.rs
index 5dc15286bab..1c98766b968 100644
--- a/src/test/mir-opt/storage_live_dead_in_statics.rs
+++ b/src/test/mir-opt/storage_live_dead_in_statics.rs
@@ -35,12 +35,12 @@ fn main() {
 
 // END RUST SOURCE
 // START rustc.XXX.mir_map.0.mir
-//    let mut _0: &'static Foo;
-//    let _1: &'static Foo;
+//    let mut _0: &Foo;
+//    let _1: &Foo;
 //    let _2: Foo;
-//    let mut _3: &'static [(u32, u32)];
-//    let mut _4: &'static [(u32, u32); 42];
-//    let _5: &'static [(u32, u32); 42];
+//    let mut _3: &[(u32, u32)];
+//    let mut _4: &[(u32, u32); 42];
+//    let _5: &[(u32, u32); 42];
 //    let _6: [(u32, u32); 42];
 //    let mut _7: (u32, u32);
 //    let mut _8: (u32, u32);
@@ -178,7 +178,7 @@ fn main() {
 //        _6 = [move _7, move _8, move _9, move _10, move _11, move _12, move _13, move _14, move _15, move _16, move _17, move _18, move _19, move _20, move _21, move _22, move _23, move _24, move _25, move _26, move _27, move _28, move _29, move _30, move _31, move _32, move _33, move _34, move _35, move _36, move _37, move _38, move _39, move _40, move _41, move _42, move _43, move _44, move _45, move _46, move _47, move _48];
 //        _5 = &_6;
 //        _4 = &(*_5);
-//        _3 = move _4 as &'static [(u32, u32)] (Pointer(Unsize));
+//        _3 = move _4 as &[(u32, u32)] (Pointer(Unsize));
 //        _2 = Foo { tup: const "hi", data: move _3 };
 //        _1 = &_2;
 //        _0 = &(*_1);
diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp
index 8aa4cdeb539..ee7586bae82 100644
--- a/src/test/pretty/issue-4264.pp
+++ b/src/test/pretty/issue-4264.pp
@@ -34,29 +34,29 @@ pub fn bar() ({
                            ((::alloc::fmt::format as
                                 for<'r> fn(std::fmt::Arguments<'r>) -> std::string::String {std::fmt::format})(((::core::fmt::Arguments::new_v1
                                                                                                                     as
-                                                                                                                    fn(&[&str], &[std::fmt::ArgumentV1<'_>]) -> std::fmt::Arguments<'_> {std::fmt::Arguments::<'_>::new_v1})((&([("test"
-                                                                                                                                                                                                                                     as
-                                                                                                                                                                                                                                     &'static str)]
-                                                                                                                                                                                                                                   as
-                                                                                                                                                                                                                                   [&str; 1])
-                                                                                                                                                                                                                                 as
-                                                                                                                                                                                                                                 &[&str; 1]),
-                                                                                                                                                                                                                             (&(match (()
-                                                                                                                                                                                                                                          as
-                                                                                                                                                                                                                                          ())
-                                                                                                                                                                                                                                    {
-                                                                                                                                                                                                                                    ()
-                                                                                                                                                                                                                                    =>
-                                                                                                                                                                                                                                    ([]
-                                                                                                                                                                                                                                        as
-                                                                                                                                                                                                                                        [std::fmt::ArgumentV1<'_>; 0]),
-                                                                                                                                                                                                                                }
-                                                                                                                                                                                                                                   as
-                                                                                                                                                                                                                                   [std::fmt::ArgumentV1<'_>; 0])
-                                                                                                                                                                                                                                 as
-                                                                                                                                                                                                                                 &[std::fmt::ArgumentV1<'_>; 0]))
+                                                                                                                    fn(&[&str], &[std::fmt::ArgumentV1]) -> std::fmt::Arguments {std::fmt::Arguments::new_v1})((&([("test"
+                                                                                                                                                                                                                       as
+                                                                                                                                                                                                                       &str)]
+                                                                                                                                                                                                                     as
+                                                                                                                                                                                                                     [&str; 1])
+                                                                                                                                                                                                                   as
+                                                                                                                                                                                                                   &[&str; 1]),
+                                                                                                                                                                                                               (&(match (()
+                                                                                                                                                                                                                            as
+                                                                                                                                                                                                                            ())
+                                                                                                                                                                                                                      {
+                                                                                                                                                                                                                      ()
+                                                                                                                                                                                                                      =>
+                                                                                                                                                                                                                      ([]
+                                                                                                                                                                                                                          as
+                                                                                                                                                                                                                          [std::fmt::ArgumentV1; 0]),
+                                                                                                                                                                                                                  }
+                                                                                                                                                                                                                     as
+                                                                                                                                                                                                                     [std::fmt::ArgumentV1; 0])
+                                                                                                                                                                                                                   as
+                                                                                                                                                                                                                   &[std::fmt::ArgumentV1; 0]))
                                                                                                                    as
-                                                                                                                   std::fmt::Arguments<'_>))
+                                                                                                                   std::fmt::Arguments))
                                as std::string::String);
                        (res as std::string::String)
                    } as std::string::String);
diff --git a/src/test/ui/consts/transmute-size-mismatch-before-typeck.stderr b/src/test/ui/consts/transmute-size-mismatch-before-typeck.stderr
index 296a55ef160..5a477714596 100644
--- a/src/test/ui/consts/transmute-size-mismatch-before-typeck.stderr
+++ b/src/test/ui/consts/transmute-size-mismatch-before-typeck.stderr
@@ -21,7 +21,7 @@ LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) };
    |                             ^^^^^^^^^^^^^^^^^^^
    |
    = note: source type: `usize` (word size)
-   = note: target type: `&'static [u8]` (2 * word size)
+   = note: target type: `&[u8]` (2 * word size)
 
 error: could not evaluate constant pattern
   --> $DIR/transmute-size-mismatch-before-typeck.rs:10:9
diff --git a/src/test/ui/error-codes/E0121.stderr b/src/test/ui/error-codes/E0121.stderr
index 5a5c6b40c5a..ad854837ae5 100644
--- a/src/test/ui/error-codes/E0121.stderr
+++ b/src/test/ui/error-codes/E0121.stderr
@@ -14,7 +14,7 @@ LL | static BAR: _ = "test";
    |             ^
    |             |
    |             not allowed in type signatures
-   |             help: replace `_` with the correct type: `&'static str`
+   |             help: replace `_` with the correct type: `&str`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-21174.stderr b/src/test/ui/issues/issue-21174.stderr
index 5ac5a8665bc..09402c3d814 100644
--- a/src/test/ui/issues/issue-21174.stderr
+++ b/src/test/ui/issues/issue-21174.stderr
@@ -4,8 +4,8 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-
 LL |     let new: T::B = unsafe { std::mem::transmute(value) };
    |                              ^^^^^^^^^^^^^^^^^^^
    |
-   = note: source type: `<T as Trait<'a>>::A` (size can vary because of <T as Trait>::A)
-   = note: target type: `<T as Trait<'a>>::B` (size can vary because of <T as Trait>::B)
+   = note: source type: `<T as Trait>::A` (this type does not have a fixed size)
+   = note: target type: `<T as Trait>::B` (this type does not have a fixed size)
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/uninitialized-zeroed.stderr b/src/test/ui/lint/uninitialized-zeroed.stderr
index 6d669184deb..bf0562713a4 100644
--- a/src/test/ui/lint/uninitialized-zeroed.stderr
+++ b/src/test/ui/lint/uninitialized-zeroed.stderr
@@ -1,4 +1,4 @@
-error: the type `&'static T` does not permit zero-initialization
+error: the type `&T` does not permit zero-initialization
   --> $DIR/uninitialized-zeroed.rs:29:32
    |
 LL |         let _val: &'static T = mem::zeroed();
@@ -14,7 +14,7 @@ LL | #![deny(invalid_value)]
    |         ^^^^^^^^^^^^^
    = note: references must be non-null
 
-error: the type `&'static T` does not permit being left uninitialized
+error: the type `&T` does not permit being left uninitialized
   --> $DIR/uninitialized-zeroed.rs:30:32
    |
 LL |         let _val: &'static T = mem::uninitialized();
@@ -25,7 +25,7 @@ LL |         let _val: &'static T = mem::uninitialized();
    |
    = note: references must be non-null
 
-error: the type `Wrap<&'static T>` does not permit zero-initialization
+error: the type `Wrap<&T>` does not permit zero-initialization
   --> $DIR/uninitialized-zeroed.rs:32:38
    |
 LL |         let _val: Wrap<&'static T> = mem::zeroed();
@@ -40,7 +40,7 @@ note: references must be non-null (in this struct field)
 LL | struct Wrap<T> { wrapped: T }
    |                  ^^^^^^^^^^
 
-error: the type `Wrap<&'static T>` does not permit being left uninitialized
+error: the type `Wrap<&T>` does not permit being left uninitialized
   --> $DIR/uninitialized-zeroed.rs:33:38
    |
 LL |         let _val: Wrap<&'static T> = mem::uninitialized();
@@ -121,7 +121,7 @@ LL |         let _val: Void = mem::uninitialized();
    |
    = note: enums with no variants have no valid value
 
-error: the type `&'static i32` does not permit zero-initialization
+error: the type `&i32` does not permit zero-initialization
   --> $DIR/uninitialized-zeroed.rs:49:34
    |
 LL |         let _val: &'static i32 = mem::zeroed();
@@ -132,7 +132,7 @@ LL |         let _val: &'static i32 = mem::zeroed();
    |
    = note: references must be non-null
 
-error: the type `&'static i32` does not permit being left uninitialized
+error: the type `&i32` does not permit being left uninitialized
   --> $DIR/uninitialized-zeroed.rs:50:34
    |
 LL |         let _val: &'static i32 = mem::uninitialized();
@@ -366,7 +366,7 @@ LL |         let _val: NonBig = mem::uninitialized();
    |
    = note: `NonBig` must be initialized inside its custom valid range
 
-error: the type `&'static i32` does not permit zero-initialization
+error: the type `&i32` does not permit zero-initialization
   --> $DIR/uninitialized-zeroed.rs:84:34
    |
 LL |         let _val: &'static i32 = mem::transmute(0usize);
@@ -377,7 +377,7 @@ LL |         let _val: &'static i32 = mem::transmute(0usize);
    |
    = note: references must be non-null
 
-error: the type `&'static [i32]` does not permit zero-initialization
+error: the type `&[i32]` does not permit zero-initialization
   --> $DIR/uninitialized-zeroed.rs:85:36
    |
 LL |         let _val: &'static [i32] = mem::transmute((0usize, 0usize));
diff --git a/src/test/ui/pattern/usefulness/always-inhabited-union-ref.rs b/src/test/ui/pattern/usefulness/always-inhabited-union-ref.rs
index 11eae2af9c9..7d1cac8a442 100644
--- a/src/test/ui/pattern/usefulness/always-inhabited-union-ref.rs
+++ b/src/test/ui/pattern/usefulness/always-inhabited-union-ref.rs
@@ -21,7 +21,7 @@ fn uninhab_union() -> Foo {
 
 fn match_on_uninhab() {
     match uninhab_ref() {
-        //~^ ERROR non-exhaustive patterns: type `&'static !` is non-empty
+        //~^ ERROR non-exhaustive patterns: type `&!` is non-empty
     }
 
     match uninhab_union() {
diff --git a/src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr b/src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr
index 1b1096c977a..e1079f912d0 100644
--- a/src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr
+++ b/src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr
@@ -1,4 +1,4 @@
-error[E0004]: non-exhaustive patterns: type `&'static !` is non-empty
+error[E0004]: non-exhaustive patterns: type `&!` is non-empty
   --> $DIR/always-inhabited-union-ref.rs:23:11
    |
 LL |     match uninhab_ref() {
diff --git a/src/test/ui/regions/regions-free-region-ordering-caller.migrate.stderr b/src/test/ui/regions/regions-free-region-ordering-caller.migrate.stderr
index a33d3583552..06e1b0f1ac2 100644
--- a/src/test/ui/regions/regions-free-region-ordering-caller.migrate.stderr
+++ b/src/test/ui/regions/regions-free-region-ordering-caller.migrate.stderr
@@ -1,32 +1,54 @@
-error[E0623]: lifetime mismatch
+error[E0491]: in type `&'b &'a usize`, reference has a longer lifetime than the data it references
   --> $DIR/regions-free-region-ordering-caller.rs:11:12
    |
-LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) {
-   |                     ---------     ---------
-   |                     |
-   |                     these two types are declared with different lifetimes...
 LL |     let z: Option<&'b &'a usize> = None;
-   |            ^^^^^^^^^^^^^^^^^^^^^ ...but data from `a` flows into `b` here
+   |            ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the pointer is valid for the lifetime `'b` as defined on the function body at 10:14
+  --> $DIR/regions-free-region-ordering-caller.rs:10:14
+   |
+LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) {
+   |              ^^
+note: but the referenced data is only valid for the lifetime `'a` as defined on the function body at 10:10
+  --> $DIR/regions-free-region-ordering-caller.rs:10:10
+   |
+LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) {
+   |          ^^
 
-error[E0623]: lifetime mismatch
+error[E0491]: in type `&'b Paramd<'a>`, reference has a longer lifetime than the data it references
   --> $DIR/regions-free-region-ordering-caller.rs:17:12
    |
-LL | fn call3<'a, 'b>(a: &'a usize, b: &'b usize) {
-   |                     ---------     ---------
-   |                     |
-   |                     these two types are declared with different lifetimes...
-LL |     let y: Paramd<'a> = Paramd { x: a };
 LL |     let z: Option<&'b Paramd<'a>> = None;
-   |            ^^^^^^^^^^^^^^^^^^^^^^ ...but data from `a` flows into `b` here
+   |            ^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the pointer is valid for the lifetime `'b` as defined on the function body at 15:14
+  --> $DIR/regions-free-region-ordering-caller.rs:15:14
+   |
+LL | fn call3<'a, 'b>(a: &'a usize, b: &'b usize) {
+   |              ^^
+note: but the referenced data is only valid for the lifetime `'a` as defined on the function body at 15:10
+  --> $DIR/regions-free-region-ordering-caller.rs:15:10
+   |
+LL | fn call3<'a, 'b>(a: &'a usize, b: &'b usize) {
+   |          ^^
 
-error[E0623]: lifetime mismatch
+error[E0491]: in type `&'a &'b usize`, reference has a longer lifetime than the data it references
   --> $DIR/regions-free-region-ordering-caller.rs:22:12
    |
-LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
-   |                     ---------     --------- these two types are declared with different lifetimes...
 LL |     let z: Option<&'a &'b usize> = None;
-   |            ^^^^^^^^^^^^^^^^^^^^^ ...but data from `b` flows into `a` here
+   |            ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the pointer is valid for the lifetime `'a` as defined on the function body at 21:10
+  --> $DIR/regions-free-region-ordering-caller.rs:21:10
+   |
+LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
+   |          ^^
+note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 21:14
+  --> $DIR/regions-free-region-ordering-caller.rs:21:14
+   |
+LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
+   |              ^^
 
 error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0623`.
+For more information about this error, try `rustc --explain E0491`.
diff --git a/src/test/ui/regions/regions-free-region-ordering-caller.rs b/src/test/ui/regions/regions-free-region-ordering-caller.rs
index c0b12f23cdb..2bf4734cf73 100644
--- a/src/test/ui/regions/regions-free-region-ordering-caller.rs
+++ b/src/test/ui/regions/regions-free-region-ordering-caller.rs
@@ -8,18 +8,18 @@
 struct Paramd<'a> { x: &'a usize }
 
 fn call2<'a, 'b>(a: &'a usize, b: &'b usize) {
-    let z: Option<&'b &'a usize> = None;//[migrate]~ ERROR E0623
+    let z: Option<&'b &'a usize> = None;//[migrate]~ ERROR E0491
     //[nll]~^ ERROR lifetime may not live long enough
 }
 
 fn call3<'a, 'b>(a: &'a usize, b: &'b usize) {
     let y: Paramd<'a> = Paramd { x: a };
-    let z: Option<&'b Paramd<'a>> = None;//[migrate]~ ERROR E0623
+    let z: Option<&'b Paramd<'a>> = None;//[migrate]~ ERROR E0491
     //[nll]~^ ERROR lifetime may not live long enough
 }
 
 fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
-    let z: Option<&'a &'b usize> = None;//[migrate]~ ERROR E0623
+    let z: Option<&'a &'b usize> = None;//[migrate]~ ERROR E0491
     //[nll]~^ ERROR lifetime may not live long enough
 }
 
diff --git a/src/test/ui/suggestions/const-no-type.rs b/src/test/ui/suggestions/const-no-type.rs
index 99200a965dd..6b79697e983 100644
--- a/src/test/ui/suggestions/const-no-type.rs
+++ b/src/test/ui/suggestions/const-no-type.rs
@@ -43,4 +43,4 @@ static S = Vec::<String>::new();
 static mut SM = "abc";
 //~^ ERROR missing type for `static mut` item
 //~| HELP provide a type for the item
-//~| SUGGESTION &'static str
+//~| SUGGESTION &str
diff --git a/src/test/ui/suggestions/const-no-type.stderr b/src/test/ui/suggestions/const-no-type.stderr
index c4f17109dc5..a7b5aa5e5b1 100644
--- a/src/test/ui/suggestions/const-no-type.stderr
+++ b/src/test/ui/suggestions/const-no-type.stderr
@@ -14,7 +14,7 @@ error: missing type for `static mut` item
   --> $DIR/const-no-type.rs:43:12
    |
 LL | static mut SM = "abc";
-   |            ^^ help: provide a type for the item: `SM: &'static str`
+   |            ^^ help: provide a type for the item: `SM: &str`
 
 error: missing type for `const` item
   --> $DIR/const-no-type.rs:14:7
diff --git a/src/test/ui/transmute/main.stderr b/src/test/ui/transmute/main.stderr
index c72876e050f..4e781318329 100644
--- a/src/test/ui/transmute/main.stderr
+++ b/src/test/ui/transmute/main.stderr
@@ -4,8 +4,7 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-
 LL |     transmute(x)
    |     ^^^^^^^^^
    |
-   = note: source type: `<C as TypeConstructor<'a>>::T` (size can vary because of <C as TypeConstructor>::T)
-   = note: target type: `<C as TypeConstructor<'b>>::T` (size can vary because of <C as TypeConstructor>::T)
+   = note: `<C as TypeConstructor>::T` does not have a fixed size
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
   --> $DIR/main.rs:20:17
diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr
index f2d02f70f4a..dc86ab30dfe 100644
--- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr
+++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr
@@ -70,7 +70,7 @@ LL | static TEST3: _ = "test";
    |               ^
    |               |
    |               not allowed in type signatures
-   |               help: replace `_` with the correct type: `&'static str`
+   |               help: replace `_` with the correct type: `&str`
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
   --> $DIR/typeck_type_placeholder_item.rs:15:15
@@ -232,7 +232,7 @@ LL |     static FN_TEST3: _ = "test";
    |                      ^
    |                      |
    |                      not allowed in type signatures
-   |                      help: replace `_` with the correct type: `&'static str`
+   |                      help: replace `_` with the correct type: `&str`
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
   --> $DIR/typeck_type_placeholder_item.rs:88:22