about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc_ast/token.rs56
-rw-r--r--src/librustc_ast/tokenstream.rs125
-rw-r--r--src/librustc_ast_lowering/lib.rs2
-rw-r--r--src/librustc_expand/base.rs10
-rw-r--r--src/librustc_expand/expand.rs1
-rw-r--r--src/librustc_hir/definitions.rs4
-rw-r--r--src/librustc_infer/infer/canonical/canonicalizer.rs1
-rw-r--r--src/librustc_infer/infer/combine.rs1
-rw-r--r--src/librustc_infer/infer/error_reporting/mod.rs199
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs2
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/outlives_closure.rs117
-rw-r--r--src/librustc_infer/infer/error_reporting/note.rs428
-rw-r--r--src/librustc_infer/infer/free_regions.rs13
-rw-r--r--src/librustc_infer/infer/freshen.rs1
-rw-r--r--src/librustc_infer/infer/lexical_region_resolve/graphviz.rs253
-rw-r--r--src/librustc_infer/infer/lexical_region_resolve/mod.rs115
-rw-r--r--src/librustc_infer/infer/mod.rs74
-rw-r--r--src/librustc_infer/infer/region_constraints/mod.rs8
-rw-r--r--src/librustc_middle/ich/impls_ty.rs3
-rw-r--r--src/librustc_middle/middle/region.rs160
-rw-r--r--src/librustc_middle/ty/context.rs45
-rw-r--r--src/librustc_middle/ty/mod.rs16
-rw-r--r--src/librustc_middle/ty/print/pretty.rs27
-rw-r--r--src/librustc_middle/ty/structural_impls.rs2
-rw-r--r--src/librustc_middle/ty/sty.rs32
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/region_errors.rs4
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/region_name.rs1
-rw-r--r--src/librustc_parse/Cargo.toml1
-rw-r--r--src/librustc_parse/lib.rs214
-rw-r--r--src/librustc_parse/parser/mod.rs186
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs4
-rw-r--r--src/librustc_resolve/lib.rs125
-rw-r--r--src/librustc_resolve/macros.rs13
-rw-r--r--src/librustc_span/hygiene.rs22
-rw-r--r--src/librustc_trait_selection/opaque_types.rs5
-rw-r--r--src/librustc_trait_selection/traits/mod.rs4
-rw-r--r--src/librustc_trait_selection/traits/select.rs25
-rw-r--r--src/librustc_traits/chalk/lowering.rs1
-rw-r--r--src/librustc_typeck/check/closure.rs20
-rw-r--r--src/librustc_typeck/check/dropck.rs4
-rw-r--r--src/librustc_typeck/check/mod.rs22
-rw-r--r--src/librustc_typeck/check/regionck.rs509
-rw-r--r--src/librustc_typeck/coherence/builtin.rs11
-rw-r--r--src/librustc_typeck/impl_wf_check/min_specialization.rs8
-rw-r--r--src/librustc_typeck/outlives/utils.rs1
-rw-r--r--src/librustc_typeck/variance/constraints.rs1
-rw-r--r--src/librustdoc/clean/mod.rs1
-rw-r--r--src/libstd/sync/once.rs2
-rw-r--r--src/test/ui/ast-json/ast-json-noexpand-output.stdout2
-rw-r--r--src/test/ui/ast-json/ast-json-output.stdout2
-rw-r--r--src/test/ui/borrowck/issue-45983.migrate.stderr12
-rw-r--r--src/test/ui/borrowck/issue-45983.nll.stderr21
-rw-r--r--src/test/ui/borrowck/issue-45983.rs16
-rw-r--r--src/test/ui/borrowck/issue-45983.stderr (renamed from src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr)4
-rw-r--r--src/test/ui/borrowck/issue-7573.nll.stderr14
-rw-r--r--src/test/ui/borrowck/issue-7573.rs22
-rw-r--r--src/test/ui/borrowck/issue-7573.stderr14
-rw-r--r--src/test/ui/borrowck/regions-escape-bound-fn-2.rs7
-rw-r--r--src/test/ui/borrowck/regions-escape-bound-fn-2.stderr12
-rw-r--r--src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr12
-rw-r--r--src/test/ui/borrowck/regions-escape-bound-fn.rs7
-rw-r--r--src/test/ui/borrowck/regions-escape-bound-fn.stderr12
-rw-r--r--src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr12
-rw-r--r--src/test/ui/borrowck/regions-escape-unboxed-closure.rs5
-rw-r--r--src/test/ui/borrowck/regions-escape-unboxed-closure.stderr12
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-4.nll.stderr123
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-4.rs26
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-4.stderr275
-rw-r--r--src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.nll.stderr24
-rw-r--r--src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.rs24
-rw-r--r--src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.stderr55
-rw-r--r--src/test/ui/closures/closure-expected-type/expect-region-supply-region.nll.stderr44
-rw-r--r--src/test/ui/closures/closure-expected-type/expect-region-supply-region.rs27
-rw-r--r--src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr87
-rw-r--r--src/test/ui/error-codes/E0490.nll.stderr28
-rw-r--r--src/test/ui/error-codes/E0490.rs8
-rw-r--r--src/test/ui/error-codes/E0490.stderr76
-rw-r--r--src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr11
-rw-r--r--src/test/ui/error-codes/E0621-does-not-trigger-for-closures.rs6
-rw-r--r--src/test/ui/error-codes/E0621-does-not-trigger-for-closures.stderr31
-rw-r--r--src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr14
-rw-r--r--src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr14
-rw-r--r--src/test/ui/proc-macro/macro-rules-capture.rs18
-rw-r--r--src/test/ui/proc-macro/macro-rules-capture.stderr12
-rw-r--r--src/test/ui/regions/regions-close-object-into-object-5.rs17
-rw-r--r--src/test/ui/regions/regions-close-object-into-object-5.stderr29
-rw-r--r--src/test/ui/regions/regions-close-over-type-parameter-1.nll.stderr4
-rw-r--r--src/test/ui/regions/regions-close-over-type-parameter-1.rs18
-rw-r--r--src/test/ui/regions/regions-close-over-type-parameter-1.stderr44
-rw-r--r--src/test/ui/regions/regions-escape-method.nll.stderr11
-rw-r--r--src/test/ui/regions/regions-escape-method.rs2
-rw-r--r--src/test/ui/regions/regions-escape-method.stderr31
-rw-r--r--src/test/ui/regions/regions-escape-via-trait-or-not.nll.stderr11
-rw-r--r--src/test/ui/regions/regions-escape-via-trait-or-not.rs2
-rw-r--r--src/test/ui/regions/regions-escape-via-trait-or-not.stderr31
-rw-r--r--src/test/ui/regions/regions-infer-call-3.nll.stderr11
-rw-r--r--src/test/ui/regions/regions-infer-call-3.rs2
-rw-r--r--src/test/ui/regions/regions-infer-call-3.stderr29
-rw-r--r--src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.nll.stderr13
-rw-r--r--src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.rs2
-rw-r--r--src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr29
-rw-r--r--src/test/ui/symbol-names/impl1.rs4
102 files changed, 1139 insertions, 3119 deletions
diff --git a/src/librustc_ast/token.rs b/src/librustc_ast/token.rs
index a5b9c2a95bb..2e2bc380e84 100644
--- a/src/librustc_ast/token.rs
+++ b/src/librustc_ast/token.rs
@@ -673,62 +673,6 @@ impl Token {
 
         Some(Token::new(kind, self.span.to(joint.span)))
     }
-
-    // See comments in `Nonterminal::to_tokenstream` for why we care about
-    // *probably* equal here rather than actual equality
-    crate fn probably_equal_for_proc_macro(&self, other: &Token) -> bool {
-        if mem::discriminant(&self.kind) != mem::discriminant(&other.kind) {
-            return false;
-        }
-        match (&self.kind, &other.kind) {
-            (&Eq, &Eq)
-            | (&Lt, &Lt)
-            | (&Le, &Le)
-            | (&EqEq, &EqEq)
-            | (&Ne, &Ne)
-            | (&Ge, &Ge)
-            | (&Gt, &Gt)
-            | (&AndAnd, &AndAnd)
-            | (&OrOr, &OrOr)
-            | (&Not, &Not)
-            | (&Tilde, &Tilde)
-            | (&At, &At)
-            | (&Dot, &Dot)
-            | (&DotDot, &DotDot)
-            | (&DotDotDot, &DotDotDot)
-            | (&DotDotEq, &DotDotEq)
-            | (&Comma, &Comma)
-            | (&Semi, &Semi)
-            | (&Colon, &Colon)
-            | (&ModSep, &ModSep)
-            | (&RArrow, &RArrow)
-            | (&LArrow, &LArrow)
-            | (&FatArrow, &FatArrow)
-            | (&Pound, &Pound)
-            | (&Dollar, &Dollar)
-            | (&Question, &Question)
-            | (&Whitespace, &Whitespace)
-            | (&Comment, &Comment)
-            | (&Eof, &Eof) => true,
-
-            (&BinOp(a), &BinOp(b)) | (&BinOpEq(a), &BinOpEq(b)) => a == b,
-
-            (&OpenDelim(a), &OpenDelim(b)) | (&CloseDelim(a), &CloseDelim(b)) => a == b,
-
-            (&DocComment(a), &DocComment(b)) | (&Shebang(a), &Shebang(b)) => a == b,
-
-            (&Literal(a), &Literal(b)) => a == b,
-
-            (&Lifetime(a), &Lifetime(b)) => a == b,
-            (&Ident(a, b), &Ident(c, d)) => {
-                b == d && (a == c || a == kw::DollarCrate || c == kw::DollarCrate)
-            }
-
-            (&Interpolated(_), &Interpolated(_)) => false,
-
-            _ => panic!("forgot to add a token?"),
-        }
-    }
 }
 
 impl PartialEq<TokenKind> for Token {
diff --git a/src/librustc_ast/tokenstream.rs b/src/librustc_ast/tokenstream.rs
index 075aaa7e5bc..9d0199078fa 100644
--- a/src/librustc_ast/tokenstream.rs
+++ b/src/librustc_ast/tokenstream.rs
@@ -21,8 +21,6 @@ use rustc_macros::HashStable_Generic;
 use rustc_span::{Span, DUMMY_SP};
 use smallvec::{smallvec, SmallVec};
 
-use log::debug;
-
 use std::{iter, mem};
 
 /// When the main rust parser encounters a syntax-extension invocation, it
@@ -68,23 +66,6 @@ impl TokenTree {
         }
     }
 
