about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/native.rs28
-rw-r--r--src/etc/installer/gfx/rust-logo.pngbin5844 -> 3909 bytes
-rw-r--r--src/libcore/marker.rs4
-rw-r--r--src/librustc/traits/error_reporting/on_unimplemented.rs10
-rw-r--r--src/librustc/traits/error_reporting/suggestions.rs5
-rw-r--r--src/librustc_expand/lib.rs1
-rw-r--r--src/librustc_expand/mbe/macro_parser.rs48
-rw-r--r--src/librustc_expand/mbe/macro_rules.rs64
-rw-r--r--src/librustc_parse/lib.rs9
-rw-r--r--src/librustc_parse/parser/mod.rs9
-rw-r--r--src/librustc_parse/parser/module.rs6
-rw-r--r--src/librustc_typeck/check/demand.rs3
-rw-r--r--src/librustc_typeck/check/mod.rs54
-rw-r--r--src/librustc_typeck/collect.rs115
-rw-r--r--src/librustdoc/html/static/brush.svg2
-rw-r--r--src/librustdoc/html/static/down-arrow.svg2
-rw-r--r--src/librustdoc/html/static/wheel.svg2
-rw-r--r--src/libserialize/leb128.rs64
-rw-r--r--src/libstd/collections/hash/map.rs126
-rw-r--r--src/libstd/collections/hash/set.rs20
-rw-r--r--src/libstd/sys/sgx/args.rs7
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.fixed37
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs2
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.stderr4
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs11
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.stderr34
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.fixed38
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs15
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.stderr12
-rw-r--r--src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.rs1
-rw-r--r--src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr19
-rw-r--r--src/test/ui/generator/static-not-unpin.rs2
-rw-r--r--src/test/ui/generator/static-not-unpin.stderr2
-rw-r--r--src/test/ui/suggestions/expected-boxed-future-isnt-pinned.rs29
-rw-r--r--src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr20
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs32
36 files changed, 584 insertions, 253 deletions
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index 5790f236cc8..21dcb1d8aa0 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -262,7 +262,7 @@ impl Step for Llvm {
             cfg.define("PYTHON_EXECUTABLE", python);
         }
 
-        configure_cmake(builder, target, &mut cfg);
+        configure_cmake(builder, target, &mut cfg, true);
 
         // FIXME: we don't actually need to build all LLVM tools and all LLVM
         //        libraries here, e.g., we just want a few components and a few
@@ -301,7 +301,12 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) {
     panic!("\n\nbad LLVM version: {}, need >=7.0\n\n", version)
 }
 
-fn configure_cmake(builder: &Builder<'_>, target: Interned<String>, cfg: &mut cmake::Config) {
+fn configure_cmake(
+    builder: &Builder<'_>,
+    target: Interned<String>,
+    cfg: &mut cmake::Config,
+    use_compiler_launcher: bool,
+) {
     // Do not print installation messages for up-to-date files.
     // LLVM and LLD builds can produce a lot of those and hit CI limits on log size.
     cfg.define("CMAKE_INSTALL_MESSAGE", "LAZY");
@@ -372,9 +377,11 @@ fn configure_cmake(builder: &Builder<'_>, target: Interned<String>, cfg: &mut cm
     } else {
         // If ccache is configured we inform the build a little differently how
         // to invoke ccache while also invoking our compilers.
-        if let Some(ref ccache) = builder.config.ccache {
-            cfg.define("CMAKE_C_COMPILER_LAUNCHER", ccache)
-                .define("CMAKE_CXX_COMPILER_LAUNCHER", ccache);
+        if use_compiler_launcher {
+            if let Some(ref ccache) = builder.config.ccache {
+                cfg.define("CMAKE_C_COMPILER_LAUNCHER", ccache)
+                    .define("CMAKE_CXX_COMPILER_LAUNCHER", ccache);
+            }
         }
         cfg.define("CMAKE_C_COMPILER", sanitize_cc(cc))
             .define("CMAKE_CXX_COMPILER", sanitize_cc(cxx));
@@ -458,7 +465,7 @@ impl Step for Lld {
         t!(fs::create_dir_all(&out_dir));
 
         let mut cfg = cmake::Config::new(builder.src.join("src/llvm-project/lld"));
-        configure_cmake(builder, target, &mut cfg);
+        configure_cmake(builder, target, &mut cfg, true);
 
         // This is an awful, awful hack. Discovered when we migrated to using
         // clang-cl to compile LLVM/LLD it turns out that LLD, when built out of
@@ -595,10 +602,7 @@ impl Step for Sanitizers {
         let _time = util::timeit(&builder);
 
         let mut cfg = cmake::Config::new(&compiler_rt_dir);
-        cfg.target(&self.target);
-        cfg.host(&builder.config.build);
         cfg.profile("Release");
-
         cfg.define("CMAKE_C_COMPILER_TARGET", self.target);
         cfg.define("COMPILER_RT_BUILD_BUILTINS", "OFF");
         cfg.define("COMPILER_RT_BUILD_CRT", "OFF");
@@ -610,6 +614,12 @@ impl Step for Sanitizers {
         cfg.define("COMPILER_RT_USE_LIBCXX", "OFF");
         cfg.define("LLVM_CONFIG_PATH", &llvm_config);
 
+        // On Darwin targets the sanitizer runtimes are build as universal binaries.
+        // Unfortunately sccache currently lacks support to build them successfully.
+        // Disable compiler launcher on Darwin targets to avoid potential issues.
+        let use_compiler_launcher = !self.target.contains("apple-darwin");
+        configure_cmake(builder, self.target, &mut cfg, use_compiler_launcher);
+
         t!(fs::create_dir_all(&out_dir));
         cfg.out_dir(out_dir);
 
diff --git a/src/etc/installer/gfx/rust-logo.png b/src/etc/installer/gfx/rust-logo.png
index 2c3de300087..99ee7507fa2 100644
--- a/src/etc/installer/gfx/rust-logo.png
+++ b/src/etc/installer/gfx/rust-logo.png
Binary files differdiff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index b4b595f330e..2800f11cc01 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -727,6 +727,10 @@ unsafe impl<T: ?Sized> Freeze for &mut T {}
 /// [`Pin<P>`]: ../pin/struct.Pin.html
 /// [`pin module`]: ../../std/pin/index.html
 #[stable(feature = "pin", since = "1.33.0")]
+#[rustc_on_unimplemented(
+    on(_Self = "std::future::Future", note = "consider using `Box::pin`",),
+    message = "`{Self}` cannot be unpinned"
+)]
 #[lang = "unpin"]
 pub auto trait Unpin {}
 
diff --git a/src/librustc/traits/error_reporting/on_unimplemented.rs b/src/librustc/traits/error_reporting/on_unimplemented.rs
index 2ba12baaf6d..ab2d74b1c8d 100644
--- a/src/librustc/traits/error_reporting/on_unimplemented.rs
+++ b/src/librustc/traits/error_reporting/on_unimplemented.rs
@@ -201,6 +201,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 }
             }
         }
+        if let ty::Dynamic(traits, _) = self_ty.kind {
+            for t in *traits.skip_binder() {
+                match t {
+                    ty::ExistentialPredicate::Trait(trait_ref) => {
+                        flags.push((sym::_Self, Some(self.tcx.def_path_str(trait_ref.def_id))))
+                    }
+                    _ => {}
+                }
+            }
+        }
 
         if let Ok(Some(command)) =
             OnUnimplementedDirective::of_item(self.tcx, trait_ref.def_id, def_id)
diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs
index 60e55bd7bd9..82b73518d09 100644
--- a/src/librustc/traits/error_reporting/suggestions.rs
+++ b/src/librustc/traits/error_reporting/suggestions.rs
@@ -701,10 +701,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     })
                     .collect::<Vec<_>>();
                 // Add the suggestion for the return type.
