about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-07-05 11:53:52 +0000
committerbors <bors@rust-lang.org>2019-07-05 11:53:52 +0000
commit853f30052d019a8ebe197a5adff3a29d6716a955 (patch)
treeedea92c0e1ce6501e5c23fd5d9c2874f15623d79
parentf119bf2761ab11ca577fac9881678c04d3e7fdb0 (diff)
parent18081890ea7c4f3cb38d51be5ddea4f51dc262c3 (diff)
Auto merge of #62407 - Centril:rollup-g0zmff7, r=Centril
Rollup of 10 pull requests

Successful merges:

 - #62123 ( Remove needless lifetimes (std))
 - #62150 (Implement mem::{zeroed,uninitialized} in terms of MaybeUninit.)
 - #62169 (Derive which queries to save using the proc macro)
 - #62238 (Fix code block information icon position)
 - #62292 (Move `async || ...` closures into `#![feature(async_closure)]`)
 - #62323 (Clarify unaligned fields in ptr::{read,write}_unaligned)
 - #62324 (Reduce reliance on `await!(...)` macro)
 - #62371 (Add tracking issue for Box::into_pin)
 - #62383 (Improve error span for async type inference error)
 - #62388 (Break out of the correct number of scopes in loops)

Failed merges:

r? @ghost
-rw-r--r--src/liballoc/boxed.rs2
-rw-r--r--src/liballoc/collections/btree/map.rs8
-rw-r--r--src/liballoc/collections/btree/node.rs2
-rw-r--r--src/liballoc/string.rs2
-rw-r--r--src/libcore/intrinsics.rs16
-rw-r--r--src/libcore/marker.rs2
-rw-r--r--src/libcore/mem/mod.rs6
-rw-r--r--src/libcore/ops/index.rs4
-rw-r--r--src/libcore/ptr/mod.rs88
-rw-r--r--src/librustc/query/mod.rs5
-rw-r--r--src/librustc/ty/query/on_disk_cache.rs32
-rw-r--r--src/librustc_codegen_llvm/intrinsic.rs2
-rw-r--r--src/librustc_macros/src/query.rs13
-rw-r--r--src/librustc_mir/build/matches/mod.rs12
-rw-r--r--src/librustc_mir/build/mod.rs21
-rw-r--r--src/librustc_mir/build/scope.rs16
-rw-r--r--src/librustc_typeck/check/generator_interior.rs2
-rw-r--r--src/librustc_typeck/check/intrinsic.rs1
-rw-r--r--src/librustdoc/clean/mod.rs10
-rw-r--r--src/librustdoc/html/render.rs2
-rw-r--r--src/librustdoc/html/static/rustdoc.css4
-rw-r--r--src/librustdoc/html/toc.rs2
-rw-r--r--src/librustdoc/markdown.rs2
-rw-r--r--src/libserialize/json.rs4
-rw-r--r--src/libstd/sync/mpsc/sync.rs2
-rw-r--r--src/libstd/sys/redox/ext/net.rs2
-rw-r--r--src/libstd/sys/unix/ext/net.rs4
-rw-r--r--src/libstd/sys/windows/mod.rs2
-rw-r--r--src/libstd/sys/windows/path.rs2
-rw-r--r--src/libstd/sys_common/io.rs2
-rw-r--r--src/libsyntax/feature_gate.rs52
-rw-r--r--src/libsyntax/parse/lexer/mod.rs1
-rw-r--r--src/libsyntax/parse/mod.rs3
-rw-r--r--src/libsyntax/parse/parser.rs36
-rw-r--r--src/libsyntax_pos/symbol.rs1
-rw-r--r--src/test/run-pass/async-await/async-fn-size.rs16
-rw-r--r--src/test/run-pass/async-await/issue-60709.rs4
-rw-r--r--src/test/run-pass/intrinsics/intrinsic-uninit.rs13
-rw-r--r--src/test/ui/async-await/async-await.rs8
-rw-r--r--src/test/ui/async-await/async-closure-matches-expr.rs12
-rw-r--r--src/test/ui/async-await/async-closure.rs81
-rw-r--r--src/test/ui/async-await/async-error-span.rs17
-rw-r--r--src/test/ui/async-await/async-error-span.stderr15
-rw-r--r--src/test/ui/async-await/async-fn-path-elision.rs2
-rw-r--r--src/test/ui/async-await/async-matches-expr.rs3
-rw-r--r--src/test/ui/async-await/async-with-closure.rs4
-rw-r--r--src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs2
-rw-r--r--src/test/ui/async-await/await-macro.rs2
-rw-r--r--src/test/ui/async-await/await-unsize.rs16
-rw-r--r--src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs2
-rw-r--r--src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs2
-rw-r--r--src/test/ui/async-await/feature-async-closure.rs8
-rw-r--r--src/test/ui/async-await/feature-async-closure.stderr12
-rw-r--r--src/test/ui/async-await/issues/issue-53249.rs6
-rw-r--r--src/test/ui/async-await/issues/issue-54974.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-55324.rs4
-rw-r--r--src/test/ui/async-await/issues/issue-58885.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-59001.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-59972.rs4
-rw-r--r--src/test/ui/async-await/issues/issue-62009-1.rs (renamed from src/test/ui/async-await/issues/issue-62009.rs)2
-rw-r--r--src/test/ui/async-await/issues/issue-62009-1.stderr (renamed from src/test/ui/async-await/issues/issue-62009.stderr)23
-rw-r--r--src/test/ui/async-await/issues/issue-62009-2.rs10
-rw-r--r--src/test/ui/async-await/issues/issue-62009-2.stderr10
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/hrtb.rs2
-rw-r--r--src/test/ui/async-await/no-args-non-move-async-closure.rs2
-rw-r--r--src/test/ui/async-await/recursive-async-impl-trait-type.rs4
-rw-r--r--src/test/ui/async-await/suggest-missing-await-closure.fixed23
-rw-r--r--src/test/ui/async-await/suggest-missing-await-closure.rs23
-rw-r--r--src/test/ui/async-await/suggest-missing-await-closure.stderr15
-rw-r--r--src/test/ui/async-await/suggest-missing-await.fixed11
-rw-r--r--src/test/ui/async-await/suggest-missing-await.rs11
-rw-r--r--src/test/ui/async-await/suggest-missing-await.stderr14
-rw-r--r--src/test/ui/feature-gates/feature-gate-async-await.rs1
-rw-r--r--src/test/ui/feature-gates/feature-gate-async-await.stderr11
-rw-r--r--src/test/ui/init-unsafe.rs1
-rw-r--r--src/test/ui/init-unsafe.stderr2
-rw-r--r--src/test/ui/loops/loop-break-unsize.rs8
77 files changed, 496 insertions, 281 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 41966360377..01dee0a3943 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -320,7 +320,7 @@ impl<T: ?Sized> Box<T> {
     /// This conversion does not allocate on the heap and happens in place.
     ///
     /// This is also available via [`From`].
-    #[unstable(feature = "box_into_pin", issue = "0")]
+    #[unstable(feature = "box_into_pin", issue = "62370")]
     pub fn into_pin(boxed: Box<T>) -> Pin<Box<T>> {
         // It's not possible to move or replace the insides of a `Pin<Box<T>>`
         // when `T: !Unpin`,  so it's safe to pin it directly without any
diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs
index ca35600e857..d466948a017 100644
--- a/src/liballoc/collections/btree/map.rs
+++ b/src/liballoc/collections/btree/map.rs
@@ -2032,7 +2032,7 @@ impl<K, V> BTreeMap<K, V> {
     /// assert_eq!(keys, [1, 2]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
+    pub fn keys(&self) -> Keys<'_, K, V> {
         Keys { inner: self.iter() }
     }
 
@@ -2053,7 +2053,7 @@ impl<K, V> BTreeMap<K, V> {
     /// assert_eq!(values, ["hello", "goodbye"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn values<'a>(&'a self) -> Values<'a, K, V> {
+    pub fn values(&self) -> Values<'_, K, V> {
         Values { inner: self.iter() }
     }
 
@@ -2557,8 +2557,8 @@ enum UnderflowResult<'a, K, V> {
     Stole(NodeRef<marker::Mut<'a>, K, V, marker::Internal>),
 }
 
-fn handle_underfull_node<'a, K, V>(node: NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>)
-                                   -> UnderflowResult<'a, K, V> {
+fn handle_underfull_node<K, V>(node: NodeRef<marker::Mut<'_>, K, V, marker::LeafOrInternal>)
+                               -> UnderflowResult<'_, K, V> {
     let parent = if let Ok(parent) = node.ascend() {
         parent
     } else {
diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs
index 581c66c7086..7cf077d61d6 100644
--- a/src/liballoc/collections/btree/node.rs
+++ b/src/liballoc/collections/btree/node.rs
@@ -394,7 +394,7 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
     }
 
     /// Temporarily takes out another, immutable reference to the same node.
-    fn reborrow<'a>(&'a self) -> NodeRef<marker::Immut<'a>, K, V, Type> {
+    fn reborrow(&self) -> NodeRef<marker::Immut<'_>, K, V, Type> {
         NodeRef {
             height: self.height,
             node: self.node,
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index 1b0d3c19692..366191e2c85 100644
--- a/src/liballoc/string.rs
+++ b/src/liballoc/string.rs
@@ -552,7 +552,7 @@ impl String {
     /// assert_eq!("Hello �World", output);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str> {
+    pub fn from_utf8_lossy(v: &[u8]) -> Cow<'_, str> {
         let mut iter = lossy::Utf8Lossy::from_bytes(v).chunks();
 
         let (first_valid, first_broken) = if let Some(chunk) = iter.next() {
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 8e53022c287..67430e5bbda 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -700,17 +700,15 @@ extern "rust-intrinsic" {
     /// which is unsafe unless `T` is `Copy`. Also, even if T is
     /// `Copy`, an all-zero value may not correspond to any legitimate
     /// state for the type in question.
+    #[unstable(feature = "core_intrinsics",
+               reason = "intrinsics are unlikely to ever be stabilized, instead \
+                         they should be used through stabilized interfaces \
+                         in the rest of the standard library",
+               issue = "0")]
+    #[rustc_deprecated(reason = "no longer used by rustc, will be removed - use MaybeUnint instead",
+                       since = "1.38.0")]
     pub fn init<T>() -> T;
 
-    /// Creates an uninitialized value.
-    ///
-    /// `uninit` is unsafe because there is no guarantee of what its
-    /// contents are. In particular its drop-flag may be set to any
-    /// state, which means it may claim either dropped or
-    /// undropped. In the general case one must use `ptr::write` to
-    /// initialize memory previous set to the result of `uninit`.
-    pub fn uninit<T>() -> T;
-
     /// Moves a value out of scope without running drop glue.
     pub fn forget<T: ?Sized>(_: T);
 
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index d9757d78dce..39c390b4df6 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -498,7 +498,7 @@ macro_rules! impls{
 /// #     end: *const T,
 /// #     phantom: PhantomData<&'a T>,
 /// # }
-/// fn borrow_vec<'a, T>(vec: &'a Vec<T>) -> Slice<'a, T> {
+/// fn borrow_vec<T>(vec: &Vec<T>) -> Slice<'_, T> {
 ///     let ptr = vec.as_ptr();
 ///     Slice {
 ///         start: ptr,
diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs
index b31522db474..b62d81affdd 100644
--- a/src/libcore/mem/mod.rs
+++ b/src/libcore/mem/mod.rs
@@ -450,8 +450,7 @@ pub const fn needs_drop<T>() -> bool {
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn zeroed<T>() -> T {
-    intrinsics::panic_if_uninhabited::<T>();
-    intrinsics::init()
+    MaybeUninit::zeroed().assume_init()
 }
 
 /// Bypasses Rust's normal memory-initialization checks by pretending to
@@ -476,8 +475,7 @@ pub unsafe fn zeroed<T>() -> T {
 #[rustc_deprecated(since = "1.38.0", reason = "use `mem::MaybeUninit` instead")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn uninitialized<T>() -> T {
-    intrinsics::panic_if_uninhabited::<T>();
-    intrinsics::uninit()
+    MaybeUninit::uninit().assume_init()
 }
 
 /// Swaps the values at two mutable locations, without deinitializing either one.
diff --git a/src/libcore/ops/index.rs b/src/libcore/ops/index.rs
index 3158f58e958..9cff474a760 100644
--- a/src/libcore/ops/index.rs
+++ b/src/libcore/ops/index.rs
@@ -105,7 +105,7 @@ pub trait Index<Idx: ?Sized> {
 /// impl Index<Side> for Balance {
 ///     type Output = Weight;
 ///
-///     fn index<'a>(&'a self, index: Side) -> &'a Self::Output {
+///     fn index(&self, index: Side) -> &Self::Output {
 ///         println!("Accessing {:?}-side of balance immutably", index);
 ///         match index {
 ///             Side::Left => &self.left,
@@ -115,7 +115,7 @@ pub trait Index<Idx: ?Sized> {
 /// }
 ///
 /// impl IndexMut<Side> for Balance {
-///     fn index_mut<'a>(&'a mut self, index: Side) -> &'a mut Self::Output {
+///     fn index_mut(&mut self, index: Side) -> &mut Self::Output {
 ///         println!("Accessing {:?}-side of balance mutably", index);
 ///         match index {
 ///             Side::Left => &mut self.left,
diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs
index da781d7e9fe..2a6c2b1331e 100644
--- a/src/libcore/ptr/mod.rs
+++ b/src/libcore/ptr/mod.rs
@@ -625,42 +625,50 @@ pub unsafe fn read<T>(src: *const T) -> T {
 /// [read-ownership]: ./fn.read.html#ownership-of-the-returned-value
 /// [valid]: ../ptr/index.html#safety
 ///
-/// # Examples
+/// ## On `packed` structs
 ///
-/// Access members of a packed struct by reference:
+/// It is currently impossible to create raw pointers to unaligned fields
+/// of a packed struct.
 ///
-/// ```
-/// use std::ptr;
+/// Attempting to create a raw pointer to an `unaligned` struct field with
+/// an expression such as `&packed.unaligned as *const FieldType` creates an
+/// intermediate unaligned reference before converting that to a raw pointer.
+/// That this reference is temporary and immediately cast is inconsequential
+/// as the compiler always expects references to be properly aligned.
+/// As a result, using `&packed.unaligned as *const FieldType` causes immediate
+/// *undefined behavior* in your program.
 ///
+/// An example of what not to do and how this relates to `read_unaligned` is:
+///
+/// ```no_run
 /// #[repr(packed, C)]
 /// struct Packed {
 ///     _padding: u8,
 ///     unaligned: u32,
 /// }
 ///
-/// let x = Packed {
+/// let packed = Packed {
 ///     _padding: 0x00,
 ///     unaligned: 0x01020304,
 /// };
 ///
 /// let v = unsafe {
-///     // Take the address of a 32-bit integer which is not aligned.
-///     // This must be done as a raw pointer; unaligned references are invalid.
-///     let unaligned = &x.unaligned as *const u32;
-///
-///     // Dereferencing normally will emit an aligned load instruction,
-///     // causing undefined behavior.
-///     // let v = *unaligned; // ERROR
+///     // Here we attempt to take the address of a 32-bit integer which is not aligned.
+///     let unaligned =
+///         // A temporary unaligned reference is created here which results in
+///         // undefined behavior regardless of whether the reference is used or not.
+///         &packed.unaligned
+///         // Casting to a raw pointer doesn't help; the mistake already happened.
+///         as *const u32;
 ///
-///     // Instead, use `read_unaligned` to read improperly aligned values.
-///     let v = ptr::read_unaligned(unaligned);
+///     let v = std::ptr::read_unaligned(unaligned);
 ///
 ///     v
 /// };
-///
-/// // Accessing unaligned values directly is safe.
-/// assert!(x.unaligned == v);
 /// ```
+///
+/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however.
+// FIXME: Update docs based on outcome of RFC #2582 and friends.
 #[inline]
 #[stable(feature = "ptr_unaligned", since = "1.17.0")]
 pub unsafe fn read_unaligned<T>(src: *const T) -> T {
@@ -789,38 +797,48 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
 ///
 /// [valid]: ../ptr/index.html#safety
 ///
-/// # Examples
+/// ## On `packed` structs
 ///
-/// Access fields in a packed struct:
+/// It is currently impossible to create raw pointers to unaligned fields
+/// of a packed struct.
 ///
-/// ```
-/// use std::{mem, ptr};
+/// Attempting to create a raw pointer to an `unaligned` struct field with
+/// an expression such as `&packed.unaligned as *const FieldType` creates an
+/// intermediate unaligned reference before converting that to a raw pointer.
+/// That this reference is temporary and immediately cast is inconsequential
+/// as the compiler always expects references to be properly aligned.
+/// As a result, using `&packed.unaligned as *const FieldType` causes immediate
+/// *undefined behavior* in your program.
 ///
+/// An example of what not to do and how this relates to `write_unaligned` is:
+///
+/// ```no_run
 /// #[repr(packed, C)]
-/// #[derive(Default)]
 /// struct Packed {
 ///     _padding: u8,
 ///     unaligned: u32,
 /// }
 ///
 /// let v = 0x01020304;
-/// let mut x: Packed = unsafe { mem::zeroed() };
-///
-/// unsafe {
-///     // Take a reference to a 32-bit integer which is not aligned.
-///     let unaligned = &mut x.unaligned as *mut u32;
+/// let mut packed: Packed = unsafe { std::mem::zeroed() };
 ///
-///     // Dereferencing normally will emit an aligned store instruction,
-///     // causing undefined behavior because the pointer is not aligned.
-///     // *unaligned = v; // ERROR
+/// let v = unsafe {
+///     // Here we attempt to take the address of a 32-bit integer which is not aligned.
+///     let unaligned =
+///         // A temporary unaligned reference is created here which results in
+///         // undefined behavior regardless of whether the reference is used or not.
+///         &mut packed.unaligned
+///         // Casting to a raw pointer doesn't help; the mistake already happened.
+///         as *mut u32;
 ///
-///     // Instead, use `write_unaligned` to write improperly aligned values.
-///     ptr::write_unaligned(unaligned, v);
-/// }
+///     std::ptr::write_unaligned(unaligned, v);
 ///
-/// // Accessing unaligned values directly is safe.
-/// assert!(x.unaligned == v);
+///     v
+/// };
 /// ```
+///
+/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however.
+// FIXME: Update docs based on outcome of RFC #2582 and friends.
 #[inline]
 #[stable(feature = "ptr_unaligned", since = "1.17.0")]
 pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index d2082ab87e7..442a90ab3f8 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -422,11 +422,6 @@ rustc_queries! {
                 "const-evaluating `{}`",
                 tcx.def_path_str(key.value.instance.def.def_id())
             }
-            cache_on_disk_if(_, opt_result) {
-                // Only store results without errors
-                // FIXME: We never store these
-                opt_result.map_or(true, |r| r.is_ok())
-            }
         }
 
         /// Results of evaluating const items or constants embedded in
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index 85153f99b19..56c9474170c 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -201,28 +201,22 @@ impl<'sess> OnDiskCache<'sess> {
             let mut query_result_index = EncodedQueryResultIndex::new();
 
             time(tcx.sess, "encode query results", || {
-                use crate::ty::query::queries::*;
                 let enc = &mut encoder;
                 let qri = &mut query_result_index;
 
-                encode_query_results::<type_of<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<generics_of<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<predicates_of<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<used_trait_imports<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<typeck_tables_of<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<codegen_fulfill_obligation<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<optimized_mir<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<unsafety_check_result<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<borrowck<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<mir_borrowck<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<mir_const_qualif<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<const_is_rvalue_promotable_to_static<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<symbol_name<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<check_match<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<codegen_fn_attrs<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<specialization_graph_of<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<const_eval<'_>, _>(tcx, enc, qri)?;
-                // FIXME: Include const_eval_raw?
+                macro_rules! encode_queries {
+                    ($($query:ident,)*) => {
+                        $(
+                            encode_query_results::<ty::query::queries::$query<'_>, _>(
+                                tcx,
+                                enc,
+                                qri
+                            )?;
+                        )*
+                    }
+                }
+
+                rustc_cached_queries!(encode_queries!);
 
                 Ok(())
             })?;
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index 7831c200114..69f8356f669 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -234,7 +234,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
                 return;
             }
             // Effectively no-ops
-            "uninit" | "forget" => {
+            "forget" => {
                 return;
             }
             "needs_drop" => {
diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs
index d47bd0580d6..a8df7e197a8 100644
--- a/src/librustc_macros/src/query.rs
+++ b/src/librustc_macros/src/query.rs
@@ -414,6 +414,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
     let mut dep_node_force_stream = quote! {};
     let mut try_load_from_on_disk_cache_stream = quote! {};
     let mut no_force_queries = Vec::new();
+    let mut cached_queries = quote! {};
 
     for group in groups.0 {
         let mut group_stream = quote! {};
@@ -427,6 +428,12 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
                 _ => quote! { #result_full },
             };
 
+            if modifiers.cache.is_some() {
+                cached_queries.extend(quote! {
+                    #name,
+                });
+            }
+
             if modifiers.cache.is_some() && !modifiers.no_force {
                 try_load_from_on_disk_cache_stream.extend(quote! {
                     DepKind::#name => {
@@ -549,6 +556,12 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
                 }
             }
         }
+        macro_rules! rustc_cached_queries {
+            ($($macro:tt)*) => {
+                $($macro)*(#cached_queries);
+            }
+        }
+
         #query_description_stream
 
         impl DepNode {
diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index f831f5105a4..75c64bb2644 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -228,10 +228,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         };
 
         // Step 5. Create everything else: the guards and the arms.
+        let match_scope = self.scopes.topmost();
+
         let arm_end_blocks: Vec<_> = arm_candidates.into_iter().map(|(arm, mut candidates)| {
             let arm_source_info = self.source_info(arm.span);
-            let region_scope = (arm.scope, arm_source_info);
-            self.in_scope(region_scope, arm.lint_level, |this| {
+            let arm_scope = (arm.scope, arm_source_info);
+            self.in_scope(arm_scope, arm.lint_level, |this| {
                 let body = this.hir.mirror(arm.body.clone());
                 let scope = this.declare_bindings(
                     None,
@@ -248,7 +250,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         arm.guard.clone(),
                         &fake_borrow_temps,
                         scrutinee_span,
-                        region_scope,
+                        match_scope,
                     );
                 } else {
                     arm_block = this.cfg.start_new_block();
@@ -259,7 +261,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                             arm.guard.clone(),
                             &fake_borrow_temps,
                             scrutinee_span,
-                            region_scope,
+                            match_scope,
                         );
                         this.cfg.terminate(
                             binding_end,
@@ -1339,7 +1341,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         guard: Option<Guard<'tcx>>,
         fake_borrows: &Vec<(&Place<'tcx>, Local)>,
         scrutinee_span: Span,
-        region_scope: (region::Scope, SourceInfo),
+        region_scope: region::Scope,
     ) -> BasicBlock {
         debug!("bind_and_guard_matched_candidate(candidate={:?})", candidate);
 
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 80a035d8287..bdcde5b33dc 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -604,9 +604,18 @@ where
         }
 
         let arg_scope_s = (arg_scope, source_info);
-        unpack!(block = builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
-            builder.args_and_body(block, &arguments, arg_scope, &body.value)
-        }));
+        // `return_block` is called when we evaluate a `return` expression, so
+        // we just use `START_BLOCK` here.
+        unpack!(block = builder.in_breakable_scope(
+            None,
+            START_BLOCK,
+            Place::RETURN_PLACE,
+            |builder| {
+                builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
+                    builder.args_and_body(block, &arguments, arg_scope, &body.value)
+                })
+            },
+        ));
         // Attribute epilogue to function's closing brace
         let fn_end = span.shrink_to_hi();
         let source_info = builder.source_info(fn_end);
@@ -860,11 +869,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
 
         let body = self.hir.mirror(ast_body);
-        // `return_block` is called when we evaluate a `return` expression, so
-        // we just use `START_BLOCK` here.
-        self.in_breakable_scope(None, START_BLOCK, Place::RETURN_PLACE, |this| {
-            this.into(&Place::RETURN_PLACE, block, body)
-        })
+        self.into(&Place::RETURN_PLACE, block, body)
     }
 
     fn get_unit_temp(&mut self) -> Place<'tcx> {
diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs
index 1b5fa1c9770..a74d5d7ab2d 100644
--- a/src/librustc_mir/build/scope.rs
+++ b/src/librustc_mir/build/scope.rs
@@ -332,9 +332,9 @@ impl<'tcx> Scopes<'tcx> {
         }
     }
 
-    fn num_scopes_to(&self, region_scope: (region::Scope, SourceInfo), span: Span) -> usize {
-        let scope_count = 1 + self.scopes.iter().rev()
-            .position(|scope| scope.region_scope == region_scope.0)
+    fn num_scopes_above(&self, region_scope: region::Scope, span: Span) -> usize {
+        let scope_count = self.scopes.iter().rev()
+            .position(|scope| scope.region_scope == region_scope)
             .unwrap_or_else(|| {
                 span_bug!(span, "region_scope {:?} does not enclose", region_scope)
             });
@@ -354,7 +354,7 @@ impl<'tcx> Scopes<'tcx> {
 
     /// Returns the topmost active scope, which is known to be alive until
     /// the next scope expression.
-    fn topmost(&self) -> region::Scope {
+    pub(super) fn topmost(&self) -> region::Scope {
         self.scopes.last().expect("topmost_scope: no scopes present").region_scope
     }
 
@@ -514,7 +514,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         } else {
             assert!(value.is_none(), "`return` and `break` should have a destination");
         }
-        self.exit_scope(source_info.span, (region_scope, source_info), block, target_block);
+        self.exit_scope(source_info.span, region_scope, block, target_block);
         self.cfg.start_new_block().unit()
     }
 
@@ -523,12 +523,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// needed. See module comment for details.
     pub fn exit_scope(&mut self,
                       span: Span,
-                      region_scope: (region::Scope, SourceInfo),
+                      region_scope: region::Scope,
                       mut block: BasicBlock,
                       target: BasicBlock) {
         debug!("exit_scope(region_scope={:?}, block={:?}, target={:?})",
                region_scope, block, target);
-        let scope_count = self.scopes.num_scopes_to(region_scope, span);
+        let scope_count = self.scopes.num_scopes_above(region_scope, span);
 
         // If we are emitting a `drop` statement, we need to have the cached
         // diverge cleanup pads ready in case that drop panics.
@@ -545,7 +545,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 continue;
             }
             let source_info = scope.source_info(span);
-            block = match scope.cached_exits.entry((target, region_scope.0)) {
+            block = match scope.cached_exits.entry((target, region_scope)) {
                 Entry::Occupied(e) => {
                     self.cfg.terminate(block, source_info,
                                     TerminatorKind::Goto { target: *e.get() });
diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs
index 0bd078dace4..7e4768d81b8 100644
--- a/src/librustc_typeck/check/generator_interior.rs
+++ b/src/librustc_typeck/check/generator_interior.rs
@@ -75,7 +75,7 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
                 // If unresolved type isn't a ty_var then unresolved_type_span is None
                 self.fcx.need_type_info_err_in_generator(
                     self.kind,
-                    unresolved_type_span.unwrap_or(yield_data.span),
+                    unresolved_type_span.unwrap_or(source_span),
                     unresolved_type,
                 )
                     .span_note(yield_data.span, &*note)
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index 9b1a8913822..82a736bf9c5 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -145,7 +145,6 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) {
             "rustc_peek" => (1, vec![param(0)], param(0)),
             "panic_if_uninhabited" => (1, Vec::new(), tcx.mk_unit()),
             "init" => (1, Vec::new(), param(0)),
-            "uninit" => (1, Vec::new(), param(0)),
             "forget" => (1, vec![param(0)], tcx.mk_unit()),
             "transmute" => (2, vec![ param(0) ], param(1)),
             "move_val_init" => {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 8ae96d86657..2fe40f4e10b 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -392,7 +392,7 @@ impl fmt::Debug for Item {
 impl Item {
     /// Finds the `doc` attribute as a NameValue and returns the corresponding
     /// value found.
-    pub fn doc_value<'a>(&'a self) -> Option<&'a str> {
+    pub fn doc_value(&self) -> Option<&str> {
         self.attrs.doc_value()
     }
     /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
@@ -699,11 +699,11 @@ impl<'a> Iterator for ListAttributesIter<'a> {
 
 pub trait AttributesExt {
     /// Finds an attribute as List and returns the list of attributes nested inside.
-    fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a>;
+    fn lists(&self, name: Symbol) -> ListAttributesIter<'_>;
 }
 
 impl AttributesExt for [ast::Attribute] {
-    fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a> {
+    fn lists(&self, name: Symbol) -> ListAttributesIter<'_> {
         ListAttributesIter {
             attrs: self.iter(),
             current_list: Vec::new().into_iter(),
@@ -952,7 +952,7 @@ impl Attributes {
 
     /// Finds the `doc` attribute as a NameValue and returns the corresponding
     /// value found.
-    pub fn doc_value<'a>(&'a self) -> Option<&'a str> {
+    pub fn doc_value(&self) -> Option<&str> {
         self.doc_strings.first().map(|s| s.as_str())
     }
 
@@ -1037,7 +1037,7 @@ impl Hash for Attributes {
 }
 
 impl AttributesExt for Attributes {
-    fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a> {
+    fn lists(&self, name: Symbol) -> ListAttributesIter<'_> {
         self.other_attrs.lists(name)
     }
 }
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 2d6503c9445..2d69c29dfae 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -2541,7 +2541,7 @@ fn full_path(cx: &Context, item: &clean::Item) -> String {
     s
 }
 
-fn shorter<'a>(s: Option<&'a str>) -> String {
+fn shorter(s: Option<&str>) -> String {
     match s {
         Some(s) => s.lines()
             .skip_while(|s| s.chars().all(|c| c.is_whitespace()))
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index 0493bf7c5c0..59704dace4d 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -146,6 +146,10 @@ img {
 	max-width: 100%;
 }
 
+li {
+	position: relative;
+}
+
 .source .content {
 	margin-top: 50px;
 	max-width: none;
diff --git a/src/librustdoc/html/toc.rs b/src/librustdoc/html/toc.rs
index 2564c611e54..2da7aceae8b 100644
--- a/src/librustdoc/html/toc.rs
+++ b/src/librustdoc/html/toc.rs
@@ -119,7 +119,7 @@ impl TocBuilder {
     /// Push a level `level` heading into the appropriate place in the
     /// hierarchy, returning a string containing the section number in
     /// `<num>.<num>.<num>` format.
-    pub fn push<'a>(&'a mut self, level: u32, name: String, id: String) -> &'a str {
+    pub fn push(&mut self, level: u32, name: String, id: String) -> &str {
         assert!(level >= 1);
 
         // collapse all previous sections into their parents until we
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index b0a37ea9c80..50a647f244d 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -17,7 +17,7 @@ use crate::html::markdown::{ErrorCodes, IdMap, Markdown, MarkdownWithToc, find_t
 use crate::test::{TestOptions, Collector};
 
 /// Separate any lines at the start of the file that begin with `# ` or `%`.
-fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) {
+fn extract_leading_metadata(s: &str) -> (Vec<&str>, &str) {
     let mut metadata = Vec::new();
     let mut count = 0;
 
diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index a7e7c09f9ae..726306d60ce 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -1031,7 +1031,7 @@ impl Json {
 
      /// If the Json value is an Object, returns the value associated with the provided key.
     /// Otherwise, returns None.
-    pub fn find<'a>(&'a self, key: &str) -> Option<&'a Json>{
+    pub fn find(&self, key: &str) -> Option<&Json> {
         match *self {
             Json::Object(ref map) => map.get(key),
             _ => None
@@ -1052,7 +1052,7 @@ impl Json {
     /// If the Json value is an Object, performs a depth-first search until
     /// a value associated with the provided key is found. If no value is found
     /// or the Json value is not an Object, returns `None`.
-    pub fn search<'a>(&'a self, key: &str) -> Option<&'a Json> {
+    pub fn search(&self, key: &str) -> Option<&Json> {
         match self {
             &Json::Object(ref map) => {
                 match map.get(key) {
diff --git a/src/libstd/sync/mpsc/sync.rs b/src/libstd/sync/mpsc/sync.rs
index f8fcd3ff5a5..fbe36d10517 100644
--- a/src/libstd/sync/mpsc/sync.rs
+++ b/src/libstd/sync/mpsc/sync.rs
@@ -140,7 +140,7 @@ fn wait_timeout_receiver<'a, 'b, T>(lock: &'a Mutex<State<T>>,
     new_guard
 }
 
-fn abort_selection<'a, T>(guard: &mut MutexGuard<'a , State<T>>) -> bool {
+fn abort_selection<T>(guard: &mut MutexGuard<'_, State<T>>) -> bool {
     match mem::replace(&mut guard.blocker, NoneBlocked) {
         NoneBlocked => true,
         BlockedSender(token) => {
diff --git a/src/libstd/sys/redox/ext/net.rs b/src/libstd/sys/redox/ext/net.rs
index b3ef5f3064c..1f5c785f419 100644
--- a/src/libstd/sys/redox/ext/net.rs
+++ b/src/libstd/sys/redox/ext/net.rs
@@ -673,7 +673,7 @@ impl UnixListener {
     /// }
     /// ```
     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn incoming<'a>(&'a self) -> Incoming<'a> {
+    pub fn incoming(&self) -> Incoming<'_> {
         Incoming { listener: self }
     }
 }
diff --git a/src/libstd/sys/unix/ext/net.rs b/src/libstd/sys/unix/ext/net.rs
index 41090caee84..42edd5dbbea 100644
--- a/src/libstd/sys/unix/ext/net.rs
+++ b/src/libstd/sys/unix/ext/net.rs
@@ -198,7 +198,7 @@ impl SocketAddr {
         }
     }
 
-    fn address<'a>(&'a self) -> AddressKind<'a> {
+    fn address(&self) -> AddressKind<'_> {
         let len = self.len as usize - sun_path_offset(&self.addr);
         let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
 
@@ -894,7 +894,7 @@ impl UnixListener {
     /// }
     /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
-    pub fn incoming<'a>(&'a self) -> Incoming<'a> {
+    pub fn incoming(&self) -> Incoming<'_> {
         Incoming { listener: self }
     }
 }
diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs
index 1cb55539129..36fb1fb5ff6 100644
--- a/src/libstd/sys/windows/mod.rs
+++ b/src/libstd/sys/windows/mod.rs
@@ -195,7 +195,7 @@ fn wide_char_to_multi_byte(code_page: u32,
     }
 }
 
-pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] {
+pub fn truncate_utf16_at_nul(v: &[u16]) -> &[u16] {
     match v.iter().position(|c| *c == 0) {
         // don't include the 0
         Some(i) => &v[..i],
diff --git a/src/libstd/sys/windows/path.rs b/src/libstd/sys/windows/path.rs
index f3178a5e9e6..7eae28cb14f 100644
--- a/src/libstd/sys/windows/path.rs
+++ b/src/libstd/sys/windows/path.rs
@@ -19,7 +19,7 @@ pub fn is_verbatim_sep(b: u8) -> bool {
     b == b'\\'
 }
 
-pub fn parse_prefix<'a>(path: &'a OsStr) -> Option<Prefix<'a>> {
+pub fn parse_prefix(path: &OsStr) -> Option<Prefix<'_>> {
     use crate::path::Prefix::*;
     unsafe {
         // The unsafety here stems from converting between &OsStr and &[u8]
diff --git a/src/libstd/sys_common/io.rs b/src/libstd/sys_common/io.rs
index 44b0963302d..8789abe55c3 100644
--- a/src/libstd/sys_common/io.rs
+++ b/src/libstd/sys_common/io.rs
@@ -16,7 +16,7 @@ pub mod test {
             p.join(path)
         }
 
-        pub fn path<'a>(&'a self) -> &'a Path {
+        pub fn path(&self) -> &Path {
             let TempDir(ref p) = *self;
             p
         }
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 4a0c957333b..ab61f77f5cb 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -31,6 +31,7 @@ use crate::tokenstream::TokenTree;
 
 use errors::{Applicability, DiagnosticBuilder, Handler};
 use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::sync::Lock;
 use rustc_target::spec::abi::Abi;
 use syntax_pos::{Span, DUMMY_SP, MultiSpan};
 use log::debug;
@@ -573,6 +574,9 @@ declare_features! (
     // Allows `impl Trait` with multiple unrelated lifetimes.
     (active, member_constraints, "1.37.0", Some(61977), None),
 
+    // Allows `async || body` closures.
+    (active, async_closure, "1.37.0", Some(62290), None),
+
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
     // -------------------------------------------------------------------------
@@ -2191,9 +2195,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                                     "labels on blocks are unstable");
                 }
             }
-            ast::ExprKind::Closure(_, ast::IsAsync::Async { .. }, ..) => {
-                gate_feature_post!(&self, async_await, e.span, "async closures are unstable");
-            }
             ast::ExprKind::Async(..) => {
                 gate_feature_post!(&self, async_await, e.span, "async blocks are unstable");
             }
@@ -2527,6 +2528,10 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
     features
 }
 
+fn for_each_in_lock<T>(vec: &Lock<Vec<T>>, f: impl Fn(&T)) {
+    vec.borrow().iter().for_each(f);
+}
+
 pub fn check_crate(krate: &ast::Crate,
                    sess: &ParseSess,
                    features: &Features,
@@ -2539,27 +2544,26 @@ pub fn check_crate(krate: &ast::Crate,
         plugin_attributes,
     };
 
-    sess
-        .param_attr_spans
-        .borrow()
-        .iter()
-        .for_each(|span| gate_feature!(
-            &ctx,
-            param_attrs,
-            *span,
-            "attributes on function parameters are unstable"
-        ));
-
-    sess
-        .let_chains_spans
-        .borrow()
-        .iter()
-        .for_each(|span| gate_feature!(
-            &ctx,
-            let_chains,
-            *span,
-            "`let` expressions in this position are experimental"
-        ));
+    for_each_in_lock(&sess.param_attr_spans, |span| gate_feature!(
+        &ctx,
+        param_attrs,
+        *span,
+        "attributes on function parameters are unstable"
+    ));
+
+    for_each_in_lock(&sess.let_chains_spans, |span| gate_feature!(
+        &ctx,
+        let_chains,
+        *span,
+        "`let` expressions in this position are experimental"
+    ));
+
+    for_each_in_lock(&sess.async_closure_spans, |span| gate_feature!(
+        &ctx,
+        async_closure,
+        *span,
+        "async closures are unstable"
+    ));
 
     let visitor = &mut PostExpansionVisitor {
         context: &ctx,
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index 49f714e4e46..3717bb435f6 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -1452,6 +1452,7 @@ mod tests {
             ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
             param_attr_spans: Lock::new(Vec::new()),
             let_chains_spans: Lock::new(Vec::new()),
+            async_closure_spans: Lock::new(Vec::new()),
         }
     }
 
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index e19eab371f4..4056905d5dd 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -57,6 +57,8 @@ pub struct ParseSess {
     pub param_attr_spans: Lock<Vec<Span>>,
     // Places where `let` exprs were used and should be feature gated according to `let_chains`.
     pub let_chains_spans: Lock<Vec<Span>>,
+    // Places where `async || ..` exprs were used and should be feature gated.
+    pub async_closure_spans: Lock<Vec<Span>>,
 }
 
 impl ParseSess {
@@ -84,6 +86,7 @@ impl ParseSess {
             ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
             param_attr_spans: Lock::new(Vec::new()),
             let_chains_spans: Lock::new(Vec::new()),
+            async_closure_spans: Lock::new(Vec::new()),
         }
     }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index cef14632e64..a95b6891fb9 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -3221,21 +3221,24 @@ impl<'a> Parser<'a> {
                              -> PResult<'a, P<Expr>>
     {
         let lo = self.token.span;
+
         let movability = if self.eat_keyword(kw::Static) {
             Movability::Static
         } else {
             Movability::Movable
         };
+
         let asyncness = if self.token.span.rust_2018() {
             self.parse_asyncness()
         } else {
             IsAsync::NotAsync
         };
-        let capture_clause = if self.eat_keyword(kw::Move) {
-            CaptureBy::Value
-        } else {
-            CaptureBy::Ref
-        };
+        if asyncness.is_async() {
+            // Feature gate `async ||` closures.
+            self.sess.async_closure_spans.borrow_mut().push(self.prev_span);
+        }
+
+        let capture_clause = self.parse_capture_clause();
         let decl = self.parse_fn_block_decl()?;
         let decl_hi = self.prev_span;
         let body = match decl.output {
@@ -3257,7 +3260,7 @@ impl<'a> Parser<'a> {
             attrs))
     }
 
-    // `else` token already eaten
+    /// `else` token already eaten
     fn parse_else_expr(&mut self) -> PResult<'a, P<Expr>> {
         if self.eat_keyword(kw::If) {
             return self.parse_if_expr(ThinVec::new());
@@ -3306,7 +3309,7 @@ impl<'a> Parser<'a> {
         Ok(self.mk_expr(span, ExprKind::While(cond, body, opt_label), attrs))
     }
 
-    // parse `loop {...}`, `loop` token already eaten
+    /// Parse `loop {...}`, `loop` token already eaten.
     fn parse_loop_expr(&mut self, opt_label: Option<Label>,
                            span_lo: Span,
                            mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
@@ -3316,17 +3319,20 @@ impl<'a> Parser<'a> {
         Ok(self.mk_expr(span, ExprKind::Loop(body, opt_label), attrs))
     }
 
-    /// Parses an `async move {...}` expression.
-    pub fn parse_async_block(&mut self, mut attrs: ThinVec<Attribute>)
-        -> PResult<'a, P<Expr>>
-    {
-        let span_lo = self.token.span;
-        self.expect_keyword(kw::Async)?;
-        let capture_clause = if self.eat_keyword(kw::Move) {
+    /// Parse an optional `move` prefix to a closure lke construct.
+    fn parse_capture_clause(&mut self) -> CaptureBy {
+        if self.eat_keyword(kw::Move) {
             CaptureBy::Value
         } else {
             CaptureBy::Ref
-        };
+        }
+    }
+
+    /// Parses an `async move? {...}` expression.
+    pub fn parse_async_block(&mut self, mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
+        let span_lo = self.token.span;
+        self.expect_keyword(kw::Async)?;
+        let capture_clause = self.parse_capture_clause();
         let (iattrs, body) = self.parse_inner_attrs_and_block()?;
         attrs.extend(iattrs);
         Ok(self.mk_expr(
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index aee988d5148..233574dda5d 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -146,6 +146,7 @@ symbols! {
         associated_type_defaults,
         associated_types,
         async_await,
+        async_closure,
         attr,
         attributes,
         attr_literals,
diff --git a/src/test/run-pass/async-await/async-fn-size.rs b/src/test/run-pass/async-await/async-fn-size.rs
index c4e328560dd..7396918196c 100644
--- a/src/test/run-pass/async-await/async-fn-size.rs
+++ b/src/test/run-pass/async-await/async-fn-size.rs
@@ -1,6 +1,6 @@
 // edition:2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 #[path = "../auxiliary/arc_wake.rs"]
 mod arc_wake;
@@ -58,31 +58,31 @@ fn wait(fut: impl Future<Output = u8>) -> u8 {
 fn base() -> WakeOnceThenComplete { WakeOnceThenComplete(false, 1) }
 
 async fn await1_level1() -> u8 {
-    await!(base())
+    base().await
 }
 
 async fn await2_level1() -> u8 {
-    await!(base()) + await!(base())
+    base().await + base().await
 }
 
 async fn await3_level1() -> u8 {
-    await!(base()) + await!(base()) + await!(base())
+    base().await + base().await + base().await
 }
 
 async fn await3_level2() -> u8 {
-    await!(await3_level1()) + await!(await3_level1()) + await!(await3_level1())
+    await3_level1().await + await3_level1().await + await3_level1().await
 }
 
 async fn await3_level3() -> u8 {
-    await!(await3_level2()) + await!(await3_level2()) + await!(await3_level2())
+    await3_level2().await + await3_level2().await + await3_level2().await
 }
 
 async fn await3_level4() -> u8 {
-    await!(await3_level3()) + await!(await3_level3()) + await!(await3_level3())
+    await3_level3().await + await3_level3().await + await3_level3().await
 }
 
 async fn await3_level5() -> u8 {
-    await!(await3_level4()) + await!(await3_level4()) + await!(await3_level4())
+    await3_level4().await + await3_level4().await + await3_level4().await
 }
 
 fn main() {
diff --git a/src/test/run-pass/async-await/issue-60709.rs b/src/test/run-pass/async-await/issue-60709.rs
index 778d3ee0c70..5ebb18b999a 100644
--- a/src/test/run-pass/async-await/issue-60709.rs
+++ b/src/test/run-pass/async-await/issue-60709.rs
@@ -2,7 +2,7 @@
 // handled incorrectly in generators.
 // compile-flags: -Copt-level=z -Cdebuginfo=2 --edition=2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 #![allow(unused)]
 
 use std::future::Future;
@@ -22,7 +22,7 @@ impl Future for Never {
 fn main() {
     let fut = async {
         let _rc = Rc::new(()); // Also crashes with Arc
-        await!(Never());
+        Never().await;
     };
     let _bla = fut; // Moving the future is required.
 }
diff --git a/src/test/run-pass/intrinsics/intrinsic-uninit.rs b/src/test/run-pass/intrinsics/intrinsic-uninit.rs
deleted file mode 100644
index 9555efb639b..00000000000
--- a/src/test/run-pass/intrinsics/intrinsic-uninit.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-// run-pass
-// pretty-expanded FIXME #23616
-
-#![feature(intrinsics)]
-
-mod rusti {
-    extern "rust-intrinsic" {
-        pub fn uninit<T>() -> T;
-    }
-}
-pub fn main() {
-    let _a : isize = unsafe {rusti::uninit()};
-}
diff --git a/src/test/ui/async-await/async-await.rs b/src/test/ui/async-await/async-await.rs
index 0eae1467fbf..29622c9d030 100644
--- a/src/test/ui/async-await/async-await.rs
+++ b/src/test/ui/async-await/async-await.rs
@@ -70,13 +70,6 @@ fn async_nonmove_block(x: u8) -> impl Future<Output = u8> {
     }
 }
 
-fn async_closure(x: u8) -> impl Future<Output = u8> {
-    (async move |x: u8| -> u8 {
-        wake_and_yield_once().await;
-        x
-    })(x)
-}
-
 async fn async_fn(x: u8) -> u8 {
     wake_and_yield_once().await;
     x
@@ -180,7 +173,6 @@ fn main() {
     test! {
         async_block,
         async_nonmove_block,
-        async_closure,
         async_fn,
         generic_async_fn,
         async_fn_with_internal_borrow,
diff --git a/src/test/ui/async-await/async-closure-matches-expr.rs b/src/test/ui/async-await/async-closure-matches-expr.rs
new file mode 100644
index 00000000000..90bd51ec5d0
--- /dev/null
+++ b/src/test/ui/async-await/async-closure-matches-expr.rs
@@ -0,0 +1,12 @@
+// compile-pass
+// edition:2018
+
+#![feature(async_await, async_closure)]
+
+macro_rules! match_expr {
+    ($x:expr) => {}
+}
+
+fn main() {
+    match_expr!(async || {});
+}
diff --git a/src/test/ui/async-await/async-closure.rs b/src/test/ui/async-await/async-closure.rs
new file mode 100644
index 00000000000..f5dc9e24d2d
--- /dev/null
+++ b/src/test/ui/async-await/async-closure.rs
@@ -0,0 +1,81 @@
+// run-pass
+
+// edition:2018
+// aux-build:arc_wake.rs
+
+#![feature(async_await, async_closure)]
+
+extern crate arc_wake;
+
+use std::pin::Pin;
+use std::future::Future;
+use std::sync::{
+    Arc,
+    atomic::{self, AtomicUsize},
+};
+use std::task::{Context, Poll};
+use arc_wake::ArcWake;
+
+struct Counter {
+    wakes: AtomicUsize,
+}
+
+impl ArcWake for Counter {
+    fn wake(self: Arc<Self>) {
+        Self::wake_by_ref(&self)
+    }
+    fn wake_by_ref(arc_self: &Arc<Self>) {
+        arc_self.wakes.fetch_add(1, atomic::Ordering::SeqCst);
+    }
+}
+
+struct WakeOnceThenComplete(bool);
+
+fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) }
+
+impl Future for WakeOnceThenComplete {
+    type Output = ();
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
+        if self.0 {
+            Poll::Ready(())
+        } else {
+            cx.waker().wake_by_ref();
+            self.0 = true;
+            Poll::Pending
+        }
+    }
+}
+
+fn async_closure(x: u8) -> impl Future<Output = u8> {
+    (async move |x: u8| -> u8 {
+        wake_and_yield_once().await;
+        x
+    })(x)
+}
+
+fn test_future_yields_once_then_returns<F, Fut>(f: F)
+where
+    F: FnOnce(u8) -> Fut,
+    Fut: Future<Output = u8>,
+{
+    let mut fut = Box::pin(f(9));
+    let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) });
+    let waker = ArcWake::into_waker(counter.clone());
+    let mut cx = Context::from_waker(&waker);
+    assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst));
+    assert_eq!(Poll::Pending, fut.as_mut().poll(&mut cx));
+    assert_eq!(1, counter.wakes.load(atomic::Ordering::SeqCst));
+    assert_eq!(Poll::Ready(9), fut.as_mut().poll(&mut cx));
+}
+
+fn main() {
+    macro_rules! test {
+        ($($fn_name:expr,)*) => { $(
+            test_future_yields_once_then_returns($fn_name);
+        )* }
+    }
+
+    test! {
+        async_closure,
+    }
+}
diff --git a/src/test/ui/async-await/async-error-span.rs b/src/test/ui/async-await/async-error-span.rs
new file mode 100644
index 00000000000..d362348a3fd
--- /dev/null
+++ b/src/test/ui/async-await/async-error-span.rs
@@ -0,0 +1,17 @@
+// edition:2018
+#![feature(async_await)]
+
+// Regression test for issue #62382
+
+use std::future::Future;
+
+fn get_future() -> impl Future<Output = ()> {
+    panic!()
+}
+
+async fn foo() {
+    let a; //~ ERROR type inside `async` object must be known in this context
+    get_future().await;
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/async-error-span.stderr b/src/test/ui/async-await/async-error-span.stderr
new file mode 100644
index 00000000000..bd8966b9c7d
--- /dev/null
+++ b/src/test/ui/async-await/async-error-span.stderr
@@ -0,0 +1,15 @@
+error[E0698]: type inside `async` object must be known in this context
+  --> $DIR/async-error-span.rs:13:9
+   |
+LL |     let a;
+   |         ^ cannot infer type
+   |
+note: the type is part of the `async` object because of this `await`
+  --> $DIR/async-error-span.rs:14:5
+   |
+LL |     get_future().await;
+   |     ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0698`.
diff --git a/src/test/ui/async-await/async-fn-path-elision.rs b/src/test/ui/async-await/async-fn-path-elision.rs
index 8db7631ef41..447e40dddd9 100644
--- a/src/test/ui/async-await/async-fn-path-elision.rs
+++ b/src/test/ui/async-await/async-fn-path-elision.rs
@@ -1,6 +1,6 @@
 // edition:2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 #![allow(dead_code)]
 
 struct HasLifetime<'a>(&'a bool);
diff --git a/src/test/ui/async-await/async-matches-expr.rs b/src/test/ui/async-await/async-matches-expr.rs
index e41a568ad29..a6f0211e41f 100644
--- a/src/test/ui/async-await/async-matches-expr.rs
+++ b/src/test/ui/async-await/async-matches-expr.rs
@@ -1,7 +1,7 @@
 // build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 macro_rules! match_expr {
     ($x:expr) => {}
@@ -9,5 +9,4 @@ macro_rules! match_expr {
 
 fn main() {
     match_expr!(async {});
-    match_expr!(async || {});
 }
diff --git a/src/test/ui/async-await/async-with-closure.rs b/src/test/ui/async-await/async-with-closure.rs
index 2b69c9b701a..f7dc874affd 100644
--- a/src/test/ui/async-await/async-with-closure.rs
+++ b/src/test/ui/async-await/async-with-closure.rs
@@ -1,7 +1,7 @@
 // build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 trait MyClosure {
     type Args;
@@ -20,7 +20,7 @@ async fn get_future<C: ?Sized + MyClosure>(_stream: MyStream<C>) {}
 
 async fn f() {
     let messages: MyStream<dyn FnMut()> = unimplemented!();
-    await!(get_future(messages));
+    get_future(messages).await;
 }
 
 fn main() {}
diff --git a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs
index f59f1160e70..92f3210ac89 100644
--- a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs
+++ b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs
@@ -1,7 +1,7 @@
 // edition:2018
 
 #![allow(non_camel_case_types)]
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 mod outer_mod {
     pub mod await { //~ ERROR expected identifier, found reserved keyword `await`
diff --git a/src/test/ui/async-await/await-macro.rs b/src/test/ui/async-await/await-macro.rs
index 7d8b7a257da..c37835d73e9 100644
--- a/src/test/ui/async-await/await-macro.rs
+++ b/src/test/ui/async-await/await-macro.rs
@@ -3,7 +3,7 @@
 // edition:2018
 // aux-build:arc_wake.rs
 
-#![feature(async_await, await_macro)]
+#![feature(async_await, async_closure, await_macro)]
 
 extern crate arc_wake;
 
diff --git a/src/test/ui/async-await/await-unsize.rs b/src/test/ui/async-await/await-unsize.rs
new file mode 100644
index 00000000000..d5e21257f4f
--- /dev/null
+++ b/src/test/ui/async-await/await-unsize.rs
@@ -0,0 +1,16 @@
+// Regression test for #62312
+
+// check-pass
+// edition:2018
+
+#![feature(async_await)]
+
+async fn make_boxed_object() -> Box<dyn Send> {
+    Box::new(()) as _
+}
+
+async fn await_object() {
+    let _ = make_boxed_object().await;
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs b/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs
index c2b59eecb99..dfd8b2e361e 100644
--- a/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs
+++ b/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs
@@ -3,7 +3,7 @@
 // run-pass
 
 #![allow(unused_variables)]
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 // Test that the drop order for parameters in a fn and async fn matches up. Also test that
 // parameters (used or unused) are not dropped until the async fn completes execution.
diff --git a/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs b/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs
index 708c5704984..2a74485afb4 100644
--- a/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs
+++ b/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs
@@ -3,7 +3,7 @@
 // run-pass
 
 #![allow(unused_variables)]
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 // Test that the drop order for parameters in a fn and async fn matches up. Also test that
 // parameters (used or unused) are not dropped until the async fn completes execution.
diff --git a/src/test/ui/async-await/feature-async-closure.rs b/src/test/ui/async-await/feature-async-closure.rs
new file mode 100644
index 00000000000..d07116b13a2
--- /dev/null
+++ b/src/test/ui/async-await/feature-async-closure.rs
@@ -0,0 +1,8 @@
+// edition:2018
+// gate-test-async_closure
+
+fn f() {
+    let _ = async || {}; //~ ERROR async closures are unstable
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/feature-async-closure.stderr b/src/test/ui/async-await/feature-async-closure.stderr
new file mode 100644
index 00000000000..61909f8659e
--- /dev/null
+++ b/src/test/ui/async-await/feature-async-closure.stderr
@@ -0,0 +1,12 @@
+error[E0658]: async closures are unstable
+  --> $DIR/feature-async-closure.rs:5:13
+   |
+LL |     let _ = async || {};
+   |             ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/62290
+   = help: add #![feature(async_closure)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/async-await/issues/issue-53249.rs b/src/test/ui/async-await/issues/issue-53249.rs
index c493878e4c2..c57dc6b0ef6 100644
--- a/src/test/ui/async-await/issues/issue-53249.rs
+++ b/src/test/ui/async-await/issues/issue-53249.rs
@@ -1,7 +1,7 @@
 // build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(arbitrary_self_types, async_await, await_macro)]
+#![feature(arbitrary_self_types, async_await)]
 
 use std::task::{self, Poll};
 use std::future::Future;
@@ -37,11 +37,11 @@ impl<R, F> Future for Lazy<F>
 async fn __receive<WantFn, Fut>(want: WantFn) -> ()
     where Fut: Future<Output = ()>, WantFn: Fn(&Box<dyn Send + 'static>) -> Fut,
 {
-    await!(lazy(|_| ()));
+    lazy(|_| ()).await;
 }
 
 pub fn basic_spawn_receive() {
-    async { await!(__receive(|_| async { () })) };
+    async { __receive(|_| async { () }).await };
 }
 
 fn main() {}
diff --git a/src/test/ui/async-await/issues/issue-54974.rs b/src/test/ui/async-await/issues/issue-54974.rs
index 0cfe859b13b..040989b33fc 100644
--- a/src/test/ui/async-await/issues/issue-54974.rs
+++ b/src/test/ui/async-await/issues/issue-54974.rs
@@ -1,7 +1,7 @@
 // build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 use std::sync::Arc;
 
diff --git a/src/test/ui/async-await/issues/issue-55324.rs b/src/test/ui/async-await/issues/issue-55324.rs
index deaba6904f4..4f383a51a88 100644
--- a/src/test/ui/async-await/issues/issue-55324.rs
+++ b/src/test/ui/async-await/issues/issue-55324.rs
@@ -1,13 +1,13 @@
 // build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 use std::future::Future;
 
 #[allow(unused)]
 async fn foo<F: Future<Output = i32>>(x: &i32, future: F) -> i32 {
-    let y = await!(future);
+    let y = future.await;
     *x + y
 }
 
diff --git a/src/test/ui/async-await/issues/issue-58885.rs b/src/test/ui/async-await/issues/issue-58885.rs
index 5868e022861..47744aeea60 100644
--- a/src/test/ui/async-await/issues/issue-58885.rs
+++ b/src/test/ui/async-await/issues/issue-58885.rs
@@ -1,7 +1,7 @@
 // build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 struct Xyz {
     a: u64,
diff --git a/src/test/ui/async-await/issues/issue-59001.rs b/src/test/ui/async-await/issues/issue-59001.rs
index ffa70d3b43c..9334ddb0af5 100644
--- a/src/test/ui/async-await/issues/issue-59001.rs
+++ b/src/test/ui/async-await/issues/issue-59001.rs
@@ -1,7 +1,7 @@
 // build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 use std::future::Future;
 
diff --git a/src/test/ui/async-await/issues/issue-59972.rs b/src/test/ui/async-await/issues/issue-59972.rs
index 31e7a65dc98..1b843720102 100644
--- a/src/test/ui/async-await/issues/issue-59972.rs
+++ b/src/test/ui/async-await/issues/issue-59972.rs
@@ -2,7 +2,7 @@
 
 // compile-flags: --edition=2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 pub enum Uninhabited { }
 
@@ -15,7 +15,7 @@ async fn noop() { }
 #[allow(unused)]
 async fn contains_never() {
     let error = uninhabited_async();
-    await!(noop());
+    noop().await;
     let error2 = error;
 }
 
diff --git a/src/test/ui/async-await/issues/issue-62009.rs b/src/test/ui/async-await/issues/issue-62009-1.rs
index e2d58cac24d..ac6605bceff 100644
--- a/src/test/ui/async-await/issues/issue-62009.rs
+++ b/src/test/ui/async-await/issues/issue-62009-1.rs
@@ -11,8 +11,6 @@ fn main() {
     //~^ ERROR `await` is only allowed inside `async` functions and blocks
         let task1 = print_dur().await;
     }.await;
-    (async || 2333)().await;
-    //~^ ERROR `await` is only allowed inside `async` functions and blocks
     (|_| 2333).await;
     //~^ ERROR `await` is only allowed inside `async` functions and blocks
     //~^^ ERROR
diff --git a/src/test/ui/async-await/issues/issue-62009.stderr b/src/test/ui/async-await/issues/issue-62009-1.stderr
index 53d1f34fe4f..2bbb6d079ea 100644
--- a/src/test/ui/async-await/issues/issue-62009.stderr
+++ b/src/test/ui/async-await/issues/issue-62009-1.stderr
@@ -1,5 +1,5 @@
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009.rs:8:5
+  --> $DIR/issue-62009-1.rs:8:5
    |
 LL | fn main() {
    |    ---- this is not `async`
@@ -7,7 +7,7 @@ LL |     async { let (); }.await;
    |     ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009.rs:10:5
+  --> $DIR/issue-62009-1.rs:10:5
    |
 LL |   fn main() {
    |      ---- this is not `async`
@@ -19,16 +19,7 @@ LL | |     }.await;
    | |___________^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009.rs:14:5
-   |
-LL | fn main() {
-   |    ---- this is not `async`
-...
-LL |     (async || 2333)().await;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
-
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009.rs:16:5
+  --> $DIR/issue-62009-1.rs:14:5
    |
 LL | fn main() {
    |    ---- this is not `async`
@@ -36,14 +27,14 @@ LL | fn main() {
 LL |     (|_| 2333).await;
    |     ^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
-error[E0277]: the trait bound `[closure@$DIR/issue-62009.rs:16:5: 16:15]: std::future::Future` is not satisfied
-  --> $DIR/issue-62009.rs:16:5
+error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:14:5: 14:15]: std::future::Future` is not satisfied
+  --> $DIR/issue-62009-1.rs:14:5
    |
 LL |     (|_| 2333).await;
-   |     ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009.rs:16:5: 16:15]`
+   |     ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:14:5: 14:15]`
    |
    = note: required by `std::future::poll_with_tls_context`
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/issues/issue-62009-2.rs b/src/test/ui/async-await/issues/issue-62009-2.rs
new file mode 100644
index 00000000000..52b62eaa9e0
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-62009-2.rs
@@ -0,0 +1,10 @@
+// edition:2018
+
+#![feature(async_await, async_closure)]
+
+async fn print_dur() {}
+
+fn main() {
+    (async || 2333)().await;
+    //~^ ERROR `await` is only allowed inside `async` functions and blocks
+}
diff --git a/src/test/ui/async-await/issues/issue-62009-2.stderr b/src/test/ui/async-await/issues/issue-62009-2.stderr
new file mode 100644
index 00000000000..79b6803263e
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-62009-2.stderr
@@ -0,0 +1,10 @@
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/issue-62009-2.rs:8:5
+   |
+LL | fn main() {
+   |    ---- this is not `async`
+LL |     (async || 2333)().await;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/async-await/multiple-lifetimes/hrtb.rs b/src/test/ui/async-await/multiple-lifetimes/hrtb.rs
index 620b0080966..589e260d084 100644
--- a/src/test/ui/async-await/multiple-lifetimes/hrtb.rs
+++ b/src/test/ui/async-await/multiple-lifetimes/hrtb.rs
@@ -3,7 +3,7 @@
 
 // Test that we can use async fns with multiple arbitrary lifetimes.
 
-#![feature(arbitrary_self_types, async_await, await_macro)]
+#![feature(async_await)]
 #![allow(dead_code)]
 
 use std::ops::Add;
diff --git a/src/test/ui/async-await/no-args-non-move-async-closure.rs b/src/test/ui/async-await/no-args-non-move-async-closure.rs
index 345f19b0623..62d4b3fb6f2 100644
--- a/src/test/ui/async-await/no-args-non-move-async-closure.rs
+++ b/src/test/ui/async-await/no-args-non-move-async-closure.rs
@@ -1,6 +1,6 @@
 // edition:2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await, async_closure)]
 
 fn main() {
     let _ = async |x: u8| {};
diff --git a/src/test/ui/async-await/recursive-async-impl-trait-type.rs b/src/test/ui/async-await/recursive-async-impl-trait-type.rs
index a4e08011934..54f3339870b 100644
--- a/src/test/ui/async-await/recursive-async-impl-trait-type.rs
+++ b/src/test/ui/async-await/recursive-async-impl-trait-type.rs
@@ -2,10 +2,10 @@
 // Test that impl trait does not allow creating recursive types that are
 // otherwise forbidden when using `async` and `await`.
 
-#![feature(await_macro, async_await, generators)]
+#![feature(async_await)]
 
 async fn recursive_async_function() -> () { //~ ERROR
-    await!(recursive_async_function());
+    recursive_async_function().await;
 }
 
 fn main() {}
diff --git a/src/test/ui/async-await/suggest-missing-await-closure.fixed b/src/test/ui/async-await/suggest-missing-await-closure.fixed
new file mode 100644
index 00000000000..60c9a8581ac
--- /dev/null
+++ b/src/test/ui/async-await/suggest-missing-await-closure.fixed
@@ -0,0 +1,23 @@
+// edition:2018
+// run-rustfix
+
+#![feature(async_await, async_closure)]
+
+fn take_u32(_x: u32) {}
+
+async fn make_u32() -> u32 {
+    22
+}
+
+#[allow(unused)]
+async fn suggest_await_in_async_closure() {
+    async || {
+        let x = make_u32();
+        take_u32(x.await)
+        //~^ ERROR mismatched types [E0308]
+        //~| HELP consider using `.await` here
+        //~| SUGGESTION x.await
+    };
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/suggest-missing-await-closure.rs b/src/test/ui/async-await/suggest-missing-await-closure.rs
new file mode 100644
index 00000000000..cb992a27bc1
--- /dev/null
+++ b/src/test/ui/async-await/suggest-missing-await-closure.rs
@@ -0,0 +1,23 @@
+// edition:2018
+// run-rustfix
+
+#![feature(async_await, async_closure)]
+
+fn take_u32(_x: u32) {}
+
+async fn make_u32() -> u32 {
+    22
+}
+
+#[allow(unused)]
+async fn suggest_await_in_async_closure() {
+    async || {
+        let x = make_u32();
+        take_u32(x)
+        //~^ ERROR mismatched types [E0308]
+        //~| HELP consider using `.await` here
+        //~| SUGGESTION x.await
+    };
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/suggest-missing-await-closure.stderr b/src/test/ui/async-await/suggest-missing-await-closure.stderr
new file mode 100644
index 00000000000..487ca6c0fc5
--- /dev/null
+++ b/src/test/ui/async-await/suggest-missing-await-closure.stderr
@@ -0,0 +1,15 @@
+error[E0308]: mismatched types
+  --> $DIR/suggest-missing-await-closure.rs:16:18
+   |
+LL |         take_u32(x)
+   |                  ^
+   |                  |
+   |                  expected u32, found opaque type
+   |                  help: consider using `.await` here: `x.await`
+   |
+   = note: expected type `u32`
+              found type `impl std::future::Future`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/async-await/suggest-missing-await.fixed b/src/test/ui/async-await/suggest-missing-await.fixed
index 282be368c69..aa032682be8 100644
--- a/src/test/ui/async-await/suggest-missing-await.fixed
+++ b/src/test/ui/async-await/suggest-missing-await.fixed
@@ -18,15 +18,4 @@ async fn suggest_await_in_async_fn() {
     //~| SUGGESTION x.await
 }
 
-#[allow(unused)]
-async fn suggest_await_in_async_closure() {
-    async || {
-        let x = make_u32();
-        take_u32(x.await)
-        //~^ ERROR mismatched types [E0308]
-        //~| HELP consider using `.await` here
-        //~| SUGGESTION x.await
-    };
-}
-
 fn main() {}
diff --git a/src/test/ui/async-await/suggest-missing-await.rs b/src/test/ui/async-await/suggest-missing-await.rs
index 36103f050c1..2ca814fbb22 100644
--- a/src/test/ui/async-await/suggest-missing-await.rs
+++ b/src/test/ui/async-await/suggest-missing-await.rs
@@ -18,15 +18,4 @@ async fn suggest_await_in_async_fn() {
     //~| SUGGESTION x.await
 }
 
-#[allow(unused)]
-async fn suggest_await_in_async_closure() {
-    async || {
-        let x = make_u32();
-        take_u32(x)
-        //~^ ERROR mismatched types [E0308]
-        //~| HELP consider using `.await` here
-        //~| SUGGESTION x.await
-    };
-}
-
 fn main() {}
diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr
index 59c20dcfbc9..9bae7150276 100644
--- a/src/test/ui/async-await/suggest-missing-await.stderr
+++ b/src/test/ui/async-await/suggest-missing-await.stderr
@@ -10,18 +10,6 @@ LL |     take_u32(x)
    = note: expected type `u32`
               found type `impl std::future::Future`
 
-error[E0308]: mismatched types
-  --> $DIR/suggest-missing-await.rs:25:18
-   |
-LL |         take_u32(x)
-   |                  ^
-   |                  |
-   |                  expected u32, found opaque type
-   |                  help: consider using `.await` here: `x.await`
-   |
-   = note: expected type `u32`
-              found type `impl std::future::Future`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/feature-gates/feature-gate-async-await.rs b/src/test/ui/feature-gates/feature-gate-async-await.rs
index 9cfefef4129..78391c0e104 100644
--- a/src/test/ui/feature-gates/feature-gate-async-await.rs
+++ b/src/test/ui/feature-gates/feature-gate-async-await.rs
@@ -15,5 +15,4 @@ async fn foo() {} //~ ERROR async fn is unstable
 
 fn main() {
     let _ = async {}; //~ ERROR async blocks are unstable
-    let _ = async || {}; //~ ERROR async closures are unstable
 }
diff --git a/src/test/ui/feature-gates/feature-gate-async-await.stderr b/src/test/ui/feature-gates/feature-gate-async-await.stderr
index 43e41b45458..1ea4da8da0c 100644
--- a/src/test/ui/feature-gates/feature-gate-async-await.stderr
+++ b/src/test/ui/feature-gates/feature-gate-async-await.stderr
@@ -40,15 +40,6 @@ LL |     let _ = async {};
    = note: for more information, see https://github.com/rust-lang/rust/issues/50547
    = help: add #![feature(async_await)] to the crate attributes to enable
 
-error[E0658]: async closures are unstable
-  --> $DIR/feature-gate-async-await.rs:18:13
-   |
-LL |     let _ = async || {};
-   |             ^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/50547
-   = help: add #![feature(async_await)] to the crate attributes to enable
-
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/init-unsafe.rs b/src/test/ui/init-unsafe.rs
index 92b21c4efa3..3d65cfc2340 100644
--- a/src/test/ui/init-unsafe.rs
+++ b/src/test/ui/init-unsafe.rs
@@ -1,3 +1,4 @@
+#![allow(deprecated)]
 #![feature(core_intrinsics)]
 
 use std::intrinsics::{init};
diff --git a/src/test/ui/init-unsafe.stderr b/src/test/ui/init-unsafe.stderr
index 857142dff64..e1126316af3 100644
--- a/src/test/ui/init-unsafe.stderr
+++ b/src/test/ui/init-unsafe.stderr
@@ -1,5 +1,5 @@
 error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
-  --> $DIR/init-unsafe.rs:7:17
+  --> $DIR/init-unsafe.rs:8:17
    |
 LL |     let stuff = init::<isize>();
    |                 ^^^^^^^^^^^^^^^ call to unsafe function
diff --git a/src/test/ui/loops/loop-break-unsize.rs b/src/test/ui/loops/loop-break-unsize.rs
new file mode 100644
index 00000000000..974c63cea85
--- /dev/null
+++ b/src/test/ui/loops/loop-break-unsize.rs
@@ -0,0 +1,8 @@
+// Regression test for #62312
+// check-pass
+
+fn main() {
+    let _ = loop {
+        break Box::new(()) as Box<dyn Send>;
+    };
+}