-    // See comments in `Nonterminal::to_tokenstream` for why we care about
-    // *probably* equal here rather than actual equality
-    //
-    // This is otherwise the same as `eq_unspanned`, only recursing with a
-    // different method.
-    pub fn probably_equal_for_proc_macro(&self, other: &TokenTree) -> bool {
-        match (self, other) {
-            (TokenTree::Token(token), TokenTree::Token(token2)) => {
-                token.probably_equal_for_proc_macro(token2)
-            }
-            (TokenTree::Delimited(_, delim, tts), TokenTree::Delimited(_, delim2, tts2)) => {
-                delim == delim2 && tts.probably_equal_for_proc_macro(&tts2)
-            }
-            _ => false,
-        }
-    }
-
     /// Retrieves the TokenTree's span.
     pub fn span(&self) -> Span {
         match self {
@@ -307,112 +288,6 @@ impl TokenStream {
         t1.next().is_none() && t2.next().is_none()
     }
 
-    // See comments in `Nonterminal::to_tokenstream` for why we care about
-    // *probably* equal here rather than actual equality
-    //
-    // This is otherwise the same as `eq_unspanned`, only recursing with a
-    // different method.
-    pub fn probably_equal_for_proc_macro(&self, other: &TokenStream) -> bool {
-        // When checking for `probably_eq`, we ignore certain tokens that aren't
-        // preserved in the AST. Because they are not preserved, the pretty
-        // printer arbitrarily adds or removes them when printing as token
-        // streams, making a comparison between a token stream generated from an
-        // AST and a token stream which was parsed into an AST more reliable.
-        fn semantic_tree(tree: &TokenTree) -> bool {
-            if let TokenTree::Token(token) = tree {
-                if let
-                    // The pretty printer tends to add trailing commas to
-                    // everything, and in particular, after struct fields.
-                    | token::Comma
-                    // The pretty printer emits `NoDelim` as whitespace.
-                    | token::OpenDelim(DelimToken::NoDelim)
-                    | token::CloseDelim(DelimToken::NoDelim)
-                    // The pretty printer collapses many semicolons into one.
-                    | token::Semi
-                    // The pretty printer collapses whitespace arbitrarily and can
-                    // introduce whitespace from `NoDelim`.
-                    | token::Whitespace
-                    // The pretty printer can turn `$crate` into `::crate_name`
-                    | token::ModSep = token.kind {
-                    return false;
-                }
-            }
-            true
-        }
-
-        // When comparing two `TokenStream`s, we ignore the `IsJoint` information.
-        //
-        // However, `rustc_parse::lexer::tokentrees::TokenStreamBuilder` will
-        // use `Token.glue` on adjacent tokens with the proper `IsJoint`.
-        // Since we are ignoreing `IsJoint`, a 'glued' token (e.g. `BinOp(Shr)`)
-        // and its 'split'/'unglued' compoenents (e.g. `Gt, Gt`) are equivalent
-        // when determining if two `TokenStream`s are 'probably equal'.
-        //
-        // Therefore, we use `break_two_token_op` to convert all tokens
-        // to the 'unglued' form (if it exists). This ensures that two
-        // `TokenStream`s which differ only in how their tokens are glued
-        // will be considered 'probably equal', which allows us to keep spans.
-        //
-        // This is important when the original `TokenStream` contained
-        // extra spaces (e.g. `f :: < Vec < _ > > ( ) ;'). These extra spaces
-        // will be omitted when we pretty-print, which can cause the original
-        // and reparsed `TokenStream`s to differ in the assignment of `IsJoint`,
-        // leading to some tokens being 'glued' together in one stream but not
-        // the other. See #68489 for more details.
-        fn break_tokens(tree: TokenTree) -> impl Iterator<Item = TokenTree> {
-            // In almost all cases, we should have either zero or one levels
-            // of 'unglueing'. However, in some unusual cases, we may need
-            // to iterate breaking tokens mutliple times. For example:
-            // '[BinOpEq(Shr)] => [Gt, Ge] -> [Gt, Gt, Eq]'
-            let mut token_trees: SmallVec<[_; 2]>;
-            if let TokenTree::Token(token) = &tree {
-                let mut out = SmallVec::<[_; 2]>::new();
-                out.push(token.clone());
-                // Iterate to fixpoint:
-                // * We start off with 'out' containing our initial token, and `temp` empty
-                // * If we are able to break any tokens in `out`, then `out` will have
-                //   at least one more element than 'temp', so we will try to break tokens
-                //   again.
-                // * If we cannot break any tokens in 'out', we are done
-                loop {
-                    let mut temp = SmallVec::<[_; 2]>::new();
-                    let mut changed = false;
-
-                    for token in out.into_iter() {
-                        if let Some((first, second)) = token.kind.break_two_token_op() {
-                            temp.push(Token::new(first, DUMMY_SP));
-                            temp.push(Token::new(second, DUMMY_SP));
-                            changed = true;
-                        } else {
-                            temp.push(token);
-                        }
-                    }
-                    out = temp;
-                    if !changed {
-                        break;
-                    }
-                }
-                token_trees = out.into_iter().map(|t| TokenTree::Token(t)).collect();
-                if token_trees.len() != 1 {
-                    debug!("break_tokens: broke {:?} to {:?}", tree, token_trees);
-                }
-            } else {
-                token_trees = SmallVec::new();
-                token_trees.push(tree);
-            }
-            token_trees.into_iter()
-        }
-
-        let mut t1 = self.trees().filter(semantic_tree).flat_map(break_tokens);
-        let mut t2 = other.trees().filter(semantic_tree).flat_map(break_tokens);
-        for (t1, t2) in t1.by_ref().zip(t2.by_ref()) {
-            if !t1.probably_equal_for_proc_macro(&t2) {
-                return false;
-            }
-        }
-        t1.next().is_none() && t2.next().is_none()
-    }
-
     pub fn map_enumerated<F: FnMut(usize, TokenTree) -> TokenTree>(self, mut f: F) -> TokenStream {
         TokenStream(Lrc::new(
             self.0
diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs
index 0eabb726b88..5d98fdeeaf9 100644
--- a/src/librustc_ast_lowering/lib.rs
+++ b/src/librustc_ast_lowering/lib.rs
@@ -688,7 +688,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     ) -> Span {
         span.fresh_expansion(ExpnData {
             allow_internal_unstable,
-            ..ExpnData::default(ExpnKind::Desugaring(reason), span, self.sess.edition())
+            ..ExpnData::default(ExpnKind::Desugaring(reason), span, self.sess.edition(), None)
         })
     }
 
diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs
index fe5bf6f82c6..0137080938f 100644
--- a/src/librustc_expand/base.rs
+++ b/src/librustc_expand/base.rs
@@ -13,6 +13,7 @@ use rustc_data_structures::sync::{self, Lrc};
 use rustc_errors::{DiagnosticBuilder, ErrorReported};
 use rustc_parse::{self, parser, MACRO_ARGUMENTS};
 use rustc_session::parse::ParseSess;
+use rustc_span::def_id::DefId;
 use rustc_span::edition::Edition;
 use rustc_span::hygiene::{AstPass, ExpnData, ExpnId, ExpnKind};
 use rustc_span::source_map::SourceMap;
@@ -857,7 +858,13 @@ impl SyntaxExtension {
         SyntaxExtension::default(SyntaxExtensionKind::NonMacroAttr { mark_used }, edition)
     }
 
-    pub fn expn_data(&self, parent: ExpnId, call_site: Span, descr: Symbol) -> ExpnData {
+    pub fn expn_data(
+        &self,
+        parent: ExpnId,
+        call_site: Span,
+        descr: Symbol,
+        macro_def_id: Option<DefId>,
+    ) -> ExpnData {
         ExpnData {
             kind: ExpnKind::Macro(self.macro_kind(), descr),
             parent,
@@ -867,6 +874,7 @@ impl SyntaxExtension {
             allow_internal_unsafe: self.allow_internal_unsafe,
             local_inner_macros: self.local_inner_macros,
             edition: self.edition,
+            macro_def_id,
         }
     }
 }
diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs
index 485c5147d2c..b505302f625 100644
--- a/src/librustc_expand/expand.rs
+++ b/src/librustc_expand/expand.rs
@@ -988,6 +988,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
                     ExpnKind::Macro(MacroKind::Attr, sym::derive),
                     item.span(),
                     self.cx.parse_sess.edition,
+                    None,
                 )
             }),
             _ => None,
diff --git a/src/librustc_hir/definitions.rs b/src/librustc_hir/definitions.rs
index 30cddac6aac..c7a0822d27d 100644
--- a/src/librustc_hir/definitions.rs
+++ b/src/librustc_hir/definitions.rs
@@ -327,7 +327,9 @@ impl Definitions {
 
     #[inline]
     pub fn local_def_id(&self, node: ast::NodeId) -> LocalDefId {
-        self.opt_local_def_id(node).unwrap()
+        self.opt_local_def_id(node).unwrap_or_else(|| {
+            panic!("no entry for node id: `{:?}` / `{:?}`", node, self.opt_node_id_to_hir_id(node))
+        })
     }
 
     #[inline]
diff --git a/src/librustc_infer/infer/canonical/canonicalizer.rs b/src/librustc_infer/infer/canonical/canonicalizer.rs
index 5551b56ab79..c2dae6ba4f8 100644
--- a/src/librustc_infer/infer/canonical/canonicalizer.rs
+++ b/src/librustc_infer/infer/canonical/canonicalizer.rs
@@ -332,7 +332,6 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
             ty::ReStatic
             | ty::ReEarlyBound(..)
             | ty::ReFree(_)
-            | ty::ReScope(_)
             | ty::ReEmpty(_)
             | ty::RePlaceholder(..)
             | ty::ReErased => self.canonicalize_region_mode.canonicalize_free_region(self, r),
diff --git a/src/librustc_infer/infer/combine.rs b/src/librustc_infer/infer/combine.rs
index 75f288f1cdc..70a2122a9ea 100644
--- a/src/librustc_infer/infer/combine.rs
+++ b/src/librustc_infer/infer/combine.rs
@@ -619,7 +619,6 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
             | ty::ReVar(..)
             | ty::ReEmpty(_)
             | ty::ReStatic
-            | ty::ReScope(..)
             | ty::ReEarlyBound(..)
             | ty::ReFree(..) => {
                 // see common code below
diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs
index a8d6c01785f..cc479aa17ce 100644
--- a/src/librustc_infer/infer/error_reporting/mod.rs
+++ b/src/librustc_infer/infer/error_reporting/mod.rs
@@ -61,7 +61,6 @@ use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::Node;
-use rustc_middle::middle::region;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::{
     self,
@@ -81,58 +80,12 @@ pub mod nice_region_error;
 
 pub(super) fn note_and_explain_region(
     tcx: TyCtxt<'tcx>,
-    region_scope_tree: &region::ScopeTree,
     err: &mut DiagnosticBuilder<'_>,
     prefix: &str,
     region: ty::Region<'tcx>,
     suffix: &str,
 ) {
     let (description, span) = match *region {
-        ty::ReScope(scope) => {
-            let new_string;
-            let unknown_scope =
-                || format!("{}unknown scope: {:?}{}.  Please report a bug.", prefix, scope, suffix);
-            let span = scope.span(tcx, region_scope_tree);
-            let hir_id = scope.hir_id(region_scope_tree);
-            let tag = match hir_id.and_then(|hir_id| tcx.hir().find(hir_id)) {
-                Some(Node::Block(_)) => "block",
-                Some(Node::Expr(expr)) => match expr.kind {
-                    hir::ExprKind::Call(..) => "call",
-                    hir::ExprKind::MethodCall(..) => "method call",
-                    hir::ExprKind::Match(.., hir::MatchSource::IfLetDesugar { .. }) => "if let",
-                    hir::ExprKind::Match(.., hir::MatchSource::WhileLetDesugar) => "while let",
-                    hir::ExprKind::Match(.., hir::MatchSource::ForLoopDesugar) => "for",
-                    hir::ExprKind::Match(..) => "match",
-                    _ => "expression",
-                },
-                Some(Node::Stmt(_)) => "statement",
-                Some(Node::Item(it)) => item_scope_tag(&it),
-                Some(Node::TraitItem(it)) => trait_item_scope_tag(&it),
-                Some(Node::ImplItem(it)) => impl_item_scope_tag(&it),
-                Some(_) | None => {
-                    err.span_note(span, &unknown_scope());
-                    return;
-                }
-            };
-            let scope_decorated_tag = match scope.data {
-                region::ScopeData::Node => tag,
-                region::ScopeData::CallSite => "scope of call-site for function",
-                region::ScopeData::Arguments => "scope of function body",
-                region::ScopeData::Destruction => {
-                    new_string = format!("destruction scope surrounding {}", tag);
-                    &new_string[..]
-                }
-                region::ScopeData::Remainder(first_statement_index) => {
-                    new_string = format!(
-                        "block suffix following statement {}",
-                        first_statement_index.index()
-                    );
-                    &new_string[..]
-                }
-            };
-            explain_span(tcx, scope_decorated_tag, span)
-        }
-
         ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic => {
             msg_span_from_free_region(tcx, region)
         }
@@ -284,7 +237,6 @@ fn explain_span(tcx: TyCtxt<'tcx>, heading: &str, span: Span) -> (String, Option
 
 pub fn unexpected_hidden_region_diagnostic(
     tcx: TyCtxt<'tcx>,
-    region_scope_tree: Option<&region::ScopeTree>,
     span: Span,
     hidden_ty: Ty<'tcx>,
     hidden_region: ty::Region<'tcx>,
@@ -297,64 +249,56 @@ pub fn unexpected_hidden_region_diagnostic(
     );
 
     // Explain the region we are capturing.
-    if let ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic | ty::ReEmpty(_) = hidden_region {
-        // Assuming regionck succeeded (*), we ought to always be
-        // capturing *some* region from the fn header, and hence it
-        // ought to be free. So under normal circumstances, we will go
-        // down this path which gives a decent human readable
-        // explanation.
-        //
-        // (*) if not, the `tainted_by_errors` field would be set to
-        // `Some(ErrorReported)` in any case, so we wouldn't be here at all.
-        note_and_explain_free_region(
-            tcx,
-            &mut err,
-            &format!("hidden type `{}` captures ", hidden_ty),
-            hidden_region,
-            "",
-        );
-    } else {
-        // Ugh. This is a painful case: the hidden region is not one
-        // that we can easily summarize or explain. This can happen
-        // in a case like
-        // `src/test/ui/multiple-lifetimes/ordinary-bounds-unsuited.rs`:
-        //
-        // ```
-        // fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> {
-        //   if condition() { a } else { b }
-        // }
-        // ```
-        //
-        // Here the captured lifetime is the intersection of `'a` and
-        // `'b`, which we can't quite express.
-
-        if let Some(region_scope_tree) = region_scope_tree {
-            // If the `region_scope_tree` is available, this is being
-            // invoked from the "region inferencer error". We can at
-            // least report a really cryptic error for now.
-            note_and_explain_region(
+    match hidden_region {
+        ty::ReEmpty(ty::UniverseIndex::ROOT) => {
+            // All lifetimes shorter than the function body are `empty` in
+            // lexical region resolution. The default explanation of "an empty
+            // lifetime" isn't really accurate here.
+            let message = format!(
+                "hidden type `{}` captures lifetime smaller than the function body",
+                hidden_ty
+            );
+            err.span_note(span, &message);
+        }
+        ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic | ty::ReEmpty(_) => {
+            // Assuming regionck succeeded (*), we ought to always be
+            // capturing *some* region from the fn header, and hence it
+            // ought to be free. So under normal circumstances, we will go
+            // down this path which gives a decent human readable
+            // explanation.
+            //
+            // (*) if not, the `tainted_by_errors` field would be set to
+            // `Some(ErrorReported)` in any case, so we wouldn't be here at all.
+            note_and_explain_free_region(
                 tcx,
-                region_scope_tree,
                 &mut err,
                 &format!("hidden type `{}` captures ", hidden_ty),
                 hidden_region,
                 "",
             );
-        } else {
-            // If the `region_scope_tree` is *unavailable*, this is
-            // being invoked by the code that comes *after* region
-            // inferencing. This is a bug, as the region inferencer
-            // ought to have noticed the failed constraint and invoked
-            // error reporting, which in turn should have prevented us
-            // from getting trying to infer the hidden type
-            // completely.
-            tcx.sess.delay_span_bug(
-                span,
-                &format!(
-                    "hidden type captures unexpected lifetime `{:?}` \
-                     but no region inference failure",
-                    hidden_region,
-                ),
+        }
+        _ => {
+            // Ugh. This is a painful case: the hidden region is not one
+            // that we can easily summarize or explain. This can happen
+            // in a case like
+            // `src/test/ui/multiple-lifetimes/ordinary-bounds-unsuited.rs`:
+            //
+            // ```
+            // fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> {
+            //   if condition() { a } else { b }
+            // }
+            // ```
+            //
+            // Here the captured lifetime is the intersection of `'a` and
+            // `'b`, which we can't quite express.
+
+            // We can at least report a really cryptic error for now.
+            note_and_explain_region(
+                tcx,
+                &mut err,
+                &format!("hidden type `{}` captures ", hidden_ty),
+                hidden_region,
+                "",
             );
         }
     }
@@ -363,11 +307,7 @@ pub fn unexpected_hidden_region_diagnostic(
 }
 
 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
-    pub fn report_region_errors(
-        &self,
-        region_scope_tree: &region::ScopeTree,
-        errors: &Vec<RegionResolutionError<'tcx>>,
-    ) {
+    pub fn report_region_errors(&self, errors: &Vec<RegionResolutionError<'tcx>>) {
         debug!("report_region_errors(): {} errors to start", errors.len());
 
         // try to pre-process the errors, which will group some of them
@@ -390,17 +330,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     // general bit of code that displays the error information
                     RegionResolutionError::ConcreteFailure(origin, sub, sup) => {
                         if sub.is_placeholder() || sup.is_placeholder() {
-                            self.report_placeholder_failure(region_scope_tree, origin, sub, sup)
-                                .emit();
+                            self.report_placeholder_failure(origin, sub, sup).emit();
                         } else {
-                            self.report_concrete_failure(region_scope_tree, origin, sub, sup)
-                                .emit();
+                            self.report_concrete_failure(origin, sub, sup).emit();
                         }
                     }
 
                     RegionResolutionError::GenericBoundFailure(origin, param_ty, sub) => {
                         self.report_generic_bound_failure(
-                            region_scope_tree,
                             origin.span(),
                             Some(origin),
                             param_ty,
@@ -417,29 +354,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                         sup_r,
                     ) => {
                         if sub_r.is_placeholder() {
-                            self.report_placeholder_failure(
-                                region_scope_tree,
-                                sub_origin,
-                                sub_r,
-                                sup_r,
-                            )
-                            .emit();
+                            self.report_placeholder_failure(sub_origin, sub_r, sup_r).emit();
                         } else if sup_r.is_placeholder() {
-                            self.report_placeholder_failure(
-                                region_scope_tree,
-                                sup_origin,
-                                sub_r,
-                                sup_r,
-                            )
-                            .emit();
+                            self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit();
                         } else {
                             self.report_sub_sup_conflict(
-                                region_scope_tree,
-                                var_origin,
-                                sub_origin,
-                                sub_r,
-                                sup_origin,
-                                sup_r,
+                                var_origin, sub_origin, sub_r, sup_origin, sup_r,
                             );
                         }
                     }
@@ -460,13 +380,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                         // value.
                         let sub_r = self.tcx.mk_region(ty::ReEmpty(var_universe));
 
-                        self.report_placeholder_failure(
-                            region_scope_tree,
-                            sup_origin,
-                            sub_r,
-                            sup_r,
-                        )
-                        .emit();
+                        self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit();
                     }
 
                     RegionResolutionError::MemberConstraintFailure {
@@ -477,7 +391,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                         let hidden_ty = self.resolve_vars_if_possible(&hidden_ty);
                         unexpected_hidden_region_diagnostic(
                             self.tcx,
-                            Some(region_scope_tree),
                             span,
                             hidden_ty,
                             member_region,
@@ -1754,19 +1667,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
     pub fn report_generic_bound_failure(
         &self,
-        region_scope_tree: &region::ScopeTree,
         span: Span,
         origin: Option<SubregionOrigin<'tcx>>,
         bound_kind: GenericKind<'tcx>,
         sub: Region<'tcx>,
     ) {
-        self.construct_generic_bound_failure(region_scope_tree, span, origin, bound_kind, sub)
-            .emit();
+        self.construct_generic_bound_failure(span, origin, bound_kind, sub).emit();
     }
 
     pub fn construct_generic_bound_failure(
         &self,
-        region_scope_tree: &region::ScopeTree,
         span: Span,
         origin: Option<SubregionOrigin<'tcx>>,
         bound_kind: GenericKind<'tcx>,
@@ -1918,7 +1828,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 ));
                 note_and_explain_region(
                     self.tcx,
-                    region_scope_tree,
                     &mut err,
                     &format!("{} must be valid for ", labeled_user_string),
                     sub,
@@ -1936,7 +1845,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
     fn report_sub_sup_conflict(
         &self,
-        region_scope_tree: &region::ScopeTree,
         var_origin: RegionVariableOrigin,
         sub_origin: SubregionOrigin<'tcx>,
         sub_region: Region<'tcx>,
@@ -1947,7 +1855,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
         note_and_explain_region(
             self.tcx,
-            region_scope_tree,
             &mut err,
             "first, the lifetime cannot outlive ",
             sup_region,
@@ -1973,7 +1880,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 if sub_expected == sup_expected && sub_found == sup_found {
                     note_and_explain_region(
                         self.tcx,
-                        region_scope_tree,
                         &mut err,
                         "...but the lifetime must also be valid for ",
                         sub_region,
@@ -1995,7 +1901,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
         note_and_explain_region(
             self.tcx,
-            region_scope_tree,
             &mut err,
             "but, the lifetime must be valid for ",
             sub_region,
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 2aed3d9a469..efe52689550 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
@@ -8,7 +8,6 @@ use rustc_span::source_map::Span;
 mod different_lifetimes;
 mod find_anon_type;
 mod named_anon_conflict;
-mod outlives_closure;
 mod placeholder_error;
 mod static_impl_trait;
 mod trait_impl_difference;
@@ -57,7 +56,6 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
                 ErrorReported
             })
             .or_else(|| self.try_report_anon_anon_conflict())
-            .or_else(|| self.try_report_outlives_closure())
             .or_else(|| self.try_report_static_impl_trait())
             .or_else(|| self.try_report_impl_not_conforming_to_trait())
     }
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/outlives_closure.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/outlives_closure.rs
deleted file mode 100644
index fc858a49759..00000000000
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/outlives_closure.rs
+++ /dev/null
@@ -1,117 +0,0 @@
-//! Error Reporting for Anonymous Region Lifetime Errors
-//! where both the regions are anonymous.
-
-use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use crate::infer::lexical_region_resolve::RegionResolutionError::SubSupConflict;
-use crate::infer::SubregionOrigin;
-use rustc_errors::ErrorReported;
-use rustc_hir::{Expr, ExprKind::Closure, Node};
-use rustc_middle::ty::RegionKind;
-
-impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
-    /// Print the error message for lifetime errors when binding escapes a closure.
-    ///
-    /// Consider a case where we have
-    ///
-    /// ```no_run
-    /// fn with_int<F>(f: F) where F: FnOnce(&isize) {
-    ///     let x = 3;
-    ///     f(&x);
-    /// }
-    /// fn main() {
-    ///     let mut x = None;
-    ///     with_int(|y| x = Some(y));
-    /// }
-    /// ```
-    ///
-    /// the output will be
-    ///
-    /// ```text
-    ///     let mut x = None;
-    ///         ----- borrowed data cannot be stored into here...
-    ///     with_int(|y| x = Some(y));
-    ///              ---          ^ cannot be stored outside of its closure
-    ///              |
-    ///              ...because it cannot outlive this closure
-    /// ```
-    pub(super) fn try_report_outlives_closure(&self) -> Option<ErrorReported> {
-        if let Some(SubSupConflict(_, origin, ref sub_origin, _, ref sup_origin, sup_region)) =
-            self.error
-        {
-            // #45983: when trying to assign the contents of an argument to a binding outside of a
-            // closure, provide a specific message pointing this out.
-            if let (
-                &SubregionOrigin::BindingTypeIsNotValidAtDecl(ref external_span),
-                &RegionKind::ReFree(ref free_region),
-            ) = (&sub_origin, sup_region)
-            {
-                let hir = &self.tcx().hir();
-                if let Some(def_id) = free_region.scope.as_local() {
-                    let hir_id = hir.as_local_hir_id(def_id);
-                    if let Node::Expr(Expr { kind: Closure(_, _, _, closure_span, None), .. }) =
-                        hir.get(hir_id)
-                    {
-                        let sup_sp = sup_origin.span();
-                        let origin_sp = origin.span();
-                        let mut err = self.tcx().sess.struct_span_err(
-                            sup_sp,
-                            "borrowed data cannot be stored outside of its closure",
-                        );
-                        err.span_label(sup_sp, "cannot be stored outside of its closure");
-                        if origin_sp == sup_sp || origin_sp.contains(sup_sp) {
-                            // // sup_sp == origin.span():
-                            //
-                            // let mut x = None;
-                            //     ----- borrowed data cannot be stored into here...
-                            // with_int(|y| x = Some(y));
-                            //          ---          ^ cannot be stored outside of its closure
-                            //          |
-                            //          ...because it cannot outlive this closure
-                            //
-                            // // origin.contains(&sup_sp):
-                            //
-                            // let mut f: Option<&u32> = None;
-                            //     ----- borrowed data cannot be stored into here...
-                            // closure_expecting_bound(|x: &'x u32| {
-                            //                         ------------ ... because it cannot outlive this closure
-                            //     f = Some(x);
-                            //              ^ cannot be stored outside of its closure
-                            err.span_label(
-                                *external_span,
-                                "borrowed data cannot be stored into here...",
-                            );
-                            err.span_label(
-                                *closure_span,
-                                "...because it cannot outlive this closure",
-                            );
-                        } else {
-                            // FIXME: the wording for this case could be much improved
-                            //
-                            // let mut lines_to_use: Vec<&CrateId> = Vec::new();
-                            //                           - cannot infer an appropriate lifetime...
-                            // let push_id = |installed_id: &CrateId| {
-                            //     -------   ------------------------ borrowed data cannot outlive this closure
-                            //     |
-                            //     ...so that variable is valid at time of its declaration
-                            //     lines_to_use.push(installed_id);
-                            //                       ^^^^^^^^^^^^ cannot be stored outside of its closure
-                            err.span_label(origin_sp, "cannot infer an appropriate lifetime...");
-                            err.span_label(
-                                *external_span,
-                                "...so that variable is valid at time of its \
-                                            declaration",
-                            );
-                            err.span_label(
-                                *closure_span,
-                                "borrowed data cannot outlive this closure",
-                            );
-                        }
-                        err.emit();
-                        return Some(ErrorReported);
-                    }
-                }
-            }
-        }
-        None
-    }
-}
diff --git a/src/librustc_infer/infer/error_reporting/note.rs b/src/librustc_infer/infer/error_reporting/note.rs
index 81f37831af2..8fbb89da5af 100644
--- a/src/librustc_infer/infer/error_reporting/note.rs
+++ b/src/librustc_infer/infer/error_reporting/note.rs
@@ -1,7 +1,6 @@
 use crate::infer::error_reporting::{note_and_explain_region, ObligationCauseExt};
 use crate::infer::{self, InferCtxt, SubregionOrigin};
 use rustc_errors::{struct_span_err, DiagnosticBuilder};
-use rustc_middle::middle::region;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::{self, Region};
 
@@ -38,65 +37,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id);
                 err.span_note(span, &format!("...so that closure can access `{}`", var_name));
             }
-            infer::InfStackClosure(span) => {
-                err.span_note(span, "...so that closure does not outlive its stack frame");
-            }
-            infer::InvokeClosure(span) => {
-                err.span_note(span, "...so that closure is not invoked outside its lifetime");
-            }
-            infer::DerefPointer(span) => {
-                err.span_note(span, "...so that pointer is not dereferenced outside its lifetime");
-            }
-            infer::ClosureCapture(span, id) => {
-                err.span_note(
-                    span,
-                    &format!(
-                        "...so that captured variable `{}` does not outlive the \
-                                        enclosing closure",
-                        self.tcx.hir().name(id)
-                    ),
-                );
-            }
-            infer::IndexSlice(span) => {
-                err.span_note(span, "...so that slice is not indexed outside the lifetime");
-            }
             infer::RelateObjectBound(span) => {
                 err.span_note(span, "...so that it can be closed over into an object");
             }
-            infer::CallRcvr(span) => {
-                err.span_note(span, "...so that method receiver is valid for the method call");
-            }
-            infer::CallArg(span) => {
-                err.span_note(span, "...so that argument is valid for the call");
-            }
             infer::CallReturn(span) => {
                 err.span_note(span, "...so that return value is valid for the call");
             }
-            infer::Operand(span) => {
-                err.span_note(span, "...so that operand is valid for operation");
-            }
-            infer::AddrOf(span) => {
-                err.span_note(span, "...so that reference is valid at the time of borrow");
-            }
-            infer::AutoBorrow(span) => {
-                err.span_note(span, "...so that auto-reference is valid at the time of borrow");
-            }
-            infer::ExprTypeIsNotInScope(t, span) => {
-                err.span_note(
-                    span,
-                    &format!(
-                        "...so type `{}` of expression is valid during the \
-                                        expression",
-                        self.ty_to_string(t)
-                    ),
-                );
-            }
-            infer::BindingTypeIsNotValidAtDecl(span) => {
-                err.span_note(span, "...so that variable is valid at time of its declaration");
-            }
-            infer::ParameterInScope(_, span) => {
-                err.span_note(span, "...so that a type/lifetime parameter is in scope here");
-            }
             infer::DataBorrowed(ty, span) => {
                 err.span_note(
                     span,
@@ -126,25 +72,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     ),
                 );
             }
-            infer::RelateDefaultParamBound(span, t) => {
-                err.span_note(
-                    span,
-                    &format!(
-                        "...so that type parameter instantiated with `{}`, will \
-                                        meet its declared lifetime bounds",
-                        self.ty_to_string(t)
-                    ),
-                );
-            }
             infer::RelateRegionParamBound(span) => {
                 err.span_note(
                     span,
                     "...so that the declared lifetime parameter bounds are satisfied",
                 );
             }
-            infer::SafeDestructor(span) => {
-                err.span_note(span, "...so that references are valid when the destructor runs");
-            }
             infer::CompareImplMethodObligation { span, .. } => {
                 err.span_note(
                     span,
@@ -157,7 +90,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
     pub(super) fn report_concrete_failure(
         &self,
-        region_scope_tree: &region::ScopeTree,
         origin: SubregionOrigin<'tcx>,
         sub: Region<'tcx>,
         sup: Region<'tcx>,
@@ -166,10 +98,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             infer::Subtype(box trace) => {
                 let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
                 let mut err = self.report_and_explain_type_error(trace, &terr);
-                note_and_explain_region(self.tcx, region_scope_tree, &mut err, "", sup, "...");
+                note_and_explain_region(self.tcx, &mut err, "", sup, "...");
                 note_and_explain_region(
                     self.tcx,
-                    region_scope_tree,
                     &mut err,
                     "...does not necessarily outlive ",
                     sub,
@@ -187,7 +118,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 );
                 note_and_explain_region(
                     self.tcx,
-                    region_scope_tree,
                     &mut err,
                     "...the reference is valid for ",
                     sub,
@@ -195,7 +125,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 );
                 note_and_explain_region(
                     self.tcx,
-                    region_scope_tree,
                     &mut err,
                     "...but the borrowed content is only valid for ",
                     sup,
@@ -215,7 +144,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 );
                 note_and_explain_region(
                     self.tcx,
-                    region_scope_tree,
                     &mut err,
                     "...the borrowed pointer is valid for ",
                     sub,
@@ -223,7 +151,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 );
                 note_and_explain_region(
                     self.tcx,
-                    region_scope_tree,
                     &mut err,
                     &format!("...but `{}` is only valid for ", var_name),
                     sup,
@@ -231,106 +158,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 );
                 err
             }
-            infer::InfStackClosure(span) => {
-                let mut err =
-                    struct_span_err!(self.tcx.sess, span, E0314, "closure outlives stack frame");
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "...the closure must be valid for ",
-                    sub,
-                    "...",
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "...but the closure's stack frame is only valid \
-                                                  for ",
-                    sup,
-                    "",
-                );
-                err
-            }
-            infer::InvokeClosure(span) => {
-                let mut err = struct_span_err!(
-                    self.tcx.sess,
-                    span,
-                    E0315,
-                    "cannot invoke closure outside of its lifetime"
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "the closure is only valid for ",
-                    sup,
-                    "",
-                );
-                err
-            }
-            infer::DerefPointer(span) => {
-                let mut err = struct_span_err!(
-                    self.tcx.sess,
-                    span,
-                    E0473,
-                    "dereference of reference outside its lifetime"
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "the reference is only valid for ",
-                    sup,
-                    "",
-                );
-                err
-            }
-            infer::ClosureCapture(span, id) => {
-                let mut err = struct_span_err!(
-                    self.tcx.sess,
-                    span,
-                    E0474,
-                    "captured variable `{}` does not outlive the \
-                                                enclosing closure",
-                    self.tcx.hir().name(id)
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "captured variable is valid for ",
-                    sup,
-                    "",
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "closure is valid for ",
-                    sub,
-                    "",
-                );
-                err
-            }
-            infer::IndexSlice(span) => {
-                let mut err = struct_span_err!(
-                    self.tcx.sess,
-                    span,
-                    E0475,
-                    "index of slice outside its lifetime"
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "the slice is only valid for ",
-                    sup,
-                    "",
-                );
-                err
-            }
             infer::RelateObjectBound(span) => {
                 let mut err = struct_span_err!(
                     self.tcx.sess,
@@ -339,17 +166,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     "lifetime of the source pointer does not outlive \
                                                 lifetime bound of the object type"
                 );
+                note_and_explain_region(self.tcx, &mut err, "object type is valid for ", sub, "");
                 note_and_explain_region(
                     self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "object type is valid for ",
-                    sub,
-                    "",
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
                     &mut err,
                     "source pointer is only valid for ",
                     sup,
@@ -367,22 +186,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     self.ty_to_string(ty)
                 );
                 match *sub {
-                    ty::ReStatic => note_and_explain_region(
-                        self.tcx,
-                        region_scope_tree,
-                        &mut err,
-                        "type must satisfy ",
-                        sub,
-                        "",
-                    ),
-                    _ => note_and_explain_region(
-                        self.tcx,
-                        region_scope_tree,
-                        &mut err,
-                        "type must outlive ",
-                        sub,
-                        "",
-                    ),
+                    ty::ReStatic => {
+                        note_and_explain_region(self.tcx, &mut err, "type must satisfy ", sub, "")
+                    }
+                    _ => note_and_explain_region(self.tcx, &mut err, "type must outlive ", sub, ""),
                 }
                 err
             }
@@ -391,7 +198,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     struct_span_err!(self.tcx.sess, span, E0478, "lifetime bound not satisfied");
                 note_and_explain_region(
                     self.tcx,
-                    region_scope_tree,
                     &mut err,
                     "lifetime parameter instantiated with ",
                     sup,
@@ -399,7 +205,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 );
                 note_and_explain_region(
                     self.tcx,
-                    region_scope_tree,
                     &mut err,
                     "but lifetime parameter must outlive ",
                     sub,
@@ -407,61 +212,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 );
                 err
             }
-            infer::RelateDefaultParamBound(span, ty) => {
-                let mut err = struct_span_err!(
-                    self.tcx.sess,
-                    span,
-                    E0479,
-                    "the type `{}` (provided as the value of a type \
-                                                parameter) is not valid at this point",
-                    self.ty_to_string(ty)
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "type must outlive ",
-                    sub,
-                    "",
-                );
-                err
-            }
-            infer::CallRcvr(span) => {
-                let mut err = struct_span_err!(
-                    self.tcx.sess,
-                    span,
-                    E0480,
-                    "lifetime of method receiver does not outlive the \
-                                                method call"
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "the receiver is only valid for ",
-                    sup,
-                    "",
-                );
-                err
-            }
-            infer::CallArg(span) => {
-                let mut err = struct_span_err!(
-                    self.tcx.sess,
-                    span,
-                    E0481,
-                    "lifetime of function argument does not outlive \
-                                                the function call"
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "the function argument is only valid for ",
-                    sup,
-                    "",
-                );
-                err
-            }
             infer::CallReturn(span) => {
                 let mut err = struct_span_err!(
                     self.tcx.sess,
@@ -472,7 +222,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 );
                 note_and_explain_region(
                     self.tcx,
-                    region_scope_tree,
                     &mut err,
                     "the return value is only valid for ",
                     sup,
@@ -480,140 +229,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 );
                 err
             }
-            infer::Operand(span) => {
-                let mut err = struct_span_err!(
-                    self.tcx.sess,
-                    span,
-                    E0483,
-                    "lifetime of operand does not outlive the \
-                                                operation"
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "the operand is only valid for ",
-                    sup,
-                    "",
-                );
-                err
-            }
-            infer::AddrOf(span) => {
-                let mut err = struct_span_err!(
-                    self.tcx.sess,
-                    span,
-                    E0484,
-                    "reference is not valid at the time of borrow"
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "the borrow is only valid for ",
-                    sup,
-                    "",
-                );
-                err
-            }
-            infer::AutoBorrow(span) => {
-                let mut err = struct_span_err!(
-                    self.tcx.sess,
-                    span,
-                    E0485,
-                    "automatically reference is not valid at the time \
-                                                of borrow"
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "the automatic borrow is only valid for ",
-                    sup,
-                    "",
-                );
-                err
-            }
-            infer::ExprTypeIsNotInScope(t, span) => {
-                let mut err = struct_span_err!(
-                    self.tcx.sess,
-                    span,
-                    E0486,
-                    "type of expression contains references that are \
-                                                not valid during the expression: `{}`",
-                    self.ty_to_string(t)
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "type is only valid for ",
-                    sup,
-                    "",
-                );
-                err
-            }
-            infer::SafeDestructor(span) => {
-                let mut err = struct_span_err!(
-                    self.tcx.sess,
-                    span,
-                    E0487,
-                    "unsafe use of destructor: destructor might be \
-                                                called while references are dead"
-                );
-                // FIXME (22171): terms "super/subregion" are suboptimal
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "superregion: ",
-                    sup,
-                    "",
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "subregion: ",
-                    sub,
-                    "",
-                );
-                err
-            }
-            infer::BindingTypeIsNotValidAtDecl(span) => {
-                let mut err = struct_span_err!(
-                    self.tcx.sess,
-                    span,
-                    E0488,
-                    "lifetime of variable does not enclose its \
-                                                declaration"
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "the variable is only valid for ",
-                    sup,
-                    "",
-                );
-                err
-            }
-            infer::ParameterInScope(_, span) => {
-                let mut err = struct_span_err!(
-                    self.tcx.sess,
-                    span,
-                    E0489,
-                    "type/lifetime parameter not in scope here"
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "the parameter is only valid for ",
-                    sub,
-                    "",
-                );
-                err
-            }
             infer::DataBorrowed(ty, span) => {
                 let mut err = struct_span_err!(
                     self.tcx.sess,
@@ -622,22 +237,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     "a value of type `{}` is borrowed for too long",
                     self.ty_to_string(ty)
                 );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "the type is valid for ",
-                    sub,
-                    "",
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "but the borrow lasts for ",
-                    sup,
-                    "",
-                );
+                note_and_explain_region(self.tcx, &mut err, "the type is valid for ", sub, "");
+                note_and_explain_region(self.tcx, &mut err, "but the borrow lasts for ", sup, "");
                 err
             }
             infer::ReferenceOutlivesReferent(ty, span) => {
@@ -648,17 +249,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     "in type `{}`, reference has a longer lifetime than the data it references",
                     self.ty_to_string(ty)
                 );
+                note_and_explain_region(self.tcx, &mut err, "the pointer is valid for ", sub, "");
                 note_and_explain_region(
                     self.tcx,
-                    region_scope_tree,
-                    &mut err,
-                    "the pointer is valid for ",
-                    sub,
-                    "",
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    region_scope_tree,
                     &mut err,
                     "but the referenced data is only valid for ",
                     sup,
@@ -683,7 +276,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
     pub(super) fn report_placeholder_failure(
         &self,
-        region_scope_tree: &region::ScopeTree,
         placeholder_origin: SubregionOrigin<'tcx>,
         sub: Region<'tcx>,
         sup: Region<'tcx>,
@@ -695,7 +287,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 self.report_and_explain_type_error(trace, &terr)
             }
 
-            _ => self.report_concrete_failure(region_scope_tree, placeholder_origin, sub, sup),
+            _ => self.report_concrete_failure(placeholder_origin, sub, sup),
         }
     }
 }
diff --git a/src/librustc_infer/infer/free_regions.rs b/src/librustc_infer/infer/free_regions.rs
index e31c524c197..d975038b010 100644
--- a/src/librustc_infer/infer/free_regions.rs
+++ b/src/librustc_infer/infer/free_regions.rs
@@ -5,7 +5,6 @@
 
 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
@@ -21,21 +20,13 @@ pub struct RegionRelations<'a, '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 new(tcx: TyCtxt<'tcx>, context: DefId, free_regions: &'a FreeRegionMap<'tcx>) -> Self {
+        Self { tcx, context, free_regions }
     }
 
     pub fn lub_free_regions(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> Region<'tcx> {
diff --git a/src/librustc_infer/infer/freshen.rs b/src/librustc_infer/infer/freshen.rs
index c9ed687eaf2..b4cfcb3a1c3 100644
--- a/src/librustc_infer/infer/freshen.rs
+++ b/src/librustc_infer/infer/freshen.rs
@@ -127,7 +127,6 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
             ty::ReStatic
             | ty::ReEarlyBound(..)
             | ty::ReFree(_)
-            | ty::ReScope(_)
             | ty::ReVar(_)
             | ty::RePlaceholder(..)
             | ty::ReEmpty(_)
diff --git a/src/librustc_infer/infer/lexical_region_resolve/graphviz.rs b/src/librustc_infer/infer/lexical_region_resolve/graphviz.rs
deleted file mode 100644
index 5d3e8f440d6..00000000000
--- a/src/librustc_infer/infer/lexical_region_resolve/graphviz.rs
+++ /dev/null
@@ -1,253 +0,0 @@
-//! This module provides linkage between libgraphviz traits and
-//! `rustc_trait_selection::infer::region_constraints`, generating a
-//! rendering of the graph represented by the list of `Constraint`
-//! instances (which make up the edges of the graph), as well as the
-//! origin for each constraint (which are attached to the labels on
-//! each edge).
-
-/// For clarity, rename the graphviz crate locally to dot.
-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::region;
-use rustc_middle::ty;
-
-use std::borrow::Cow;
-use std::collections::btree_map::BTreeMap;
-use std::collections::hash_map::Entry::Vacant;
-use std::env;
-use std::fs;
-use std::io;
-use std::sync::atomic::{AtomicBool, Ordering};
-
-fn print_help_message() {
-    println!(
-        "\
--Z print-region-graph by default prints a region constraint graph for every \n\
-function body, to the path `constraints.nodeXXX.dot`, where the XXX is \n\
-replaced with the node id of the function under analysis.                   \n\
-                                                                            \n\
-To select one particular function body, set `RUST_REGION_GRAPH_NODE=XXX`,   \n\
-where XXX is the node id desired.                                           \n\
-                                                                            \n\
-To generate output to some path other than the default                      \n\
-`constraints.nodeXXX.dot`, set `RUST_REGION_GRAPH=/path/desired.dot`;  \n\
-occurrences of the character `%` in the requested path will be replaced with\n\
-the node id of the function under analysis.                                 \n\
-                                                                            \n\
-(Since you requested help via RUST_REGION_GRAPH=help, no region constraint  \n\
-graphs will be printed.                                                     \n\
-"
-    );
-}
-
-pub fn maybe_print_constraints_for<'a, 'tcx>(
-    region_data: &RegionConstraintData<'tcx>,
-    region_rels: &RegionRelations<'a, 'tcx>,
-) {
-    let tcx = region_rels.tcx;
-    let context = region_rels.context;
-
-    if !tcx.sess.opts.debugging_opts.print_region_graph {
-        return;
-    }
-
-    let requested_node = env::var("RUST_REGION_GRAPH_NODE")
-        .ok()
-        .and_then(|s| s.parse().map(DefIndex::from_u32).ok());
-
-    if requested_node.is_some() && requested_node != Some(context.index) {
-        return;
-    }
-
-    let requested_output = env::var("RUST_REGION_GRAPH");
-    debug!("requested_output: {:?} requested_node: {:?}", requested_output, requested_node);
-
-    let output_path = {
-        let output_template = match requested_output {
-            Ok(ref s) if s == "help" => {
-                static PRINTED_YET: AtomicBool = AtomicBool::new(false);
-                if !PRINTED_YET.load(Ordering::SeqCst) {
-                    print_help_message();
-                    PRINTED_YET.store(true, Ordering::SeqCst);
-                }
-                return;
-            }
-
-            Ok(other_path) => other_path,
-            Err(_) => "constraints.node%.dot".to_string(),
-        };
-
-        if output_template.is_empty() {
-            panic!("empty string provided as RUST_REGION_GRAPH");
-        }
-
-        if output_template.contains('%') {
-            let mut new_str = String::new();
-            for c in output_template.chars() {
-                if c == '%' {
-                    new_str.push_str(&context.index.as_u32().to_string());
-                } else {
-                    new_str.push(c);
-                }
-            }
-            new_str
-        } else {
-            output_template
-        }
-    };
-
-    if let Err(e) = dump_region_data_to(region_rels, &region_data.constraints, &output_path) {
-        let msg = format!("io error dumping region constraints: {}", e);
-        tcx.sess.err(&msg)
-    }
-}
-
-struct ConstraintGraph<'a, 'tcx> {
-    graph_name: String,
-    region_rels: &'a RegionRelations<'a, 'tcx>,
-    map: &'a BTreeMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,
-    node_ids: FxHashMap<Node, usize>,
-}
-
-#[derive(Clone, Hash, PartialEq, Eq, Debug, Copy)]
-enum Node {
-    RegionVid(ty::RegionVid),
-    Region(ty::RegionKind),
-}
-
-#[derive(Clone, PartialEq, Eq, Debug, Copy)]
-enum Edge<'tcx> {
-    Constraint(Constraint<'tcx>),
-    EnclScope(region::Scope, region::Scope),
-}
-
-impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> {
-    fn new(
-        name: String,
-        region_rels: &'a RegionRelations<'a, 'tcx>,
-        map: &'a ConstraintMap<'tcx>,
-    ) -> ConstraintGraph<'a, 'tcx> {
-        let mut i = 0;
-        let mut node_ids = FxHashMap::default();
-        {
-            let mut add_node = |node| {
-                if let Vacant(e) = node_ids.entry(node) {
-                    e.insert(i);
-                    i += 1;
-                }
-            };
-
-            for (n1, n2) in map.keys().map(|c| constraint_to_nodes(c)) {
-                add_node(n1);
-                add_node(n2);
-            }
-
-            region_rels.region_scope_tree.each_encl_scope(|sub, sup| {
-                add_node(Node::Region(ty::ReScope(sub)));
-                add_node(Node::Region(ty::ReScope(sup)));
-            });
-        }
-
-        ConstraintGraph { map, node_ids, region_rels, graph_name: name }
-    }
-}
-
-impl<'a, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'tcx> {
-    type Node = Node;
-    type Edge = Edge<'tcx>;
-    fn graph_id(&self) -> dot::Id<'_> {
-        dot::Id::new(&*self.graph_name).unwrap()
-    }
-    fn node_id(&self, n: &Node) -> dot::Id<'_> {
-        let node_id = match self.node_ids.get(n) {
-            Some(node_id) => node_id,
-            None => bug!("no node_id found for node: {:?}", n),
-        };
-        let name = || format!("node_{}", node_id);
-
-        dot::Id::new(name())
-            .unwrap_or_else(|_| bug!("failed to create graphviz node identified by {}", name()))
-    }
-    fn node_label(&self, n: &Node) -> dot::LabelText<'_> {
-        match *n {
-            Node::RegionVid(n_vid) => dot::LabelText::label(format!("{:?}", n_vid)),
-            Node::Region(n_rgn) => dot::LabelText::label(format!("{:?}", n_rgn)),
-        }
-    }
-    fn edge_label(&self, e: &Edge<'_>) -> dot::LabelText<'_> {
-        match *e {
-            Edge::Constraint(ref c) => {
-                dot::LabelText::label(format!("{:?}", self.map.get(c).unwrap()))
-            }
-            Edge::EnclScope(..) => dot::LabelText::label("(enclosed)".to_owned()),
-        }
-    }
-}
-
-fn constraint_to_nodes(c: &Constraint<'_>) -> (Node, Node) {
-    match *c {
-        Constraint::VarSubVar(rv_1, rv_2) => (Node::RegionVid(rv_1), Node::RegionVid(rv_2)),
-        Constraint::RegSubVar(r_1, rv_2) => (Node::Region(*r_1), Node::RegionVid(rv_2)),
-        Constraint::VarSubReg(rv_1, r_2) => (Node::RegionVid(rv_1), Node::Region(*r_2)),
-        Constraint::RegSubReg(r_1, r_2) => (Node::Region(*r_1), Node::Region(*r_2)),
-    }
-}
-
-fn edge_to_nodes(e: &Edge<'_>) -> (Node, Node) {
-    match *e {
-        Edge::Constraint(ref c) => constraint_to_nodes(c),
-        Edge::EnclScope(sub, sup) => {
-            (Node::Region(ty::ReScope(sub)), Node::Region(ty::ReScope(sup)))
-        }
-    }
-}
-
-impl<'a, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'tcx> {
-    type Node = Node;
-    type Edge = Edge<'tcx>;
-    fn nodes(&self) -> dot::Nodes<'_, Node> {
-        let set = self.node_ids.keys().cloned().collect::<FxHashSet<_>>();
-        debug!("constraint graph has {} nodes", set.len());
-        set.into_iter().collect()
-    }
-    fn edges(&self) -> dot::Edges<'_, Edge<'tcx>> {
-        debug!("constraint graph has {} edges", self.map.len());
-        let mut v: Vec<_> = self.map.keys().map(|e| Edge::Constraint(*e)).collect();
-        self.region_rels
-            .region_scope_tree
-            .each_encl_scope(|sub, sup| v.push(Edge::EnclScope(sub, sup)));
-        debug!("region graph has {} edges", v.len());
-        Cow::Owned(v)
-    }
-    fn source(&self, edge: &Edge<'tcx>) -> Node {
-        let (n1, _) = edge_to_nodes(edge);
-        debug!("edge {:?} has source {:?}", edge, n1);
-        n1
-    }
-    fn target(&self, edge: &Edge<'tcx>) -> Node {
-        let (_, n2) = edge_to_nodes(edge);
-        debug!("edge {:?} has target {:?}", edge, n2);
-        n2
-    }
-}
-
-pub type ConstraintMap<'tcx> = BTreeMap<Constraint<'tcx>, SubregionOrigin<'tcx>>;
-
-fn dump_region_data_to<'a, 'tcx>(
-    region_rels: &RegionRelations<'a, 'tcx>,
-    map: &ConstraintMap<'tcx>,
-    path: &str,
-) -> io::Result<()> {
-    debug!("dump_region_data map (len: {}) path: {}", map.len(), path);
-    let g = ConstraintGraph::new("region_data".to_string(), region_rels, map);
-    debug!("dump_region_data calling render");
-    let mut v = Vec::new();
-    dot::render(&g, &mut v).unwrap();
-    fs::write(path, &v)
-}
diff --git a/src/librustc_infer/infer/lexical_region_resolve/mod.rs b/src/librustc_infer/infer/lexical_region_resolve/mod.rs
index 33a80fb7471..fcf1949933b 100644
--- a/src/librustc_infer/infer/lexical_region_resolve/mod.rs
+++ b/src/librustc_infer/infer/lexical_region_resolve/mod.rs
@@ -18,13 +18,11 @@ use rustc_index::vec::{Idx, IndexVec};
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::ty::{ReEarlyBound, ReEmpty, ReErased, ReFree, ReStatic};
-use rustc_middle::ty::{ReLateBound, RePlaceholder, ReScope, ReVar};
+use rustc_middle::ty::{ReLateBound, RePlaceholder, ReVar};
 use rustc_middle::ty::{Region, RegionVid};
 use rustc_span::Span;
 use std::fmt;
 
-mod graphviz;
-
 /// This function performs lexical region resolution given a complete
 /// set of constraints and variable origins. It performs a fixed-point
 /// iteration to find region values which satisfy all constraints,
@@ -49,7 +47,10 @@ pub fn resolve<'tcx>(
             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.values.iter_mut().for_each(|v| match *v {
+                VarValue::Value(ref mut r) => *r = re_erased,
+                VarValue::ErrorValue => {}
+            });
             (values, errors)
         }
         RegionckMode::Erase { suppress_errors: true } => {
@@ -146,7 +147,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
             self.region_rels.context,
             self.dump_constraints(self.region_rels)
         );
-        graphviz::maybe_print_constraints_for(&self.data, self.region_rels);
 
         let graph = self.construct_graph();
         self.expand_givens(&graph);
@@ -290,8 +290,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
 
         // Find all the "upper bounds" -- that is, each region `b` such that
         // `r0 <= b` must hold.
-        let (member_upper_bounds, _) =
-            self.collect_concrete_regions(graph, member_vid, OUTGOING, None);
+        let (member_upper_bounds, ..) =
+            self.collect_bounding_regions(graph, member_vid, OUTGOING, None);
 
         // Get an iterator over the *available choice* -- that is,
         // each choice region `c` where `lb <= c` and `c <= ub` for all the
@@ -423,15 +423,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
 
         match *b_data {
             VarValue::Value(cur_region) => {
-                // Identical scopes can show up quite often, if the fixed point
-                // iteration converges slowly. Skip them. This is purely an
-                // optimization.
-                if let (ReScope(a_scope), ReScope(cur_scope)) = (a_region, cur_region) {
-                    if a_scope == cur_scope {
-                        return false;
-                    }
-                }
-
                 // This is a specialized version of the `lub_concrete_regions`
                 // check below for a common case, here purely as an
                 // optimization.
@@ -525,8 +516,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
                 self.tcx().lifetimes.re_static
             }
 
-            (&ReEmpty(_), r @ (ReEarlyBound(_) | ReFree(_) | ReScope(_)))
-            | (r @ (ReEarlyBound(_) | ReFree(_) | ReScope(_)), &ReEmpty(_)) => {
+            (&ReEmpty(_), r @ (ReEarlyBound(_) | ReFree(_)))
+            | (r @ (ReEarlyBound(_) | ReFree(_)), &ReEmpty(_)) => {
                 // All empty regions are less than early-bound, free,
                 // and scope regions.
                 r
@@ -551,46 +542,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
                 }
             }
 
-            (&ReEarlyBound(_) | &ReFree(_), &ReScope(s_id))
-            | (&ReScope(s_id), &ReEarlyBound(_) | &ReFree(_)) => {
-                // A "free" region can be interpreted as "some region
-                // at least as big as fr.scope".  So, we can
-                // reasonably compare free regions and scopes:
-                let fr_scope = match (a, b) {
-                    (&ReEarlyBound(ref br), _) | (_, &ReEarlyBound(ref br)) => {
-                        self.region_rels.region_scope_tree.early_free_scope(self.tcx(), br)
-                    }
-                    (&ReFree(ref fr), _) | (_, &ReFree(ref fr)) => {
-                        self.region_rels.region_scope_tree.free_scope(self.tcx(), fr)
-                    }
-                    _ => bug!(),
-                };
-                let r_id =
-                    self.region_rels.region_scope_tree.nearest_common_ancestor(fr_scope, s_id);
-                if r_id == fr_scope {
-                    // if the free region's scope `fr.scope` is bigger than
-                    // the scope region `s_id`, then the LUB is the free
-                    // region itself:
-                    match (a, b) {
-                        (_, &ReScope(_)) => return a,
-                        (&ReScope(_), _) => return b,
-                        _ => bug!(),
-                    }
-                }
-
-                // otherwise, we don't know what the free region is,
-                // so we must conservatively say the LUB is static:
-                self.tcx().lifetimes.re_static
-            }
-
-            (&ReScope(a_id), &ReScope(b_id)) => {
-                // The region corresponding to an outer block is a
-                // subtype of the region corresponding to an inner
-                // block.
-                let lub = self.region_rels.region_scope_tree.nearest_common_ancestor(a_id, b_id);
-                self.tcx().mk_region(ReScope(lub))
-            }
-
             (&ReEarlyBound(_) | &ReFree(_), &ReEarlyBound(_) | &ReFree(_)) => {
                 self.region_rels.lub_free_regions(a, b)
             }
@@ -659,7 +610,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
                     if !self.sub_concrete_regions(a_region, b_region) {
                         debug!(
                             "collect_errors: region error at {:?}: \
-                             cannot verify that {:?}={:?} <= {:?}",
+                            cannot verify that {:?}={:?} <= {:?}",
                             origin, a_vid, a_region, b_region
                         );
                         *a_data = VarValue::ErrorValue;
@@ -716,7 +667,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
         graph: &RegionGraph<'tcx>,
         errors: &mut Vec<RegionResolutionError<'tcx>>,
     ) {
-        debug!("collect_var_errors");
+        debug!("collect_var_errors, var_data = {:#?}", var_data.values);
 
         // This is the best way that I have found to suppress
         // duplicate and related errors. Basically we keep a set of
@@ -815,10 +766,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
     ) {
         // Errors in expanding nodes result from a lower-bound that is
         // not contained by an upper-bound.
-        let (mut lower_bounds, lower_dup) =
-            self.collect_concrete_regions(graph, node_idx, INCOMING, Some(dup_vec));
-        let (mut upper_bounds, upper_dup) =
-            self.collect_concrete_regions(graph, node_idx, OUTGOING, Some(dup_vec));
+        let (mut lower_bounds, lower_vid_bounds, lower_dup) =
+            self.collect_bounding_regions(graph, node_idx, INCOMING, Some(dup_vec));
+        let (mut upper_bounds, _, upper_dup) =
+            self.collect_bounding_regions(graph, node_idx, OUTGOING, Some(dup_vec));
 
         if lower_dup || upper_dup {
             return;
@@ -874,15 +825,22 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
         // If we have a scenario like `exists<'a> { forall<'b> { 'b:
         // 'a } }`, we wind up without any lower-bound -- all we have
         // are placeholders as upper bounds, but the universe of the
-        // variable `'a` doesn't permit those placeholders.
+        // variable `'a`, or some variable that `'a` has to outlive, doesn't
+        // permit those placeholders.
+        let min_universe = lower_vid_bounds
+            .into_iter()
+            .map(|vid| self.var_infos[vid].universe)
+            .min()
+            .expect("lower_vid_bounds should at least include `node_idx`");
+
         for upper_bound in &upper_bounds {
             if let ty::RePlaceholder(p) = upper_bound.region {
-                if node_universe.cannot_name(p.universe) {
+                if min_universe.cannot_name(p.universe) {
                     let origin = self.var_infos[node_idx].origin;
                     errors.push(RegionResolutionError::UpperBoundUniverseConflict(
                         node_idx,
                         origin,
-                        node_universe,
+                        min_universe,
                         upper_bound.origin.clone(),
                         upper_bound.region,
                     ));
@@ -904,13 +862,24 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
         );
     }
 
-    fn collect_concrete_regions(
+    /// Collects all regions that "bound" the variable `orig_node_idx` in the
+    /// given direction.
+    ///
+    /// If `dup_vec` is `Some` it's used to track duplicates between successive
+    /// calls of this function.
+    ///
+    /// The return tuple fields are:
+    /// - a list of all concrete regions bounding the given region.
+    /// - the set of all region variables bounding the given region.
+    /// - a `bool` that's true if the returned region variables overlap with
+    ///   those returned by a previous call for another region.
+    fn collect_bounding_regions(
         &self,
         graph: &RegionGraph<'tcx>,
         orig_node_idx: RegionVid,
         dir: Direction,
         mut dup_vec: Option<&mut IndexVec<RegionVid, Option<RegionVid>>>,
-    ) -> (Vec<RegionAndOrigin<'tcx>>, bool) {
+    ) -> (Vec<RegionAndOrigin<'tcx>>, FxHashSet<RegionVid>, bool) {
         struct WalkState<'tcx> {
             set: FxHashSet<RegionVid>,
             stack: Vec<RegionVid>,
@@ -929,9 +898,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
         // direction specified
         process_edges(&self.data, &mut state, graph, orig_node_idx, dir);
 
-        while !state.stack.is_empty() {
-            let node_idx = state.stack.pop().unwrap();
-
+        while let Some(node_idx) = state.stack.pop() {
             // check whether we've visited this node on some previous walk
             if let Some(dup_vec) = &mut dup_vec {
                 if dup_vec[node_idx].is_none() {
@@ -949,8 +916,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
             process_edges(&self.data, &mut state, graph, node_idx, dir);
         }
 
-        let WalkState { result, dup_found, .. } = state;
-        return (result, dup_found);
+        let WalkState { result, dup_found, set, .. } = state;
+        return (result, set, dup_found);
 
         fn process_edges<'tcx>(
             this: &RegionConstraintData<'tcx>,
diff --git a/src/librustc_infer/infer/mod.rs b/src/librustc_infer/infer/mod.rs
index 9c81a115395..30af7d06744 100644
--- a/src/librustc_infer/infer/mod.rs
+++ b/src/librustc_infer/infer/mod.rs
@@ -20,7 +20,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::region;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::ConstEvalResult;
 use rustc_middle::traits::select;
@@ -378,22 +377,6 @@ pub enum SubregionOrigin<'tcx> {
     /// Arose from a subtyping relation
     Subtype(Box<TypeTrace<'tcx>>),
 
-    /// Stack-allocated closures cannot outlive innermost loop
-    /// or function so as to ensure we only require finite stack
-    InfStackClosure(Span),
-
-    /// Invocation of closure must be within its lifetime
-    InvokeClosure(Span),
-
-    /// Dereference of reference must be within its lifetime
-    DerefPointer(Span),
-
-    /// Closure bound must not outlive captured variables
-    ClosureCapture(Span, hir::HirId),
-
-    /// Index into slice must be within its lifetime
-    IndexSlice(Span),
-
     /// When casting `&'a T` to an `&'b Trait` object,
     /// relating `'a` to `'b`
     RelateObjectBound(Span),
@@ -406,10 +389,6 @@ pub enum SubregionOrigin<'tcx> {
     /// that must outlive some other region.
     RelateRegionParamBound(Span),
 
-    /// A bound placed on type parameters that states that must outlive
-    /// the moment of their instantiation.
-    RelateDefaultParamBound(Span, Ty<'tcx>),
-
     /// Creating a pointer `b` to contents of another reference
     Reborrow(Span),
 
@@ -422,36 +401,9 @@ pub enum SubregionOrigin<'tcx> {
     /// (&'a &'b T) where a >= b
     ReferenceOutlivesReferent(Ty<'tcx>, Span),
 
-    /// Type or region parameters must be in scope.
-    ParameterInScope(ParameterOrigin, Span),
-
-    /// The type T of an expression E must outlive the lifetime for E.
-    ExprTypeIsNotInScope(Ty<'tcx>, Span),
-
-    /// A `ref b` whose region does not enclose the decl site
-    BindingTypeIsNotValidAtDecl(Span),
-
-    /// Regions appearing in a method receiver must outlive method call
-    CallRcvr(Span),
-
-    /// Regions appearing in a function argument must outlive func call
-    CallArg(Span),
-
     /// Region in return type of invoked fn must enclose call
     CallReturn(Span),
 
-    /// Operands must be in scope
-    Operand(Span),
-
-    /// Region resulting from a `&` expr must enclose the `&` expr
-    AddrOf(Span),
-
-    /// An auto-borrow that does not enclose the expr where it occurs
-    AutoBorrow(Span),
-
-    /// Region constraint arriving from destructor safety
-    SafeDestructor(Span),
-
     /// Comparing the signature and requirements of an impl method against
     /// the containing trait.
     CompareImplMethodObligation {
@@ -1260,7 +1212,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     pub fn resolve_regions_and_report_errors(
         &self,
         region_context: DefId,
-        region_map: &region::ScopeTree,
         outlives_env: &OutlivesEnvironment<'tcx>,
         mode: RegionckMode,
     ) {
@@ -1280,12 +1231,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 .into_infos_and_data()
         };
 
-        let region_rels = &RegionRelations::new(
-            self.tcx,
-            region_context,
-            region_map,
-            outlives_env.free_region_map(),
-        );
+        let region_rels =
+            &RegionRelations::new(self.tcx, region_context, outlives_env.free_region_map());
 
         let (lexical_region_resolutions, errors) =
             lexical_region_resolve::resolve(region_rels, var_infos, data, mode);
@@ -1299,7 +1246,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);
+            self.report_region_errors(&errors);
         }
     }
 
@@ -1809,29 +1756,14 @@ impl<'tcx> SubregionOrigin<'tcx> {
     pub fn span(&self) -> Span {
         match *self {
             Subtype(ref a) => a.span(),
-            InfStackClosure(a) => a,
-            InvokeClosure(a) => a,
-            DerefPointer(a) => a,
-            ClosureCapture(a, _) => a,
-            IndexSlice(a) => a,
             RelateObjectBound(a) => a,
             RelateParamBound(a, _) => a,
             RelateRegionParamBound(a) => a,
-            RelateDefaultParamBound(a, _) => a,
             Reborrow(a) => a,
             ReborrowUpvar(a, _) => a,
             DataBorrowed(_, a) => a,
             ReferenceOutlivesReferent(_, a) => a,
-            ParameterInScope(_, a) => a,
-            ExprTypeIsNotInScope(_, a) => a,
-            BindingTypeIsNotValidAtDecl(a) => a,
-            CallRcvr(a) => a,
-            CallArg(a) => a,
             CallReturn(a) => a,
-            Operand(a) => a,
-            AddrOf(a) => a,
-            AutoBorrow(a) => a,
-            SafeDestructor(a) => a,
             CompareImplMethodObligation { span, .. } => span,
         }
     }
diff --git a/src/librustc_infer/infer/region_constraints/mod.rs b/src/librustc_infer/infer/region_constraints/mod.rs
index 3983e557179..f45b2242755 100644
--- a/src/librustc_infer/infer/region_constraints/mod.rs
+++ b/src/librustc_infer/infer/region_constraints/mod.rs
@@ -758,11 +758,9 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
 
     pub fn universe(&self, region: Region<'tcx>) -> ty::UniverseIndex {
         match *region {
-            ty::ReScope(..)
-            | ty::ReStatic
-            | ty::ReErased
-            | ty::ReFree(..)
-            | ty::ReEarlyBound(..) => ty::UniverseIndex::ROOT,
+            ty::ReStatic | ty::ReErased | ty::ReFree(..) | ty::ReEarlyBound(..) => {
+                ty::UniverseIndex::ROOT
+            }
             ty::ReEmpty(ui) => ui,
             ty::RePlaceholder(placeholder) => placeholder.universe,
             ty::ReVar(vid) => self.var_universe(vid),
diff --git a/src/librustc_middle/ich/impls_ty.rs b/src/librustc_middle/ich/impls_ty.rs
index 377c8661cbd..ef6247881c0 100644
--- a/src/librustc_middle/ich/impls_ty.rs
+++ b/src/librustc_middle/ich/impls_ty.rs
@@ -87,9 +87,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionKind {
                 index.hash_stable(hcx, hasher);
                 name.hash_stable(hcx, hasher);
             }
-            ty::ReScope(scope) => {
-                scope.hash_stable(hcx, hasher);
-            }
             ty::ReFree(ref free_region) => {
                 free_region.hash_stable(hcx, hasher);
             }
diff --git a/src/librustc_middle/middle/region.rs b/src/librustc_middle/middle/region.rs
index f02d8fe8ad6..943a065a8b5 100644
--- a/src/librustc_middle/middle/region.rs
+++ b/src/librustc_middle/middle/region.rs
@@ -7,7 +7,7 @@
 //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/borrow_check.html
 
 use crate::ich::{NodeIdHashingMode, StableHashingContext};
-use crate::ty::{self, DefIdTree, TyCtxt};
+use crate::ty::TyCtxt;
 use rustc_hir as hir;
 use rustc_hir::Node;
 
@@ -333,7 +333,7 @@ pub struct YieldData {
     pub source: hir::YieldSource,
 }
 
-impl<'tcx> ScopeTree {
+impl ScopeTree {
     pub fn record_scope_parent(&mut self, child: Scope, parent: Option<(Scope, ScopeDepth)>) {
         debug!("{:?}.parent = {:?}", child, parent);
 
@@ -348,24 +348,6 @@ impl<'tcx> ScopeTree {
         }
     }
 
-    pub fn each_encl_scope<E>(&self, mut e: E)
-    where
-        E: FnMut(Scope, Scope),
-    {
-        for (&child, &parent) in &self.parent_map {
-            e(child, parent.0)
-        }
-    }
-
-    pub fn each_var_scope<E>(&self, mut e: E)
-    where
-        E: FnMut(&hir::ItemLocalId, Scope),
-    {
-        for (child, &parent) in self.var_map.iter() {
-            e(child, parent)
-        }
-    }
-
     pub fn opt_destruction_scope(&self, n: hir::ItemLocalId) -> Option<Scope> {
         self.destruction_scopes.get(&n).cloned()
     }
@@ -406,12 +388,6 @@ impl<'tcx> ScopeTree {
         self.parent_map.get(&id).cloned().map(|(p, _)| p)
     }
 
-    /// Returns the narrowest scope that encloses `id`, if any.
-    #[allow(dead_code)] // used in cfg
-    pub fn encl_scope(&self, id: Scope) -> Scope {
-        self.opt_encl_scope(id).unwrap()
-    }
-
     /// Returns the lifetime of the local variable `var_id`
     pub fn var_scope(&self, var_id: hir::ItemLocalId) -> Scope {
         self.var_map
@@ -448,17 +424,6 @@ impl<'tcx> ScopeTree {
         None
     }
 
-    /// Returns the lifetime of the variable `id`.
-    pub fn var_region(&self, id: hir::ItemLocalId) -> ty::RegionKind {
-        let scope = ty::ReScope(self.var_scope(id));
-        debug!("var_region({:?}) = {:?}", id, scope);
-        scope
-    }
-
-    pub fn scopes_intersect(&self, scope1: Scope, scope2: Scope) -> bool {
-        self.is_subscope_of(scope1, scope2) || self.is_subscope_of(scope2, scope1)
-    }
-
     /// Returns `true` if `subscope` is equal to or is lexically nested inside `superscope`, and
     /// `false` otherwise.
     pub fn is_subscope_of(&self, subscope: Scope, superscope: Scope) -> bool {
@@ -479,127 +444,6 @@ impl<'tcx> ScopeTree {
         true
     }
 
-    /// Returns the ID of the innermost containing body.
-    pub fn containing_body(&self, mut scope: Scope) -> Option<hir::ItemLocalId> {
-        loop {
-            if let ScopeData::CallSite = scope.data {
-                return Some(scope.item_local_id());
-            }
-
-            scope = self.opt_encl_scope(scope)?;
-        }
-    }
-
-    /// Finds the nearest common ancestor of two scopes. That is, finds the
-    /// smallest scope which is greater than or equal to both `scope_a` and
-    /// `scope_b`.
-    pub fn nearest_common_ancestor(&self, scope_a: Scope, scope_b: Scope) -> Scope {
-        if scope_a == scope_b {
-            return scope_a;
-        }
-
-        let mut a = scope_a;
-        let mut b = scope_b;
-
-        // Get the depth of each scope's parent. If either scope has no parent,
-        // it must be the root, which means we can stop immediately because the
-        // root must be the nearest common ancestor. (In practice, this is
-        // moderately common.)
-        let (parent_a, parent_a_depth) = match self.parent_map.get(&a) {
-            Some(pd) => *pd,
-            None => return a,
-        };
-        let (parent_b, parent_b_depth) = match self.parent_map.get(&b) {
-            Some(pd) => *pd,
-            None => return b,
-        };
-
-        if parent_a_depth > parent_b_depth {
-            // `a` is lower than `b`. Move `a` up until it's at the same depth
-            // as `b`. The first move up is trivial because we already found
-            // `parent_a` above; the loop does the remaining N-1 moves.
-            a = parent_a;
-            for _ in 0..(parent_a_depth - parent_b_depth - 1) {
-                a = self.parent_map.get(&a).unwrap().0;
-            }
-        } else if parent_b_depth > parent_a_depth {
-            // `b` is lower than `a`.
-            b = parent_b;
-            for _ in 0..(parent_b_depth - parent_a_depth - 1) {
-                b = self.parent_map.get(&b).unwrap().0;
-            }
-        } else {
-            // Both scopes are at the same depth, and we know they're not equal
-            // because that case was tested for at the top of this function. So
-            // we can trivially move them both up one level now.
-            assert!(parent_a_depth != 0);
-            a = parent_a;
-            b = parent_b;
-        }
-
-        // Now both scopes are at the same level. We move upwards in lockstep
-        // until they match. In practice, this loop is almost always executed
-        // zero times because `a` is almost always a direct ancestor of `b` or
-        // vice versa.
-        while a != b {
-            a = self.parent_map.get(&a).unwrap().0;
-            b = self.parent_map.get(&b).unwrap().0;
-        }
-
-        a
-    }
-
-    /// Assuming that the provided region was defined within this `ScopeTree`,
-    /// returns the outermost `Scope` that the region outlives.
-    pub fn early_free_scope(&self, tcx: TyCtxt<'tcx>, br: &ty::EarlyBoundRegion) -> Scope {
-        let param_owner = tcx.parent(br.def_id).unwrap();
-
-        let param_owner_id = tcx.hir().as_local_hir_id(param_owner.expect_local());
-        let scope = tcx
-            .hir()
-            .maybe_body_owned_by(param_owner_id)
-            .map(|body_id| tcx.hir().body(body_id).value.hir_id.local_id)
-            .unwrap_or_else(|| {
-                // The lifetime was defined on node that doesn't own a body,
-                // which in practice can only mean a trait or an impl, that
-                // is the parent of a method, and that is enforced below.
-                if Some(param_owner_id) != self.root_parent {
-                    tcx.sess.delay_span_bug(
-                        DUMMY_SP,
-                        &format!(
-                            "free_scope: {:?} not recognized by the \
-                              region scope tree for {:?} / {:?}",
-                            param_owner,
-                            self.root_parent.map(|id| tcx.hir().local_def_id(id)),
-                            self.root_body.map(|hir_id| hir_id.owner)
-                        ),
-                    );
-                }
-
-                // The trait/impl lifetime is in scope for the method's body.
-                self.root_body.unwrap().local_id
-            });
-
-        Scope { id: scope, data: ScopeData::CallSite }
-    }
-
-    /// Assuming that the provided region was defined within this `ScopeTree`,
-    /// returns the outermost `Scope` that the region outlives.
-    pub fn free_scope(&self, tcx: TyCtxt<'tcx>, fr: &ty::FreeRegion) -> Scope {
-        let param_owner = match fr.bound_region {
-            ty::BoundRegion::BrNamed(def_id, _) => tcx.parent(def_id).unwrap(),
-            _ => fr.scope,
-        };
-
-        // Ensure that the named late-bound lifetimes were defined
-        // on the same function that they ended up being freed in.
-        assert_eq!(param_owner, fr.scope);
-
-        let param_owner_id = tcx.hir().as_local_hir_id(param_owner.expect_local());
-        let body_id = tcx.hir().body_owned_by(param_owner_id);
-        Scope { id: tcx.hir().body(body_id).value.hir_id.local_id, data: ScopeData::CallSite }
-    }
-
     /// Checks whether the given scope contains a `yield`. If so,
     /// returns `Some((span, expr_count))` with the span of a yield we found and
     /// the number of expressions and patterns appearing before the `yield` in the body + 1.
diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs
index 68c31c68075..5b53ab1778e 100644
--- a/src/librustc_middle/ty/context.rs
+++ b/src/librustc_middle/ty/context.rs
@@ -35,7 +35,6 @@ use crate::ty::{InferTy, ParamTy, PolyFnSig, ProjectionTy};
 use crate::ty::{List, TyKind, TyS};
 use rustc_ast::ast;
 use rustc_ast::expand::allocator::AllocatorKind;
-use rustc_ast::node_id::NodeMap;
 use rustc_attr as attr;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::profiling::SelfProfilerRef;
@@ -926,7 +925,7 @@ pub struct GlobalCtxt<'tcx> {
     pub consts: CommonConsts<'tcx>,
 
     /// Resolutions of `extern crate` items produced by resolver.
-    extern_crate_map: NodeMap<CrateNum>,
+    extern_crate_map: FxHashMap<DefId, CrateNum>,
 
     /// Map indicating what traits are in scope for places where this
     /// is relevant; generated by resolve.
@@ -1116,13 +1115,8 @@ impl<'tcx> TyCtxt<'tcx> {
         };
 
         let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default();
-        for (k, v) in resolutions.trait_map {
-            let hir_id = definitions.node_id_to_hir_id(k);
+        for (hir_id, v) in resolutions.trait_map.into_iter() {
             let map = trait_map.entry(hir_id.owner).or_default();
-            let v = v
-                .into_iter()
-                .map(|tc| tc.map_import_ids(|id| definitions.node_id_to_hir_id(id)))
-                .collect();
             map.insert(hir_id.local_id, StableVec::new(v));
         }
 
@@ -1139,32 +1133,10 @@ impl<'tcx> TyCtxt<'tcx> {
             consts: common_consts,
             extern_crate_map: resolutions.extern_crate_map,
             trait_map,
-            export_map: resolutions
-                .export_map
-                .into_iter()
-                .map(|(k, v)| {
-                    let exports: Vec<_> = v
-                        .into_iter()
-                        .map(|e| e.map_id(|id| definitions.node_id_to_hir_id(id)))
-                        .collect();
-                    (k, exports)
-                })
-                .collect(),
-            maybe_unused_trait_imports: resolutions
-                .maybe_unused_trait_imports
-                .into_iter()
-                .map(|id| definitions.local_def_id(id))
-                .collect(),
-            maybe_unused_extern_crates: resolutions
-                .maybe_unused_extern_crates
-                .into_iter()
-                .map(|(id, sp)| (definitions.local_def_id(id).to_def_id(), sp))
-                .collect(),
-            glob_map: resolutions
-                .glob_map
-                .into_iter()
-                .map(|(id, names)| (definitions.local_def_id(id), names))
-                .collect(),
+            export_map: resolutions.export_map,
+            maybe_unused_trait_imports: resolutions.maybe_unused_trait_imports,
+            maybe_unused_extern_crates: resolutions.maybe_unused_extern_crates,
+            glob_map: resolutions.glob_map,
             extern_prelude: resolutions.extern_prelude,
             untracked_crate: krate,
             definitions,
@@ -2729,10 +2701,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
         let id = tcx.hir().local_def_id_to_hir_id(id.expect_local());
         tcx.stability().local_deprecation_entry(id)
     };
-    providers.extern_mod_stmt_cnum = |tcx, id| {
-        let id = tcx.hir().as_local_node_id(id).unwrap();
-        tcx.extern_crate_map.get(&id).cloned()
-    };
+    providers.extern_mod_stmt_cnum = |tcx, id| tcx.extern_crate_map.get(&id).cloned();
     providers.all_crate_nums = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
         tcx.arena.alloc_slice(&tcx.cstore.crates_untracked())
diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs
index 9e845668909..aad3c6889c3 100644
--- a/src/librustc_middle/ty/mod.rs
+++ b/src/librustc_middle/ty/mod.rs
@@ -17,11 +17,11 @@ use crate::ty;
 use crate::ty::subst::{InternalSubsts, Subst, SubstsRef};
 use crate::ty::util::{Discr, IntTypeExt};
 use rustc_ast::ast;
-use rustc_ast::node_id::{NodeId, NodeMap, NodeSet};
 use rustc_attr as attr;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::sorted_map::SortedIndexMultiMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -31,7 +31,7 @@ use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX};
 use rustc_hir::lang_items::{FnMutTraitLangItem, FnOnceTraitLangItem, FnTraitLangItem};
-use rustc_hir::{Constness, GlobMap, Node, TraitMap};
+use rustc_hir::{Constness, Node};
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_macros::HashStable;
 use rustc_serialize::{self, Encodable, Encoder};
@@ -120,12 +120,12 @@ mod sty;
 pub struct ResolverOutputs {
     pub definitions: rustc_hir::definitions::Definitions,
     pub cstore: Box<CrateStoreDyn>,
-    pub extern_crate_map: NodeMap<CrateNum>,
-    pub trait_map: TraitMap<NodeId>,
-    pub maybe_unused_trait_imports: NodeSet,
-    pub maybe_unused_extern_crates: Vec<(NodeId, Span)>,
-    pub export_map: ExportMap<NodeId>,
-    pub glob_map: GlobMap,
+    pub extern_crate_map: FxHashMap<DefId, CrateNum>,
+    pub trait_map: FxHashMap<hir::HirId, Vec<hir::TraitCandidate<hir::HirId>>>,
+    pub maybe_unused_trait_imports: FxHashSet<LocalDefId>,
+    pub maybe_unused_extern_crates: Vec<(DefId, Span)>,
+    pub export_map: ExportMap<hir::HirId>,
+    pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
     /// Extern prelude entries. The value is `true` if the entry was introduced
     /// via `extern crate` item and not `--extern` option or compiler built-in.
     pub extern_prelude: FxHashMap<Symbol, bool>,
diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs
index f4b795e5488..f03d91aa64b 100644
--- a/src/librustc_middle/ty/print/pretty.rs
+++ b/src/librustc_middle/ty/print/pretty.rs
@@ -1,5 +1,4 @@
 use crate::middle::cstore::{ExternCrate, ExternCrateSource};
-use crate::middle::region;
 use crate::mir::interpret::{sign_extend, truncate, AllocId, ConstValue, Pointer, Scalar};
 use crate::ty::layout::IntegerExt;
 use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
@@ -1588,9 +1587,9 @@ impl<F: fmt::Write> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> {
                 false
             }
 
-            ty::ReScope(_) | ty::ReVar(_) if identify_regions => true,
+            ty::ReVar(_) if identify_regions => true,
 
-            ty::ReVar(_) | ty::ReScope(_) | ty::ReErased => false,
+            ty::ReVar(_) | ty::ReErased => false,
 
             ty::ReStatic | ty::ReEmpty(_) => true,
         }
@@ -1666,32 +1665,12 @@ impl<F: fmt::Write> FmtPrinter<'_, '_, F> {
                     }
                 }
             }
-            ty::ReScope(scope) if identify_regions => {
-                match scope.data {
-                    region::ScopeData::Node => p!(write("'{}s", scope.item_local_id().as_usize())),
-                    region::ScopeData::CallSite => {
-                        p!(write("'{}cs", scope.item_local_id().as_usize()))
-                    }
-                    region::ScopeData::Arguments => {
-                        p!(write("'{}as", scope.item_local_id().as_usize()))
-                    }
-                    region::ScopeData::Destruction => {
-                        p!(write("'{}ds", scope.item_local_id().as_usize()))
-                    }
-                    region::ScopeData::Remainder(first_statement_index) => p!(write(
-                        "'{}_{}rs",
-                        scope.item_local_id().as_usize(),
-                        first_statement_index.index()
-                    )),
-                }
-                return Ok(self);
-            }
             ty::ReVar(region_vid) if identify_regions => {
                 p!(write("{:?}", region_vid));
                 return Ok(self);
             }
             ty::ReVar(_) => {}
-            ty::ReScope(_) | ty::ReErased => {}
+            ty::ReErased => {}
             ty::ReStatic => {
                 p!(write("'static"));
                 return Ok(self);
diff --git a/src/librustc_middle/ty/structural_impls.rs b/src/librustc_middle/ty/structural_impls.rs
index babe0c54801..569a8d90bfc 100644
--- a/src/librustc_middle/ty/structural_impls.rs
+++ b/src/librustc_middle/ty/structural_impls.rs
@@ -87,8 +87,6 @@ impl fmt::Debug for ty::RegionKind {
 
             ty::ReFree(ref fr) => fr.fmt(f),
 
-            ty::ReScope(id) => write!(f, "ReScope({:?})", id),
-
             ty::ReStatic => write!(f, "ReStatic"),
 
             ty::ReVar(ref vid) => vid.fmt(f),
diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs
index 0c9eef8093f..370702f7f22 100644
--- a/src/librustc_middle/ty/sty.rs
+++ b/src/librustc_middle/ty/sty.rs
@@ -6,7 +6,6 @@ use self::InferTy::*;
 use self::TyKind::*;
 
 use crate::infer::canonical::Canonical;
-use crate::middle::region;
 use crate::mir::interpret::ConstValue;
 use crate::mir::interpret::{LitToConstInput, Scalar};
 use crate::mir::Promoted;
@@ -1179,17 +1178,15 @@ rustc_index::newtype_index! {
 
 pub type Region<'tcx> = &'tcx RegionKind;
 
-/// Representation of (lexical) regions. Note that the NLL checker
-/// uses a distinct representation of regions. For this reason, it
-/// internally replaces all the regions with inference variables --
-/// the index of the variable is then used to index into internal NLL
-/// data structures. See `rustc_mir::borrow_check` module for more
-/// information.
+/// Representation of regions. Note that the NLL checker uses a distinct
+/// representation of regions. For this reason, it internally replaces all the
+/// regions with inference variables -- the index of the variable is then used
+/// to index into internal NLL data structures. See `rustc_mir::borrow_check`
+/// module for more information.
 ///
 /// ## The Region lattice within a given function
 ///
-/// In general, the (lexical, and hence deprecated) region lattice
-/// looks like
+/// In general, the region lattice looks like
 ///
 /// ```
 /// static ----------+-----...------+       (greatest)
@@ -1197,7 +1194,6 @@ pub type Region<'tcx> = &'tcx RegionKind;
 /// early-bound and  |              |
 /// free regions     |              |
 /// |                |              |
-/// scope regions    |              |
 /// |                |              |
 /// empty(root)   placeholder(U1)   |
 /// |            /                  |
@@ -1212,13 +1208,7 @@ pub type Region<'tcx> = &'tcx RegionKind;
 /// Early-bound/free regions are the named lifetimes in scope from the
 /// function declaration. They have relationships to one another
 /// determined based on the declared relationships from the
-/// function. They all collectively outlive the scope regions. (See
-/// `RegionRelations` type, and particularly
-/// `crate::infer::outlives::free_region_map::FreeRegionMap`.)
-///
-/// The scope regions are related to one another based on the AST
-/// structure. (See `RegionRelations` type, and particularly the
-/// `rustc_middle::middle::region::ScopeTree`.)
+/// function.
 ///
 /// Note that inference variables and bound regions are not included
 /// in this diagram. In the case of inference variables, they should
@@ -1307,11 +1297,6 @@ pub enum RegionKind {
     /// region parameters.
     ReFree(FreeRegion),
 
-    /// A concrete region naming some statically determined scope
-    /// (e.g., an expression or sequence of statements) within the
-    /// current function.
-    ReScope(region::Scope),
-
     /// Static data that has an "infinite" lifetime. Top in the region lattice.
     ReStatic,
 
@@ -1535,7 +1520,6 @@ impl RegionKind {
             RegionKind::ReEarlyBound(ebr) => ebr.has_name(),
             RegionKind::ReLateBound(_, br) => br.is_named(),
             RegionKind::ReFree(fr) => fr.bound_region.is_named(),
-            RegionKind::ReScope(..) => false,
             RegionKind::ReStatic => true,
             RegionKind::ReVar(..) => false,
             RegionKind::RePlaceholder(placeholder) => placeholder.name.is_named(),
@@ -1616,7 +1600,7 @@ impl RegionKind {
                 flags = flags | TypeFlags::HAS_RE_PARAM;
                 flags = flags | TypeFlags::STILL_FURTHER_SPECIALIZABLE;
             }
-            ty::ReFree { .. } | ty::ReScope { .. } => {
+            ty::ReFree { .. } => {
                 flags = flags | TypeFlags::HAS_FREE_REGIONS;
                 flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
             }
diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs
index ebc8021a3c5..e19fab89eab 100644
--- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs
@@ -162,10 +162,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                     let type_test_span = type_test.locations.span(&self.body);
 
                     if let Some(lower_bound_region) = lower_bound_region {
-                        let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id);
                         self.infcx
                             .construct_generic_bound_failure(
-                                region_scope_tree,
                                 type_test_span,
                                 None,
                                 type_test.generic_kind,
@@ -194,12 +192,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 }
 
                 RegionErrorKind::UnexpectedHiddenRegion { span, hidden_ty, member_region } => {
-                    let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id);
                     let named_ty = self.regioncx.name_regions(self.infcx.tcx, hidden_ty);
                     let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region);
                     unexpected_hidden_region_diagnostic(
                         self.infcx.tcx,
-                        Some(region_scope_tree),
                         span,
                         named_ty,
                         named_region,
diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/src/librustc_mir/borrow_check/diagnostics/region_name.rs
index 37e2e047504..e912ef7b202 100644
--- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/region_name.rs
@@ -284,7 +284,6 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
             },
 
             ty::ReLateBound(..)
-            | ty::ReScope(..)
             | ty::ReVar(..)
             | ty::RePlaceholder(..)
             | ty::ReEmpty(_)
diff --git a/src/librustc_parse/Cargo.toml b/src/librustc_parse/Cargo.toml
index 7164c678808..0d31a8c7bc1 100644
--- a/src/librustc_parse/Cargo.toml
+++ b/src/librustc_parse/Cargo.toml
@@ -12,6 +12,7 @@ doctest = false
 [dependencies]
 bitflags = "1.0"
 log = "0.4"
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 rustc_ast_pretty = { path = "../librustc_ast_pretty" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_feature = { path = "../librustc_feature" }
diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs
index 8e2a9513d6b..0c817a71281 100644
--- a/src/librustc_parse/lib.rs
+++ b/src/librustc_parse/lib.rs
@@ -7,18 +7,22 @@
 #![feature(or_patterns)]
 
 use rustc_ast::ast;
-use rustc_ast::token::{self, Nonterminal};
-use rustc_ast::tokenstream::{self, TokenStream, TokenTree};
+use rustc_ast::token::{self, DelimToken, Nonterminal, Token, TokenKind};
+use rustc_ast::tokenstream::{self, IsJoint, TokenStream, TokenTree};
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Diagnostic, FatalError, Level, PResult};
 use rustc_session::parse::ParseSess;
-use rustc_span::{FileName, SourceFile, Span};
+use rustc_span::symbol::kw;
+use rustc_span::{FileName, SourceFile, Span, DUMMY_SP};
 
+use smallvec::SmallVec;
+
+use std::mem;
 use std::path::Path;
 use std::str;
 
-use log::info;
+use log::{debug, info};
 
 pub const MACRO_ARGUMENTS: Option<&'static str> = Some("macro arguments");
 
@@ -300,7 +304,7 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke
     // modifications, including adding/removing typically non-semantic
     // tokens such as extra braces and commas, don't happen.
     if let Some(tokens) = tokens {
-        if tokens.probably_equal_for_proc_macro(&tokens_for_real) {
+        if tokenstream_probably_equal_for_proc_macro(&tokens, &tokens_for_real, sess) {
             return tokens;
         }
         info!(
@@ -373,3 +377,203 @@ fn prepend_attrs(
     builder.push(tokens.clone());
     Some(builder.build())
 }
+
+// See comments in `Nonterminal::to_tokenstream` for why we care about
+// *probably* equal here rather than actual equality
+//
+// This is otherwise the same as `eq_unspanned`, only recursing with a
+// different method.
+pub fn tokenstream_probably_equal_for_proc_macro(
+    first: &TokenStream,
+    other: &TokenStream,
+    sess: &ParseSess,
+) -> bool {
+    // When checking for `probably_eq`, we ignore certain tokens that aren't
+    // preserved in the AST. Because they are not preserved, the pretty
+    // printer arbitrarily adds or removes them when printing as token
+    // streams, making a comparison between a token stream generated from an
+    // AST and a token stream which was parsed into an AST more reliable.
+    fn semantic_tree(tree: &TokenTree) -> bool {
+        if let TokenTree::Token(token) = tree {
+            if let
+                // The pretty printer tends to add trailing commas to
+                // everything, and in particular, after struct fields.
+                | token::Comma
+                // The pretty printer emits `NoDelim` as whitespace.
+                | token::OpenDelim(DelimToken::NoDelim)
+                | token::CloseDelim(DelimToken::NoDelim)
+                // The pretty printer collapses many semicolons into one.
+                | token::Semi
+                // The pretty printer collapses whitespace arbitrarily and can
+                // introduce whitespace from `NoDelim`.
+                | token::Whitespace
+                // The pretty printer can turn `$crate` into `::crate_name`
+                | token::ModSep = token.kind {
+                return false;
+            }
+        }
+        true
+    }
+
+    // When comparing two `TokenStream`s, we ignore the `IsJoint` information.
+    //
+    // However, `rustc_parse::lexer::tokentrees::TokenStreamBuilder` will
+    // use `Token.glue` on adjacent tokens with the proper `IsJoint`.
+    // Since we are ignoreing `IsJoint`, a 'glued' token (e.g. `BinOp(Shr)`)
+    // and its 'split'/'unglued' compoenents (e.g. `Gt, Gt`) are equivalent
+    // when determining if two `TokenStream`s are 'probably equal'.
+    //
+    // Therefore, we use `break_two_token_op` to convert all tokens
+    // to the 'unglued' form (if it exists). This ensures that two
+    // `TokenStream`s which differ only in how their tokens are glued
+    // will be considered 'probably equal', which allows us to keep spans.
+    //
+    // This is important when the original `TokenStream` contained
+    // extra spaces (e.g. `f :: < Vec < _ > > ( ) ;'). These extra spaces
+    // will be omitted when we pretty-print, which can cause the original
+    // and reparsed `TokenStream`s to differ in the assignment of `IsJoint`,
+    // leading to some tokens being 'glued' together in one stream but not
+    // the other. See #68489 for more details.
+    fn break_tokens(tree: TokenTree) -> impl Iterator<Item = TokenTree> {
+        // In almost all cases, we should have either zero or one levels
+        // of 'unglueing'. However, in some unusual cases, we may need
+        // to iterate breaking tokens mutliple times. For example:
+        // '[BinOpEq(Shr)] => [Gt, Ge] -> [Gt, Gt, Eq]'
+        let mut token_trees: SmallVec<[_; 2]>;
+        if let TokenTree::Token(token) = &tree {
+            let mut out = SmallVec::<[_; 2]>::new();
+            out.push(token.clone());
+            // Iterate to fixpoint:
+            // * We start off with 'out' containing our initial token, and `temp` empty
+            // * If we are able to break any tokens in `out`, then `out` will have
+            //   at least one more element than 'temp', so we will try to break tokens
+            //   again.
+            // * If we cannot break any tokens in 'out', we are done
+            loop {
+                let mut temp = SmallVec::<[_; 2]>::new();
+                let mut changed = false;
+
+                for token in out.into_iter() {
+                    if let Some((first, second)) = token.kind.break_two_token_op() {
+                        temp.push(Token::new(first, DUMMY_SP));
+                        temp.push(Token::new(second, DUMMY_SP));
+                        changed = true;
+                    } else {
+                        temp.push(token);
+                    }
+                }
+                out = temp;
+                if !changed {
+                    break;
+                }
+            }
+            token_trees = out.into_iter().map(|t| TokenTree::Token(t)).collect();
+            if token_trees.len() != 1 {
+                debug!("break_tokens: broke {:?} to {:?}", tree, token_trees);
+            }
+        } else {
+            token_trees = SmallVec::new();
+            token_trees.push(tree);
+        }
+        token_trees.into_iter()
+    }
+
+    let expand_nt = |tree: TokenTree| {
+        if let TokenTree::Token(Token { kind: TokenKind::Interpolated(nt), span }) = &tree {
+            nt_to_tokenstream(nt, sess, *span).into_trees()
+        } else {
+            TokenStream::new(vec![(tree, IsJoint::NonJoint)]).into_trees()
+        }
+    };
+
+    // Break tokens after we expand any nonterminals, so that we break tokens
+    // that are produced as a result of nonterminal expansion.
+    let mut t1 = first.trees().filter(semantic_tree).flat_map(expand_nt).flat_map(break_tokens);
+    let mut t2 = other.trees().filter(semantic_tree).flat_map(expand_nt).flat_map(break_tokens);
+    for (t1, t2) in t1.by_ref().zip(t2.by_ref()) {
+        if !tokentree_probably_equal_for_proc_macro(&t1, &t2, sess) {
+            return false;
+        }
+    }
+    t1.next().is_none() && t2.next().is_none()
+}
+
+// See comments in `Nonterminal::to_tokenstream` for why we care about
+// *probably* equal here rather than actual equality
+crate fn token_probably_equal_for_proc_macro(first: &Token, other: &Token) -> bool {
+    use TokenKind::*;
+
+    if mem::discriminant(&first.kind) != mem::discriminant(&other.kind) {
+        return false;
+    }
+    match (&first.kind, &other.kind) {
+        (&Eq, &Eq)
+        | (&Lt, &Lt)
+        | (&Le, &Le)
+        | (&EqEq, &EqEq)
+        | (&Ne, &Ne)
+        | (&Ge, &Ge)
+        | (&Gt, &Gt)
+        | (&AndAnd, &AndAnd)
+        | (&OrOr, &OrOr)
+        | (&Not, &Not)
+        | (&Tilde, &Tilde)
+        | (&At, &At)
+        | (&Dot, &Dot)
+        | (&DotDot, &DotDot)
+        | (&DotDotDot, &DotDotDot)
+        | (&DotDotEq, &DotDotEq)
+        | (&Comma, &Comma)
+        | (&Semi, &Semi)
+        | (&Colon, &Colon)
+        | (&ModSep, &ModSep)
+        | (&RArrow, &RArrow)
+        | (&LArrow, &LArrow)
+        | (&FatArrow, &FatArrow)
+        | (&Pound, &Pound)
+        | (&Dollar, &Dollar)
+        | (&Question, &Question)
+        | (&Whitespace, &Whitespace)
+        | (&Comment, &Comment)
+        | (&Eof, &Eof) => true,
+
+        (&BinOp(a), &BinOp(b)) | (&BinOpEq(a), &BinOpEq(b)) => a == b,
+
+        (&OpenDelim(a), &OpenDelim(b)) | (&CloseDelim(a), &CloseDelim(b)) => a == b,
+
+        (&DocComment(a), &DocComment(b)) | (&Shebang(a), &Shebang(b)) => a == b,
+
+        (&Literal(a), &Literal(b)) => a == b,
+
+        (&Lifetime(a), &Lifetime(b)) => a == b,
+        (&Ident(a, b), &Ident(c, d)) => {
+            b == d && (a == c || a == kw::DollarCrate || c == kw::DollarCrate)
+        }
+
+        // Expanded by `tokenstream_probably_equal_for_proc_macro`
+        (&Interpolated(_), &Interpolated(_)) => unreachable!(),
+
+        _ => panic!("forgot to add a token?"),
+    }
+}
+
+// See comments in `Nonterminal::to_tokenstream` for why we care about
+// *probably* equal here rather than actual equality
+//
+// This is otherwise the same as `eq_unspanned`, only recursing with a
+// different method.
+pub fn tokentree_probably_equal_for_proc_macro(
+    first: &TokenTree,
+    other: &TokenTree,
+    sess: &ParseSess,
+) -> bool {
+    match (first, other) {
+        (TokenTree::Token(token), TokenTree::Token(token2)) => {
+            token_probably_equal_for_proc_macro(token, token2)
+        }
+        (TokenTree::Delimited(_, delim, tts), TokenTree::Delimited(_, delim2, tts2)) => {
+            delim == delim2 && tokenstream_probably_equal_for_proc_macro(&tts, &tts2, sess)
+        }
+        _ => false,
+    }
+}
diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs
index bdb4d7c9df6..b21524cb9bd 100644
--- a/src/librustc_parse/parser/mod.rs
+++ b/src/librustc_parse/parser/mod.rs
@@ -118,6 +118,8 @@ impl<'a> Drop for Parser<'a> {
 struct TokenCursor {
     frame: TokenCursorFrame,
     stack: Vec<TokenCursorFrame>,
+    cur_token: Option<TreeAndJoint>,
+    collecting: Option<Collecting>,
 }
 
 #[derive(Clone)]
@@ -127,30 +129,24 @@ struct TokenCursorFrame {
     open_delim: bool,
     tree_cursor: tokenstream::Cursor,
     close_delim: bool,
-    last_token: LastToken,
 }
 
-/// This is used in `TokenCursorFrame` above to track tokens that are consumed
-/// by the parser, and then that's transitively used to record the tokens that
-/// each parse AST item is created with.
-///
-/// Right now this has two states, either collecting tokens or not collecting
-/// tokens. If we're collecting tokens we just save everything off into a local
-/// `Vec`. This should eventually though likely save tokens from the original
-/// token stream and just use slicing of token streams to avoid creation of a
-/// whole new vector.
-///
-/// The second state is where we're passively not recording tokens, but the last
-/// token is still tracked for when we want to start recording tokens. This
-/// "last token" means that when we start recording tokens we'll want to ensure
-/// that this, the first token, is included in the output.
-///
-/// You can find some more example usage of this in the `collect_tokens` method
-/// on the parser.
-#[derive(Clone)]
-enum LastToken {
-    Collecting(Vec<TreeAndJoint>),
-    Was(Option<TreeAndJoint>),
+/// Used to track additional state needed by `collect_tokens`
+#[derive(Clone, Debug)]
+struct Collecting {
+    /// Holds the current tokens captured during the most
+    /// recent call to `collect_tokens`
+    buf: Vec<TreeAndJoint>,
+    /// The depth of the `TokenCursor` stack at the time
+    /// collection was started. When we encounter a `TokenTree::Delimited`,
+    /// we want to record the `TokenTree::Delimited` itself,
+    /// but *not* any of the inner tokens while we are inside
+    /// the new frame (this would cause us to record duplicate tokens).
+    ///
+    /// This `depth` fields tracks stack depth we are recording tokens.
+    /// Only tokens encountered at this depth will be recorded. See
+    /// `TokenCursor::next` for more details.
+    depth: usize,
 }
 
 impl TokenCursorFrame {
@@ -161,7 +157,6 @@ impl TokenCursorFrame {
             open_delim: delim == token::NoDelim,
             tree_cursor: tts.clone().into_trees(),
             close_delim: delim == token::NoDelim,
-            last_token: LastToken::Was(None),
         }
     }
 }
@@ -171,12 +166,12 @@ impl TokenCursor {
         loop {
             let tree = if !self.frame.open_delim {
                 self.frame.open_delim = true;
-                TokenTree::open_tt(self.frame.span, self.frame.delim)
-            } else if let Some(tree) = self.frame.tree_cursor.next() {
+                TokenTree::open_tt(self.frame.span, self.frame.delim).into()
+            } else if let Some(tree) = self.frame.tree_cursor.next_with_joint() {
                 tree
             } else if !self.frame.close_delim {
                 self.frame.close_delim = true;
-                TokenTree::close_tt(self.frame.span, self.frame.delim)
+                TokenTree::close_tt(self.frame.span, self.frame.delim).into()
             } else if let Some(frame) = self.stack.pop() {
                 self.frame = frame;
                 continue;
@@ -184,12 +179,25 @@ impl TokenCursor {
                 return Token::new(token::Eof, DUMMY_SP);
             };
 
-            match self.frame.last_token {
-                LastToken::Collecting(ref mut v) => v.push(tree.clone().into()),
-                LastToken::Was(ref mut t) => *t = Some(tree.clone().into()),
+            // Don't set an open delimiter as our current token - we want
+            // to leave it as the full `TokenTree::Delimited` from the previous
+            // iteration of this loop
+            if !matches!(tree.0, TokenTree::Token(Token { kind: TokenKind::OpenDelim(_), .. })) {
+                self.cur_token = Some(tree.clone());
+            }
+
+            if let Some(collecting) = &mut self.collecting {
+                if collecting.depth == self.stack.len() {
+                    debug!(
+                        "TokenCursor::next():  collected {:?} at depth {:?}",
+                        tree,
+                        self.stack.len()
+                    );
+                    collecting.buf.push(tree.clone().into())
+                }
             }
 
-            match tree {
+            match tree.0 {
                 TokenTree::Token(token) => return token,
                 TokenTree::Delimited(sp, delim, tts) => {
                     let frame = TokenCursorFrame::new(sp, delim, &tts);
@@ -350,6 +358,8 @@ impl<'a> Parser<'a> {
             token_cursor: TokenCursor {
                 frame: TokenCursorFrame::new(DelimSpan::dummy(), token::NoDelim, &tokens),
                 stack: Vec::new(),
+                cur_token: None,
+                collecting: None,
             },
             desugar_doc_comments,
             unmatched_angle_bracket_count: 0,
@@ -1105,65 +1115,95 @@ impl<'a> Parser<'a> {
         }
     }
 
+    /// Records all tokens consumed by the provided callback,
+    /// including the current token. These tokens are collected
+    /// into a `TokenStream`, and returned along with the result
+    /// of the callback.
+    ///
+    /// Note: If your callback consumes an opening delimiter
+    /// (including the case where you call `collect_tokens`
+    /// when the current token is an opening delimeter),
+    /// you must also consume the corresponding closing delimiter.
+    ///
+    /// That is, you can consume
+    /// `something ([{ }])` or `([{}])`, but not `([{}]`
+    ///
+    /// This restriction shouldn't be an issue in practice,
+    /// since this function is used to record the tokens for
+    /// a parsed AST item, which always has matching delimiters.
     fn collect_tokens<R>(
         &mut self,
         f: impl FnOnce(&mut Self) -> PResult<'a, R>,
     ) -> PResult<'a, (R, TokenStream)> {
         // Record all tokens we parse when parsing this item.
-        let mut tokens = Vec::new();
-        let prev_collecting = match self.token_cursor.frame.last_token {
-            LastToken::Collecting(ref mut list) => Some(mem::take(list)),
-            LastToken::Was(ref mut last) => {
-                tokens.extend(last.take());
-                None
-            }
-        };
-        self.token_cursor.frame.last_token = LastToken::Collecting(tokens);
-        let prev = self.token_cursor.stack.len();
+        let tokens: Vec<TreeAndJoint> = self.token_cursor.cur_token.clone().into_iter().collect();
+        debug!("collect_tokens: starting with {:?}", tokens);
+
+        // We need special handling for the case where `collect_tokens` is called
+        // on an opening delimeter (e.g. '('). At this point, we have already pushed
+        // a new frame - however, we want to record the original `TokenTree::Delimited`,
+        // for consistency with the case where we start recording one token earlier.
+        // See `TokenCursor::next` to see how `cur_token` is set up.
+        let prev_depth =
+            if matches!(self.token_cursor.cur_token, Some((TokenTree::Delimited(..), _))) {
+                if self.token_cursor.stack.is_empty() {
+                    // There is nothing below us in the stack that
+                    // the function could consume, so the only thing it can legally
+                    // capture is the entire contents of the current frame.
+                    return Ok((f(self)?, TokenStream::new(tokens)));
+                }
+                // We have already recorded the full `TokenTree::Delimited` when we created
+                // our `tokens` vector at the start of this function. We are now inside
+                // a new frame corresponding to the `TokenTree::Delimited` we already recoreded.
+                // We don't want to record any of the tokens inside this frame, since they
+                // will be duplicates of the tokens nested inside the `TokenTree::Delimited`.
+                // Therefore, we set our recording depth to the *previous* frame. This allows
+                // us to record a sequence like: `(foo).bar()`: the `(foo)` will be recored
+                // as our initial `cur_token`, while the `.bar()` will be recored after we
+                // pop the `(foo)` frame.
+                self.token_cursor.stack.len() - 1
+            } else {
+                self.token_cursor.stack.len()
+            };
+        let prev_collecting =
+            self.token_cursor.collecting.replace(Collecting { buf: tokens, depth: prev_depth });
+
         let ret = f(self);
-        let last_token = if self.token_cursor.stack.len() == prev {
-            &mut self.token_cursor.frame.last_token
-        } else if self.token_cursor.stack.get(prev).is_none() {
-            // This can happen due to a bad interaction of two unrelated recovery mechanisms with
-            // mismatched delimiters *and* recovery lookahead on the likely typo `pub ident(`
-            // (#62881).
-            return Ok((ret?, TokenStream::default()));
+
+        let mut collected_tokens = if let Some(collecting) = self.token_cursor.collecting.take() {
+            collecting.buf
         } else {
-            &mut self.token_cursor.stack[prev].last_token
+            let msg = format!("our vector went away?");
+            debug!("collect_tokens: {}", msg);
+            self.sess.span_diagnostic.delay_span_bug(self.token.span, &msg);
+            // This can happen due to a bad interaction of two unrelated recovery mechanisms
+            // with mismatched delimiters *and* recovery lookahead on the likely typo
+            // `pub ident(` (#62895, different but similar to the case above).
+            return Ok((ret?, TokenStream::default()));
         };
 
-        // Pull out the tokens that we've collected from the call to `f` above.
-        let mut collected_tokens = match *last_token {
-            LastToken::Collecting(ref mut v) => mem::take(v),
-            LastToken::Was(ref was) => {
-                let msg = format!("our vector went away? - found Was({:?})", was);
-                debug!("collect_tokens: {}", msg);
-                self.sess.span_diagnostic.delay_span_bug(self.token.span, &msg);
-                // This can happen due to a bad interaction of two unrelated recovery mechanisms
-                // with mismatched delimiters *and* recovery lookahead on the likely typo
-                // `pub ident(` (#62895, different but similar to the case above).
-                return Ok((ret?, TokenStream::default()));
-            }
-        };
+        debug!("collect_tokens: got raw tokens {:?}", collected_tokens);
 
         // If we're not at EOF our current token wasn't actually consumed by
         // `f`, but it'll still be in our list that we pulled out. In that case
         // put it back.
         let extra_token = if self.token != token::Eof { collected_tokens.pop() } else { None };
 
-        // If we were previously collecting tokens, then this was a recursive
-        // call. In that case we need to record all the tokens we collected in
-        // our parent list as well. To do that we push a clone of our stream
-        // onto the previous list.
-        match prev_collecting {
-            Some(mut list) => {
-                list.extend(collected_tokens.iter().cloned());
-                list.extend(extra_token);
-                *last_token = LastToken::Collecting(list);
-            }
-            None => {
-                *last_token = LastToken::Was(extra_token);
+        if let Some(mut collecting) = prev_collecting {
+            // If we were previously collecting at the same depth,
+            // then the previous call to `collect_tokens` needs to see
+            // the tokens we just recorded.
+            //
+            // If we were previously recording at an lower `depth`,
+            // then the previous `collect_tokens` call already recorded
+            // this entire frame in the form of a `TokenTree::Delimited`,
+            // so there is nothing else for us to do.
+            if collecting.depth == prev_depth {
+                collecting.buf.extend(collected_tokens.iter().cloned());
+                collecting.buf.extend(extra_token);
+                debug!("collect_tokens: updating previous buf to {:?}", collecting);
             }
+            self.token_cursor.collecting = Some(collecting)
         }
 
         Ok((ret?, TokenStream::new(collected_tokens)))
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 988ec3d4374..c32b823fe73 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -126,8 +126,8 @@ impl<'a> Resolver<'a> {
     }
 
     crate fn macro_def_scope(&mut self, expn_id: ExpnId) -> Module<'a> {
-        let def_id = match self.macro_defs.get(&expn_id) {
-            Some(def_id) => *def_id,
+        let def_id = match expn_id.expn_data().macro_def_id {
+            Some(def_id) => def_id,
             None => return self.ast_transform_scopes.get(&expn_id).unwrap_or(&self.graph_root),
         };
         if let Some(id) = self.definitions.as_local_node_id(def_id) {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index bfb7f081fc3..63a4cdfbf29 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1,3 +1,5 @@
+// ignore-tidy-filelength
+
 //! This crate is responsible for the part of name resolution that doesn't require type checker.
 //!
 //! Module structure of the crate is built here.
@@ -922,7 +924,6 @@ pub struct Resolver<'a> {
     dummy_ext_bang: Lrc<SyntaxExtension>,
     dummy_ext_derive: Lrc<SyntaxExtension>,
     non_macro_attrs: [Lrc<SyntaxExtension>; 2],
-    macro_defs: FxHashMap<ExpnId, DefId>,
     local_macro_def_scopes: FxHashMap<NodeId, Module<'a>>,
     ast_transform_scopes: FxHashMap<ExpnId, Module<'a>>,
     unused_macros: NodeMap<Span>,
@@ -1152,9 +1153,6 @@ impl<'a> Resolver<'a> {
         let mut invocation_parent_scopes = FxHashMap::default();
         invocation_parent_scopes.insert(ExpnId::root(), ParentScope::module(graph_root));
 
-        let mut macro_defs = FxHashMap::default();
-        macro_defs.insert(ExpnId::root(), root_def_id);
-
         let features = session.features_untracked();
         let non_macro_attr =
             |mark_used| Lrc::new(SyntaxExtension::non_macro_attr(mark_used, session.edition()));
@@ -1229,7 +1227,6 @@ impl<'a> Resolver<'a> {
             invocation_parent_scopes,
             output_macro_rules_scopes: Default::default(),
             helper_attrs: Default::default(),
-            macro_defs,
             local_macro_def_scopes: FxHashMap::default(),
             name_already_seen: FxHashMap::default(),
             potentially_unused_imports: Vec::new(),
@@ -1271,15 +1268,60 @@ impl<'a> Resolver<'a> {
     }
 
     pub fn into_outputs(self) -> ResolverOutputs {
+        let definitions = self.definitions;
+        let extern_crate_map = self
+            .extern_crate_map
+            .into_iter()
+            .map(|(k, v)| (definitions.local_def_id(k).to_def_id(), v))
+            .collect();
+        let export_map = self
+            .export_map
+            .into_iter()
+            .map(|(k, v)| {
+                (
+                    k,
+                    v.into_iter()
+                        .map(|e| e.map_id(|id| definitions.node_id_to_hir_id(id)))
+                        .collect(),
+                )
+            })
+            .collect();
+        let trait_map = self
+            .trait_map
+            .into_iter()
+            .map(|(k, v)| {
+                (
+                    definitions.node_id_to_hir_id(k),
+                    v.into_iter()
+                        .map(|tc| tc.map_import_ids(|id| definitions.node_id_to_hir_id(id)))
+                        .collect(),
+                )
+            })
+            .collect();
+        let maybe_unused_trait_imports = self
+            .maybe_unused_trait_imports
+            .into_iter()
+            .map(|id| definitions.local_def_id(id))
+            .collect();
+        let maybe_unused_extern_crates = self
+            .maybe_unused_extern_crates
+            .into_iter()
+            .map(|(id, sp)| (definitions.local_def_id(id).to_def_id(), sp))
+            .collect();
+        let glob_map = self
+            .glob_map
+            .into_iter()
+            .map(|(id, names)| (definitions.local_def_id(id), names))
+            .collect();
         ResolverOutputs {
-            definitions: self.definitions,
+            definitions: definitions,
             cstore: Box::new(self.crate_loader.into_cstore()),
-            extern_crate_map: self.extern_crate_map,
-            export_map: self.export_map,
-            trait_map: self.trait_map,
-            glob_map: self.glob_map,
-            maybe_unused_trait_imports: self.maybe_unused_trait_imports,
-            maybe_unused_extern_crates: self.maybe_unused_extern_crates,
+            extern_crate_map,
+            export_map,
+            trait_map,
+            glob_map,
+            maybe_unused_trait_imports,
+            maybe_unused_extern_crates,
             extern_prelude: self
                 .extern_prelude
                 .iter()
@@ -1292,12 +1334,53 @@ impl<'a> Resolver<'a> {
         ResolverOutputs {
             definitions: self.definitions.clone(),
             cstore: Box::new(self.cstore().clone()),
-            extern_crate_map: self.extern_crate_map.clone(),
-            export_map: self.export_map.clone(),
-            trait_map: self.trait_map.clone(),
-            glob_map: self.glob_map.clone(),
-            maybe_unused_trait_imports: self.maybe_unused_trait_imports.clone(),
-            maybe_unused_extern_crates: self.maybe_unused_extern_crates.clone(),
+            extern_crate_map: self
+                .extern_crate_map
+                .iter()
+                .map(|(&k, &v)| (self.definitions.local_def_id(k).to_def_id(), v))
+                .collect(),
+            export_map: self
+                .export_map
+                .iter()
+                .map(|(&k, v)| {
+                    (
+                        k,
+                        v.iter()
+                            .map(|e| e.map_id(|id| self.definitions.node_id_to_hir_id(id)))
+                            .collect(),
+                    )
+                })
+                .collect(),
+            trait_map: self
+                .trait_map
+                .iter()
+                .map(|(&k, v)| {
+                    (
+                        self.definitions.node_id_to_hir_id(k),
+                        v.iter()
+                            .cloned()
+                            .map(|tc| {
+                                tc.map_import_ids(|id| self.definitions.node_id_to_hir_id(id))
+                            })
+                            .collect(),
+                    )
+                })
+                .collect(),
+            glob_map: self
+                .glob_map
+                .iter()
+                .map(|(&id, names)| (self.definitions.local_def_id(id), names.clone()))
+                .collect(),
+            maybe_unused_trait_imports: self
+                .maybe_unused_trait_imports
+                .iter()
+                .map(|&id| self.definitions.local_def_id(id))
+                .collect(),
+            maybe_unused_extern_crates: self
+                .maybe_unused_extern_crates
+                .iter()
+                .map(|&(id, sp)| (self.definitions.local_def_id(id).to_def_id(), sp))
+                .collect(),
             extern_prelude: self
                 .extern_prelude
                 .iter()
@@ -1335,8 +1418,8 @@ impl<'a> Resolver<'a> {
 
     fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
         loop {
-            match self.macro_defs.get(&ctxt.outer_expn()) {
-                Some(&def_id) => return def_id,
+            match ctxt.outer_expn().expn_data().macro_def_id {
+                Some(def_id) => return def_id,
                 None => ctxt.remove_mark(),
             };
         }
@@ -1820,7 +1903,7 @@ impl<'a> Resolver<'a> {
                 && module.expansion.is_descendant_of(parent.expansion)
             {
                 // The macro is a proc macro derive
-                if let Some(&def_id) = self.macro_defs.get(&module.expansion) {
+                if let Some(def_id) = module.expansion.expn_data().macro_def_id {
                     if let Some(ext) = self.get_macro_by_def_id(def_id) {
                         if !ext.is_builtin && ext.macro_kind() == MacroKind::Derive {
                             if parent.expansion.outer_expn_is_descendant_of(span.ctxt()) {
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 1b6268dc8cb..7027c826267 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -186,6 +186,7 @@ impl<'a> base::Resolver for Resolver<'a> {
             call_site,
             self.session.edition(),
             features.into(),
+            None,
         )));
 
         let parent_scope = if let Some(module_id) = parent_module_id {
@@ -290,13 +291,17 @@ impl<'a> base::Resolver for Resolver<'a> {
         let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, force)?;
 
         let span = invoc.span();
-        invoc_id.set_expn_data(ext.expn_data(parent_scope.expansion, span, fast_print_path(path)));
-
-        if let Res::Def(_, def_id) = res {
+        invoc_id.set_expn_data(ext.expn_data(
+            parent_scope.expansion,
+            span,
+            fast_print_path(path),
+            res.opt_def_id(),
+        ));
+
+        if let Res::Def(_, _) = res {
             if after_derive {
                 self.session.span_err(span, "macro attributes must be placed before `#[derive]`");
             }
-            self.macro_defs.insert(invoc_id, def_id);
             let normal_module_def_id = self.macro_def_scope(invoc_id).normal_ancestor_id;
             self.definitions.add_parent_module_of_macro_def(invoc_id, normal_module_def_id);
         }
diff --git a/src/librustc_span/hygiene.rs b/src/librustc_span/hygiene.rs
index 23c3dccb130..c0fb84e741f 100644
--- a/src/librustc_span/hygiene.rs
+++ b/src/librustc_span/hygiene.rs
@@ -25,6 +25,7 @@
 // because getting it wrong can lead to nested `HygieneData::with` calls that
 // trigger runtime aborts. (Fortunately these are obvious and easy to fix.)
 
+use crate::def_id::{DefId, CRATE_DEF_INDEX};
 use crate::edition::Edition;
 use crate::symbol::{kw, sym, Symbol};
 use crate::GLOBALS;
@@ -155,7 +156,12 @@ crate struct HygieneData {
 impl HygieneData {
     crate fn new(edition: Edition) -> Self {
         HygieneData {
-            expn_data: vec![Some(ExpnData::default(ExpnKind::Root, DUMMY_SP, edition))],
+            expn_data: vec![Some(ExpnData::default(
+                ExpnKind::Root,
+                DUMMY_SP,
+                edition,
+                Some(DefId::local(CRATE_DEF_INDEX)),
+            ))],
             syntax_context_data: vec![SyntaxContextData {
                 outer_expn: ExpnId::root(),
                 outer_transparency: Transparency::Opaque,
@@ -673,11 +679,19 @@ pub struct ExpnData {
     pub local_inner_macros: bool,
     /// Edition of the crate in which the macro is defined.
     pub edition: Edition,
+    /// The `DefId` of the macro being invoked,
+    /// if this `ExpnData` corresponds to a macro invocation
+    pub macro_def_id: Option<DefId>,
 }
 
 impl ExpnData {
     /// Constructs expansion data with default properties.
-    pub fn default(kind: ExpnKind, call_site: Span, edition: Edition) -> ExpnData {
+    pub fn default(
+        kind: ExpnKind,
+        call_site: Span,
+        edition: Edition,
+        macro_def_id: Option<DefId>,
+    ) -> ExpnData {
         ExpnData {
             kind,
             parent: ExpnId::root(),
@@ -687,6 +701,7 @@ impl ExpnData {
             allow_internal_unsafe: false,
             local_inner_macros: false,
             edition,
+            macro_def_id,
         }
     }
 
@@ -695,10 +710,11 @@ impl ExpnData {
         call_site: Span,
         edition: Edition,
         allow_internal_unstable: Lrc<[Symbol]>,
+        macro_def_id: Option<DefId>,
     ) -> ExpnData {
         ExpnData {
             allow_internal_unstable: Some(allow_internal_unstable),
-            ..ExpnData::default(kind, call_site, edition)
+            ..ExpnData::default(kind, call_site, edition, macro_def_id)
         }
     }
 
diff --git a/src/librustc_trait_selection/opaque_types.rs b/src/librustc_trait_selection/opaque_types.rs
index 2544e4ddea2..484677ded24 100644
--- a/src/librustc_trait_selection/opaque_types.rs
+++ b/src/librustc_trait_selection/opaque_types.rs
@@ -670,7 +670,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
 // `least_region`. We cannot use `push_outlives_components` because regions in
 // closure signatures are not included in their outlives components. We need to
 // ensure all regions outlive the given bound so that we don't end up with,
-// say, `ReScope` appearing in a return type and causing ICEs when other
+// say, `ReVar` appearing in a return type and causing ICEs when other
 // functions end up with region constraints involving regions from other
 // functions.
 //
@@ -816,7 +816,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
             // The regions that we expect from borrow checking.
             ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReEmpty(ty::UniverseIndex::ROOT) => {}
 
-            ty::ReEmpty(_) | ty::RePlaceholder(_) | ty::ReVar(_) | ty::ReScope(_) => {
+            ty::ReEmpty(_) | ty::RePlaceholder(_) | ty::ReVar(_) => {
                 // All of the regions in the type should either have been
                 // erased by writeback, or mapped back to named regions by
                 // borrow checking.
@@ -835,7 +835,6 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
                 if let Some(hidden_ty) = self.hidden_ty.take() {
                     unexpected_hidden_region_diagnostic(
                         self.tcx,
-                        None,
                         self.tcx.def_span(self.opaque_type_def_id),
                         hidden_ty,
                         r,
diff --git a/src/librustc_trait_selection/traits/mod.rs b/src/librustc_trait_selection/traits/mod.rs
index 3daa9109aaf..d8e99dc10af 100644
--- a/src/librustc_trait_selection/traits/mod.rs
+++ b/src/librustc_trait_selection/traits/mod.rs
@@ -28,7 +28,6 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc_errors::ErrorReported;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
-use rustc_middle::middle::region;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
 use rustc_middle::ty::{
@@ -237,15 +236,12 @@ fn do_normalize_predicates<'tcx>(
 
         debug!("do_normalize_predictes: normalized predicates = {:?}", predicates);
 
-        let region_scope_tree = region::ScopeTree::default();
-
         // We can use the `elaborated_env` here; the region code only
         // cares about declarations like `'a: 'b`.
         let outlives_env = OutlivesEnvironment::new(elaborated_env);
 
         infcx.resolve_regions_and_report_errors(
             region_context,
-            &region_scope_tree,
             &outlives_env,
             RegionckMode::default(),
         );
diff --git a/src/librustc_trait_selection/traits/select.rs b/src/librustc_trait_selection/traits/select.rs
index b402aba65cd..9b3381066a1 100644
--- a/src/librustc_trait_selection/traits/select.rs
+++ b/src/librustc_trait_selection/traits/select.rs
@@ -1058,20 +1058,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 // Heuristics: show the diagnostics when there are no candidates in crate.
                 if let Ok(candidate_set) = self.assemble_candidates(stack) {
                     let mut no_candidates_apply = true;
-                    {
-                        let evaluated_candidates =
-                            candidate_set.vec.iter().map(|c| self.evaluate_candidate(stack, &c));
-
-                        for ec in evaluated_candidates {
-                            match ec {
-                                Ok(c) => {
-                                    if c.may_apply() {
-                                        no_candidates_apply = false;
-                                        break;
-                                    }
-                                }
-                                Err(e) => return Err(e.into()),
-                            }
+
+                    for c in candidate_set.vec.iter() {
+                        if self.evaluate_candidate(stack, &c)?.may_apply() {
+                            no_candidates_apply = false;
+                            break;
                         }
                     }
 
@@ -3182,11 +3173,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 assert_eq!(tys_a.len(), tys_b.len());
 
                 // The last field of the tuple has to exist.
-                let (&a_last, a_mid) = if let Some(x) = tys_a.split_last() {
-                    x
-                } else {
-                    return Err(Unimplemented);
-                };
+                let (&a_last, a_mid) = tys_a.split_last().ok_or(Unimplemented)?;
                 let &b_last = tys_b.last().unwrap();
 
                 // Check that the source tuple with the target's
diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs
index 7d48b457538..a33ada2fb6e 100644
--- a/src/librustc_traits/chalk/lowering.rs
+++ b/src/librustc_traits/chalk/lowering.rs
@@ -394,7 +394,6 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime<RustInterner<'tcx>>> for Region<'t
                 ty::BrEnv => unimplemented!(),
             },
             ReFree(_) => unimplemented!(),
-            ReScope(_) => unimplemented!(),
             ReStatic => unimplemented!(),
             ReVar(_) => unimplemented!(),
             RePlaceholder(placeholder_region) => {
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index f393121a0ad..8fa901d8a98 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -3,7 +3,6 @@
 use super::{check_fn, Expectation, FnCtxt, GeneratorTypes};
 
 use crate::astconv::AstConv;
-use crate::middle::region;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::{FutureTraitLangItem, GeneratorTraitLangItem};
@@ -12,12 +11,11 @@ use rustc_infer::infer::LateBoundRegionConversionTime;
 use rustc_infer::infer::{InferOk, InferResult};
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::subst::InternalSubsts;
-use rustc_middle::ty::{self, GenericParamDefKind, ToPredicate, Ty};
+use rustc_middle::ty::{self, GenericParamDefKind, Ty};
 use rustc_span::source_map::Span;
 use rustc_target::spec::abi::Abi;
 use rustc_trait_selection::traits::error_reporting::ArgKind;
 use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
-use rustc_trait_selection::traits::Obligation;
 use std::cmp;
 use std::iter;
 
@@ -518,22 +516,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let InferOk { value: (), obligations } =
                     self.at(&cause, self.param_env).eq(*expected_ty, supplied_ty)?;
                 all_obligations.extend(obligations);
-
-                // Also, require that the supplied type must outlive
-                // the closure body.
-                let closure_body_region = self.tcx.mk_region(ty::ReScope(region::Scope {
-                    id: body.value.hir_id.local_id,
-                    data: region::ScopeData::Node,
-                }));
-                all_obligations.push(Obligation::new(
-                    cause,
-                    self.param_env,
-                    ty::PredicateKind::TypeOutlives(ty::Binder::dummy(ty::OutlivesPredicate(
-                        supplied_ty,
-                        closure_body_region,
-                    )))
-                    .to_predicate(self.tcx),
-                ));
             }
 
             let (supplied_output_ty, _) = self.infcx.replace_bound_vars_with_fresh_vars(
diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs
index 594cdab852f..24c319f26e7 100644
--- a/src/librustc_typeck/check/dropck.rs
+++ b/src/librustc_typeck/check/dropck.rs
@@ -5,7 +5,6 @@ use rustc_errors::{struct_span_err, ErrorReported};
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{InferOk, RegionckMode, TyCtxtInferExt};
 use rustc_infer::traits::TraitEngineExt as _;
-use rustc_middle::middle::region;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::subst::{Subst, SubstsRef};
@@ -120,8 +119,6 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
             return Err(ErrorReported);
         }
 
-        let region_scope_tree = region::ScopeTree::default();
-
         // NB. It seems a bit... suspicious to use an empty param-env
         // here. The correct thing, I imagine, would be
         // `OutlivesEnvironment::new(impl_param_env)`, which would
@@ -134,7 +131,6 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
 
         infcx.resolve_regions_and_report_errors(
             drop_impl_did.to_def_id(),
-            &region_scope_tree,
             &outlives_env,
             RegionckMode::default(),
         );
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index c452859414c..6b7adb728e7 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -106,13 +106,13 @@ use rustc_hir::lang_items::{
 use rustc_hir::{ExprKind, GenericArg, HirIdMap, Item, ItemKind, Node, PatKind, QPath};
 use rustc_index::bit_set::BitSet;
 use rustc_index::vec::Idx;
+use rustc_infer::infer;
 use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
 use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
-use rustc_infer::infer::{self, InferCtxt, InferOk, InferResult, TyCtxtInferExt};
+use rustc_infer::infer::{InferCtxt, InferOk, InferResult, RegionVariableOrigin, TyCtxtInferExt};
 use rustc_middle::hir::map::blocks::FnLikeNode;
-use rustc_middle::middle::region;
 use rustc_middle::mir::interpret::ConstValue;
 use rustc_middle::ty::adjustment::{
     Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
@@ -667,13 +667,6 @@ impl Inherited<'a, 'tcx> {
         let tcx = infcx.tcx;
         let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
         let body_id = tcx.hir().maybe_body_owned_by(item_id);
-        let implicit_region_bound = body_id.map(|body_id| {
-            let body = tcx.hir().body(body_id);
-            tcx.mk_region(ty::ReScope(region::Scope {
-                id: body.value.hir_id.local_id,
-                data: region::ScopeData::CallSite,
-            }))
-        });
 
         Inherited {
             tables: MaybeInProgressTables { maybe_tables: infcx.in_progress_tables },
@@ -686,7 +679,7 @@ impl Inherited<'a, 'tcx> {
             deferred_generator_interiors: RefCell::new(Vec::new()),
             opaque_types: RefCell::new(Default::default()),
             opaque_types_vars: RefCell::new(Default::default()),
-            implicit_region_bound,
+            implicit_region_bound: None,
             body_id,
         }
     }
@@ -1337,12 +1330,9 @@ fn check_fn<'a, 'tcx>(
     // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
     // (as it's created inside the body itself, not passed in from outside).
     let maybe_va_list = if fn_sig.c_variadic {
-        let va_list_did =
-            tcx.require_lang_item(VaListTypeLangItem, Some(body.params.last().unwrap().span));
-        let region = tcx.mk_region(ty::ReScope(region::Scope {
-            id: body.value.hir_id.local_id,
-            data: region::ScopeData::CallSite,
-        }));
+        let span = body.params.last().unwrap().span;
+        let va_list_did = tcx.require_lang_item(VaListTypeLangItem, Some(span));
+        let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span));
 
         Some(tcx.type_of(va_list_did).subst(tcx, &[region.into()]))
     } else {
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index 049f4767247..90ba15aa089 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -83,12 +83,10 @@ use rustc_hir::PatKind;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{self, RegionObligation, RegionckMode};
 use rustc_middle::ty::adjustment;
-use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
 use rustc_middle::ty::{self, Ty};
 use rustc_span::Span;
 use rustc_trait_selection::infer::OutlivesEnvironmentExt;
 use rustc_trait_selection::opaque_types::InferCtxtExt;
-use std::mem;
 use std::ops::Deref;
 
 // a variation on try that just returns unit
@@ -111,8 +109,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn regionck_expr(&self, body: &'tcx hir::Body<'tcx>) {
         let subject = self.tcx.hir().body_owner_def_id(body.id());
         let id = body.value.hir_id;
-        let mut rcx =
-            RegionCtxt::new(self, RepeatingScope(id), id, Subject(subject), self.param_env);
+        let mut rcx = RegionCtxt::new(self, id, Subject(subject), self.param_env);
 
         // There are no add'l implied bounds when checking a
         // standalone expr (e.g., the `E` in a type like `[u32; E]`).
@@ -131,13 +128,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn regionck_item(&self, item_id: hir::HirId, span: Span, wf_tys: &[Ty<'tcx>]) {
         debug!("regionck_item(item.id={:?}, wf_tys={:?})", item_id, wf_tys);
         let subject = self.tcx.hir().local_def_id(item_id);
-        let mut rcx = RegionCtxt::new(
-            self,
-            RepeatingScope(item_id),
-            item_id,
-            Subject(subject),
-            self.param_env,
-        );
+        let mut rcx = RegionCtxt::new(self, item_id, Subject(subject), self.param_env);
         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);
@@ -156,8 +147,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         debug!("regionck_fn(id={})", fn_id);
         let subject = self.tcx.hir().body_owner_def_id(body.id());
         let hir_id = body.value.hir_id;
-        let mut rcx =
-            RegionCtxt::new(self, RepeatingScope(hir_id), hir_id, Subject(subject), self.param_env);
+        let mut rcx = RegionCtxt::new(self, hir_id, Subject(subject), self.param_env);
 
         if !self.errors_reported_since_creation() {
             // regionck assumes typeck succeeded
@@ -182,12 +172,6 @@ pub struct RegionCtxt<'a, 'tcx> {
     body_id: hir::HirId,
     body_owner: LocalDefId,
 
-    // call_site scope of innermost fn
-    call_site_scope: Option<region::Scope>,
-
-    // id of innermost fn or loop
-    repeating_scope: hir::HirId,
-
     // id of AST node being analyzed (the subject of the analysis).
     subject_def_id: LocalDefId,
 }
@@ -199,13 +183,11 @@ impl<'a, 'tcx> Deref for RegionCtxt<'a, 'tcx> {
     }
 }
 
-pub struct RepeatingScope(hir::HirId);
 pub struct Subject(LocalDefId);
 
 impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
     pub fn new(
         fcx: &'a FnCtxt<'a, 'tcx>,
-        RepeatingScope(initial_repeating_scope): RepeatingScope,
         initial_body_id: hir::HirId,
         Subject(subject): Subject,
         param_env: ty::ParamEnv<'tcx>,
@@ -215,19 +197,13 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
         RegionCtxt {
             fcx,
             region_scope_tree,
-            repeating_scope: initial_repeating_scope,
             body_id: initial_body_id,
             body_owner: subject,
-            call_site_scope: None,
             subject_def_id: subject,
             outlives_environment,
         }
     }
 
-    fn set_repeating_scope(&mut self, scope: hir::HirId) -> hir::HirId {
-        mem::replace(&mut self.repeating_scope, scope)
-    }
-
     /// Try to resolve the type for the given node, returning `t_err` if an error results. Note that
     /// we never care about the details of the error, the same error will be detected and reported
     /// in the writeback phase.
@@ -261,16 +237,10 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
         self.resolve_type(t)
     }
 
-    /// Try to resolve the type for the given node.
-    pub fn resolve_expr_type_adjusted(&mut self, expr: &hir::Expr<'_>) -> Ty<'tcx> {
-        let ty = self.tables.borrow().expr_ty_adjusted(expr);
-        self.resolve_type(ty)
-    }
-
-    /// This is the "main" function when region-checking a function item or a closure
-    /// within a function item. It begins by updating various fields (e.g., `call_site_scope`
-    /// and `outlives_environment`) to be appropriate to the function and then adds constraints
-    /// derived from the function body.
+    /// This is the "main" function when region-checking a function item or a
+    /// closure within a function item. It begins by updating various fields
+    /// (e.g., `outlives_environment`) to be appropriate to the function and
+    /// then adds constraints derived from the function body.
     ///
     /// Note that it does **not** restore the state of the fields that
     /// it updates! This is intentional, since -- for the main
@@ -292,10 +262,6 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
         self.body_id = body_id.hir_id;
         self.body_owner = self.tcx.hir().body_owner_def_id(body_id);
 
-        let call_site =
-            region::Scope { id: body.value.hir_id.local_id, data: region::ScopeData::CallSite };
-        self.call_site_scope = Some(call_site);
-
         let fn_sig = {
             match self.tables.borrow().liberated_fn_sigs().get(id) {
                 Some(f) => *f,
@@ -324,12 +290,6 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
         self.visit_body(body);
         self.visit_region_obligations(body_id.hir_id);
 
-        let call_site_scope = self.call_site_scope.unwrap();
-        debug!("visit_fn_body body.id {:?} call_site_scope: {:?}", body.id(), call_site_scope);
-        let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope));
-
-        self.type_of_node_must_outlive(infer::CallReturn(span), body_id.hir_id, call_site_region);
-
         self.constrain_opaque_types(
             &self.fcx.opaque_types.borrow(),
             self.outlives_environment.free_region_map(),
@@ -354,7 +314,6 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
 
         self.fcx.resolve_regions_and_report_errors(
             self.subject_def_id.to_def_id(),
-            &self.region_scope_tree,
             &self.outlives_environment,
             mode,
         );
@@ -363,34 +322,6 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
     fn constrain_bindings_in_pat(&mut self, pat: &hir::Pat<'_>) {
         debug!("regionck::visit_pat(pat={:?})", pat);
         pat.each_binding(|_, hir_id, span, _| {
-            // If we have a variable that contains region'd data, that
-            // data will be accessible from anywhere that the variable is
-            // accessed. We must be wary of loops like this:
-            //
-            //     // from src/test/compile-fail/borrowck-lend-flow.rs
-            //     let mut v = box 3, w = box 4;
-            //     let mut x = &mut w;
-            //     loop {
-            //         **x += 1;   // (2)
-            //         borrow(v);  //~ ERROR cannot borrow
-            //         x = &mut v; // (1)
-            //     }
-            //
-            // Typically, we try to determine the region of a borrow from
-            // those points where it is dereferenced. In this case, one
-            // might imagine that the lifetime of `x` need only be the
-            // body of the loop. But of course this is incorrect because
-            // the pointer that is created at point (1) is consumed at
-            // point (2), meaning that it must be live across the loop
-            // iteration. The easiest way to guarantee this is to require
-            // that the lifetime of any regions that appear in a
-            // variable's type enclose at least the variable's scope.
-            let var_scope = self.region_scope_tree.var_scope(hir_id.local_id);
-            let var_region = self.tcx.mk_region(ty::ReScope(var_scope));
-
-            let origin = infer::BindingTypeIsNotValidAtDecl(span);
-            self.type_of_node_must_outlive(origin, hir_id, var_region);
-
             let typ = self.resolve_node_type(hir_id);
             let body_id = self.body_id;
             let _ = dropck::check_drop_obligations(self, typ, span, body_id);
@@ -433,7 +364,6 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> {
         // `visit_fn_body`.  We will restore afterwards.
         let old_body_id = self.body_id;
         let old_body_owner = self.body_owner;
-        let old_call_site_scope = self.call_site_scope;
         let env_snapshot = self.outlives_environment.push_snapshot_pre_closure();
 
         let body = self.tcx.hir().body(body_id);
@@ -441,7 +371,6 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> {
 
         // Restore state from previous function.
         self.outlives_environment.pop_snapshot_post_closure(env_snapshot);
-        self.call_site_scope = old_call_site_scope;
         self.body_id = old_body_id;
         self.body_owner = old_body_owner;
     }
@@ -462,42 +391,6 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> {
     }
 
     fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
-        debug!("regionck::visit_expr(e={:?}, repeating_scope={:?})", expr, self.repeating_scope);
-
-        // No matter what, the type of each expression must outlive the
-        // scope of that expression. This also guarantees basic WF.
-        let expr_ty = self.resolve_node_type(expr.hir_id);
-        // the region corresponding to this expression
-        let expr_region = self.tcx.mk_region(ty::ReScope(region::Scope {
-            id: expr.hir_id.local_id,
-            data: region::ScopeData::Node,
-        }));
-        self.type_must_outlive(
-            infer::ExprTypeIsNotInScope(expr_ty, expr.span),
-            expr_ty,
-            expr_region,
-        );
-
-        let is_method_call = self.tables.borrow().is_method_call(expr);
-
-        // If we are calling a method (either explicitly or via an
-        // overloaded operator), check that all of the types provided as
-        // arguments for its type parameters are well-formed, and all the regions
-        // provided as arguments outlive the call.
-        if is_method_call {
-            let origin = match expr.kind {
-                hir::ExprKind::MethodCall(..) => infer::ParameterOrigin::MethodCall,
-                hir::ExprKind::Unary(op, _) if op == hir::UnOp::UnDeref => {
-                    infer::ParameterOrigin::OverloadedDeref
-                }
-                _ => infer::ParameterOrigin::OverloadedOperator,
-            };
-
-            let substs = self.tables.borrow().node_substs(expr.hir_id);
-            self.substs_wf_in_scope(origin, substs, expr.span, expr_region);
-            // Arguments (sub-expressions) are checked via `constrain_call`, below.
-        }
-
         // Check any autoderefs or autorefs that appear.
         let cmt_result = self.constrain_adjustments(expr);
 
@@ -512,117 +405,10 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> {
             }
         }
 
-        debug!(
-            "regionck::visit_expr(e={:?}, repeating_scope={:?}) - visiting subexprs",
-            expr, self.repeating_scope
-        );
         match expr.kind {
-            hir::ExprKind::Path(_) => {
-                let substs = self.tables.borrow().node_substs(expr.hir_id);
-                let origin = infer::ParameterOrigin::Path;
-                self.substs_wf_in_scope(origin, substs, expr.span, expr_region);
-            }
-
-            hir::ExprKind::Call(ref callee, ref args) => {
-                if is_method_call {
-                    self.constrain_call(expr, Some(&callee), args.iter().map(|e| &*e));
-                } else {
-                    self.constrain_callee(&callee);
-                    self.constrain_call(expr, None, args.iter().map(|e| &*e));
-                }
-
-                intravisit::walk_expr(self, expr);
-            }
-
-            hir::ExprKind::MethodCall(.., ref args) => {
-                self.constrain_call(expr, Some(&args[0]), args[1..].iter().map(|e| &*e));
-
-                intravisit::walk_expr(self, expr);
-            }
-
-            hir::ExprKind::AssignOp(_, ref lhs, ref rhs) => {
-                if is_method_call {
-                    self.constrain_call(expr, Some(&lhs), Some(&**rhs).into_iter());
-                }
-
-                intravisit::walk_expr(self, expr);
-            }
-
-            hir::ExprKind::Index(ref lhs, ref rhs) if is_method_call => {
-                self.constrain_call(expr, Some(&lhs), Some(&**rhs).into_iter());
-
-                intravisit::walk_expr(self, expr);
-            }
-
-            hir::ExprKind::Binary(_, ref lhs, ref rhs) if is_method_call => {
-                // As `ExprKind::MethodCall`, but the call is via an overloaded op.
-                self.constrain_call(expr, Some(&lhs), Some(&**rhs).into_iter());
-
-                intravisit::walk_expr(self, expr);
-            }
-
-            hir::ExprKind::Binary(_, ref lhs, ref rhs) => {
-                // If you do `x OP y`, then the types of `x` and `y` must
-                // outlive the operation you are performing.
-                let lhs_ty = self.resolve_expr_type_adjusted(&lhs);
-                let rhs_ty = self.resolve_expr_type_adjusted(&rhs);
-                for &ty in &[lhs_ty, rhs_ty] {
-                    self.type_must_outlive(infer::Operand(expr.span), ty, expr_region);
-                }
-                intravisit::walk_expr(self, expr);
-            }
-
-            hir::ExprKind::Unary(hir::UnOp::UnDeref, ref base) => {
-                // For *a, the lifetime of a must enclose the deref
-                if is_method_call {
-                    self.constrain_call(expr, Some(base), None::<hir::Expr<'_>>.iter());
-                }
-                // For overloaded derefs, base_ty is the input to `Deref::deref`,
-                // but it's a reference type uing the same region as the output.
-                let base_ty = self.resolve_expr_type_adjusted(base);
-                if let ty::Ref(r_ptr, _, _) = base_ty.kind {
-                    self.mk_subregion_due_to_dereference(expr.span, expr_region, r_ptr);
-                }
-
-                intravisit::walk_expr(self, expr);
-            }
-
-            hir::ExprKind::Unary(_, ref lhs) if is_method_call => {
-                // As above.
-                self.constrain_call(expr, Some(&lhs), None::<hir::Expr<'_>>.iter());
-
-                intravisit::walk_expr(self, expr);
-            }
-
-            hir::ExprKind::Index(ref vec_expr, _) => {
-                // For a[b], the lifetime of a must enclose the deref
-                let vec_type = self.resolve_expr_type_adjusted(&vec_expr);
-                self.constrain_index(expr, vec_type);
-
-                intravisit::walk_expr(self, expr);
-            }
-
-            hir::ExprKind::Cast(ref source, _) => {
-                // Determine if we are casting `source` to a trait
-                // instance.  If so, we have to be sure that the type of
-                // the source obeys the trait's region bound.
-                self.constrain_cast(expr, &source);
-                intravisit::walk_expr(self, expr);
-            }
-
             hir::ExprKind::AddrOf(hir::BorrowKind::Ref, m, ref base) => {
                 self.link_addr_of(expr, m, &base);
 
-                // Require that when you write a `&expr` expression, the
-                // resulting pointer has a lifetime that encompasses the
-                // `&expr` expression itself. Note that we constraining
-                // the type of the node expr.id here *before applying
-                // adjustments*.
-                //
-                // FIXME(https://github.com/rust-lang/rfcs/issues/811)
-                // nested method calls requires that this rule change
-                let ty0 = self.resolve_node_type(expr.hir_id);
-                self.type_must_outlive(infer::AddrOf(expr.span), ty0, expr_region);
                 intravisit::walk_expr(self, expr);
             }
 
@@ -632,140 +418,12 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> {
                 intravisit::walk_expr(self, expr);
             }
 
-            hir::ExprKind::Closure(.., body_id, _, _) => {
-                self.check_expr_fn_block(expr, body_id);
-            }
-
-            hir::ExprKind::Loop(ref body, _, _) => {
-                let repeating_scope = self.set_repeating_scope(body.hir_id);
-                intravisit::walk_expr(self, expr);
-                self.set_repeating_scope(repeating_scope);
-            }
-
-            hir::ExprKind::Ret(Some(ref ret_expr)) => {
-                let call_site_scope = self.call_site_scope;
-                debug!(
-                    "visit_expr ExprKind::Ret ret_expr.hir_id {} call_site_scope: {:?}",
-                    ret_expr.hir_id, call_site_scope
-                );
-                let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope.unwrap()));
-                self.type_of_node_must_outlive(
-                    infer::CallReturn(ret_expr.span),
-                    ret_expr.hir_id,
-                    call_site_region,
-                );
-                intravisit::walk_expr(self, expr);
-            }
-
-            _ => {
-                intravisit::walk_expr(self, expr);
-            }
+            _ => intravisit::walk_expr(self, expr),
         }
     }
 }
 
 impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
-    fn constrain_cast(&mut self, cast_expr: &hir::Expr<'_>, source_expr: &hir::Expr<'_>) {
-        debug!("constrain_cast(cast_expr={:?}, source_expr={:?})", cast_expr, source_expr);
-
-        let source_ty = self.resolve_node_type(source_expr.hir_id);
-        let target_ty = self.resolve_node_type(cast_expr.hir_id);
-
-        self.walk_cast(cast_expr, source_ty, target_ty);
-    }
-
-    fn walk_cast(&mut self, cast_expr: &hir::Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) {
-        debug!("walk_cast(from_ty={:?}, to_ty={:?})", from_ty, to_ty);
-        match (&from_ty.kind, &to_ty.kind) {
-            /*From:*/
-            (&ty::Ref(from_r, from_ty, _), /*To:  */ &ty::Ref(to_r, to_ty, _)) => {
-                // Target cannot outlive source, naturally.
-                self.sub_regions(infer::Reborrow(cast_expr.span), to_r, from_r);
-                self.walk_cast(cast_expr, from_ty, to_ty);
-            }
-
-            /*From:*/
-            (_, /*To:  */ &ty::Dynamic(.., r)) => {
-                // When T is existentially quantified as a trait
-                // `Foo+'to`, it must outlive the region bound `'to`.
-                self.type_must_outlive(infer::RelateObjectBound(cast_expr.span), from_ty, r);
-            }
-
-            /*From:*/
-            (&ty::Adt(from_def, _), /*To:  */ &ty::Adt(to_def, _))
-                if from_def.is_box() && to_def.is_box() =>
-            {
-                self.walk_cast(cast_expr, from_ty.boxed_ty(), to_ty.boxed_ty());
-            }
-
-            _ => {}
-        }
-    }
-
-    fn check_expr_fn_block(&mut self, expr: &'tcx hir::Expr<'tcx>, body_id: hir::BodyId) {
-        let repeating_scope = self.set_repeating_scope(body_id.hir_id);
-        intravisit::walk_expr(self, expr);
-        self.set_repeating_scope(repeating_scope);
-    }
-
-    fn constrain_callee(&mut self, callee_expr: &hir::Expr<'_>) {
-        let callee_ty = self.resolve_node_type(callee_expr.hir_id);
-        match callee_ty.kind {
-            ty::FnDef(..) | ty::FnPtr(_) => {}
-            _ => {
-                // this should not happen, but it does if the program is
-                // erroneous
-                //
-                // bug!(
-                //     callee_expr.span,
-                //     "Calling non-function: {}",
-                //     callee_ty);
-            }
-        }
-    }
-
-    fn constrain_call<'b, I: Iterator<Item = &'b hir::Expr<'b>>>(
-        &mut self,
-        call_expr: &hir::Expr<'_>,
-        receiver: Option<&hir::Expr<'_>>,
-        arg_exprs: I,
-    ) {
-        //! Invoked on every call site (i.e., normal calls, method calls,
-        //! and overloaded operators). Constrains the regions which appear
-        //! in the type of the function. Also constrains the regions that
-        //! appear in the arguments appropriately.
-
-        debug!("constrain_call(call_expr={:?}, receiver={:?})", call_expr, receiver);
-
-        // `callee_region` is the scope representing the time in which the
-        // call occurs.
-        //
-        // FIXME(#6268) to support nested method calls, should be callee_id
-        let callee_scope =
-            region::Scope { id: call_expr.hir_id.local_id, data: region::ScopeData::Node };
-        let callee_region = self.tcx.mk_region(ty::ReScope(callee_scope));
-
-        debug!("callee_region={:?}", callee_region);
-
-        for arg_expr in arg_exprs {
-            debug!("argument: {:?}", arg_expr);
-
-            // ensure that any regions appearing in the argument type are
-            // valid for at least the lifetime of the function:
-            self.type_of_node_must_outlive(
-                infer::CallArg(arg_expr.span),
-                arg_expr.hir_id,
-                callee_region,
-            );
-        }
-
-        // as loop above, but for receiver
-        if let Some(r) = receiver {
-            debug!("receiver: {:?}", r);
-            self.type_of_node_must_outlive(infer::CallRcvr(r.span), r.hir_id, callee_region);
-        }
-    }
-
     /// Creates a temporary `MemCategorizationContext` and pass it to the closure.
     fn with_mc<F, R>(&self, f: F) -> R
     where
@@ -784,79 +442,40 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
     fn constrain_adjustments(&mut self, expr: &hir::Expr<'_>) -> mc::McResult<mc::Place<'tcx>> {
         debug!("constrain_adjustments(expr={:?})", expr);
 
-        let mut cmt = self.with_mc(|mc| mc.cat_expr_unadjusted(expr))?;
+        let mut place = self.with_mc(|mc| mc.cat_expr_unadjusted(expr))?;
 
         let tables = self.tables.borrow();
         let adjustments = tables.expr_adjustments(&expr);
         if adjustments.is_empty() {
-            return Ok(cmt);
+            return Ok(place);
         }
 
         debug!("constrain_adjustments: adjustments={:?}", adjustments);
 
         // If necessary, constrain destructors in the unadjusted form of this
         // expression.
-        self.check_safety_of_rvalue_destructor_if_necessary(&cmt, expr.span);
+        self.check_safety_of_rvalue_destructor_if_necessary(&place, expr.span);
 
-        let expr_region = self.tcx.mk_region(ty::ReScope(region::Scope {
-            id: expr.hir_id.local_id,
-            data: region::ScopeData::Node,
-        }));
         for adjustment in adjustments {
-            debug!("constrain_adjustments: adjustment={:?}, cmt={:?}", adjustment, cmt);
+            debug!("constrain_adjustments: adjustment={:?}, place={:?}", adjustment, place);
 
             if let adjustment::Adjust::Deref(Some(deref)) = adjustment.kind {
-                debug!("constrain_adjustments: overloaded deref: {:?}", deref);
-
-                // Treat overloaded autoderefs as if an AutoBorrow adjustment
-                // was applied on the base type, as that is always the case.
-                let input = self
-                    .tcx
-                    .mk_ref(deref.region, ty::TypeAndMut { ty: cmt.ty, mutbl: deref.mutbl });
-                let output = self.tcx.mk_ref(
-                    deref.region,
-                    ty::TypeAndMut { ty: adjustment.target, mutbl: deref.mutbl },
-                );
-
                 self.link_region(
                     expr.span,
                     deref.region,
                     ty::BorrowKind::from_mutbl(deref.mutbl),
-                    &cmt,
+                    &place,
                 );
-
-                // Specialized version of constrain_call.
-                self.type_must_outlive(infer::CallRcvr(expr.span), input, expr_region);
-                self.type_must_outlive(infer::CallReturn(expr.span), output, expr_region);
             }
 
             if let adjustment::Adjust::Borrow(ref autoref) = adjustment.kind {
-                self.link_autoref(expr, &cmt, autoref);
-
-                // Require that the resulting region encompasses
-                // the current node.
-                //
-                // FIXME(#6268) remove to support nested method calls
-                self.type_of_node_must_outlive(
-                    infer::AutoBorrow(expr.span),
-                    expr.hir_id,
-                    expr_region,
-                );
+                self.link_autoref(expr, &place, autoref);
             }
 
-            cmt = self.with_mc(|mc| mc.cat_expr_adjusted(expr, cmt, &adjustment))?;
+            place = self.with_mc(|mc| mc.cat_expr_adjusted(expr, place, &adjustment))?;
         }
 
-        Ok(cmt)
-    }
-
-    pub fn mk_subregion_due_to_dereference(
-        &mut self,
-        deref_span: Span,
-        minimum_lifetime: ty::Region<'tcx>,
-        maximum_lifetime: ty::Region<'tcx>,
-    ) {
-        self.sub_regions(infer::DerefPointer(deref_span), minimum_lifetime, maximum_lifetime)
+        Ok(place)
     }
 
     fn check_safety_of_rvalue_destructor_if_necessary(
@@ -872,59 +491,6 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
             }
         }
     }
-
-    /// Invoked on any index expression that occurs. Checks that if this is a slice
-    /// being indexed, the lifetime of the pointer includes the deref expr.
-    fn constrain_index(&mut self, index_expr: &hir::Expr<'_>, indexed_ty: Ty<'tcx>) {
-        debug!("constrain_index(index_expr=?, indexed_ty={}", self.ty_to_string(indexed_ty));
-
-        let r_index_expr = ty::ReScope(region::Scope {
-            id: index_expr.hir_id.local_id,
-            data: region::ScopeData::Node,
-        });
-        if let ty::Ref(r_ptr, r_ty, _) = indexed_ty.kind {
-            match r_ty.kind {
-                ty::Slice(_) | ty::Str => {
-                    self.sub_regions(
-                        infer::IndexSlice(index_expr.span),
-                        self.tcx.mk_region(r_index_expr),
-                        r_ptr,
-                    );
-                }
-                _ => {}
-            }
-        }
-    }
-
-    /// Guarantees that any lifetimes that appear in the type of the node `id` (after applying
-    /// adjustments) are valid for at least `minimum_lifetime`.
-    fn type_of_node_must_outlive(
-        &mut self,
-        origin: infer::SubregionOrigin<'tcx>,
-        hir_id: hir::HirId,
-        minimum_lifetime: ty::Region<'tcx>,
-    ) {
-        // Try to resolve the type.  If we encounter an error, then typeck
-        // is going to fail anyway, so just stop here and let typeck
-        // report errors later on in the writeback phase.
-        let ty0 = self.resolve_node_type(hir_id);
-
-        let ty = self
-            .tables
-            .borrow()
-            .adjustments()
-            .get(hir_id)
-            .and_then(|adj| adj.last())
-            .map_or(ty0, |adj| adj.target);
-        let ty = self.resolve_type(ty);
-        debug!(
-            "constrain_regions_in_type_of_node(\
-             ty={}, ty0={}, id={:?}, minimum_lifetime={:?})",
-            ty, ty0, hir_id, minimum_lifetime
-        );
-        self.type_must_outlive(origin, ty, minimum_lifetime);
-    }
-
     /// Adds constraints to inference such that `T: 'a` holds (or
     /// reports an error if it cannot).
     ///
@@ -1035,13 +601,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
                 self.link_region(expr.span, r, ty::BorrowKind::from_mutbl(m.into()), expr_cmt);
             }
 
-            adjustment::AutoBorrow::RawPtr(m) => {
-                let r = self.tcx.mk_region(ty::ReScope(region::Scope {
-                    id: expr.hir_id.local_id,
-                    data: region::ScopeData::Node,
-                }));
-                self.link_region(expr.span, r, ty::BorrowKind::from_mutbl(m), expr_cmt);
-            }
+            adjustment::AutoBorrow::RawPtr(_) => {}
         }
     }
 
@@ -1251,39 +811,4 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
             }
         }
     }
-
-    /// Checks that the values provided for type/region arguments in a given
-    /// expression are well-formed and in-scope.
-    fn substs_wf_in_scope(
-        &mut self,
-        origin: infer::ParameterOrigin,
-        substs: SubstsRef<'tcx>,
-        expr_span: Span,
-        expr_region: ty::Region<'tcx>,
-    ) {
-        debug!(
-            "substs_wf_in_scope(substs={:?}, \
-             expr_region={:?}, \
-             origin={:?}, \
-             expr_span={:?})",
-            substs, expr_region, origin, expr_span
-        );
-
-        let origin = infer::ParameterInScope(origin, expr_span);
-
-        for kind in substs {
-            match kind.unpack() {
-                GenericArgKind::Lifetime(lt) => {
-                    self.sub_regions(origin.clone(), expr_region, lt);
-                }
-                GenericArgKind::Type(ty) => {
-                    let ty = self.resolve_type(ty);
-                    self.type_must_outlive(origin.clone(), ty, expr_region);
-                }
-                GenericArgKind::Const(_) => {
-                    // Const parameters don't impose constraints.
-                }
-            }
-        }
-    }
 }
diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs
index efa3cd9955b..c5dd314dc65 100644
--- a/src/librustc_typeck/coherence/builtin.rs
+++ b/src/librustc_typeck/coherence/builtin.rs
@@ -11,7 +11,6 @@ use rustc_hir::ItemKind;
 use rustc_infer::infer;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{RegionckMode, TyCtxtInferExt};
-use rustc_middle::middle::region;
 use rustc_middle::ty::adjustment::CoerceUnsizedInfo;
 use rustc_middle::ty::TypeFoldable;
 use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -293,11 +292,9 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
                     }
 
                     // Finally, resolve all regions.
-                    let region_scope_tree = region::ScopeTree::default();
                     let outlives_env = OutlivesEnvironment::new(param_env);
                     infcx.resolve_regions_and_report_errors(
                         impl_did.to_def_id(),
-                        &region_scope_tree,
                         &outlives_env,
                         RegionckMode::default(),
                     );
@@ -552,14 +549,8 @@ pub fn coerce_unsized_info(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUnsizedI
         }
 
         // Finally, resolve all regions.
-        let region_scope_tree = region::ScopeTree::default();
         let outlives_env = OutlivesEnvironment::new(param_env);
-        infcx.resolve_regions_and_report_errors(
-            impl_did,
-            &region_scope_tree,
-            &outlives_env,
-            RegionckMode::default(),
-        );
+        infcx.resolve_regions_and_report_errors(impl_did, &outlives_env, 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 d30dc1b7a47..08404bea561 100644
--- a/src/librustc_typeck/impl_wf_check/min_specialization.rs
+++ b/src/librustc_typeck/impl_wf_check/min_specialization.rs
@@ -73,7 +73,6 @@ use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{InferCtxt, RegionckMode, TyCtxtInferExt};
 use rustc_infer::traits::specialization_graph::Node;
-use rustc_middle::middle::region::ScopeTree;
 use rustc_middle::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
 use rustc_middle::ty::trait_def::TraitSpecializationKind;
 use rustc_middle::ty::{self, InstantiatedPredicates, TyCtxt, TypeFoldable};
@@ -165,12 +164,7 @@ fn get_impl_substs<'tcx>(
 
     // Conservatively use an empty `ParamEnv`.
     let outlives_env = OutlivesEnvironment::new(ty::ParamEnv::empty());
-    infcx.resolve_regions_and_report_errors(
-        impl1_def_id,
-        &ScopeTree::default(),
-        &outlives_env,
-        RegionckMode::default(),
-    );
+    infcx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env, RegionckMode::default());
     let impl2_substs = match infcx.fully_resolve(&impl2_substs) {
         Ok(s) => s,
         Err(_) => {
diff --git a/src/librustc_typeck/outlives/utils.rs b/src/librustc_typeck/outlives/utils.rs
index 3bbe3e34a6a..8b069678796 100644
--- a/src/librustc_typeck/outlives/utils.rs
+++ b/src/librustc_typeck/outlives/utils.rs
@@ -170,7 +170,6 @@ fn is_free_region(tcx: TyCtxt<'_>, region: Region<'_>) -> bool {
 
         // These regions don't appear in types from type declarations:
         RegionKind::ReErased
-        | RegionKind::ReScope(..)
         | RegionKind::ReVar(..)
         | RegionKind::RePlaceholder(..)
         | RegionKind::ReFree(..) => {
diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs
index 3a680f55c8c..e04af6850de 100644
--- a/src/librustc_typeck/variance/constraints.rs
+++ b/src/librustc_typeck/variance/constraints.rs
@@ -444,7 +444,6 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
             }
 
             ty::ReFree(..)
-            | ty::ReScope(..)
             | ty::ReVar(..)
             | ty::RePlaceholder(..)
             | ty::ReEmpty(_)
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index cf1a39232bc..702c7d1e0f1 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -447,7 +447,6 @@ impl Clean<Option<Lifetime>> for ty::RegionKind {
 
             ty::ReLateBound(..)
             | ty::ReFree(..)
-            | ty::ReScope(..)
             | ty::ReVar(..)
             | ty::RePlaceholder(..)
             | ty::ReEmpty(_)
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index a3ee14e85d2..7dc822db3d0 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -272,7 +272,7 @@ impl Once {
     /// result in an immediate panic. If `f` panics, the `Once` will remain
     /// in a poison state. If `f` does _not_ panic, the `Once` will no
     /// longer be in a poison state and all future calls to `call_once` or
-    /// `call_one_force` will be no-ops.
+    /// `call_once_force` will be no-ops.
     ///
     /// The closure `f` is yielded a [`OnceState`] structure which can be used
     /// to query the poison status of the `Once`.
diff --git a/src/test/ui/ast-json/ast-json-noexpand-output.stdout b/src/test/ui/ast-json/ast-json-noexpand-output.stdout
index 1a07968bdf1..f60b6a00be1 100644
--- a/src/test/ui/ast-json/ast-json-noexpand-output.stdout
+++ b/src/test/ui/ast-json/ast-json-noexpand-output.stdout
@@ -1 +1 @@
-{"module":{"inner":{"lo":0,"hi":0},"items":[{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":{"_field0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["extern",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["core",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":"Semi","span":{"lo":0,"hi":0}}]},"NonJoint"]]}}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"_field0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"NonJoint"]]}]}}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
+{"module":{"inner":{"lo":0,"hi":0},"items":[{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":{"_field0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["extern",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["core",false]},"span":{"lo":0,"hi":0}}]},"Joint"],[{"variant":"Token","fields":[{"kind":"Semi","span":{"lo":0,"hi":0}}]},"NonJoint"]]}}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"_field0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"NonJoint"]]}]}}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
diff --git a/src/test/ui/ast-json/ast-json-output.stdout b/src/test/ui/ast-json/ast-json-output.stdout
index 0b3704e8e00..42e7e789980 100644
--- a/src/test/ui/ast-json/ast-json-output.stdout
+++ b/src/test/ui/ast-json/ast-json-output.stdout
@@ -1 +1 @@
-{"module":{"inner":{"lo":0,"hi":0},"items":[{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"prelude_import","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":"Empty"}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"","span":{"lo":0,"hi":0}},"kind":{"variant":"Use","fields":[{"prefix":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"{{root}}","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"std","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"prelude","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"v1","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"kind":"Glob","span":{"lo":0,"hi":0}}]},"tokens":null},{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"macro_use","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":"Empty"}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"std","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null},{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":{"_field0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["extern",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["core",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":"Semi","span":{"lo":0,"hi":0}}]},"NonJoint"]]}}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"_field0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"NonJoint"]]}]}}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
+{"module":{"inner":{"lo":0,"hi":0},"items":[{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"prelude_import","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":"Empty"}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"","span":{"lo":0,"hi":0}},"kind":{"variant":"Use","fields":[{"prefix":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"{{root}}","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"std","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"prelude","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"v1","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"kind":"Glob","span":{"lo":0,"hi":0}}]},"tokens":null},{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"macro_use","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":"Empty"}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"std","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null},{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":{"_field0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["extern",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["core",false]},"span":{"lo":0,"hi":0}}]},"Joint"],[{"variant":"Token","fields":[{"kind":"Semi","span":{"lo":0,"hi":0}}]},"NonJoint"]]}}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"_field0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"NonJoint"]]}]}}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
diff --git a/src/test/ui/borrowck/issue-45983.migrate.stderr b/src/test/ui/borrowck/issue-45983.migrate.stderr
deleted file mode 100644
index c1564cf07e6..00000000000
--- a/src/test/ui/borrowck/issue-45983.migrate.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error: borrowed data cannot be stored outside of its closure
-  --> $DIR/issue-45983.rs:20:27
-   |
-LL |     let x = None;
-   |         - borrowed data cannot be stored into here...
-LL |     give_any(|y| x = Some(y));
-   |              ---          ^ cannot be stored outside of its closure
-   |              |
-   |              ...because it cannot outlive this closure
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/borrowck/issue-45983.nll.stderr b/src/test/ui/borrowck/issue-45983.nll.stderr
deleted file mode 100644
index 51bb4dee676..00000000000
--- a/src/test/ui/borrowck/issue-45983.nll.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0521]: borrowed data escapes outside of closure
-  --> $DIR/issue-45983.rs:20:18
-   |
-LL |     let x = None;
-   |         - `x` declared here, outside of the closure body
-LL |     give_any(|y| x = Some(y));
-   |               -  ^^^^^^^^^^^ `y` escapes the closure body here
-   |               |
-   |               `y` is a reference that is only valid in the closure body
-
-error[E0594]: cannot assign to `x`, as it is not declared as mutable
-  --> $DIR/issue-45983.rs:20:18
-   |
-LL |     let x = None;
-   |         - help: consider changing this to be mutable: `mut x`
-LL |     give_any(|y| x = Some(y));
-   |                  ^^^^^^^^^^^ cannot assign
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0594`.
diff --git a/src/test/ui/borrowck/issue-45983.rs b/src/test/ui/borrowck/issue-45983.rs
index 3cd28207742..6784f6f86a0 100644
--- a/src/test/ui/borrowck/issue-45983.rs
+++ b/src/test/ui/borrowck/issue-45983.rs
@@ -1,24 +1,12 @@
 // As documented in Issue #45983, this test is evaluating the quality
 // of our diagnostics on erroneous code using higher-ranked closures.
 
-// revisions: migrate nll
-
-// Since we are testing nll (and migration) explicitly as a separate
-// revisions, don't worry about the --compare-mode=nll on this test.
-
-// ignore-compare-mode-nll
-// ignore-compare-mode-polonius
-
-//[nll]compile-flags: -Z borrowck=mir
-
 fn give_any<F: for<'r> FnOnce(&'r ())>(f: F) {
     f(&());
 }
 
 fn main() {
-    let x = None;
+    let mut x = None;
     give_any(|y| x = Some(y));
-    //[migrate]~^ ERROR borrowed data cannot be stored outside of its closure
-    //[nll]~^^ ERROR borrowed data escapes outside of closure
-    //[nll]~| ERROR cannot assign to `x`, as it is not declared as mutable
+    //~^ ERROR borrowed data escapes outside of closure
 }
diff --git a/src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr b/src/test/ui/borrowck/issue-45983.stderr
index 68a0fe0b4f0..efd414a2d44 100644
--- a/src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr
+++ b/src/test/ui/borrowck/issue-45983.stderr
@@ -1,9 +1,9 @@
 error[E0521]: borrowed data escapes outside of closure
-  --> $DIR/regions-escape-bound-fn-2.rs:8:18
+  --> $DIR/issue-45983.rs:10:18
    |
 LL |     let mut x = None;
    |         ----- `x` declared here, outside of the closure body
-LL |     with_int(|y| x = Some(y));
+LL |     give_any(|y| x = Some(y));
    |               -  ^^^^^^^^^^^ `y` escapes the closure body here
    |               |
    |               `y` is a reference that is only valid in the closure body
diff --git a/src/test/ui/borrowck/issue-7573.nll.stderr b/src/test/ui/borrowck/issue-7573.nll.stderr
deleted file mode 100644
index 20afecfe5de..00000000000
--- a/src/test/ui/borrowck/issue-7573.nll.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0521]: borrowed data escapes outside of closure
-  --> $DIR/issue-7573.rs:21:9
-   |
-LL |     let mut lines_to_use: Vec<&CrateId> = Vec::new();
-   |         ---------------- `lines_to_use` declared here, outside of the closure body
-LL |
-LL |     let push_id = |installed_id: &CrateId| {
-   |                    ------------ `installed_id` is a reference that is only valid in the closure body
-...
-LL |         lines_to_use.push(installed_id);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `installed_id` escapes the closure body here
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/borrowck/issue-7573.rs b/src/test/ui/borrowck/issue-7573.rs
index 20a6a5c92f1..7c07411533f 100644
--- a/src/test/ui/borrowck/issue-7573.rs
+++ b/src/test/ui/borrowck/issue-7573.rs
@@ -1,36 +1,34 @@
 pub struct CrateId {
     local_path: String,
-    junk: String
+    junk: String,
 }
 
 impl CrateId {
     fn new(s: &str) -> CrateId {
-        CrateId {
-            local_path: s.to_string(),
-            junk: "wutevs".to_string()
-        }
+        CrateId { local_path: s.to_string(), junk: "wutevs".to_string() }
     }
 }
 
 pub fn remove_package_from_database() {
     let mut lines_to_use: Vec<&CrateId> = Vec::new();
-        //~^ NOTE cannot infer an appropriate lifetime
+    //~^ NOTE `lines_to_use` declared here, outside of the closure body
     let push_id = |installed_id: &CrateId| {
-        //~^ NOTE borrowed data cannot outlive this closure
-        //~| NOTE ...so that variable is valid at time of its declaration
+        //~^ NOTE `installed_id` is a reference that is only valid in the closure body
         lines_to_use.push(installed_id);
-        //~^ ERROR borrowed data cannot be stored outside of its closure
-        //~| NOTE cannot be stored outside of its closure
+        //~^ ERROR borrowed data escapes outside of closure
+        //~| NOTE `installed_id` escapes the closure body here
     };
     list_database(push_id);
 
     for l in &lines_to_use {
         println!("{}", l.local_path);
     }
-
 }
 
-pub fn list_database<F>(mut f: F) where F: FnMut(&CrateId) {
+pub fn list_database<F>(mut f: F)
+where
+    F: FnMut(&CrateId),
+{
     let stuff = ["foo", "bar"];
 
     for l in &stuff {
diff --git a/src/test/ui/borrowck/issue-7573.stderr b/src/test/ui/borrowck/issue-7573.stderr
index 32b3ef72d8b..815419db833 100644
--- a/src/test/ui/borrowck/issue-7573.stderr
+++ b/src/test/ui/borrowck/issue-7573.stderr
@@ -1,16 +1,14 @@
-error: borrowed data cannot be stored outside of its closure
-  --> $DIR/issue-7573.rs:21:27
+error[E0521]: borrowed data escapes outside of closure
+  --> $DIR/issue-7573.rs:17:9
    |
 LL |     let mut lines_to_use: Vec<&CrateId> = Vec::new();
-   |                               - cannot infer an appropriate lifetime...
+   |         ---------------- `lines_to_use` declared here, outside of the closure body
 LL |
 LL |     let push_id = |installed_id: &CrateId| {
-   |         -------   ------------------------ borrowed data cannot outlive this closure
-   |         |
-   |         ...so that variable is valid at time of its declaration
-...
+   |                    ------------ `installed_id` is a reference that is only valid in the closure body
+LL |
 LL |         lines_to_use.push(installed_id);
-   |                           ^^^^^^^^^^^^ cannot be stored outside of its closure
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `installed_id` escapes the closure body here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/regions-escape-bound-fn-2.rs b/src/test/ui/borrowck/regions-escape-bound-fn-2.rs
index cb423032b46..0e98d98cf87 100644
--- a/src/test/ui/borrowck/regions-escape-bound-fn-2.rs
+++ b/src/test/ui/borrowck/regions-escape-bound-fn-2.rs
@@ -1,4 +1,7 @@
-fn with_int<F>(f: F) where F: FnOnce(&isize) {
+fn with_int<F>(f: F)
+where
+    F: FnOnce(&isize),
+{
     let x = 3;
     f(&x);
 }
@@ -6,5 +9,5 @@ fn with_int<F>(f: F) where F: FnOnce(&isize) {
 fn main() {
     let mut x = None;
     with_int(|y| x = Some(y));
-    //~^ ERROR borrowed data cannot be stored outside of its closure
+    //~^ ERROR borrowed data escapes outside of closure
 }
diff --git a/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr b/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr
index 4b37edafa12..1dc60bb1554 100644
--- a/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr
+++ b/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr
@@ -1,12 +1,12 @@
-error: borrowed data cannot be stored outside of its closure
-  --> $DIR/regions-escape-bound-fn-2.rs:8:27
+error[E0521]: borrowed data escapes outside of closure
+  --> $DIR/regions-escape-bound-fn-2.rs:11:18
    |
 LL |     let mut x = None;
-   |         ----- borrowed data cannot be stored into here...
+   |         ----- `x` declared here, outside of the closure body
 LL |     with_int(|y| x = Some(y));
-   |              ---          ^ cannot be stored outside of its closure
-   |              |
-   |              ...because it cannot outlive this closure
+   |               -  ^^^^^^^^^^^ `y` escapes the closure body here
+   |               |
+   |               `y` is a reference that is only valid in the closure body
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr b/src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr
deleted file mode 100644
index d304de92c7e..00000000000
--- a/src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0521]: borrowed data escapes outside of closure
-  --> $DIR/regions-escape-bound-fn.rs:8:18
-   |
-LL |     let mut x: Option<&isize> = None;
-   |         ----- `x` declared here, outside of the closure body
-LL |     with_int(|y| x = Some(y));
-   |               -  ^^^^^^^^^^^ `y` escapes the closure body here
-   |               |
-   |               `y` is a reference that is only valid in the closure body
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/borrowck/regions-escape-bound-fn.rs b/src/test/ui/borrowck/regions-escape-bound-fn.rs
index 772df3e6c58..f896ae7bdad 100644
--- a/src/test/ui/borrowck/regions-escape-bound-fn.rs
+++ b/src/test/ui/borrowck/regions-escape-bound-fn.rs
@@ -1,4 +1,7 @@
-fn with_int<F>(f: F) where F: FnOnce(&isize) {
+fn with_int<F>(f: F)
+where
+    F: FnOnce(&isize),
+{
     let x = 3;
     f(&x);
 }
@@ -6,5 +9,5 @@ fn with_int<F>(f: F) where F: FnOnce(&isize) {
 fn main() {
     let mut x: Option<&isize> = None;
     with_int(|y| x = Some(y));
-    //~^ ERROR borrowed data cannot be stored outside of its closure
+    //~^ ERROR borrowed data escapes outside of closure
 }
diff --git a/src/test/ui/borrowck/regions-escape-bound-fn.stderr b/src/test/ui/borrowck/regions-escape-bound-fn.stderr
index 4973d5306f9..5c548ec2876 100644
--- a/src/test/ui/borrowck/regions-escape-bound-fn.stderr
+++ b/src/test/ui/borrowck/regions-escape-bound-fn.stderr
@@ -1,12 +1,12 @@
-error: borrowed data cannot be stored outside of its closure
-  --> $DIR/regions-escape-bound-fn.rs:8:27
+error[E0521]: borrowed data escapes outside of closure
+  --> $DIR/regions-escape-bound-fn.rs:11:18
    |
 LL |     let mut x: Option<&isize> = None;
-   |         ----- borrowed data cannot be stored into here...
+   |         ----- `x` declared here, outside of the closure body
 LL |     with_int(|y| x = Some(y));
-   |              ---          ^ cannot be stored outside of its closure
-   |              |
-   |              ...because it cannot outlive this closure
+   |               -  ^^^^^^^^^^^ `y` escapes the closure body here
+   |               |
+   |               `y` is a reference that is only valid in the closure body
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr b/src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr
deleted file mode 100644
index d9931302f75..00000000000
--- a/src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0521]: borrowed data escapes outside of closure
-  --> $DIR/regions-escape-unboxed-closure.rs:6:23
-   |
-LL |     let mut x: Option<&isize> = None;
-   |         ----- `x` declared here, outside of the closure body
-LL |     with_int(&mut |y| x = Some(y));
-   |                    -  ^^^^^^^^^^^ `y` escapes the closure body here
-   |                    |
-   |                    `y` is a reference that is only valid in the closure body
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/borrowck/regions-escape-unboxed-closure.rs b/src/test/ui/borrowck/regions-escape-unboxed-closure.rs
index d8bef927fd7..f01e47122d1 100644
--- a/src/test/ui/borrowck/regions-escape-unboxed-closure.rs
+++ b/src/test/ui/borrowck/regions-escape-unboxed-closure.rs
@@ -1,8 +1,7 @@
-fn with_int(f: &mut dyn FnMut(&isize)) {
-}
+fn with_int(f: &mut dyn FnMut(&isize)) {}
 
 fn main() {
     let mut x: Option<&isize> = None;
     with_int(&mut |y| x = Some(y));
-    //~^ ERROR borrowed data cannot be stored outside of its closure
+    //~^ ERROR borrowed data escapes outside of closure
 }
diff --git a/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr b/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr
index 047e290acae..f2a49e70d27 100644
--- a/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr
+++ b/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr
@@ -1,12 +1,12 @@
-error: borrowed data cannot be stored outside of its closure
-  --> $DIR/regions-escape-unboxed-closure.rs:6:32
+error[E0521]: borrowed data escapes outside of closure
+  --> $DIR/regions-escape-unboxed-closure.rs:5:23
    |
 LL |     let mut x: Option<&isize> = None;
-   |         ----- borrowed data cannot be stored into here...
+   |         ----- `x` declared here, outside of the closure body
 LL |     with_int(&mut |y| x = Some(y));
-   |                   ---          ^ cannot be stored outside of its closure
-   |                   |
-   |                   ...because it cannot outlive this closure
+   |                    -  ^^^^^^^^^^^ `y` escapes the closure body here
+   |                    |
+   |                    `y` is a reference that is only valid in the closure body
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr b/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr
deleted file mode 100644
index 89107e799bd..00000000000
--- a/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr
+++ /dev/null
@@ -1,123 +0,0 @@
-error: lifetime may not live long enough
-  --> $DIR/variadic-ffi-4.rs:8:5
-   |
-LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> {
-   |                                     --            -- has type `core::ffi::VaListImpl<'1>`
-   |                                     |
-   |                                     lifetime `'f` defined here
-LL |     ap
-   |     ^^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'f`
-
-error: lifetime may not live long enough
-  --> $DIR/variadic-ffi-4.rs:8:5
-   |
-LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> {
-   |                                     --            -- has type `core::ffi::VaListImpl<'1>`
-   |                                     |
-   |                                     lifetime `'f` defined here
-LL |     ap
-   |     ^^ returning this value requires that `'1` must outlive `'f`
-
-error: lifetime may not live long enough
-  --> $DIR/variadic-ffi-4.rs:12:5
-   |
-LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> {
-   |                                               -- has type `core::ffi::VaListImpl<'1>`
-LL |     ap
-   |     ^^ returning this value requires that `'1` must outlive `'static`
-
-error: lifetime may not live long enough
-  --> $DIR/variadic-ffi-4.rs:16:33
-   |
-LL |     let _ = ap.with_copy(|ap| { ap });
-   |                           ---   ^^ returning this value requires that `'1` must outlive `'2`
-   |                           | |
-   |                           | return type of closure is core::ffi::VaList<'2, '_>
-   |                           has type `core::ffi::VaList<'1, '_>`
-
-error: lifetime may not live long enough
-  --> $DIR/variadic-ffi-4.rs:20:5
-   |
-LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
-   |                                               -------                   ------- has type `core::ffi::VaListImpl<'2>`
-   |                                               |
-   |                                               has type `&mut core::ffi::VaListImpl<'1>`
-LL |     *ap0 = ap1;
-   |     ^^^^ assignment requires that `'1` must outlive `'2`
-
-error: lifetime may not live long enough
-  --> $DIR/variadic-ffi-4.rs:20:5
-   |
-LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
-   |                                               -------                   ------- has type `core::ffi::VaListImpl<'2>`
-   |                                               |
-   |                                               has type `&mut core::ffi::VaListImpl<'1>`
-LL |     *ap0 = ap1;
-   |     ^^^^ assignment requires that `'2` must outlive `'1`
-
-error: lifetime may not live long enough
-  --> $DIR/variadic-ffi-4.rs:24:5
-   |
-LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
-   |                                               ---                   ------- has type `core::ffi::VaListImpl<'2>`
-   |                                               |
-   |                                               has type `&mut core::ffi::VaListImpl<'1>`
-LL |     ap0 = &mut ap1;
-   |     ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2`
-
-error: lifetime may not live long enough
-  --> $DIR/variadic-ffi-4.rs:24:5
-   |
-LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
-   |                                               ---                   ------- has type `core::ffi::VaListImpl<'2>`
-   |                                               |
-   |                                               has type `&mut core::ffi::VaListImpl<'1>`
-LL |     ap0 = &mut ap1;
-   |     ^^^^^^^^^^^^^^ assignment requires that `'2` must outlive `'1`
-
-error[E0384]: cannot assign to immutable argument `ap0`
-  --> $DIR/variadic-ffi-4.rs:24:5
-   |
-LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
-   |                                               --- help: make this binding mutable: `mut ap0`
-LL |     ap0 = &mut ap1;
-   |     ^^^^^^^^^^^^^^ cannot assign to immutable argument
-
-error[E0597]: `ap1` does not live long enough
-  --> $DIR/variadic-ffi-4.rs:24:11
-   |
-LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
-   |                                                    - let's call the lifetime of this reference `'3`
-LL |     ap0 = &mut ap1;
-   |     ------^^^^^^^^
-   |     |     |
-   |     |     borrowed value does not live long enough
-   |     assignment requires that `ap1` is borrowed for `'3`
-...
-LL | }
-   | - `ap1` dropped here while still borrowed
-
-error: lifetime may not live long enough
-  --> $DIR/variadic-ffi-4.rs:31:12
-   |
-LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
-   |                                               -------                   ------- has type `core::ffi::VaListImpl<'2>`
-   |                                               |
-   |                                               has type `&mut core::ffi::VaListImpl<'1>`
-LL |     *ap0 = ap1.clone();
-   |            ^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
-
-error: lifetime may not live long enough
-  --> $DIR/variadic-ffi-4.rs:31:12
-   |
-LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
-   |                                               -------                   ------- has type `core::ffi::VaListImpl<'2>`
-   |                                               |
-   |                                               has type `&mut core::ffi::VaListImpl<'1>`
-LL |     *ap0 = ap1.clone();
-   |            ^^^^^^^^^^^ argument requires that `'2` must outlive `'1`
-
-error: aborting due to 12 previous errors
-
-Some errors have detailed explanations: E0384, E0597.
-For more information about an error, try `rustc --explain E0384`.
diff --git a/src/test/ui/c-variadic/variadic-ffi-4.rs b/src/test/ui/c-variadic/variadic-ffi-4.rs
index a4d658cef16..80640379422 100644
--- a/src/test/ui/c-variadic/variadic-ffi-4.rs
+++ b/src/test/ui/c-variadic/variadic-ffi-4.rs
@@ -1,32 +1,38 @@
-#![crate_type="lib"]
+#![crate_type = "lib"]
 #![no_std]
 #![feature(c_variadic)]
 
 use core::ffi::{VaList, VaListImpl};
 
 pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> {
-    ap //~ ERROR: mismatched types
+    ap
+    //~^ ERROR: lifetime may not live long enough
+    //~| ERROR: lifetime may not live long enough
 }
 
 pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> {
-    ap //~ ERROR: mismatched types
+    ap //~ ERROR: lifetime may not live long enough
 }
 
 pub unsafe extern "C" fn no_escape2(_: usize, ap: ...) {
-    let _ = ap.with_copy(|ap| { ap }); //~ ERROR: cannot infer an appropriate lifetime
+    let _ = ap.with_copy(|ap| ap); //~ ERROR: lifetime may not live long enough
 }
 
 pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
-    *ap0 = ap1; //~ ERROR: mismatched types
+    *ap0 = ap1;
+    //~^ ERROR: lifetime may not live long enough
+    //~| ERROR: lifetime may not live long enough
 }
 
-pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
+pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
     ap0 = &mut ap1;
-    //~^ ERROR: a value of type `core::ffi::VaListImpl<'_>` is borrowed for too long
-    //~| ERROR: mismatched types
-    //~| ERROR: cannot infer an appropriate lifetime
+    //~^ ERROR: `ap1` does not live long enough
+    //~| ERROR: lifetime may not live long enough
+    //~| ERROR: lifetime may not live long enough
 }
 
 pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
-    *ap0 = ap1.clone(); //~ ERROR: mismatched types
+    *ap0 = ap1.clone();
+    //~^ ERROR: lifetime may not live long enough
+    //~| ERROR: lifetime may not live long enough
 }
diff --git a/src/test/ui/c-variadic/variadic-ffi-4.stderr b/src/test/ui/c-variadic/variadic-ffi-4.stderr
index cd4cd8b198d..65623501569 100644
--- a/src/test/ui/c-variadic/variadic-ffi-4.stderr
+++ b/src/test/ui/c-variadic/variadic-ffi-4.stderr
@@ -1,217 +1,114 @@
-error[E0308]: mismatched types
+error: lifetime may not live long enough
   --> $DIR/variadic-ffi-4.rs:8:5
    |
+LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> {
+   |                                     --            -- has type `core::ffi::VaListImpl<'1>`
+   |                                     |
+   |                                     lifetime `'f` defined here
 LL |     ap
-   |     ^^ lifetime mismatch
-   |
-   = note: expected struct `core::ffi::VaListImpl<'f>`
-              found struct `core::ffi::VaListImpl<'_>`
-note: the scope of call-site for function at 7:78...
-  --> $DIR/variadic-ffi-4.rs:7:78
-   |
-LL |   pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> {
-   |  ______________________________________________________________________________^
-LL | |     ap
-LL | | }
-   | |_^
-note: ...does not necessarily outlive the lifetime `'f` as defined on the function body at 7:37
-  --> $DIR/variadic-ffi-4.rs:7:37
+   |     ^^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'f`
+
+error: lifetime may not live long enough
+  --> $DIR/variadic-ffi-4.rs:8:5
    |
 LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> {
-   |                                     ^^
+   |                                     --            -- has type `core::ffi::VaListImpl<'1>`
+   |                                     |
+   |                                     lifetime `'f` defined here
+LL |     ap
+   |     ^^ returning this value requires that `'1` must outlive `'f`
 
-error[E0308]: mismatched types
-  --> $DIR/variadic-ffi-4.rs:12:5
+error: lifetime may not live long enough
+  --> $DIR/variadic-ffi-4.rs:14:5
    |
+LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> {
+   |                                               -- has type `core::ffi::VaListImpl<'1>`
 LL |     ap
-   |     ^^ lifetime mismatch
-   |
-   = note: expected struct `core::ffi::VaListImpl<'static>`
-              found struct `core::ffi::VaListImpl<'_>`
-note: the scope of call-site for function at 11:79...
-  --> $DIR/variadic-ffi-4.rs:11:79
-   |
-LL |   pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> {
-   |  _______________________________________________________________________________^
-LL | |     ap
-LL | | }
-   | |_^
-   = note: ...does not necessarily outlive the static lifetime
+   |     ^^ returning this value requires that `'1` must outlive `'static`
 
-error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
-  --> $DIR/variadic-ffi-4.rs:16:33
-   |
-LL |     let _ = ap.with_copy(|ap| { ap });
-   |                                 ^^
-   |
-note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 16:26...
-  --> $DIR/variadic-ffi-4.rs:16:26
-   |
-LL |     let _ = ap.with_copy(|ap| { ap });
-   |                          ^^^^^^^^^^^
-note: ...so that the expression is assignable
-  --> $DIR/variadic-ffi-4.rs:16:33
-   |
-LL |     let _ = ap.with_copy(|ap| { ap });
-   |                                 ^^
-   = note: expected  `core::ffi::VaList<'_, '_>`
-              found  `core::ffi::VaList<'_, '_>`
-note: but, the lifetime must be valid for the method call at 16:13...
-  --> $DIR/variadic-ffi-4.rs:16:13
-   |
-LL |     let _ = ap.with_copy(|ap| { ap });
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...so type `core::ffi::VaList<'_, '_>` of expression is valid during the expression
-  --> $DIR/variadic-ffi-4.rs:16:13
-   |
-LL |     let _ = ap.with_copy(|ap| { ap });
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+error: lifetime may not live long enough
+  --> $DIR/variadic-ffi-4.rs:18:31
+   |
+LL |     let _ = ap.with_copy(|ap| ap);
+   |                           --- ^^ returning this value requires that `'1` must outlive `'2`
+   |                           | |
+   |                           | return type of closure is core::ffi::VaList<'2, '_>
+   |                           has type `core::ffi::VaList<'1, '_>`
 
-error[E0308]: mismatched types
-  --> $DIR/variadic-ffi-4.rs:20:12
+error: lifetime may not live long enough
+  --> $DIR/variadic-ffi-4.rs:22:5
    |
+LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
+   |                                               -------                   ------- has type `core::ffi::VaListImpl<'2>`
+   |                                               |
+   |                                               has type `&mut core::ffi::VaListImpl<'1>`
 LL |     *ap0 = ap1;
-   |            ^^^ lifetime mismatch
-   |
-   = note: expected struct `core::ffi::VaListImpl<'_>`
-              found struct `core::ffi::VaListImpl<'_>`
-note: the scope of call-site for function at 19:87...
-  --> $DIR/variadic-ffi-4.rs:19:87
-   |
-LL |   pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
-   |  _______________________________________________________________________________________^
-LL | |     *ap0 = ap1;
-LL | | }
-   | |_^
-note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 19:1
-  --> $DIR/variadic-ffi-4.rs:19:1
-   |
-LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
-LL | |     *ap0 = ap1;
-LL | | }
-   | |_^
+   |     ^^^^ assignment requires that `'1` must outlive `'2`
 
-error[E0490]: a value of type `core::ffi::VaListImpl<'_>` is borrowed for too long
-  --> $DIR/variadic-ffi-4.rs:24:11
+error: lifetime may not live long enough
+  --> $DIR/variadic-ffi-4.rs:22:5
    |
-LL |     ap0 = &mut ap1;
-   |           ^^^^^^^^
-   |
-note: the type is valid for the anonymous lifetime #1 defined on the function body at 23:1
-  --> $DIR/variadic-ffi-4.rs:23:1
-   |
-LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
-LL | |     ap0 = &mut ap1;
-LL | |
-LL | |
-LL | |
-LL | | }
-   | |_^
-note: but the borrow lasts for the scope of call-site for function at 23:83
-  --> $DIR/variadic-ffi-4.rs:23:83
-   |
-LL |   pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
-   |  ___________________________________________________________________________________^
-LL | |     ap0 = &mut ap1;
-LL | |
-LL | |
-LL | |
-LL | | }
-   | |_^
+LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
+   |                                               -------                   ------- has type `core::ffi::VaListImpl<'2>`
+   |                                               |
+   |                                               has type `&mut core::ffi::VaListImpl<'1>`
+LL |     *ap0 = ap1;
+   |     ^^^^ assignment requires that `'2` must outlive `'1`
 
-error[E0308]: mismatched types
-  --> $DIR/variadic-ffi-4.rs:24:11
+error: lifetime may not live long enough
+  --> $DIR/variadic-ffi-4.rs:28:5
    |
+LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
+   |                                               -------                   ------- has type `core::ffi::VaListImpl<'2>`
+   |                                               |
+   |                                               has type `&mut core::ffi::VaListImpl<'1>`
 LL |     ap0 = &mut ap1;
-   |           ^^^^^^^^ lifetime mismatch
-   |
-   = note: expected mutable reference `&mut core::ffi::VaListImpl<'_>`
-              found mutable reference `&mut core::ffi::VaListImpl<'_>`
-note: the scope of call-site for function at 23:83...
-  --> $DIR/variadic-ffi-4.rs:23:83
-   |
-LL |   pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
-   |  ___________________________________________________________________________________^
-LL | |     ap0 = &mut ap1;
-LL | |
-LL | |
-LL | |
-LL | | }
-   | |_^
-note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 23:1
-  --> $DIR/variadic-ffi-4.rs:23:1
-   |
-LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
-LL | |     ap0 = &mut ap1;
-LL | |
-LL | |
-LL | |
-LL | | }
-   | |_^
+   |     ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2`
 
-error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
-  --> $DIR/variadic-ffi-4.rs:24:11
+error: lifetime may not live long enough
+  --> $DIR/variadic-ffi-4.rs:28:5
    |
+LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
+   |                                               -------                   ------- has type `core::ffi::VaListImpl<'2>`
+   |                                               |
+   |                                               has type `&mut core::ffi::VaListImpl<'1>`
 LL |     ap0 = &mut ap1;
-   |           ^^^^^^^^
-   |
-note: first, the lifetime cannot outlive the scope of call-site for function at 23:83...
-  --> $DIR/variadic-ffi-4.rs:23:83
-   |
-LL |   pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
-   |  ___________________________________________________________________________________^
-LL | |     ap0 = &mut ap1;
-LL | |
-LL | |
-LL | |
-LL | | }
-   | |_^
-note: ...so that the type `core::ffi::VaListImpl<'_>` is not borrowed for too long
-  --> $DIR/variadic-ffi-4.rs:24:11
-   |
-LL |     ap0 = &mut ap1;
-   |           ^^^^^^^^
-note: but, the lifetime must be valid for the anonymous lifetime #1 defined on the function body at 23:1...
-  --> $DIR/variadic-ffi-4.rs:23:1
-   |
-LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
-LL | |     ap0 = &mut ap1;
-LL | |
-LL | |
-LL | |
-LL | | }
-   | |_^
-note: ...so that reference does not outlive borrowed content
-  --> $DIR/variadic-ffi-4.rs:24:11
+   |     ^^^^^^^^^^^^^^ assignment requires that `'2` must outlive `'1`
+
+error[E0597]: `ap1` does not live long enough
+  --> $DIR/variadic-ffi-4.rs:28:11
    |
+LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
+   |                                                        - let's call the lifetime of this reference `'3`
 LL |     ap0 = &mut ap1;
-   |           ^^^^^^^^
+   |     ------^^^^^^^^
+   |     |     |
+   |     |     borrowed value does not live long enough
+   |     assignment requires that `ap1` is borrowed for `'3`
+...
+LL | }
+   | - `ap1` dropped here while still borrowed
 
-error[E0308]: mismatched types
-  --> $DIR/variadic-ffi-4.rs:31:12
+error: lifetime may not live long enough
+  --> $DIR/variadic-ffi-4.rs:35:12
    |
+LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
+   |                                               -------                   ------- has type `core::ffi::VaListImpl<'2>`
+   |                                               |
+   |                                               has type `&mut core::ffi::VaListImpl<'1>`
 LL |     *ap0 = ap1.clone();
-   |            ^^^^^^^^^^^ lifetime mismatch
-   |
-   = note: expected struct `core::ffi::VaListImpl<'_>`
-              found struct `core::ffi::VaListImpl<'_>`
-note: the scope of call-site for function at 30:87...
-  --> $DIR/variadic-ffi-4.rs:30:87
-   |
-LL |   pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
-   |  _______________________________________________________________________________________^
-LL | |     *ap0 = ap1.clone();
-LL | | }
-   | |_^
-note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 30:1
-  --> $DIR/variadic-ffi-4.rs:30:1
+   |            ^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
+error: lifetime may not live long enough
+  --> $DIR/variadic-ffi-4.rs:35:12
    |
-LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
-LL | |     *ap0 = ap1.clone();
-LL | | }
-   | |_^
+LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
+   |                                               -------                   ------- has type `core::ffi::VaListImpl<'2>`
+   |                                               |
+   |                                               has type `&mut core::ffi::VaListImpl<'1>`
+LL |     *ap0 = ap1.clone();
+   |            ^^^^^^^^^^^ argument requires that `'2` must outlive `'1`
 
-error: aborting due to 8 previous errors
+error: aborting due to 11 previous errors
 
-Some errors have detailed explanations: E0308, E0495.
-For more information about an error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.nll.stderr b/src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.nll.stderr
new file mode 100644
index 00000000000..52bca8dd63e
--- /dev/null
+++ b/src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.nll.stderr
@@ -0,0 +1,24 @@
+error: lifetime may not live long enough
+  --> $DIR/expect-region-supply-region-2.rs:14:30
+   |
+LL | fn expect_bound_supply_named<'x>() {
+   |                              -- lifetime `'x` defined here
+...
+LL |     closure_expecting_bound(|x: &'x u32| {
+   |                              ^  - let's call the lifetime of this reference `'1`
+   |                              |
+   |                              requires that `'1` must outlive `'x`
+
+error: lifetime may not live long enough
+  --> $DIR/expect-region-supply-region-2.rs:14:30
+   |
+LL | fn expect_bound_supply_named<'x>() {
+   |                              -- lifetime `'x` defined here
+...
+LL |     closure_expecting_bound(|x: &'x u32| {
+   |                              ^ requires that `'x` must outlive `'static`
+   |
+   = help: consider replacing `'x` with `'static`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.rs b/src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.rs
new file mode 100644
index 00000000000..7405b1a1e3a
--- /dev/null
+++ b/src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.rs
@@ -0,0 +1,24 @@
+#![allow(warnings)]
+
+fn closure_expecting_bound<F>(_: F)
+where
+    F: FnOnce(&u32),
+{
+}
+
+fn expect_bound_supply_named<'x>() {
+    let mut f: Option<&u32> = None;
+
+    // Here we give a type annotation that `x` should be free. We get
+    // an error because of that.
+    closure_expecting_bound(|x: &'x u32| {
+        //~^ ERROR mismatched types
+        //~| ERROR mismatched types
+
+        // Borrowck doesn't get a chance to run, but if it did it should error
+        // here.
+        f = Some(x);
+    });
+}
+
+fn main() {}
diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.stderr b/src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.stderr
new file mode 100644
index 00000000000..7f527904a69
--- /dev/null
+++ b/src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.stderr
@@ -0,0 +1,55 @@
+error[E0308]: mismatched types
+  --> $DIR/expect-region-supply-region-2.rs:14:33
+   |
+LL |     closure_expecting_bound(|x: &'x u32| {
+   |                                 ^^^^^^^ lifetime mismatch
+   |
+   = note: expected reference `&u32`
+              found reference `&'x u32`
+note: the anonymous lifetime #2 defined on the body at 14:29...
+  --> $DIR/expect-region-supply-region-2.rs:14:29
+   |
+LL |       closure_expecting_bound(|x: &'x u32| {
+   |  _____________________________^
+LL | |
+LL | |
+LL | |
+...  |
+LL | |         f = Some(x);
+LL | |     });
+   | |_____^
+note: ...does not necessarily outlive the lifetime `'x` as defined on the function body at 9:30
+  --> $DIR/expect-region-supply-region-2.rs:9:30
+   |
+LL | fn expect_bound_supply_named<'x>() {
+   |                              ^^
+
+error[E0308]: mismatched types
+  --> $DIR/expect-region-supply-region-2.rs:14:33
+   |
+LL |     closure_expecting_bound(|x: &'x u32| {
+   |                                 ^^^^^^^ lifetime mismatch
+   |
+   = note: expected reference `&u32`
+              found reference `&'x u32`
+note: the lifetime `'x` as defined on the function body at 9:30...
+  --> $DIR/expect-region-supply-region-2.rs:9:30
+   |
+LL | fn expect_bound_supply_named<'x>() {
+   |                              ^^
+note: ...does not necessarily outlive the anonymous lifetime #2 defined on the body at 14:29
+  --> $DIR/expect-region-supply-region-2.rs:14:29
+   |
+LL |       closure_expecting_bound(|x: &'x u32| {
+   |  _____________________________^
+LL | |
+LL | |
+LL | |
+...  |
+LL | |         f = Some(x);
+LL | |     });
+   | |_____^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.nll.stderr b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.nll.stderr
deleted file mode 100644
index d7d716ed4cb..00000000000
--- a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.nll.stderr
+++ /dev/null
@@ -1,44 +0,0 @@
-error[E0521]: borrowed data escapes outside of closure
-  --> $DIR/expect-region-supply-region.rs:18:9
-   |
-LL |     let mut f: Option<&u32> = None;
-   |         ----- `f` declared here, outside of the closure body
-LL |     closure_expecting_bound(|x| {
-   |                              - `x` is a reference that is only valid in the closure body
-LL |         f = Some(x);
-   |         ^^^^^^^^^^^ `x` escapes the closure body here
-
-error[E0521]: borrowed data escapes outside of closure
-  --> $DIR/expect-region-supply-region.rs:28:9
-   |
-LL |     let mut f: Option<&u32> = None;
-   |         ----- `f` declared here, outside of the closure body
-LL |     closure_expecting_bound(|x: &u32| {
-   |                              - `x` is a reference that is only valid in the closure body
-LL |         f = Some(x);
-   |         ^^^^^^^^^^^ `x` escapes the closure body here
-
-error: lifetime may not live long enough
-  --> $DIR/expect-region-supply-region.rs:37:30
-   |
-LL | fn expect_bound_supply_named<'x>() {
-   |                              -- lifetime `'x` defined here
-...
-LL |     closure_expecting_bound(|x: &'x u32| {
-   |                              ^  - let's call the lifetime of this reference `'1`
-   |                              |
-   |                              requires that `'1` must outlive `'x`
-
-error: lifetime may not live long enough
-  --> $DIR/expect-region-supply-region.rs:37:30
-   |
-LL | fn expect_bound_supply_named<'x>() {
-   |                              -- lifetime `'x` defined here
-...
-LL |     closure_expecting_bound(|x: &'x u32| {
-   |                              ^ requires that `'x` must outlive `'static`
-   |
-   = help: consider replacing `'x` with `'static`
-
-error: aborting due to 4 previous errors
-
diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.rs b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.rs
index 28a6ab77a91..55c6aa795c2 100644
--- a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.rs
+++ b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.rs
@@ -1,12 +1,14 @@
 #![allow(warnings)]
 
 fn closure_expecting_bound<F>(_: F)
-    where F: FnOnce(&u32)
+where
+    F: FnOnce(&u32),
 {
 }
 
 fn closure_expecting_free<'a, F>(_: F)
-    where F: FnOnce(&'a u32)
+where
+    F: FnOnce(&'a u32),
 {
 }
 
@@ -15,7 +17,7 @@ fn expect_bound_supply_nothing() {
     // it to escape into `f`:
     let mut f: Option<&u32> = None;
     closure_expecting_bound(|x| {
-        f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure
+        f = Some(x); //~ ERROR borrowed data escapes outside of closure
     });
 }
 
@@ -25,22 +27,7 @@ fn expect_bound_supply_bound() {
     // closure:
     let mut f: Option<&u32> = None;
     closure_expecting_bound(|x: &u32| {
-        f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure
-    });
-}
-
-fn expect_bound_supply_named<'x>() {
-    let mut f: Option<&u32> = None;
-
-    // Here we give a type annotation that `x` should be free. We get
-    // an error because of that.
-    closure_expecting_bound(|x: &'x u32| {
-        //~^ ERROR mismatched types
-        //~| ERROR mismatched types
-
-        // And we still cannot let `x` escape into `f`.
-        f = Some(x);
-        //~^ ERROR borrowed data cannot be stored outside of its closure
+        f = Some(x); //~ ERROR borrowed data escapes outside of closure
     });
 }
 
@@ -67,4 +54,4 @@ fn expect_free_supply_named<'x>() {
     closure_expecting_free(|x: &'x u32| f = Some(x)); // OK
 }
 
-fn main() { }
+fn main() {}
diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr
index eb860f9aef2..213071abfff 100644
--- a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr
+++ b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr
@@ -1,87 +1,22 @@
-error: borrowed data cannot be stored outside of its closure
-  --> $DIR/expect-region-supply-region.rs:18:18
+error[E0521]: borrowed data escapes outside of closure
+  --> $DIR/expect-region-supply-region.rs:20:9
    |
 LL |     let mut f: Option<&u32> = None;
-   |         ----- borrowed data cannot be stored into here...
+   |         ----- `f` declared here, outside of the closure body
 LL |     closure_expecting_bound(|x| {
-   |                             --- ...because it cannot outlive this closure
+   |                              - `x` is a reference that is only valid in the closure body
 LL |         f = Some(x);
-   |                  ^ cannot be stored outside of its closure
+   |         ^^^^^^^^^^^ `x` escapes the closure body here
 
-error: borrowed data cannot be stored outside of its closure
-  --> $DIR/expect-region-supply-region.rs:28:18
+error[E0521]: borrowed data escapes outside of closure
+  --> $DIR/expect-region-supply-region.rs:30:9
    |
 LL |     let mut f: Option<&u32> = None;
-   |         ----- borrowed data cannot be stored into here...
+   |         ----- `f` declared here, outside of the closure body
 LL |     closure_expecting_bound(|x: &u32| {
-   |                             --------- ...because it cannot outlive this closure
+   |                              - `x` is a reference that is only valid in the closure body
 LL |         f = Some(x);
-   |                  ^ cannot be stored outside of its closure
+   |         ^^^^^^^^^^^ `x` escapes the closure body here
 
-error[E0308]: mismatched types
-  --> $DIR/expect-region-supply-region.rs:37:33
-   |
-LL |     closure_expecting_bound(|x: &'x u32| {
-   |                                 ^^^^^^^ lifetime mismatch
-   |
-   = note: expected reference `&u32`
-              found reference `&'x u32`
-note: the anonymous lifetime #2 defined on the body at 37:29...
-  --> $DIR/expect-region-supply-region.rs:37:29
-   |
-LL |       closure_expecting_bound(|x: &'x u32| {
-   |  _____________________________^
-LL | |
-LL | |
-LL | |
-...  |
-LL | |
-LL | |     });
-   | |_____^
-note: ...does not necessarily outlive the lifetime `'x` as defined on the function body at 32:30
-  --> $DIR/expect-region-supply-region.rs:32:30
-   |
-LL | fn expect_bound_supply_named<'x>() {
-   |                              ^^
-
-error[E0308]: mismatched types
-  --> $DIR/expect-region-supply-region.rs:37:33
-   |
-LL |     closure_expecting_bound(|x: &'x u32| {
-   |                                 ^^^^^^^ lifetime mismatch
-   |
-   = note: expected reference `&u32`
-              found reference `&'x u32`
-note: the lifetime `'x` as defined on the function body at 32:30...
-  --> $DIR/expect-region-supply-region.rs:32:30
-   |
-LL | fn expect_bound_supply_named<'x>() {
-   |                              ^^
-note: ...does not necessarily outlive the anonymous lifetime #2 defined on the body at 37:29
-  --> $DIR/expect-region-supply-region.rs:37:29
-   |
-LL |       closure_expecting_bound(|x: &'x u32| {
-   |  _____________________________^
-LL | |
-LL | |
-LL | |
-...  |
-LL | |
-LL | |     });
-   | |_____^
-
-error: borrowed data cannot be stored outside of its closure
-  --> $DIR/expect-region-supply-region.rs:42:18
-   |
-LL |     let mut f: Option<&u32> = None;
-   |         ----- borrowed data cannot be stored into here...
-...
-LL |     closure_expecting_bound(|x: &'x u32| {
-   |                             ------------ ...because it cannot outlive this closure
-...
-LL |         f = Some(x);
-   |                  ^ cannot be stored outside of its closure
-
-error: aborting due to 5 previous errors
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/error-codes/E0490.nll.stderr b/src/test/ui/error-codes/E0490.nll.stderr
new file mode 100644
index 00000000000..a1c33bbcd5f
--- /dev/null
+++ b/src/test/ui/error-codes/E0490.nll.stderr
@@ -0,0 +1,28 @@
+error: lifetime may not live long enough
+  --> $DIR/E0490.rs:2:12
+   |
+LL | fn f<'a, 'b>(y: &'b ()) {
+   |      --  -- lifetime `'b` defined here
+   |      |
+   |      lifetime `'a` defined here
+LL |     let x: &'a _ = &y;
+   |            ^^^^^ type annotation requires that `'b` must outlive `'a`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+
+error[E0597]: `y` does not live long enough
+  --> $DIR/E0490.rs:2:20
+   |
+LL | fn f<'a, 'b>(y: &'b ()) {
+   |      -- lifetime `'a` defined here
+LL |     let x: &'a _ = &y;
+   |            -----   ^^ borrowed value does not live long enough
+   |            |
+   |            type annotation requires that `y` is borrowed for `'a`
+...
+LL | }
+   |  - `y` dropped here while still borrowed
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/error-codes/E0490.rs b/src/test/ui/error-codes/E0490.rs
new file mode 100644
index 00000000000..36bafa2bd86
--- /dev/null
+++ b/src/test/ui/error-codes/E0490.rs
@@ -0,0 +1,8 @@
+fn f<'a, 'b>(y: &'b ()) {
+    let x: &'a _ = &y;
+    //~^ E0490
+    //~| E0495
+    //~| E0495
+}
+
+fn main() {}
diff --git a/src/test/ui/error-codes/E0490.stderr b/src/test/ui/error-codes/E0490.stderr
new file mode 100644
index 00000000000..03fce213605
--- /dev/null
+++ b/src/test/ui/error-codes/E0490.stderr
@@ -0,0 +1,76 @@
+error[E0490]: a value of type `&'b ()` is borrowed for too long
+  --> $DIR/E0490.rs:2:20
+   |
+LL |     let x: &'a _ = &y;
+   |                    ^^
+   |
+note: the type is valid for the lifetime `'a` as defined on the function body at 1:6
+  --> $DIR/E0490.rs:1:6
+   |
+LL | fn f<'a, 'b>(y: &'b ()) {
+   |      ^^
+note: but the borrow lasts for the lifetime `'b` as defined on the function body at 1:10
+  --> $DIR/E0490.rs:1:10
+   |
+LL | fn f<'a, 'b>(y: &'b ()) {
+   |          ^^
+
+error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
+  --> $DIR/E0490.rs:2:20
+   |
+LL |     let x: &'a _ = &y;
+   |                    ^^
+   |
+note: first, the lifetime cannot outlive the lifetime `'b` as defined on the function body at 1:10...
+  --> $DIR/E0490.rs:1:10
+   |
+LL | fn f<'a, 'b>(y: &'b ()) {
+   |          ^^
+note: ...so that the type `&'b ()` is not borrowed for too long
+  --> $DIR/E0490.rs:2:20
+   |
+LL |     let x: &'a _ = &y;
+   |                    ^^
+note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 1:6...
+  --> $DIR/E0490.rs:1:6
+   |
+LL | fn f<'a, 'b>(y: &'b ()) {
+   |      ^^
+note: ...so that reference does not outlive borrowed content
+  --> $DIR/E0490.rs:2:20
+   |
+LL |     let x: &'a _ = &y;
+   |                    ^^
+
+error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+  --> $DIR/E0490.rs:2:20
+   |
+LL |     let x: &'a _ = &y;
+   |                    ^^
+   |
+note: first, the lifetime cannot outlive the lifetime `'b` as defined on the function body at 1:10...
+  --> $DIR/E0490.rs:1:10
+   |
+LL | fn f<'a, 'b>(y: &'b ()) {
+   |          ^^
+note: ...so that the expression is assignable
+  --> $DIR/E0490.rs:2:20
+   |
+LL |     let x: &'a _ = &y;
+   |                    ^^
+   = note: expected  `&'a &()`
+              found  `&'a &'b ()`
+note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 1:6...
+  --> $DIR/E0490.rs:1:6
+   |
+LL | fn f<'a, 'b>(y: &'b ()) {
+   |      ^^
+note: ...so that the reference type `&'a &()` does not outlive the data it points at
+  --> $DIR/E0490.rs:2:12
+   |
+LL |     let x: &'a _ = &y;
+   |            ^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr
deleted file mode 100644
index 5140d1a9a7a..00000000000
--- a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error: lifetime may not live long enough
-  --> $DIR/E0621-does-not-trigger-for-closures.rs:15:45
-   |
-LL |     invoke(&x, |a, b| if a > b { a } else { b });
-   |                    --                       ^ returning this value requires that `'1` must outlive `'2`
-   |                    ||
-   |                    |return type of closure is &'2 i32
-   |                    has type `&'1 i32`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.rs b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.rs
index c58744d386c..44f174c0fb7 100644
--- a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.rs
+++ b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.rs
@@ -1,9 +1,7 @@
-// Test that we give the generic E0495 when one of the free regions is
+// Test that we give the generic error when one of the free regions is
 // bound in a closure (rather than suggesting a change to the signature
 // of the closure, which is not specified in `foo` but rather in `invoke`).
 
-// FIXME - This might be better as a UI test, but the finer details
-// of the error seem to vary on different machines.
 fn invoke<'a, F>(x: &'a i32, f: F) -> &'a i32
 where F: FnOnce(&'a i32, &i32) -> &'a i32
 {
@@ -12,7 +10,7 @@ where F: FnOnce(&'a i32, &i32) -> &'a i32
 }
 
 fn foo<'a>(x: &'a i32) {
-    invoke(&x, |a, b| if a > b { a } else { b }); //~ ERROR E0495
+    invoke(&x, |a, b| if a > b { a } else { b }); //~ ERROR lifetime may not live long enough
 }
 
 fn main() {}
diff --git a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.stderr b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.stderr
index feca7f10b70..b9edeb8346b 100644
--- a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.stderr
+++ b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.stderr
@@ -1,30 +1,11 @@
-error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
-  --> $DIR/E0621-does-not-trigger-for-closures.rs:15:5
+error: lifetime may not live long enough
+  --> $DIR/E0621-does-not-trigger-for-closures.rs:13:45
    |
 LL |     invoke(&x, |a, b| if a > b { a } else { b });
-   |     ^^^^^^
-   |
-note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 15:16...
-  --> $DIR/E0621-does-not-trigger-for-closures.rs:15:16
-   |
-LL |     invoke(&x, |a, b| if a > b { a } else { b });
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...so that reference does not outlive borrowed content
-  --> $DIR/E0621-does-not-trigger-for-closures.rs:15:45
-   |
-LL |     invoke(&x, |a, b| if a > b { a } else { b });
-   |                                             ^
-note: but, the lifetime must be valid for the call at 15:5...
-  --> $DIR/E0621-does-not-trigger-for-closures.rs:15:5
-   |
-LL |     invoke(&x, |a, b| if a > b { a } else { b });
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...so type `&i32` of expression is valid during the expression
-  --> $DIR/E0621-does-not-trigger-for-closures.rs:15:5
-   |
-LL |     invoke(&x, |a, b| if a > b { a } else { b });
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                    --                       ^ returning this value requires that `'1` must outlive `'2`
+   |                    ||
+   |                    |return type of closure is &'2 i32
+   |                    has type `&'1 i32`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr
index cd2d46ac182..b42ff1486f0 100644
--- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr
+++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr
@@ -4,17 +4,11 @@ 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 the scope of call-site for function at 23:1
-  --> $DIR/ordinary-bounds-unrelated.rs:23:1
+note: hidden type `Ordinary<'_>` captures lifetime smaller than the function body
+  --> $DIR/ordinary-bounds-unrelated.rs:18:74
    |
-LL | / {
-LL | |     // Hidden type `Ordinary<'0>` with constraints:
-LL | |     //
-LL | |     // ```
-...  |
-LL | |     if condition() { a } else { b }
-LL | | }
-   | |_^
+LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
+   |                                                                          ^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr
index 59ce93fa78b..254643c406c 100644
--- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr
+++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr
@@ -4,17 +4,11 @@ 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 the scope of call-site for function at 22:1
-  --> $DIR/ordinary-bounds-unsuited.rs:22:1
+note: hidden type `Ordinary<'_>` captures lifetime smaller than the function body
+  --> $DIR/ordinary-bounds-unsuited.rs:20:62
    |
-LL | / {
-LL | |     // We return a value:
-LL | |     //
-LL | |     // ```
-...  |
-LL | |     if condition() { a } else { b }
-LL | | }
-   | |_^
+LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
+   |                                                              ^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/proc-macro/macro-rules-capture.rs b/src/test/ui/proc-macro/macro-rules-capture.rs
new file mode 100644
index 00000000000..37436567d70
--- /dev/null
+++ b/src/test/ui/proc-macro/macro-rules-capture.rs
@@ -0,0 +1,18 @@
+// aux-build: test-macros.rs
+
+extern crate test_macros;
+use test_macros::recollect_attr;
+
+macro_rules! reemit {
+    ($name:ident => $($token:expr)*) => {
+
+        #[recollect_attr]
+        pub fn $name() {
+            $($token)*;
+        }
+    }
+}
+
+reemit! { foo => 45u32.into() } //~ ERROR type annotations
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/macro-rules-capture.stderr b/src/test/ui/proc-macro/macro-rules-capture.stderr
new file mode 100644
index 00000000000..6d512846ff7
--- /dev/null
+++ b/src/test/ui/proc-macro/macro-rules-capture.stderr
@@ -0,0 +1,12 @@
+error[E0282]: type annotations needed
+  --> $DIR/macro-rules-capture.rs:16:24
+   |
+LL | reemit! { foo => 45u32.into() }
+   |                  ------^^^^--
+   |                  |     |
+   |                  |     cannot infer type for type parameter `T` declared on the trait `Into`
+   |                  this method call resolves to `T`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/regions/regions-close-object-into-object-5.rs b/src/test/ui/regions/regions-close-object-into-object-5.rs
index 2921a2bb398..ff35b9ada45 100644
--- a/src/test/ui/regions/regions-close-object-into-object-5.rs
+++ b/src/test/ui/regions/regions-close-object-into-object-5.rs
@@ -6,22 +6,21 @@ trait A<T>
     fn get(&self) -> T { panic!() }
 }
 
-struct B<'a, T:'a>(&'a (A<T>+'a));
+struct B<'a, T: 'a>(&'a (A<T> + 'a));
 
 trait X { fn foo(&self) {} }
 
 impl<'a, T> X for B<'a, T> {}
 
-fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
+fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
     // oh dear!
     box B(&*v) as Box<X>
-        //~^ ERROR the parameter type `T` may not live long enough
-        //~| ERROR the parameter type `T` may not live long enough
-        //~| ERROR the parameter type `T` may not live long enough
-        //~| ERROR the parameter type `T` may not live long enough
-        //~| ERROR the parameter type `T` may not live long enough
-        //~| ERROR the parameter type `T` may not live long enough
-        //~| ERROR the parameter type `T` may not live long enough
+    //~^ ERROR the parameter type `T` may not live long enough
+    //~| ERROR the parameter type `T` may not live long enough
+    //~| ERROR the parameter type `T` may not live long enough
+    //~| ERROR the parameter type `T` may not live long enough
+    //~| ERROR the parameter type `T` may not live long enough
+    //~| ERROR the parameter type `T` may not live long enough
 }
 
 fn main() {}
diff --git a/src/test/ui/regions/regions-close-object-into-object-5.stderr b/src/test/ui/regions/regions-close-object-into-object-5.stderr
index 14727000b2c..2bcdcd1864e 100644
--- a/src/test/ui/regions/regions-close-object-into-object-5.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-5.stderr
@@ -1,7 +1,7 @@
 error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/regions-close-object-into-object-5.rs:17:5
    |
-LL | fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
+LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
    |          - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // oh dear!
 LL |     box B(&*v) as Box<X>
@@ -14,24 +14,9 @@ LL |     box B(&*v) as Box<X>
    |     ^^^^^^^^^^
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/regions-close-object-into-object-5.rs:17:5
-   |
-LL | fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
-   |          - help: consider adding an explicit lifetime bound...: `T: 'static`
-LL |     // oh dear!
-LL |     box B(&*v) as Box<X>
-   |     ^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...so that it can be closed over into an object
-  --> $DIR/regions-close-object-into-object-5.rs:17:5
-   |
-LL |     box B(&*v) as Box<X>
-   |     ^^^^^^^^^^^^^^^^^^^^
-
-error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/regions-close-object-into-object-5.rs:17:9
    |
-LL | fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
+LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
    |          - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // oh dear!
 LL |     box B(&*v) as Box<X>
@@ -46,7 +31,7 @@ LL |     box B(&*v) as Box<X>
 error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/regions-close-object-into-object-5.rs:17:9
    |
-LL | fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
+LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
    |          - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // oh dear!
 LL |     box B(&*v) as Box<X>
@@ -61,7 +46,7 @@ LL |     box B(&*v) as Box<X>
 error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/regions-close-object-into-object-5.rs:17:11
    |
-LL | fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
+LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
    |          - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // oh dear!
 LL |     box B(&*v) as Box<X>
@@ -76,7 +61,7 @@ LL |     box B(&*v) as Box<X>
 error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/regions-close-object-into-object-5.rs:17:11
    |
-LL | fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
+LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
    |          - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // oh dear!
 LL |     box B(&*v) as Box<X>
@@ -91,7 +76,7 @@ LL |     box B(&*v) as Box<X>
 error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/regions-close-object-into-object-5.rs:17:11
    |
-LL | fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
+LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
    |          - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // oh dear!
 LL |     box B(&*v) as Box<X>
@@ -103,6 +88,6 @@ note: ...so that the type `(dyn A<T> + 'static)` is not borrowed for too long
 LL |     box B(&*v) as Box<X>
    |           ^^^
 
-error: aborting due to 7 previous errors
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0310`.
diff --git a/src/test/ui/regions/regions-close-over-type-parameter-1.nll.stderr b/src/test/ui/regions/regions-close-over-type-parameter-1.nll.stderr
index 7d3d51bdb43..3101d815881 100644
--- a/src/test/ui/regions/regions-close-over-type-parameter-1.nll.stderr
+++ b/src/test/ui/regions/regions-close-over-type-parameter-1.nll.stderr
@@ -1,5 +1,5 @@
 error[E0310]: the parameter type `A` may not live long enough
-  --> $DIR/regions-close-over-type-parameter-1.rs:10:5
+  --> $DIR/regions-close-over-type-parameter-1.rs:12:5
    |
 LL |     box v as Box<dyn SomeTrait + 'static>
    |     ^^^^^
@@ -7,7 +7,7 @@ LL |     box v as Box<dyn SomeTrait + 'static>
    = help: consider adding an explicit lifetime bound `A: 'static`...
 
 error[E0309]: the parameter type `A` may not live long enough
-  --> $DIR/regions-close-over-type-parameter-1.rs:20:5
+  --> $DIR/regions-close-over-type-parameter-1.rs:21:5
    |
 LL |     box v as Box<dyn SomeTrait + 'b>
    |     ^^^^^
diff --git a/src/test/ui/regions/regions-close-over-type-parameter-1.rs b/src/test/ui/regions/regions-close-over-type-parameter-1.rs
index 6a9aa66a446..6e708a5f70f 100644
--- a/src/test/ui/regions/regions-close-over-type-parameter-1.rs
+++ b/src/test/ui/regions/regions-close-over-type-parameter-1.rs
@@ -4,22 +4,22 @@
 // an object. This should yield errors unless `A` (and the object)
 // both have suitable bounds.
 
-trait SomeTrait { fn get(&self) -> isize; }
+trait SomeTrait {
+    fn get(&self) -> isize;
+}
 
-fn make_object1<A:SomeTrait>(v: A) -> Box<dyn SomeTrait + 'static> {
+fn make_object1<A: SomeTrait>(v: A) -> Box<dyn SomeTrait + 'static> {
     box v as Box<dyn SomeTrait + 'static>
-        //~^ ERROR the parameter type `A` may not live long enough
-        //~| ERROR the parameter type `A` may not live long enough
+    //~^ ERROR the parameter type `A` may not live long enough
 }
 
-fn make_object2<'a,A:SomeTrait+'a>(v: A) -> Box<dyn SomeTrait + 'a> {
+fn make_object2<'a, A: SomeTrait + 'a>(v: A) -> Box<dyn SomeTrait + 'a> {
     box v as Box<dyn SomeTrait + 'a>
 }
 
-fn make_object3<'a,'b,A:SomeTrait+'a>(v: A) -> Box<dyn SomeTrait + 'b> {
+fn make_object3<'a, 'b, A: SomeTrait + 'a>(v: A) -> Box<dyn SomeTrait + 'b> {
     box v as Box<dyn SomeTrait + 'b>
-        //~^ ERROR the parameter type `A` may not live long enough
-        //~| ERROR the parameter type `A` may not live long enough
+    //~^ ERROR the parameter type `A` may not live long enough
 }
 
-fn main() { }
+fn main() {}
diff --git a/src/test/ui/regions/regions-close-over-type-parameter-1.stderr b/src/test/ui/regions/regions-close-over-type-parameter-1.stderr
index ed9a604e717..a7509cb608c 100644
--- a/src/test/ui/regions/regions-close-over-type-parameter-1.stderr
+++ b/src/test/ui/regions/regions-close-over-type-parameter-1.stderr
@@ -1,60 +1,32 @@
 error[E0310]: the parameter type `A` may not live long enough
-  --> $DIR/regions-close-over-type-parameter-1.rs:10:5
+  --> $DIR/regions-close-over-type-parameter-1.rs:12:5
    |
-LL | fn make_object1<A:SomeTrait>(v: A) -> Box<dyn SomeTrait + 'static> {
+LL | fn make_object1<A: SomeTrait>(v: A) -> Box<dyn SomeTrait + 'static> {
    |                 -- help: consider adding an explicit lifetime bound...: `A: 'static +`
 LL |     box v as Box<dyn SomeTrait + 'static>
    |     ^^^^^
    |
 note: ...so that the type `A` will meet its required lifetime bounds
-  --> $DIR/regions-close-over-type-parameter-1.rs:10:5
+  --> $DIR/regions-close-over-type-parameter-1.rs:12:5
    |
 LL |     box v as Box<dyn SomeTrait + 'static>
    |     ^^^^^
 
-error[E0310]: the parameter type `A` may not live long enough
-  --> $DIR/regions-close-over-type-parameter-1.rs:10:5
-   |
-LL | fn make_object1<A:SomeTrait>(v: A) -> Box<dyn SomeTrait + 'static> {
-   |                 -- help: consider adding an explicit lifetime bound...: `A: 'static +`
-LL |     box v as Box<dyn SomeTrait + 'static>
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...so that it can be closed over into an object
-  --> $DIR/regions-close-over-type-parameter-1.rs:10:5
-   |
-LL |     box v as Box<dyn SomeTrait + 'static>
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
 error[E0309]: the parameter type `A` may not live long enough
-  --> $DIR/regions-close-over-type-parameter-1.rs:20:5
+  --> $DIR/regions-close-over-type-parameter-1.rs:21:5
    |
-LL | fn make_object3<'a,'b,A:SomeTrait+'a>(v: A) -> Box<dyn SomeTrait + 'b> {
-   |                       -- help: consider adding an explicit lifetime bound...: `A: 'b +`
+LL | fn make_object3<'a, 'b, A: SomeTrait + 'a>(v: A) -> Box<dyn SomeTrait + 'b> {
+   |                         -- help: consider adding an explicit lifetime bound...: `A: 'b +`
 LL |     box v as Box<dyn SomeTrait + 'b>
    |     ^^^^^
    |
 note: ...so that the type `A` will meet its required lifetime bounds
-  --> $DIR/regions-close-over-type-parameter-1.rs:20:5
+  --> $DIR/regions-close-over-type-parameter-1.rs:21:5
    |
 LL |     box v as Box<dyn SomeTrait + 'b>
    |     ^^^^^
 
-error[E0309]: the parameter type `A` may not live long enough
-  --> $DIR/regions-close-over-type-parameter-1.rs:20:5
-   |
-LL | fn make_object3<'a,'b,A:SomeTrait+'a>(v: A) -> Box<dyn SomeTrait + 'b> {
-   |                       -- help: consider adding an explicit lifetime bound...: `A: 'b +`
-LL |     box v as Box<dyn SomeTrait + 'b>
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...so that it can be closed over into an object
-  --> $DIR/regions-close-over-type-parameter-1.rs:20:5
-   |
-LL |     box v as Box<dyn SomeTrait + 'b>
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0309, E0310.
 For more information about an error, try `rustc --explain E0309`.
diff --git a/src/test/ui/regions/regions-escape-method.nll.stderr b/src/test/ui/regions/regions-escape-method.nll.stderr
deleted file mode 100644
index 9f425125b98..00000000000
--- a/src/test/ui/regions/regions-escape-method.nll.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error: lifetime may not live long enough
-  --> $DIR/regions-escape-method.rs:15:13
-   |
-LL |     s.f(|p| p)
-   |          -- ^ returning this value requires that `'1` must outlive `'2`
-   |          ||
-   |          |return type of closure is &'2 i32
-   |          has type `&'1 i32`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/regions/regions-escape-method.rs b/src/test/ui/regions/regions-escape-method.rs
index 5127d4d1ceb..69c01ae6906 100644
--- a/src/test/ui/regions/regions-escape-method.rs
+++ b/src/test/ui/regions/regions-escape-method.rs
@@ -12,5 +12,5 @@ impl S {
 
 fn main() {
     let s = S;
-    s.f(|p| p) //~ ERROR cannot infer
+    s.f(|p| p) //~ ERROR lifetime may not live long enough
 }
diff --git a/src/test/ui/regions/regions-escape-method.stderr b/src/test/ui/regions/regions-escape-method.stderr
index ffc2a259485..9f425125b98 100644
--- a/src/test/ui/regions/regions-escape-method.stderr
+++ b/src/test/ui/regions/regions-escape-method.stderr
@@ -1,32 +1,11 @@
-error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+error: lifetime may not live long enough
   --> $DIR/regions-escape-method.rs:15:13
    |
 LL |     s.f(|p| p)
-   |             ^
-   |
-note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 15:9...
-  --> $DIR/regions-escape-method.rs:15:9
-   |
-LL |     s.f(|p| p)
-   |         ^^^^^
-note: ...so that the expression is assignable
-  --> $DIR/regions-escape-method.rs:15:13
-   |
-LL |     s.f(|p| p)
-   |             ^
-   = note: expected  `&i32`
-              found  `&i32`
-note: but, the lifetime must be valid for the method call at 15:5...
-  --> $DIR/regions-escape-method.rs:15:5
-   |
-LL |     s.f(|p| p)
-   |     ^^^^^^^^^^
-note: ...so that a type/lifetime parameter is in scope here
-  --> $DIR/regions-escape-method.rs:15:5
-   |
-LL |     s.f(|p| p)
-   |     ^^^^^^^^^^
+   |          -- ^ returning this value requires that `'1` must outlive `'2`
+   |          ||
+   |          |return type of closure is &'2 i32
+   |          has type `&'1 i32`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-escape-via-trait-or-not.nll.stderr b/src/test/ui/regions/regions-escape-via-trait-or-not.nll.stderr
deleted file mode 100644
index cae6c33ac6e..00000000000
--- a/src/test/ui/regions/regions-escape-via-trait-or-not.nll.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error: lifetime may not live long enough
-  --> $DIR/regions-escape-via-trait-or-not.rs:18:14
-   |
-LL |     with(|o| o)
-   |           -- ^ returning this value requires that `'1` must outlive `'2`
-   |           ||
-   |           |return type of closure is &'2 isize
-   |           has type `&'1 isize`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/regions/regions-escape-via-trait-or-not.rs b/src/test/ui/regions/regions-escape-via-trait-or-not.rs
index 1e089616f59..ac0e56de4a0 100644
--- a/src/test/ui/regions/regions-escape-via-trait-or-not.rs
+++ b/src/test/ui/regions/regions-escape-via-trait-or-not.rs
@@ -15,7 +15,7 @@ fn with<R:Deref, F>(f: F) -> isize where F: FnOnce(&isize) -> R {
 }
 
 fn return_it() -> isize {
-    with(|o| o) //~ ERROR cannot infer
+    with(|o| o) //~ ERROR lifetime may not live long enough
 }
 
 fn main() {
diff --git a/src/test/ui/regions/regions-escape-via-trait-or-not.stderr b/src/test/ui/regions/regions-escape-via-trait-or-not.stderr
index 90823464c56..cae6c33ac6e 100644
--- a/src/test/ui/regions/regions-escape-via-trait-or-not.stderr
+++ b/src/test/ui/regions/regions-escape-via-trait-or-not.stderr
@@ -1,32 +1,11 @@
-error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+error: lifetime may not live long enough
   --> $DIR/regions-escape-via-trait-or-not.rs:18:14
    |
 LL |     with(|o| o)
-   |              ^
-   |
-note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 18:10...
-  --> $DIR/regions-escape-via-trait-or-not.rs:18:10
-   |
-LL |     with(|o| o)
-   |          ^^^^^
-note: ...so that the expression is assignable
-  --> $DIR/regions-escape-via-trait-or-not.rs:18:14
-   |
-LL |     with(|o| o)
-   |              ^
-   = note: expected  `&isize`
-              found  `&isize`
-note: but, the lifetime must be valid for the expression at 18:5...
-  --> $DIR/regions-escape-via-trait-or-not.rs:18:5
-   |
-LL |     with(|o| o)
-   |     ^^^^
-note: ...so type `fn([closure@$DIR/regions-escape-via-trait-or-not.rs:18:10: 18:15]) -> isize {with::<&isize, [closure@$DIR/regions-escape-via-trait-or-not.rs:18:10: 18:15]>}` of expression is valid during the expression
-  --> $DIR/regions-escape-via-trait-or-not.rs:18:5
-   |
-LL |     with(|o| o)
-   |     ^^^^
+   |           -- ^ returning this value requires that `'1` must outlive `'2`
+   |           ||
+   |           |return type of closure is &'2 isize
+   |           has type `&'1 isize`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-infer-call-3.nll.stderr b/src/test/ui/regions/regions-infer-call-3.nll.stderr
deleted file mode 100644
index ca51555a077..00000000000
--- a/src/test/ui/regions/regions-infer-call-3.nll.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error: lifetime may not live long enough
-  --> $DIR/regions-infer-call-3.rs:8:24
-   |
-LL |     let z = with(|y| { select(x, y) });
-   |                   --   ^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
-   |                   ||
-   |                   |return type of closure is &'2 isize
-   |                   has type `&'1 isize`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/regions/regions-infer-call-3.rs b/src/test/ui/regions/regions-infer-call-3.rs
index a76fccbdc52..063ec84288d 100644
--- a/src/test/ui/regions/regions-infer-call-3.rs
+++ b/src/test/ui/regions/regions-infer-call-3.rs
@@ -6,7 +6,7 @@ fn with<T, F>(f: F) -> T where F: FnOnce(&isize) -> T {
 
 fn manip<'a>(x: &'a isize) -> isize {
     let z = with(|y| { select(x, y) });
-    //~^ ERROR cannot infer
+    //~^ ERROR lifetime may not live long enough
     *z
 }
 
diff --git a/src/test/ui/regions/regions-infer-call-3.stderr b/src/test/ui/regions/regions-infer-call-3.stderr
index 1d6dbdb2c7b..ca51555a077 100644
--- a/src/test/ui/regions/regions-infer-call-3.stderr
+++ b/src/test/ui/regions/regions-infer-call-3.stderr
@@ -1,30 +1,11 @@
-error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'r in function call due to conflicting requirements
+error: lifetime may not live long enough
   --> $DIR/regions-infer-call-3.rs:8:24
    |
 LL |     let z = with(|y| { select(x, y) });
-   |                        ^^^^^^^^^^^^
-   |
-note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 8:18...
-  --> $DIR/regions-infer-call-3.rs:8:18
-   |
-LL |     let z = with(|y| { select(x, y) });
-   |                  ^^^^^^^^^^^^^^^^^^^^
-note: ...so that reference does not outlive borrowed content
-  --> $DIR/regions-infer-call-3.rs:8:34
-   |
-LL |     let z = with(|y| { select(x, y) });
-   |                                  ^
-note: but, the lifetime must be valid for the call at 8:13...
-  --> $DIR/regions-infer-call-3.rs:8:13
-   |
-LL |     let z = with(|y| { select(x, y) });
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...so type `&isize` of expression is valid during the expression
-  --> $DIR/regions-infer-call-3.rs:8:13
-   |
-LL |     let z = with(|y| { select(x, y) });
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                   --   ^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
+   |                   ||
+   |                   |return type of closure is &'2 isize
+   |                   has type `&'1 isize`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.nll.stderr b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.nll.stderr
deleted file mode 100644
index 4c275b19492..00000000000
--- a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.nll.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error: captured variable cannot escape `FnMut` closure body
-  --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:7:24
-   |
-LL |         let mut f = || &mut x;
-   |                      - ^^^^^^ returns a reference to a captured variable which escapes the closure body
-   |                      |
-   |                      inferred to be a `FnMut` closure
-   |
-   = note: `FnMut` closures only have access to their captured variables while they are executing...
-   = note: ...therefore, they cannot allow references to captured variables to escape
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.rs b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.rs
index afe87f47ead..86e759f088a 100644
--- a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.rs
+++ b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.rs
@@ -4,7 +4,7 @@ fn main() {
     // Unboxed closure case
     {
         let mut x = 0;
-        let mut f = || &mut x; //~ ERROR cannot infer
+        let mut f = || &mut x; //~ ERROR captured variable cannot escape `FnMut` closure body
         let x = f();
         let y = f();
     }
diff --git a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr
index 946465bcb5f..4c275b19492 100644
--- a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr
+++ b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr
@@ -1,30 +1,13 @@
-error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
+error: captured variable cannot escape `FnMut` closure body
   --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:7:24
    |
 LL |         let mut f = || &mut x;
-   |                        ^^^^^^
+   |                      - ^^^^^^ returns a reference to a captured variable which escapes the closure body
+   |                      |
+   |                      inferred to be a `FnMut` closure
    |
-note: first, the lifetime cannot outlive the lifetime `'_` as defined on the body at 7:21...
-  --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:7:21
-   |
-LL |         let mut f = || &mut x;
-   |                     ^^^^^^^^^
-note: ...so that closure can access `x`
-  --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:7:24
-   |
-LL |         let mut f = || &mut x;
-   |                        ^^^^^^
-note: but, the lifetime must be valid for the call at 9:17...
-  --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:9:17
-   |
-LL |         let y = f();
-   |                 ^^^
-note: ...so type `&mut i32` of expression is valid during the expression
-  --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:9:17
-   |
-LL |         let y = f();
-   |                 ^^^
+   = note: `FnMut` closures only have access to their captured variables while they are executing...
+   = note: ...therefore, they cannot allow references to captured variables to escape
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs
index 1f689a5bd25..cdcf89e4e61 100644
--- a/src/test/ui/symbol-names/impl1.rs
+++ b/src/test/ui/symbol-names/impl1.rs
@@ -3,8 +3,8 @@
 // revisions: legacy v0
 //[legacy]compile-flags: -Z symbol-mangling-version=legacy
     //[v0]compile-flags: -Z symbol-mangling-version=v0
-//[legacy]normalize-stderr-32bit: "hdb62078998ce7ea8" -> "SYMBOL_HASH"
-//[legacy]normalize-stderr-64bit: "h62e540f14f879d56" -> "SYMBOL_HASH"
+//[legacy]normalize-stderr-32bit: "h5ef5dfc14aeecbfc" -> "SYMBOL_HASH"
+//[legacy]normalize-stderr-64bit: "h9e54d216f70fcbc5" -> "SYMBOL_HASH"
 
 #![feature(optin_builtin_traits, rustc_attrs)]
 #![allow(dead_code)]