-                suggestions.push((
-                    ret_ty.span,
-                    format!("Box<{}{}>", if has_dyn { "" } else { "dyn " }, snippet),
-                ));
+                suggestions.push((ret_ty.span, format!("Box<dyn {}>", trait_obj)));
                 err.multipart_suggestion(
                     "return a boxed trait object instead",
                     suggestions,
diff --git a/src/librustc_expand/lib.rs b/src/librustc_expand/lib.rs
index 4fe7c268c4f..f119c956ced 100644
--- a/src/librustc_expand/lib.rs
+++ b/src/librustc_expand/lib.rs
@@ -1,3 +1,4 @@
+#![feature(cow_is_borrowed)]
 #![feature(crate_visibility_modifier)]
 #![feature(decl_macro)]
 #![feature(proc_macro_diagnostic)]
diff --git a/src/librustc_expand/mbe/macro_parser.rs b/src/librustc_expand/mbe/macro_parser.rs
index b14725fd731..5bf7602ea6e 100644
--- a/src/librustc_expand/mbe/macro_parser.rs
+++ b/src/librustc_expand/mbe/macro_parser.rs
@@ -78,13 +78,11 @@ use crate::mbe::{self, TokenTree};
 
 use rustc_ast_pretty::pprust;
 use rustc_parse::parser::{FollowedByType, Parser, PathStyle};
-use rustc_parse::Directory;
 use rustc_session::parse::ParseSess;
 use rustc_span::symbol::{kw, sym, Symbol};
 use syntax::ast::{Ident, Name};
 use syntax::ptr::P;
 use syntax::token::{self, DocComment, Nonterminal, Token};
-use syntax::tokenstream::TokenStream;
 
 use rustc_errors::{FatalError, PResult};
 use rustc_span::Span;
@@ -92,6 +90,7 @@ use smallvec::{smallvec, SmallVec};
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
+use std::borrow::Cow;
 use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::mem;
 use std::ops::{Deref, DerefMut};
@@ -613,28 +612,9 @@ fn inner_parse_loop<'root, 'tt>(
     Success(())
 }
 
-/// Use the given sequence of token trees (`ms`) as a matcher. Match the given token stream `tts`
-/// against it and return the match.
-///
-/// # Parameters
-///
-/// - `sess`: The session into which errors are emitted
-/// - `tts`: The tokenstream we are matching against the pattern `ms`
-/// - `ms`: A sequence of token trees representing a pattern against which we are matching
-/// - `directory`: Information about the file locations (needed for the black-box parser)
-/// - `recurse_into_modules`: Whether or not to recurse into modules (needed for the black-box
-///   parser)
-pub(super) fn parse(
-    sess: &ParseSess,
-    tts: TokenStream,
-    ms: &[TokenTree],
-    directory: Option<Directory<'_>>,
-    recurse_into_modules: bool,
-) -> NamedParseResult {
-    // Create a parser that can be used for the "black box" parts.
-    let mut parser =
-        Parser::new(sess, tts, directory, recurse_into_modules, true, rustc_parse::MACRO_ARGUMENTS);
-
+/// Use the given sequence of token trees (`ms`) as a matcher. Match the token
+/// stream from the given `parser` against it and return the match.
+pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> NamedParseResult {
     // A queue of possible matcher positions. We initialize it with the matcher position in which
     // the "dot" is before the first token of the first token tree in `ms`. `inner_parse_loop` then
     // processes all of these possible matcher positions and produces possible next positions into
@@ -659,7 +639,7 @@ pub(super) fn parse(
         // parsing from the black-box parser done. The result is that `next_items` will contain a
         // bunch of possible next matcher positions in `next_items`.
         match inner_parse_loop(
-            sess,
+            parser.sess,
             &mut cur_items,
             &mut next_items,
             &mut eof_items,
@@ -684,7 +664,7 @@ pub(super) fn parse(
             if eof_items.len() == 1 {
                 let matches =
                     eof_items[0].matches.iter_mut().map(|dv| Lrc::make_mut(dv).pop().unwrap());
-                return nameize(sess, ms, matches);
+                return nameize(parser.sess, ms, matches);
             } else if eof_items.len() > 1 {
                 return Error(
                     parser.token.span,
@@ -709,9 +689,14 @@ pub(super) fn parse(
         // unnecessary implicit clone later in Rc::make_mut.
         drop(eof_items);
 
+        // If there are no possible next positions AND we aren't waiting for the black-box parser,
+        // then there is a syntax error.
+        if bb_items.is_empty() && next_items.is_empty() {
+            return Failure(parser.token.clone(), "no rules expected this token in macro call");
+        }
         // Another possibility is that we need to call out to parse some rust nonterminal
         // (black-box) parser. However, if there is not EXACTLY ONE of these, something is wrong.
-        if (!bb_items.is_empty() && !next_items.is_empty()) || bb_items.len() > 1 {
+        else if (!bb_items.is_empty() && !next_items.is_empty()) || bb_items.len() > 1 {
             let nts = bb_items
                 .iter()
                 .map(|item| match item.top_elts.get_tt(item.idx) {
@@ -733,16 +718,11 @@ pub(super) fn parse(
                 ),
             );
         }
-        // If there are no possible next positions AND we aren't waiting for the black-box parser,
-        // then there is a syntax error.
-        else if bb_items.is_empty() && next_items.is_empty() {
-            return Failure(parser.token.take(), "no rules expected this token in macro call");
-        }
         // Dump all possible `next_items` into `cur_items` for the next iteration.
         else if !next_items.is_empty() {
             // Now process the next token
             cur_items.extend(next_items.drain(..));
-            parser.bump();
+            parser.to_mut().bump();
         }
         // Finally, we have the case where we need to call the black-box parser to get some
         // nonterminal.
@@ -754,7 +734,7 @@ pub(super) fn parse(
                 let match_cur = item.match_cur;
                 item.push_match(
                     match_cur,
-                    MatchedNonterminal(Lrc::new(parse_nt(&mut parser, span, ident.name))),
+                    MatchedNonterminal(Lrc::new(parse_nt(parser.to_mut(), span, ident.name))),
                 );
                 item.idx += 1;
                 item.match_cur += 1;
diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs
index 29d41543fbf..9e6edee265c 100644
--- a/src/librustc_expand/mbe/macro_rules.rs
+++ b/src/librustc_expand/mbe/macro_rules.rs
@@ -1,11 +1,11 @@
-use crate::base::{DummyResult, ExtCtxt, MacResult, TTMacroExpander};
+use crate::base::{DummyResult, ExpansionData, ExtCtxt, MacResult, TTMacroExpander};
 use crate::base::{SyntaxExtension, SyntaxExtensionKind};
 use crate::expand::{ensure_complete_parse, parse_ast_fragment, AstFragment, AstFragmentKind};
 use crate::mbe;
 use crate::mbe::macro_check;
-use crate::mbe::macro_parser::parse;
+use crate::mbe::macro_parser::parse_tt;
 use crate::mbe::macro_parser::{Error, Failure, Success};
-use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedParseResult};
+use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq};
 use crate::mbe::transcribe::transcribe;
 
 use rustc_ast_pretty::pprust;
@@ -166,9 +166,9 @@ impl TTMacroExpander for MacroRulesMacroExpander {
     }
 }
 
-fn trace_macros_note(cx: &mut ExtCtxt<'_>, sp: Span, message: String) {
+fn trace_macros_note(cx_expansions: &mut FxHashMap<Span, Vec<String>>, sp: Span, message: String) {
     let sp = sp.macro_backtrace().last().map(|trace| trace.call_site).unwrap_or(sp);
-    cx.expansions.entry(sp).or_default().push(message);
+    cx_expansions.entry(sp).or_default().push(message);
 }
 
 /// Given `lhses` and `rhses`, this is the new macro we create
@@ -184,12 +184,36 @@ fn generic_extension<'cx>(
 ) -> Box<dyn MacResult + 'cx> {
     if cx.trace_macros() {
         let msg = format!("expanding `{}! {{ {} }}`", name, pprust::tts_to_string(arg.clone()));
-        trace_macros_note(cx, sp, msg);
+        trace_macros_note(&mut cx.expansions, sp, msg);
     }
 
     // Which arm's failure should we report? (the one furthest along)
     let mut best_failure: Option<(Token, &str)> = None;
+
+    // We create a base parser that can be used for the "black box" parts.
+    // Every iteration needs a fresh copy of that base parser. However, the
+    // parser is not mutated on many of the iterations, particularly when
+    // dealing with macros like this:
+    //
+    // macro_rules! foo {
+    //     ("a") => (A);
+    //     ("b") => (B);
+    //     ("c") => (C);
+    //     // ... etc. (maybe hundreds more)
+    // }
+    //
+    // as seen in the `html5ever` benchmark. We use a `Cow` so that the base
+    // parser is only cloned when necessary (upon mutation). Furthermore, we
+    // reinitialize the `Cow` with the base parser at the start of every
+    // iteration, so that any mutated parsers are not reused. This is all quite
+    // hacky, but speeds up the `html5ever` benchmark significantly. (Issue
+    // 68836 suggests a more comprehensive but more complex change to deal with
+    // this situation.)
+    let base_parser = base_parser_from_cx(&cx.current_expansion, &cx.parse_sess, arg.clone());
+
     for (i, lhs) in lhses.iter().enumerate() {
+        let mut parser = Cow::Borrowed(&base_parser);
+
         // try each arm's matchers
         let lhs_tt = match *lhs {
             mbe::TokenTree::Delimited(_, ref delim) => &delim.tts[..],
@@ -202,7 +226,7 @@ fn generic_extension<'cx>(
         // are not recorded. On the first `Success(..)`ful matcher, the spans are merged.
         let mut gated_spans_snaphot = mem::take(&mut *cx.parse_sess.gated_spans.spans.borrow_mut());
 
-        match parse_tt(cx, lhs_tt, arg.clone()) {
+        match parse_tt(&mut parser, lhs_tt) {
             Success(named_matches) => {
                 // The matcher was `Success(..)`ful.
                 // Merge the gated spans from parsing the matcher with the pre-existing ones.
@@ -232,11 +256,11 @@ fn generic_extension<'cx>(
 
                 if cx.trace_macros() {
                     let msg = format!("to `{}`", pprust::tts_to_string(tts.clone()));
-                    trace_macros_note(cx, sp, msg);
+                    trace_macros_note(&mut cx.expansions, sp, msg);
                 }
 
                 let directory = Directory {
-                    path: Cow::from(cx.current_expansion.module.directory.as_path()),
+                    path: cx.current_expansion.module.directory.clone(),
                     ownership: cx.current_expansion.directory_ownership,
                 };
                 let mut p = Parser::new(cx.parse_sess(), tts, Some(directory), true, false, None);
@@ -269,6 +293,7 @@ fn generic_extension<'cx>(
         // Restore to the state before snapshotting and maybe try again.
         mem::swap(&mut gated_spans_snaphot, &mut cx.parse_sess.gated_spans.spans.borrow_mut());
     }
+    drop(base_parser);
 
     let (token, label) = best_failure.expect("ran no matchers");
     let span = token.span.substitute_dummy(sp);
@@ -286,7 +311,9 @@ fn generic_extension<'cx>(
                 mbe::TokenTree::Delimited(_, ref delim) => &delim.tts[..],
                 _ => continue,
             };
-            match parse_tt(cx, lhs_tt, arg.clone()) {
+            let base_parser =
+                base_parser_from_cx(&cx.current_expansion, &cx.parse_sess, arg.clone());
+            match parse_tt(&mut Cow::Borrowed(&base_parser), lhs_tt) {
                 Success(_) => {
                     if comma_span.is_dummy() {
                         err.note("you might be missing a comma");
@@ -368,7 +395,8 @@ pub fn compile_declarative_macro(
         ),
     ];
 
-    let argument_map = match parse(sess, body, &argument_gram, None, true) {
+    let base_parser = Parser::new(sess, body, None, true, true, rustc_parse::MACRO_ARGUMENTS);
+    let argument_map = match parse_tt(&mut Cow::Borrowed(&base_parser), &argument_gram) {
         Success(m) => m,
         Failure(token, msg) => {
             let s = parse_failure_msg(&token);
@@ -1184,14 +1212,16 @@ fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String {
     }
 }
 
-/// Use this token tree as a matcher to parse given tts.
-fn parse_tt(cx: &ExtCtxt<'_>, mtch: &[mbe::TokenTree], tts: TokenStream) -> NamedParseResult {
-    // `None` is because we're not interpolating
+fn base_parser_from_cx<'cx>(
+    current_expansion: &'cx ExpansionData,
+    sess: &'cx ParseSess,
+    tts: TokenStream,
+) -> Parser<'cx> {
     let directory = Directory {
-        path: Cow::from(cx.current_expansion.module.directory.as_path()),
-        ownership: cx.current_expansion.directory_ownership,
+        path: current_expansion.module.directory.clone(),
+        ownership: current_expansion.directory_ownership,
     };
-    parse(cx.parse_sess(), tts, mtch, Some(directory), true)
+    Parser::new(sess, tts, Some(directory), true, true, rustc_parse::MACRO_ARGUMENTS)
 }
 
 /// Generates an appropriate parsing failure message. For EOF, this is "unexpected end...". For
diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs
index cd674e3c5eb..4aad2c0f68a 100644
--- a/src/librustc_parse/lib.rs
+++ b/src/librustc_parse/lib.rs
@@ -12,8 +12,7 @@ use syntax::ast;
 use syntax::token::{self, Nonterminal};
 use syntax::tokenstream::{self, TokenStream, TokenTree};
 
-use std::borrow::Cow;
-use std::path::Path;
+use std::path::{Path, PathBuf};
 use std::str;
 
 use log::info;
@@ -29,8 +28,8 @@ pub mod validate_attr;
 pub mod config;
 
 #[derive(Clone)]
-pub struct Directory<'a> {
-    pub path: Cow<'a, Path>,
+pub struct Directory {
+    pub path: PathBuf,
     pub ownership: DirectoryOwnership,
 }
 
@@ -274,7 +273,7 @@ pub fn stream_to_parser<'a>(
 pub fn stream_to_parser_with_base_dir<'a>(
     sess: &'a ParseSess,
     stream: TokenStream,
-    base_dir: Directory<'a>,
+    base_dir: Directory,
 ) -> Parser<'a> {
     Parser::new(sess, stream, Some(base_dir), true, false, None)
 }
diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs
index 37b03cf32f4..e1461dbb8e7 100644
--- a/src/librustc_parse/parser/mod.rs
+++ b/src/librustc_parse/parser/mod.rs
@@ -29,7 +29,6 @@ use syntax::token::{self, DelimToken, Token, TokenKind};
 use syntax::tokenstream::{self, DelimSpan, TokenStream, TokenTree, TreeAndJoint};
 use syntax::util::comments::{doc_comment_style, strip_doc_comment_decoration};
 
-use std::borrow::Cow;
 use std::path::PathBuf;
 use std::{cmp, mem, slice};
 
@@ -108,7 +107,7 @@ pub struct Parser<'a> {
     pub prev_span: Span,
     restrictions: Restrictions,
     /// Used to determine the path to externally loaded source files.
-    pub(super) directory: Directory<'a>,
+    pub(super) directory: Directory,
     /// `true` to parse sub-modules in other files.
     // Public for rustfmt usage.
     pub recurse_into_file_modules: bool,
@@ -370,7 +369,7 @@ impl<'a> Parser<'a> {
     pub fn new(
         sess: &'a ParseSess,
         tokens: TokenStream,
-        directory: Option<Directory<'a>>,
+        directory: Option<Directory>,
         recurse_into_file_modules: bool,
         desugar_doc_comments: bool,
         subparser_name: Option<&'static str>,
@@ -385,7 +384,7 @@ impl<'a> Parser<'a> {
             restrictions: Restrictions::empty(),
             recurse_into_file_modules,
             directory: Directory {
-                path: Cow::from(PathBuf::new()),
+                path: PathBuf::new(),
                 ownership: DirectoryOwnership::Owned { relative: None },
             },
             root_module_name: None,
@@ -413,7 +412,7 @@ impl<'a> Parser<'a> {
                 &sess.source_map().lookup_char_pos(parser.token.span.lo()).file.unmapped_path
             {
                 if let Some(directory_path) = path.parent() {
-                    parser.directory.path = Cow::from(directory_path.to_path_buf());
+                    parser.directory.path = directory_path.to_path_buf();
                 }
             }
         }
diff --git a/src/librustc_parse/parser/module.rs b/src/librustc_parse/parser/module.rs
index 6ce94d3c679..0c8fad03d86 100644
--- a/src/librustc_parse/parser/module.rs
+++ b/src/librustc_parse/parser/module.rs
@@ -285,7 +285,7 @@ impl<'a> Parser<'a> {
 
     fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) {
         if let Some(path) = attr::first_attr_value_str_by_name(attrs, sym::path) {
-            self.directory.path.to_mut().push(&*path.as_str());
+            self.directory.path.push(&*path.as_str());
             self.directory.ownership = DirectoryOwnership::Owned { relative: None };
         } else {
             // We have to push on the current module name in the case of relative
@@ -297,10 +297,10 @@ impl<'a> Parser<'a> {
             if let DirectoryOwnership::Owned { relative } = &mut self.directory.ownership {
                 if let Some(ident) = relative.take() {
                     // remove the relative offset
-                    self.directory.path.to_mut().push(&*ident.as_str());
+                    self.directory.path.push(&*ident.as_str());
                 }
             }
-            self.directory.path.to_mut().push(&*id.as_str());
+            self.directory.path.push(&*id.as_str());
         }
     }
 }
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 3c2e02fc79b..4a98095ec89 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -24,6 +24,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.annotate_expected_due_to_let_ty(err, expr);
         self.suggest_compatible_variants(err, expr, expected, expr_ty);
         self.suggest_ref_or_into(err, expr, expected, expr_ty);
+        if self.suggest_calling_boxed_future_when_appropriate(err, expr, expected, expr_ty) {
+            return;
+        }
         self.suggest_boxing_when_appropriate(err, expr, expected, expr_ty);
         self.suggest_missing_await(err, expr, expected, expr_ty);
     }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 0bdf7ba1a56..fd0c994a6ea 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -5038,14 +5038,60 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 Applicability::MachineApplicable,
             );
             err.note(
-                "for more on the distinction between the stack and the \
-                        heap, read https://doc.rust-lang.org/book/ch15-01-box.html, \
-                        https://doc.rust-lang.org/rust-by-example/std/box.html, and \
-                        https://doc.rust-lang.org/std/boxed/index.html",
+                "for more on the distinction between the stack and the heap, read \
+                 https://doc.rust-lang.org/book/ch15-01-box.html, \
+                 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
+                 https://doc.rust-lang.org/std/boxed/index.html",
             );
         }
     }
 
+    /// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
+    fn suggest_calling_boxed_future_when_appropriate(
+        &self,
+        err: &mut DiagnosticBuilder<'_>,
+        expr: &hir::Expr<'_>,
+        expected: Ty<'tcx>,
+        found: Ty<'tcx>,
+    ) -> bool {
+        // Handle #68197.
+
+        if self.tcx.hir().is_const_context(expr.hir_id) {
+            // Do not suggest `Box::new` in const context.
+            return false;
+        }
+        let pin_did = self.tcx.lang_items().pin_type();
+        match expected.kind {
+            ty::Adt(def, _) if Some(def.did) != pin_did => return false,
+            // This guards the `unwrap` and `mk_box` below.
+            _ if pin_did.is_none() || self.tcx.lang_items().owned_box().is_none() => return false,
+            _ => {}
+        }
+        let boxed_found = self.tcx.mk_box(found);
+        let new_found = self.tcx.mk_lang_item(boxed_found, lang_items::PinTypeLangItem).unwrap();
+        if let (true, Ok(snippet)) = (
+            self.can_coerce(new_found, expected),
+            self.sess().source_map().span_to_snippet(expr.span),
+        ) {
+            match found.kind {
+                ty::Adt(def, _) if def.is_box() => {
+                    err.help("use `Box::pin`");
+                }
+                _ => {
+                    err.span_suggestion(
+                        expr.span,
+                        "you need to pin and box this expression",
+                        format!("Box::pin({})", snippet),
+                        Applicability::MachineApplicable,
+                    );
+                }
+            }
+            true
+        } else {
+            false
+        }
+    }
+
     /// A common error is to forget to add a semicolon at the end of a block, e.g.,
     ///
     /// ```
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index ea0e4719a24..f3a1f412d0d 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -278,6 +278,17 @@ impl ItemCtxt<'tcx> {
     pub fn to_ty(&self, ast_ty: &'tcx hir::Ty<'tcx>) -> Ty<'tcx> {
         AstConv::ast_ty_to_ty(self, ast_ty)
     }
+
+    pub fn hir_id(&self) -> hir::HirId {
+        self.tcx
+            .hir()
+            .as_local_hir_id(self.item_def_id)
+            .expect("Non-local call to local provider is_const_fn")
+    }
+
+    pub fn node(&self) -> hir::Node<'tcx> {
+        self.tcx.hir().get(self.hir_id())
+    }
 }
 
 impl AstConv<'tcx> for ItemCtxt<'tcx> {
@@ -290,15 +301,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
     }
 
     fn default_constness_for_trait_bounds(&self) -> ast::Constness {
-        // FIXME: refactor this into a method
-        let hir_id = self
-            .tcx
-            .hir()
-            .as_local_hir_id(self.item_def_id)
-            .expect("Non-local call to local provider is_const_fn");
-
-        let node = self.tcx.hir().get(hir_id);
-        if let Some(fn_like) = FnLikeNode::from_node(node) {
+        if let Some(fn_like) = FnLikeNode::from_node(self.node()) {
             fn_like.constness()
         } else {
             ast::Constness::NotConst
@@ -352,14 +355,80 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
             self.tcx().mk_projection(item_def_id, item_substs)
         } else {
             // There are no late-bound regions; we can just ignore the binder.
-            struct_span_err!(
+            let mut err = struct_span_err!(
                 self.tcx().sess,
                 span,
                 E0212,
                 "cannot extract an associated type from a higher-ranked trait bound \
                  in this context"
-            )
-            .emit();
+            );
+
+            match self.node() {
+                hir::Node::Field(_) | hir::Node::Ctor(_) | hir::Node::Variant(_) => {
+                    let item =
+                        self.tcx.hir().expect_item(self.tcx.hir().get_parent_item(self.hir_id()));
+                    match &item.kind {
+                        hir::ItemKind::Enum(_, generics)
+                        | hir::ItemKind::Struct(_, generics)
+                        | hir::ItemKind::Union(_, generics) => {
+                            // FIXME: look for an appropriate lt name if `'a` is already used
+                            let (lt_sp, sugg) = match &generics.params[..] {
+                                [] => (generics.span, "<'a>".to_string()),
+                                [bound, ..] => (bound.span.shrink_to_lo(), "'a, ".to_string()),
+                            };
+                            let suggestions = vec![
+                                (lt_sp, sugg),
+                                (
+                                    span,
+                                    format!(
+                                        "{}::{}",
+                                        // Replace the existing lifetimes with a new named lifetime.
+                                        self.tcx
+                                            .replace_late_bound_regions(&poly_trait_ref, |_| {
+                                                self.tcx.mk_region(ty::ReEarlyBound(
+                                                    ty::EarlyBoundRegion {
+                                                        def_id: item_def_id,
+                                                        index: 0,
+                                                        name: Symbol::intern("'a"),
+                                                    },
+                                                ))
+                                            })
+                                            .0,
+                                        item_segment.ident
+                                    ),
+                                ),
+                            ];
+                            err.multipart_suggestion(
+                                "use a fully qualified path with explicit lifetimes",
+                                suggestions,
+                                Applicability::MaybeIncorrect,
+                            );
+                        }
+                        _ => {}
+                    }
+                }
+                hir::Node::Item(hir::Item { kind: hir::ItemKind::Struct(..), .. })
+                | hir::Node::Item(hir::Item { kind: hir::ItemKind::Enum(..), .. })
+                | hir::Node::Item(hir::Item { kind: hir::ItemKind::Union(..), .. }) => {}
+                hir::Node::Item(_)
+                | hir::Node::ForeignItem(_)
+                | hir::Node::TraitItem(_)
+                | hir::Node::ImplItem(_) => {
+                    err.span_suggestion(
+                        span,
+                        "use a fully qualified path with inferred lifetimes",
+                        format!(
+                            "{}::{}",
+                            // Erase named lt, we want `<A as B<'_>::C`, not `<A as B<'a>::C`.
+                            self.tcx.anonymize_late_bound_regions(&poly_trait_ref).skip_binder(),
+                            item_segment.ident
+                        ),
+                        Applicability::MaybeIncorrect,
+                    );
+                }
+                _ => {}
+            }
+            err.emit();
             self.tcx().types.err
         }
     }
@@ -1054,7 +1123,27 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics {
             Some(tcx.closure_base_def_id(def_id))
         }
         Node::Item(item) => match item.kind {
-            ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn, .. }) => impl_trait_fn,
+            ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn, .. }) => {
+                impl_trait_fn.or_else(|| {
+                    let parent_id = tcx.hir().get_parent_item(hir_id);
+                    if parent_id != hir_id && parent_id != CRATE_HIR_ID {
+                        debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id);
+                        // If this 'impl Trait' is nested inside another 'impl Trait'
+                        // (e.g. `impl Foo<MyType = impl Bar<A>>`), we need to use the 'parent'
+                        // 'impl Trait' for its generic parameters, since we can reference them
+                        // from the 'child' 'impl Trait'
+                        if let Node::Item(hir::Item { kind: ItemKind::OpaqueTy(..), .. }) =
+                            tcx.hir().get(parent_id)
+                        {
+                            Some(tcx.hir().local_def_id(parent_id))
+                        } else {
+                            None
+                        }
+                    } else {
+                        None
+                    }
+                })
+            }
             _ => None,
         },
         _ => None,
diff --git a/src/librustdoc/html/static/brush.svg b/src/librustdoc/html/static/brush.svg
index 072264a6408..ea266e856a9 100644
--- a/src/librustdoc/html/static/brush.svg
+++ b/src/librustdoc/html/static/brush.svg
@@ -1 +1 @@
-<?xml version="1.0" ?><svg height="1792" viewBox="0 0 1792 1792" width="1792" xmlns="http://www.w3.org/2000/svg"><path d="M1615 0q70 0 122.5 46.5t52.5 116.5q0 63-45 151-332 629-465 752-97 91-218 91-126 0-216.5-92.5t-90.5-219.5q0-128 92-212l638-579q59-54 130-54zm-909 1034q39 76 106.5 130t150.5 76l1 71q4 213-129.5 347t-348.5 134q-123 0-218-46.5t-152.5-127.5-86.5-183-29-220q7 5 41 30t62 44.5 59 36.5 46 17q41 0 55-37 25-66 57.5-112.5t69.5-76 88-47.5 103-25.5 125-10.5z"/></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" width="1792" height="1792" viewBox="0 0 1792 1792"><path d="M1615 0q70 0 122.5 46.5t52.5 116.5q0 63-45 151-332 629-465 752-97 91-218 91-126 0-216.5-92.5t-90.5-219.5q0-128 92-212l638-579q59-54 130-54zm-909 1034q39 76 106.5 130t150.5 76l1 71q4 213-129.5 347t-348.5 134q-123 0-218-46.5t-152.5-127.5-86.5-183-29-220q7 5 41 30t62 44.5 59 36.5 46 17q41 0 55-37 25-66 57.5-112.5t69.5-76 88-47.5 103-25.5 125-10.5z"/></svg>
\ No newline at end of file
diff --git a/src/librustdoc/html/static/down-arrow.svg b/src/librustdoc/html/static/down-arrow.svg
index c0f59f0c36f..35437e77a71 100644
--- a/src/librustdoc/html/static/down-arrow.svg
+++ b/src/librustdoc/html/static/down-arrow.svg
@@ -1 +1 @@
-<?xml version="1.0" ?><!DOCTYPE svg  PUBLIC '-//W3C//DTD SVG 1.1//EN'  'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg height="128px" id="Layer_1" style="enable-background:new 0 0 128 128;" version="1.1" viewBox="-30 -20 176 176" width="128px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g><line style="fill:none;stroke:#2F3435;stroke-width:12;stroke-linecap:square;stroke-miterlimit:10;" x1="111" x2="64" y1="40.5" y2="87.499"/><line style="fill:none;stroke:#2F3435;stroke-width:12;stroke-linecap:square;stroke-miterlimit:10;" x1="64" x2="17" y1="87.499" y2="40.5"/></g></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" width="128" height="128" enable-background="new 0 0 128 128" version="1.1" viewBox="-30 -20 176 176" xml:space="preserve"><g><line x1="111" x2="64" y1="40.5" y2="87.499" fill="none" stroke="#2F3435" stroke-linecap="square" stroke-miterlimit="10" stroke-width="12"/><line x1="64" x2="17" y1="87.499" y2="40.5" fill="none" stroke="#2F3435" stroke-linecap="square" stroke-miterlimit="10" stroke-width="12"/></g></svg>
\ No newline at end of file
diff --git a/src/librustdoc/html/static/wheel.svg b/src/librustdoc/html/static/wheel.svg
index 44381a401a8..01da3b24c7c 100644
--- a/src/librustdoc/html/static/wheel.svg
+++ b/src/librustdoc/html/static/wheel.svg
@@ -1 +1 @@
-<?xml version="1.0" ?><!DOCTYPE svg  PUBLIC '-//W3C//DTD SVG 1.1//EN'  'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg enable-background="new 0 0 27.434 29.5" height="29.5px" id="Capa_1" version="1.1" viewBox="0 0 27.434 29.5" width="27.434px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g><path d="M27.315,18.389c-0.165-0.604-0.509-1.113-0.981-1.459c-0.042-0.144-0.083-0.429-0.015-0.761l0.037-0.177v-0.182V14.8   c0-1.247-0.006-1.277-0.048-1.472c-0.076-0.354-0.035-0.653,0.007-0.803c0.477-0.346,0.828-0.861,0.996-1.476   c0.261-0.956,0.076-2.091-0.508-3.114l-0.591-1.032c-0.746-1.307-1.965-2.119-3.182-2.119c-0.378,0-0.75,0.081-1.085,0.235   c-0.198-0.025-0.554-0.15-0.855-0.389l-0.103-0.082l-0.114-0.065l-1.857-1.067L18.92,3.36l-0.105-0.044   c-0.376-0.154-0.658-0.41-0.768-0.556C17.918,1.172,16.349,0,14.296,0H13.14c-2.043,0-3.608,1.154-3.749,2.721   C9.277,2.862,8.999,3.104,8.633,3.25l-0.1,0.039L8.439,3.341L6.495,4.406L6.363,4.479L6.245,4.573   C5.936,4.82,5.596,4.944,5.416,4.977c-0.314-0.139-0.66-0.21-1.011-0.21c-1.198,0-2.411,0.819-3.165,2.139L0.65,7.938   c-0.412,0.72-0.642,1.521-0.644,2.258c-0.003,0.952,0.362,1.756,1.013,2.256c0.034,0.155,0.061,0.448-0.016,0.786   c-0.038,0.168-0.062,0.28-0.062,1.563c0,1.148,0,1.148,0.015,1.262l0.009,0.073l0.017,0.073c0.073,0.346,0.045,0.643,0.011,0.802   C0.348,17.512-0.01,18.314,0,19.268c0.008,0.729,0.238,1.523,0.648,2.242l0.589,1.031c0.761,1.331,1.967,2.159,3.15,2.159   c0.324,0,0.645-0.064,0.938-0.187c0.167,0.038,0.492,0.156,0.813,0.416l0.11,0.088l0.124,0.07l2.045,1.156l0.102,0.057l0.107,0.043   c0.364,0.147,0.646,0.381,0.766,0.521c0.164,1.52,1.719,2.634,3.745,2.634h1.155c2.037,0,3.598-1.134,3.747-2.675   c0.117-0.145,0.401-0.393,0.774-0.549l0.111-0.047l0.105-0.062l1.96-1.159l0.105-0.062l0.097-0.075   c0.309-0.246,0.651-0.371,0.832-0.402c0.313,0.138,0.662,0.212,1.016,0.212c1.199,0,2.412-0.82,3.166-2.139l0.59-1.032   C27.387,20.48,27.575,19.342,27.315,18.389z M25.274,20.635l-0.59,1.032c-0.438,0.765-1.104,1.251-1.639,1.251   c-0.133,0-0.258-0.029-0.369-0.094c-0.15-0.086-0.346-0.127-0.566-0.127c-0.596,0-1.383,0.295-2.01,0.796l-1.96,1.157   c-1.016,0.425-1.846,1.291-1.846,1.929s-0.898,1.159-1.998,1.159H13.14c-1.1,0-1.998-0.514-1.998-1.141s-0.834-1.477-1.854-1.888   l-2.046-1.157c-0.636-0.511-1.425-0.814-2.006-0.814c-0.202,0-0.379,0.037-0.516,0.115c-0.101,0.057-0.214,0.084-0.333,0.084   c-0.518,0-1.179-0.498-1.62-1.271l-0.591-1.032c-0.545-0.954-0.556-1.983-0.024-2.286c0.532-0.305,0.78-1.432,0.551-2.506   c0,0,0-0.003,0-1.042c0-1.088,0.021-1.18,0.021-1.18c0.238-1.072-0.01-2.203-0.552-2.513C1.631,10.8,1.634,9.765,2.18,8.812   L2.769,7.78c0.438-0.766,1.103-1.251,1.636-1.251c0.131,0,0.255,0.029,0.365,0.092C4.92,6.707,5.114,6.747,5.334,6.747   c0.596,0,1.38-0.296,2.007-0.795l1.944-1.065c1.021-0.407,1.856-1.277,1.856-1.933c0-0.656,0.898-1.192,1.998-1.192h1.156V1.761   c1.1,0,1.998,0.545,1.998,1.211c0,0.667,0.832,1.554,1.849,1.973L20,6.013c0.618,0.489,1.401,0.775,2.012,0.775   c0.24,0,0.454-0.045,0.62-0.139c0.122-0.069,0.259-0.102,0.403-0.102c0.551,0,1.221,0.476,1.653,1.231l0.59,1.032   c0.544,0.953,0.518,2.004-0.062,2.334c-0.577,0.331-0.859,1.48-0.627,2.554c0,0,0.01,0.042,0.01,1.103c0,1.012,0,1.012,0,1.012   c-0.218,1.049,0.068,2.174,0.636,2.498C25.802,18.635,25.819,19.68,25.274,20.635z"/><path d="M13.61,7.611c-3.913,0-7.084,3.173-7.084,7.085c0,3.914,3.171,7.085,7.084,7.085s7.085-3.172,7.085-7.085   C20.695,10.784,17.523,7.611,13.61,7.611z M13.61,20.02c-2.936,0-5.323-2.388-5.323-5.323c0-2.935,2.388-5.323,5.323-5.323   s5.324,2.388,5.324,5.323C18.934,17.632,16.546,20.02,13.61,20.02z"/><path d="M13.682,9.908c-2.602,0-4.718,2.116-4.718,4.718c0,2.601,2.116,4.716,4.718,4.716c2.601,0,4.717-2.115,4.717-4.716   C18.399,12.024,16.283,9.908,13.682,9.908z M13.682,17.581c-1.633,0-2.956-1.323-2.956-2.955s1.323-2.956,2.956-2.956   c1.632,0,2.956,1.324,2.956,2.956S15.314,17.581,13.682,17.581z"/></g></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Capa_1" width="27.434" height="29.5" enable-background="new 0 0 27.434 29.5" version="1.1" viewBox="0 0 27.434 29.5" xml:space="preserve"><g><path d="M27.315,18.389c-0.165-0.604-0.509-1.113-0.981-1.459c-0.042-0.144-0.083-0.429-0.015-0.761l0.037-0.177v-0.182V14.8 c0-1.247-0.006-1.277-0.048-1.472c-0.076-0.354-0.035-0.653,0.007-0.803c0.477-0.346,0.828-0.861,0.996-1.476 c0.261-0.956,0.076-2.091-0.508-3.114l-0.591-1.032c-0.746-1.307-1.965-2.119-3.182-2.119c-0.378,0-0.75,0.081-1.085,0.235 c-0.198-0.025-0.554-0.15-0.855-0.389l-0.103-0.082l-0.114-0.065l-1.857-1.067L18.92,3.36l-0.105-0.044 c-0.376-0.154-0.658-0.41-0.768-0.556C17.918,1.172,16.349,0,14.296,0H13.14c-2.043,0-3.608,1.154-3.749,2.721 C9.277,2.862,8.999,3.104,8.633,3.25l-0.1,0.039L8.439,3.341L6.495,4.406L6.363,4.479L6.245,4.573 C5.936,4.82,5.596,4.944,5.416,4.977c-0.314-0.139-0.66-0.21-1.011-0.21c-1.198,0-2.411,0.819-3.165,2.139L0.65,7.938 c-0.412,0.72-0.642,1.521-0.644,2.258c-0.003,0.952,0.362,1.756,1.013,2.256c0.034,0.155,0.061,0.448-0.016,0.786 c-0.038,0.168-0.062,0.28-0.062,1.563c0,1.148,0,1.148,0.015,1.262l0.009,0.073l0.017,0.073c0.073,0.346,0.045,0.643,0.011,0.802 C0.348,17.512-0.01,18.314,0,19.268c0.008,0.729,0.238,1.523,0.648,2.242l0.589,1.031c0.761,1.331,1.967,2.159,3.15,2.159 c0.324,0,0.645-0.064,0.938-0.187c0.167,0.038,0.492,0.156,0.813,0.416l0.11,0.088l0.124,0.07l2.045,1.156l0.102,0.057l0.107,0.043 c0.364,0.147,0.646,0.381,0.766,0.521c0.164,1.52,1.719,2.634,3.745,2.634h1.155c2.037,0,3.598-1.134,3.747-2.675 c0.117-0.145,0.401-0.393,0.774-0.549l0.111-0.047l0.105-0.062l1.96-1.159l0.105-0.062l0.097-0.075 c0.309-0.246,0.651-0.371,0.832-0.402c0.313,0.138,0.662,0.212,1.016,0.212c1.199,0,2.412-0.82,3.166-2.139l0.59-1.032 C27.387,20.48,27.575,19.342,27.315,18.389z M25.274,20.635l-0.59,1.032c-0.438,0.765-1.104,1.251-1.639,1.251 c-0.133,0-0.258-0.029-0.369-0.094c-0.15-0.086-0.346-0.127-0.566-0.127c-0.596,0-1.383,0.295-2.01,0.796l-1.96,1.157 c-1.016,0.425-1.846,1.291-1.846,1.929s-0.898,1.159-1.998,1.159H13.14c-1.1,0-1.998-0.514-1.998-1.141s-0.834-1.477-1.854-1.888 l-2.046-1.157c-0.636-0.511-1.425-0.814-2.006-0.814c-0.202,0-0.379,0.037-0.516,0.115c-0.101,0.057-0.214,0.084-0.333,0.084 c-0.518,0-1.179-0.498-1.62-1.271l-0.591-1.032c-0.545-0.954-0.556-1.983-0.024-2.286c0.532-0.305,0.78-1.432,0.551-2.506 c0,0,0-0.003,0-1.042c0-1.088,0.021-1.18,0.021-1.18c0.238-1.072-0.01-2.203-0.552-2.513C1.631,10.8,1.634,9.765,2.18,8.812 L2.769,7.78c0.438-0.766,1.103-1.251,1.636-1.251c0.131,0,0.255,0.029,0.365,0.092C4.92,6.707,5.114,6.747,5.334,6.747 c0.596,0,1.38-0.296,2.007-0.795l1.944-1.065c1.021-0.407,1.856-1.277,1.856-1.933c0-0.656,0.898-1.192,1.998-1.192h1.156V1.761 c1.1,0,1.998,0.545,1.998,1.211c0,0.667,0.832,1.554,1.849,1.973L20,6.013c0.618,0.489,1.401,0.775,2.012,0.775 c0.24,0,0.454-0.045,0.62-0.139c0.122-0.069,0.259-0.102,0.403-0.102c0.551,0,1.221,0.476,1.653,1.231l0.59,1.032 c0.544,0.953,0.518,2.004-0.062,2.334c-0.577,0.331-0.859,1.48-0.627,2.554c0,0,0.01,0.042,0.01,1.103c0,1.012,0,1.012,0,1.012 c-0.218,1.049,0.068,2.174,0.636,2.498C25.802,18.635,25.819,19.68,25.274,20.635z"/><path d="M13.61,7.611c-3.913,0-7.084,3.173-7.084,7.085c0,3.914,3.171,7.085,7.084,7.085s7.085-3.172,7.085-7.085 C20.695,10.784,17.523,7.611,13.61,7.611z M13.61,20.02c-2.936,0-5.323-2.388-5.323-5.323c0-2.935,2.388-5.323,5.323-5.323 s5.324,2.388,5.324,5.323C18.934,17.632,16.546,20.02,13.61,20.02z"/><path d="M13.682,9.908c-2.602,0-4.718,2.116-4.718,4.718c0,2.601,2.116,4.716,4.718,4.716c2.601,0,4.717-2.115,4.717-4.716 C18.399,12.024,16.283,9.908,13.682,9.908z M13.682,17.581c-1.633,0-2.956-1.323-2.956-2.955s1.323-2.956,2.956-2.956 c1.632,0,2.956,1.324,2.956,2.956S15.314,17.581,13.682,17.581z"/></g></svg>
\ No newline at end of file
diff --git a/src/libserialize/leb128.rs b/src/libserialize/leb128.rs
index b8242f7154e..1fe6a309e96 100644
--- a/src/libserialize/leb128.rs
+++ b/src/libserialize/leb128.rs
@@ -1,46 +1,14 @@
-#[inline]
-pub fn write_to_vec(vec: &mut Vec<u8>, byte: u8) {
-    vec.push(byte);
-}
-
-#[cfg(target_pointer_width = "32")]
-const USIZE_LEB128_SIZE: usize = 5;
-#[cfg(target_pointer_width = "64")]
-const USIZE_LEB128_SIZE: usize = 10;
-
-macro_rules! leb128_size {
-    (u16) => {
-        3
-    };
-    (u32) => {
-        5
-    };
-    (u64) => {
-        10
-    };
-    (u128) => {
-        19
-    };
-    (usize) => {
-        USIZE_LEB128_SIZE
-    };
-}
-
 macro_rules! impl_write_unsigned_leb128 {
     ($fn_name:ident, $int_ty:ident) => {
         #[inline]
         pub fn $fn_name(out: &mut Vec<u8>, mut value: $int_ty) {
-            for _ in 0..leb128_size!($int_ty) {
-                let mut byte = (value & 0x7F) as u8;
-                value >>= 7;
-                if value != 0 {
-                    byte |= 0x80;
-                }
-
-                write_to_vec(out, byte);
-
-                if value == 0 {
+            loop {
+                if value < 0x80 {
+                    out.push(value as u8);
                     break;
+                } else {
+                    out.push(((value & 0x7f) | 0x80) as u8);
+                    value >>= 7;
                 }
             }
         }
@@ -57,24 +25,20 @@ macro_rules! impl_read_unsigned_leb128 {
     ($fn_name:ident, $int_ty:ident) => {
         #[inline]
         pub fn $fn_name(slice: &[u8]) -> ($int_ty, usize) {
-            let mut result: $int_ty = 0;
+            let mut result = 0;
             let mut shift = 0;
             let mut position = 0;
-
-            for _ in 0..leb128_size!($int_ty) {
-                let byte = unsafe { *slice.get_unchecked(position) };
+            loop {
+                let byte = slice[position];
                 position += 1;
-                result |= ((byte & 0x7F) as $int_ty) << shift;
                 if (byte & 0x80) == 0 {
-                    break;
+                    result |= (byte as $int_ty) << shift;
+                    return (result, position);
+                } else {
+                    result |= ((byte & 0x7F) as $int_ty) << shift;
                 }
                 shift += 7;
             }
-
-            // Do a single bounds check at the end instead of for every byte.
-            assert!(position <= slice.len());
-
-            (result, position)
         }
     };
 }
@@ -116,7 +80,7 @@ where
 
 #[inline]
 pub fn write_signed_leb128(out: &mut Vec<u8>, value: i128) {
-    write_signed_leb128_to(value, |v| write_to_vec(out, v))
+    write_signed_leb128_to(value, |v| out.push(v))
 }
 
 #[inline]
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index fdc587ba5da..d0e1a01b006 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -203,7 +203,7 @@ pub struct HashMap<K, V, S = RandomState> {
     base: base::HashMap<K, V, S>,
 }
 
-impl<K: Hash + Eq, V> HashMap<K, V, RandomState> {
+impl<K, V> HashMap<K, V, RandomState> {
     /// Creates an empty `HashMap`.
     ///
     /// The hash map is initially created with a capacity of 0, so it will not allocate until it
@@ -240,6 +240,59 @@ impl<K: Hash + Eq, V> HashMap<K, V, RandomState> {
 }
 
 impl<K, V, S> HashMap<K, V, S> {
+    /// Creates an empty `HashMap` which will use the given hash builder to hash
+    /// keys.
+    ///
+    /// The created map has the default initial capacity.
+    ///
+    /// Warning: `hash_builder` is normally randomly generated, and
+    /// is designed to allow HashMaps to be resistant to attacks that
+    /// cause many collisions and very poor performance. Setting it
+    /// manually using this function can expose a DoS attack vector.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    /// use std::collections::hash_map::RandomState;
+    ///
+    /// let s = RandomState::new();
+    /// let mut map = HashMap::with_hasher(s);
+    /// map.insert(1, 2);
+    /// ```
+    #[inline]
+    #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
+    pub fn with_hasher(hash_builder: S) -> HashMap<K, V, S> {
+        HashMap { base: base::HashMap::with_hasher(hash_builder) }
+    }
+
+    /// Creates an empty `HashMap` with the specified capacity, using `hash_builder`
+    /// to hash the keys.
+    ///
+    /// The hash map will be able to hold at least `capacity` elements without
+    /// reallocating. If `capacity` is 0, the hash map will not allocate.
+    ///
+    /// Warning: `hash_builder` is normally randomly generated, and
+    /// is designed to allow HashMaps to be resistant to attacks that
+    /// cause many collisions and very poor performance. Setting it
+    /// manually using this function can expose a DoS attack vector.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    /// use std::collections::hash_map::RandomState;
+    ///
+    /// let s = RandomState::new();
+    /// let mut map = HashMap::with_capacity_and_hasher(10, s);
+    /// map.insert(1, 2);
+    /// ```
+    #[inline]
+    #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
+    pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap<K, V, S> {
+        HashMap { base: base::HashMap::with_capacity_and_hasher(capacity, hash_builder) }
+    }
+
     /// Returns the number of elements the map can hold without reallocating.
     ///
     /// This number is a lower bound; the `HashMap<K, V>` might be able to hold
@@ -457,65 +510,6 @@ impl<K, V, S> HashMap<K, V, S> {
     pub fn clear(&mut self) {
         self.base.clear();
     }
-}
-
-impl<K, V, S> HashMap<K, V, S>
-where
-    K: Eq + Hash,
-    S: BuildHasher,
-{
-    /// Creates an empty `HashMap` which will use the given hash builder to hash
-    /// keys.
-    ///
-    /// The created map has the default initial capacity.
-    ///
-    /// Warning: `hash_builder` is normally randomly generated, and
-    /// is designed to allow HashMaps to be resistant to attacks that
-    /// cause many collisions and very poor performance. Setting it
-    /// manually using this function can expose a DoS attack vector.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    /// use std::collections::hash_map::RandomState;
-    ///
-    /// let s = RandomState::new();
-    /// let mut map = HashMap::with_hasher(s);
-    /// map.insert(1, 2);
-    /// ```
-    #[inline]
-    #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
-    pub fn with_hasher(hash_builder: S) -> HashMap<K, V, S> {
-        HashMap { base: base::HashMap::with_hasher(hash_builder) }
-    }
-
-    /// Creates an empty `HashMap` with the specified capacity, using `hash_builder`
-    /// to hash the keys.
-    ///
-    /// The hash map will be able to hold at least `capacity` elements without
-    /// reallocating. If `capacity` is 0, the hash map will not allocate.
-    ///
-    /// Warning: `hash_builder` is normally randomly generated, and
-    /// is designed to allow HashMaps to be resistant to attacks that
-    /// cause many collisions and very poor performance. Setting it
-    /// manually using this function can expose a DoS attack vector.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    /// use std::collections::hash_map::RandomState;
-    ///
-    /// let s = RandomState::new();
-    /// let mut map = HashMap::with_capacity_and_hasher(10, s);
-    /// map.insert(1, 2);
-    /// ```
-    #[inline]
-    #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
-    pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap<K, V, S> {
-        HashMap { base: base::HashMap::with_capacity_and_hasher(capacity, hash_builder) }
-    }
 
     /// Returns a reference to the map's [`BuildHasher`].
     ///
@@ -536,7 +530,13 @@ where
     pub fn hasher(&self) -> &S {
         self.base.hasher()
     }
+}
 
+impl<K, V, S> HashMap<K, V, S>
+where
+    K: Eq + Hash,
+    S: BuildHasher,
+{
     /// Reserves capacity for at least `additional` more elements to be inserted
     /// in the `HashMap`. The collection may reserve more space to avoid
     /// frequent reallocations.
@@ -984,9 +984,8 @@ where
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K, V, S> Debug for HashMap<K, V, S>
 where
-    K: Eq + Hash + Debug,
+    K: Debug,
     V: Debug,
-    S: BuildHasher,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_map().entries(self.iter()).finish()
@@ -996,8 +995,7 @@ where
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K, V, S> Default for HashMap<K, V, S>
 where
-    K: Eq + Hash,
-    S: BuildHasher + Default,
+    S: Default,
 {
     /// Creates an empty `HashMap<K, V, S>`, with the `Default` value for the hasher.
     #[inline]
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index b48700fb944..1ad99f03703 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -110,7 +110,7 @@ pub struct HashSet<T, S = RandomState> {
     map: HashMap<T, (), S>,
 }
 
-impl<T: Hash + Eq> HashSet<T, RandomState> {
+impl<T> HashSet<T, RandomState> {
     /// Creates an empty `HashSet`.
     ///
     /// The hash set is initially created with a capacity of 0, so it will not allocate until it
@@ -261,13 +261,7 @@ impl<T, S> HashSet<T, S> {
     pub fn clear(&mut self) {
         self.map.clear()
     }
-}
 
-impl<T, S> HashSet<T, S>
-where
-    T: Eq + Hash,
-    S: BuildHasher,
-{
     /// Creates a new empty hash set which will use the given hasher to hash
     /// keys.
     ///
@@ -340,7 +334,13 @@ where
     pub fn hasher(&self) -> &S {
         self.map.hasher()
     }
+}
 
+impl<T, S> HashSet<T, S>
+where
+    T: Eq + Hash,
+    S: BuildHasher,
+{
     /// Reserves capacity for at least `additional` more elements to be inserted
     /// in the `HashSet`. The collection may reserve more space to avoid
     /// frequent reallocations.
@@ -928,8 +928,7 @@ where
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T, S> fmt::Debug for HashSet<T, S>
 where
-    T: Eq + Hash + fmt::Debug,
-    S: BuildHasher,
+    T: fmt::Debug,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_set().entries(self.iter()).finish()
@@ -977,8 +976,7 @@ where
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T, S> Default for HashSet<T, S>
 where
-    T: Eq + Hash,
-    S: BuildHasher + Default,
+    S: Default,
 {
     /// Creates an empty `HashSet<T, S>` with the `Default` value for the hasher.
     #[inline]
diff --git a/src/libstd/sys/sgx/args.rs b/src/libstd/sys/sgx/args.rs
index b47a48e752c..5a53695a846 100644
--- a/src/libstd/sys/sgx/args.rs
+++ b/src/libstd/sys/sgx/args.rs
@@ -22,12 +22,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
     }
 }
 
-pub unsafe fn cleanup() {
-    let args = ARGS.swap(0, Ordering::Relaxed);
-    if args != 0 {
-        drop(Box::<ArgsStore>::from_raw(args as _))
-    }
-}
+pub unsafe fn cleanup() {}
 
 pub fn args() -> Args {
     let args = unsafe { (ARGS.load(Ordering::Relaxed) as *const ArgsStore).as_ref() };
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.fixed b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.fixed
new file mode 100644
index 00000000000..760d2b433c8
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.fixed
@@ -0,0 +1,37 @@
+#![allow(dead_code, unused_variables)]
+// run-rustfix
+// Check projection of an associated type out of a higher-ranked trait-bound
+// in the context of a function signature.
+
+pub trait Foo<T> {
+    type A;
+
+    fn get(&self, t: T) -> Self::A;
+}
+
+fn foo2<I : for<'x> Foo<&'x isize>>(
+    x: <I as Foo<&isize>>::A)
+    //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
+{
+    // This case is illegal because we have to instantiate `'x`, and
+    // we don't know what region to instantiate it with.
+    //
+    // This could perhaps be made equivalent to the examples below,
+    // specifically for fn signatures.
+}
+
+fn foo3<I : for<'x> Foo<&'x isize>>(
+    x: <I as Foo<&isize>>::A)
+{
+    // OK, in this case we spelled out the precise regions involved, though we left one of
+    // them anonymous.
+}
+
+fn foo4<'a, I : for<'x> Foo<&'x isize>>(
+    x: <I as Foo<&'a isize>>::A)
+{
+    // OK, in this case we spelled out the precise regions involved.
+}
+
+
+pub fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs
index bf13c410cc6..6eb584ea645 100644
--- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs
@@ -1,3 +1,5 @@
+#![allow(dead_code, unused_variables)]
+// run-rustfix
 // Check projection of an associated type out of a higher-ranked trait-bound
 // in the context of a function signature.
 
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.stderr b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.stderr
index 09f4f99703f..f2137f68665 100644
--- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.stderr
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.stderr
@@ -1,8 +1,8 @@
 error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context
-  --> $DIR/associated-types-project-from-hrtb-in-fn.rs:11:8
+  --> $DIR/associated-types-project-from-hrtb-in-fn.rs:13:8
    |
 LL |     x: I::A)
-   |        ^^^^
+   |        ^^^^ help: use a fully qualified path with inferred lifetimes: `<I as Foo<&isize>>::A`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs
index 20f11ecf638..8a5777d4d7c 100644
--- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs
@@ -7,18 +7,25 @@ pub trait Foo<T> {
     fn get(&self, t: T) -> Self::A;
 }
 
-struct SomeStruct<I : for<'x> Foo<&'x isize>> {
+struct SomeStruct<I: for<'x> Foo<&'x isize>> {
     field: I::A
     //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
 }
 
+enum SomeEnum<I: for<'x> Foo<&'x isize>> {
+    TupleVariant(I::A),
+    //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
+    StructVariant { field: I::A },
+    //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
+}
+
 // FIXME(eddyb) This one doesn't even compile because of the unsupported syntax.
 
 // struct AnotherStruct<I : for<'x> Foo<&'x isize>> {
 //     field: <I as for<'y> Foo<&'y isize>>::A
 // }
 
-struct YetAnotherStruct<'a, I : for<'x> Foo<&'x isize>> {
+struct YetAnotherStruct<'a, I: for<'x> Foo<&'x isize>> {
     field: <I as Foo<&'a isize>>::A
 }
 
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.stderr b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.stderr
index 189b19461f4..c71bc70ea6c 100644
--- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.stderr
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.stderr
@@ -3,6 +3,38 @@ error[E0212]: cannot extract an associated type from a higher-ranked trait bound
    |
 LL |     field: I::A
    |            ^^^^
+   |
+help: use a fully qualified path with explicit lifetimes
+   |
+LL | struct SomeStruct<'a, I: for<'x> Foo<&'x isize>> {
+LL |     field: <I as Foo<&'a isize>>::A
+   |
+
+error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context
+  --> $DIR/associated-types-project-from-hrtb-in-struct.rs:16:18
+   |
+LL |     TupleVariant(I::A),
+   |                  ^^^^
+   |
+help: use a fully qualified path with explicit lifetimes
+   |
+LL | enum SomeEnum<'a, I: for<'x> Foo<&'x isize>> {
+LL |     TupleVariant(<I as Foo<&'a isize>>::A),
+   |
+
+error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context
+  --> $DIR/associated-types-project-from-hrtb-in-struct.rs:18:28
+   |
+LL |     StructVariant { field: I::A },
+   |                            ^^^^
+   |
+help: use a fully qualified path with explicit lifetimes
+   |
+LL | enum SomeEnum<'a, I: for<'x> Foo<&'x isize>> {
+LL |     TupleVariant(I::A),
+LL |
+LL |     StructVariant { field: <I as Foo<&'a isize>>::A },
+   |
 
-error: aborting due to previous error
+error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.fixed b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.fixed
new file mode 100644
index 00000000000..acf32bccbec
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.fixed
@@ -0,0 +1,38 @@
+#![allow(dead_code)]
+// run-rustfix
+// Check projection of an associated type out of a higher-ranked trait-bound
+// in the context of a method definition in a trait.
+
+pub trait Foo<T> {
+    type A;
+
+    fn get(&self, t: T) -> Self::A;
+}
+
+trait SomeTrait<I : for<'x> Foo<&'x isize>> {
+    fn some_method(&self, arg: <I as Foo<&isize>>::A);
+    //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
+}
+
+trait AnotherTrait<I : for<'x> Foo<&'x isize>> {
+    fn some_method(&self, arg: <I as Foo<&isize>>::A);
+}
+
+trait YetAnotherTrait<I : for<'x> Foo<&'x isize>> {
+    fn some_method<'a>(&self, arg: <I as Foo<&'a isize>>::A);
+}
+
+trait Banana<'a> {
+    type Assoc: Default;
+}
+
+struct Peach<X>(std::marker::PhantomData<X>);
+
+impl<X: for<'a> Banana<'a>> Peach<X> {
+    fn mango(&self) -> <X as Banana<'_>>::Assoc {
+    //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
+        Default::default()
+    }
+}
+
+pub fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs
index cb52c2b4f15..a249f89685e 100644
--- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs
@@ -1,3 +1,5 @@
+#![allow(dead_code)]
+// run-rustfix
 // Check projection of an associated type out of a higher-ranked trait-bound
 // in the context of a method definition in a trait.
 
@@ -20,4 +22,17 @@ trait YetAnotherTrait<I : for<'x> Foo<&'x isize>> {
     fn some_method<'a>(&self, arg: <I as Foo<&'a isize>>::A);
 }
 
+trait Banana<'a> {
+    type Assoc: Default;
+}
+
+struct Peach<X>(std::marker::PhantomData<X>);
+
+impl<X: for<'a> Banana<'a>> Peach<X> {
+    fn mango(&self) -> X::Assoc {
+    //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
+        Default::default()
+    }
+}
+
 pub fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.stderr b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.stderr
index e1c169028c5..a37fec24493 100644
--- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.stderr
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.stderr
@@ -1,8 +1,14 @@
 error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context
-  --> $DIR/associated-types-project-from-hrtb-in-trait-method.rs:11:32
+  --> $DIR/associated-types-project-from-hrtb-in-trait-method.rs:13:32
    |
 LL |     fn some_method(&self, arg: I::A);
-   |                                ^^^^
+   |                                ^^^^ help: use a fully qualified path with inferred lifetimes: `<I as Foo<&isize>>::A`
 
-error: aborting due to previous error
+error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context
+  --> $DIR/associated-types-project-from-hrtb-in-trait-method.rs:32:24
+   |
+LL |     fn mango(&self) -> X::Assoc {
+   |                        ^^^^^^^^ help: use a fully qualified path with inferred lifetimes: `<X as Banana<'_>>::Assoc`
+
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.rs b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.rs
index 7fa059583f5..8397d204f35 100644
--- a/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.rs
+++ b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.rs
@@ -6,7 +6,6 @@ pub fn no_debug() {
 pub fn no_hash() {
     use std::collections::HashSet;
     let mut set = HashSet::new();
-    //~^ ERROR arrays only have std trait implementations for lengths 0..=32
     set.insert([0_usize; 33]);
     //~^ ERROR arrays only have std trait implementations for lengths 0..=32
 }
diff --git a/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr
index cba71db86a9..781a179624e 100644
--- a/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr
+++ b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr
@@ -9,24 +9,15 @@ LL |     println!("{:?}", [0_usize; 33]);
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: arrays only have std trait implementations for lengths 0..=32
-  --> $DIR/core-traits-no-impls-length-33.rs:10:16
+  --> $DIR/core-traits-no-impls-length-33.rs:9:16
    |
 LL |     set.insert([0_usize; 33]);
    |                ^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[usize; 33]`
    |
    = note: required because of the requirements on the impl of `std::cmp::Eq` for `[usize; 33]`
 
-error[E0277]: arrays only have std trait implementations for lengths 0..=32
-  --> $DIR/core-traits-no-impls-length-33.rs:8:19
-   |
-LL |     let mut set = HashSet::new();
-   |                   ^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[usize; 33]`
-   |
-   = note: required because of the requirements on the impl of `std::cmp::Eq` for `[usize; 33]`
-   = note: required by `std::collections::HashSet::<T>::new`
-
 error[E0369]: binary operation `==` cannot be applied to type `[usize; 33]`
-  --> $DIR/core-traits-no-impls-length-33.rs:15:19
+  --> $DIR/core-traits-no-impls-length-33.rs:14:19
    |
 LL |     [0_usize; 33] == [1_usize; 33]
    |     ------------- ^^ ------------- [usize; 33]
@@ -36,7 +27,7 @@ LL |     [0_usize; 33] == [1_usize; 33]
    = note: an implementation of `std::cmp::PartialEq` might be missing for `[usize; 33]`
 
 error[E0369]: binary operation `<` cannot be applied to type `[usize; 33]`
-  --> $DIR/core-traits-no-impls-length-33.rs:20:19
+  --> $DIR/core-traits-no-impls-length-33.rs:19:19
    |
 LL |     [0_usize; 33] < [1_usize; 33]
    |     ------------- ^ ------------- [usize; 33]
@@ -46,7 +37,7 @@ LL |     [0_usize; 33] < [1_usize; 33]
    = note: an implementation of `std::cmp::PartialOrd` might be missing for `[usize; 33]`
 
 error[E0277]: the trait bound `&[usize; 33]: std::iter::IntoIterator` is not satisfied
-  --> $DIR/core-traits-no-impls-length-33.rs:25:14
+  --> $DIR/core-traits-no-impls-length-33.rs:24:14
    |
 LL |     for _ in &[0_usize; 33] {
    |              ^^^^^^^^^^^^^^ the trait `std::iter::IntoIterator` is not implemented for `&[usize; 33]`
@@ -58,7 +49,7 @@ LL |     for _ in &[0_usize; 33] {
              <&'a mut [T] as std::iter::IntoIterator>
    = note: required by `std::iter::IntoIterator::into_iter`
 
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0277, E0369.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/generator/static-not-unpin.rs b/src/test/ui/generator/static-not-unpin.rs
index b271e982fb4..cfcb94737be 100644
--- a/src/test/ui/generator/static-not-unpin.rs
+++ b/src/test/ui/generator/static-not-unpin.rs
@@ -11,5 +11,5 @@ fn main() {
     let mut generator = static || {
         yield;
     };
-    assert_unpin(generator); //~ ERROR std::marker::Unpin` is not satisfied
+    assert_unpin(generator); //~ ERROR E0277
 }
diff --git a/src/test/ui/generator/static-not-unpin.stderr b/src/test/ui/generator/static-not-unpin.stderr
index f2b1078e2b5..6512d67319b 100644
--- a/src/test/ui/generator/static-not-unpin.stderr
+++ b/src/test/ui/generator/static-not-unpin.stderr
@@ -1,4 +1,4 @@
-error[E0277]: the trait bound `[static generator@$DIR/static-not-unpin.rs:11:25: 13:6 _]: std::marker::Unpin` is not satisfied
+error[E0277]: `[static generator@$DIR/static-not-unpin.rs:11:25: 13:6 _]` cannot be unpinned
   --> $DIR/static-not-unpin.rs:14:18
    |
 LL | fn assert_unpin<T: Unpin>(_: T) {
diff --git a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.rs b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.rs
new file mode 100644
index 00000000000..0a1686eac9d
--- /dev/null
+++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.rs
@@ -0,0 +1,29 @@
+// edition:2018
+#![allow(dead_code)]
+use std::future::Future;
+use std::pin::Pin;
+
+type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
+//   ^^^^^^^^^ This would come from the `futures` crate in real code.
+
+fn foo<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
+    // We could instead use an `async` block, but this way we have no std spans.
+    x //~ ERROR mismatched types
+}
+
+// FIXME: uncomment these once this commit is in Beta and we can rely on `rustc_on_unimplemented`
+//        having filtering for `Self` being a trait.
+//
+// fn bar<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
+//     Box::new(x)
+// }
+//
+// fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
+//     Pin::new(x)
+// }
+//
+// fn qux<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
+//     Pin::new(Box::new(x))
+// }
+
+fn main() {}
diff --git a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
new file mode 100644
index 00000000000..48d941283b6
--- /dev/null
+++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
@@ -0,0 +1,20 @@
+error[E0308]: mismatched types
+  --> $DIR/expected-boxed-future-isnt-pinned.rs:11:5
+   |
+LL | fn foo<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
+   |        - this type parameter                            ----------------------- expected `std::pin::Pin<std::boxed::Box<(dyn std::future::Future<Output = i32> + std::marker::Send + 'static)>>` because of return type
+LL |     // We could instead use an `async` block, but this way we have no std spans.
+LL |     x
+   |     ^
+   |     |
+   |     expected struct `std::pin::Pin`, found type parameter `F`
+   |     help: you need to pin and box this expression: `Box::pin(x)`
+   |
+   = note:      expected struct `std::pin::Pin<std::boxed::Box<(dyn std::future::Future<Output = i32> + std::marker::Send + 'static)>>`
+           found type parameter `F`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs b/src/test/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs
new file mode 100644
index 00000000000..2f844b4a05f
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs
@@ -0,0 +1,32 @@
+// check-pass
+// Regression test for issue #67844
+// Ensures that we properly handle nested TAIT occurences
+// with generic parameters
+
+#![feature(type_alias_impl_trait)]
+
+trait WithAssoc { type AssocType; }
+
+trait WithParam<A> {}
+
+type Return<A> = impl WithAssoc<AssocType = impl WithParam<A>>;
+
+struct MyParam;
+impl<A> WithParam<A> for MyParam {}
+
+struct MyStruct;
+
+impl WithAssoc for MyStruct {
+    type AssocType = MyParam;
+}
+
+
+fn my_fun<A>() -> Return<A> {
+    MyStruct
+}
+
+fn my_other_fn<A>() -> impl WithAssoc<AssocType = impl WithParam<A>> {
+    MyStruct
+}
+
+fn main() {}