about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock83
-rw-r--r--compiler/rustc_ast/src/ast.rs10
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs3
-rw-r--r--compiler/rustc_ast/src/visit.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs77
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs7
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/assert/context.rs2
-rw-r--r--compiler/rustc_lint/src/early.rs3
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs2
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs4
-rw-r--r--library/core/src/num/mod.rs2
-rw-r--r--src/librustdoc/clean/mod.rs88
-rw-r--r--src/librustdoc/clean/types.rs61
-rw-r--r--src/librustdoc/doctest.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_async_block.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils.rs2
-rw-r--r--src/tools/compiletest/src/common.rs2
-rw-r--r--src/tools/compiletest/src/main.rs15
-rw-r--r--src/tools/rustfmt/src/expr.rs2
-rw-r--r--tests/rustdoc-ui/issue-109282-import-inline-merge.rs14
-rw-r--r--tests/ui/simple_global_asm.rs1
23 files changed, 235 insertions, 156 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 449f0c73588..b07a7a8e5cb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -149,9 +149,9 @@ dependencies = [
 
 [[package]]
 name = "askama_derive"
-version = "0.12.0"
+version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e80b5ad1afe82872b7aa3e9de9b206ecb85584aa324f0f60fa4c903ce935936b"
+checksum = "c22fbe0413545c098358e56966ff22cdd039e10215ae213cfbd65032b119fc94"
 dependencies = [
  "basic-toml",
  "mime",
@@ -160,7 +160,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "serde",
- "syn",
+ "syn 2.0.8",
 ]
 
 [[package]]
@@ -590,7 +590,7 @@ checksum = "d552b2fa341f5fc35c6b917b1d289d3c3a34d0b74e579390ea6192d6152a8cdb"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
  "synstructure",
 ]
 
@@ -702,7 +702,7 @@ dependencies = [
  "proc-macro-error",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
 ]
 
 [[package]]
@@ -715,7 +715,7 @@ dependencies = [
  "proc-macro-error",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
 ]
 
 [[package]]
@@ -757,7 +757,7 @@ dependencies = [
  "rustc_tools_util",
  "semver",
  "serde",
- "syn",
+ "syn 1.0.102",
  "tempfile",
  "termize",
  "tester",
@@ -1108,7 +1108,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
 dependencies = [
  "quote",
- "syn",
+ "syn 1.0.102",
 ]
 
 [[package]]
@@ -1154,7 +1154,7 @@ version = "0.1.70"
 dependencies = [
  "itertools",
  "quote",
- "syn",
+ "syn 1.0.102",
 ]
 
 [[package]]
@@ -1176,7 +1176,7 @@ checksum = "71f31892cd5c62e414316f2963c5689242c43d8e7bbcaaeca97e5e28c95d91d9"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
 ]
 
 [[package]]
@@ -1189,7 +1189,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "rustc_version",
- "syn",
+ "syn 1.0.102",
 ]
 
 [[package]]
@@ -1267,7 +1267,7 @@ checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
 ]
 
 [[package]]
@@ -1683,7 +1683,7 @@ checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
 ]
 
 [[package]]
@@ -2530,7 +2530,7 @@ dependencies = [
  "markup5ever",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
 ]
 
 [[package]]
@@ -2619,7 +2619,7 @@ checksum = "9ddb07844c2ffc4c28840e799e9e54ff054393cf090740decf25624e9d94b93a"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
 ]
 
 [[package]]
@@ -3089,7 +3089,7 @@ checksum = "0f1b8c13cb1f814b634a96b2c725449fe7ed464a7b8781de8688be5ffbd3f305"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
 ]
 
 [[package]]
@@ -3679,7 +3679,7 @@ dependencies = [
  "pest_meta",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
 ]
 
 [[package]]
@@ -3823,7 +3823,7 @@ dependencies = [
  "proc-macro-error-attr",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
  "version_check",
 ]
 
@@ -3846,9 +3846,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.46"
+version = "1.0.53"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b"
+checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73"
 dependencies = [
  "unicode-ident",
 ]
@@ -3925,9 +3925,9 @@ checksum = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45"
 
 [[package]]
 name = "quote"
-version = "1.0.21"
+version = "1.0.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
+checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
 dependencies = [
  "proc-macro2",
 ]
@@ -4224,7 +4224,7 @@ dependencies = [
  "regex",
  "serde_json",
  "smallvec",
- "syn",
+ "syn 1.0.102",
  "url",
  "winapi",
 ]
@@ -4934,7 +4934,7 @@ dependencies = [
  "fluent-syntax",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
  "synstructure",
  "unic-langid",
 ]
@@ -5514,7 +5514,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "serde",
- "syn",
+ "syn 1.0.102",
 ]
 
 [[package]]
@@ -5684,7 +5684,7 @@ checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
 ]
 
 [[package]]
@@ -6028,7 +6028,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "rustversion",
- "syn",
+ "syn 1.0.102",
 ]
 
 [[package]]
@@ -6049,6 +6049,17 @@ dependencies = [
 ]
 
 [[package]]
+name = "syn"
+version = "2.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bcc02725fd69ab9f26eab07fad303e2497fad6fb9eba4f96c4d1687bdf704ad9"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
 name = "synstructure"
 version = "0.12.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6056,7 +6067,7 @@ checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
  "unicode-xid",
 ]
 
@@ -6190,7 +6201,7 @@ checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
 ]
 
 [[package]]
@@ -6387,7 +6398,7 @@ checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
 ]
 
 [[package]]
@@ -6586,7 +6597,7 @@ checksum = "1f5cdec05b907f4e2f6843f4354f4ce6a5bebe1a56df320a49134944477ce4d8"
 dependencies = [
  "proc-macro-hack",
  "quote",
- "syn",
+ "syn 1.0.102",
  "unic-langid-impl",
 ]
 
@@ -6834,7 +6845,7 @@ dependencies = [
  "once_cell",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
  "wasm-bindgen-shared",
 ]
 
@@ -6856,7 +6867,7 @@ checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
@@ -7082,7 +7093,7 @@ checksum = "ca800d73d6b7a7ee54f2608205c98b549fca71c9500c1abcb3abdc7708b4a8cb"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
  "synstructure",
 ]
 
@@ -7103,7 +7114,7 @@ checksum = "2e8aa86add9ddbd2409c1ed01e033cd457d79b1b1229b64922c25095c595e829"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
  "synstructure",
 ]
 
@@ -7132,6 +7143,6 @@ checksum = "2154cb6e2a748163354165e22c6a555effb09ca2d16334767bf66bb404f2206e"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.102",
  "synstructure",
 ]
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 5d164bc4b3c..ab8b7f632e8 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1426,13 +1426,9 @@ pub enum ExprKind {
     Block(P<Block>, Option<Label>),
     /// An async block (`async move { ... }`).
     ///
-    /// The `NodeId` is the `NodeId` for the closure that results from
-    /// desugaring an async block, just like the NodeId field in the
-    /// `Async::Yes` variant. This is necessary in order to create a def for the
-    /// closure which can be used as a parent of any child defs. Defs
-    /// created during lowering cannot be made the parent of any other
-    /// preexisting defs.
-    Async(CaptureBy, NodeId, P<Block>),
+    /// The async block used to have a `NodeId`, which was removed in favor of
+    /// using the parent `NodeId` of the parent `Expr`.
+    Async(CaptureBy, P<Block>),
     /// An await expression (`my_future.await`).
     Await(P<Expr>),
 
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 45a5a3ecb53..46e46ab575e 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -1407,8 +1407,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
             vis.visit_block(blk);
             visit_opt(label, |label| vis.visit_label(label));
         }
-        ExprKind::Async(_capture_by, node_id, body) => {
-            vis.visit_id(node_id);
+        ExprKind::Async(_capture_by, body) => {
             vis.visit_block(body);
         }
         ExprKind::Await(expr) => vis.visit_expr(expr),
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 9a4da6d4396..608f87ab6eb 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -860,7 +860,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
             walk_list!(visitor, visit_label, opt_label);
             visitor.visit_block(block);
         }
-        ExprKind::Async(_, _, body) => {
+        ExprKind::Async(_, body) => {
             visitor.visit_block(body);
         }
         ExprKind::Await(expr) => visitor.visit_expr(expr),
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 181f94ab74f..3247802345b 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -63,20 +63,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 ExprKind::ForLoop(pat, head, body, opt_label) => {
                     return self.lower_expr_for(e, pat, head, body, *opt_label);
                 }
-                // Similarly, async blocks do not use `e.id` but rather `closure_node_id`.
-                ExprKind::Async(capture_clause, closure_node_id, block) => {
-                    let hir_id = self.lower_node_id(*closure_node_id);
-                    self.lower_attrs(hir_id, &e.attrs);
-                    return self.make_async_expr(
-                        *capture_clause,
-                        hir_id,
-                        *closure_node_id,
-                        None,
-                        e.span,
-                        hir::AsyncGeneratorKind::Block,
-                        |this| this.with_new_scopes(|this| this.lower_block_expr(block)),
-                    );
-                }
                 _ => (),
             }
 
@@ -187,6 +173,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     self.arena.alloc_from_iter(arms.iter().map(|x| self.lower_arm(x))),
                     hir::MatchSource::Normal,
                 ),
+                ExprKind::Async(capture_clause, block) => self.make_async_expr(
+                    *capture_clause,
+                    e.id,
+                    None,
+                    e.span,
+                    hir::AsyncGeneratorKind::Block,
+                    |this| this.with_new_scopes(|this| this.lower_block_expr(block)),
+                ),
                 ExprKind::Await(expr) => {
                     let dot_await_span = if expr.span.hi() < e.span.hi() {
                         let span_with_whitespace = self
@@ -320,7 +314,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 ),
                 ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr),
 
-                ExprKind::Paren(_) | ExprKind::ForLoop(..) | ExprKind::Async(..) => {
+                ExprKind::Paren(_) | ExprKind::ForLoop(..) => {
                     unreachable!("already handled")
                 }
 
@@ -591,13 +585,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
     pub(super) fn make_async_expr(
         &mut self,
         capture_clause: CaptureBy,
-        outer_hir_id: hir::HirId,
         closure_node_id: NodeId,
         ret_ty: Option<hir::FnRetTy<'hir>>,
         span: Span,
         async_gen_kind: hir::AsyncGeneratorKind,
         body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
-    ) -> hir::Expr<'hir> {
+    ) -> hir::ExprKind<'hir> {
         let output = ret_ty.unwrap_or_else(|| hir::FnRetTy::DefaultReturn(self.lower_span(span)));
 
         // Resume argument type: `ResumeTy`
@@ -644,24 +637,28 @@ impl<'hir> LoweringContext<'_, 'hir> {
         });
 
         // `static |_task_context| -> <ret_ty> { body }`:
-        let generator_kind = {
-            let c = self.arena.alloc(hir::Closure {
-                def_id: self.local_def_id(closure_node_id),
-                binder: hir::ClosureBinder::Default,
-                capture_clause,
-                bound_generic_params: &[],
-                fn_decl,
-                body,
-                fn_decl_span: self.lower_span(span),
-                fn_arg_span: None,
-                movability: Some(hir::Movability::Static),
-                constness: hir::Constness::NotConst,
-            });
-
-            hir::ExprKind::Closure(c)
-        };
+        hir::ExprKind::Closure(self.arena.alloc(hir::Closure {
+            def_id: self.local_def_id(closure_node_id),
+            binder: hir::ClosureBinder::Default,
+            capture_clause,
+            bound_generic_params: &[],
+            fn_decl,
+            body,
+            fn_decl_span: self.lower_span(span),
+            fn_arg_span: None,
+            movability: Some(hir::Movability::Static),
+            constness: hir::Constness::NotConst,
+        }))
+    }
 
-        let hir_id = self.lower_node_id(closure_node_id);
+    /// Forwards a possible `#[track_caller]` annotation from `outer_hir_id` to
+    /// `inner_hir_id` in case the `closure_track_caller` feature is enabled.
+    pub(super) fn maybe_forward_track_caller(
+        &mut self,
+        span: Span,
+        outer_hir_id: hir::HirId,
+        inner_hir_id: hir::HirId,
+    ) {
         if self.tcx.features().closure_track_caller
             && let Some(attrs) = self.attrs.get(&outer_hir_id.local_id)
             && attrs.into_iter().any(|attr| attr.has_name(sym::track_caller))
@@ -669,7 +666,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             let unstable_span =
                 self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
             self.lower_attrs(
-                hir_id,
+                inner_hir_id,
                 &[Attribute {
                     kind: AttrKind::Normal(ptr::P(NormalAttr {
                         item: AttrItem {
@@ -685,8 +682,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 }],
             );
         }
-
-        hir::Expr { hir_id, kind: generator_kind, span: self.lower_span(span) }
     }
 
     /// Desugar `<expr>.await` into:
@@ -1001,15 +996,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     None
                 };
 
-                this.make_async_expr(
+                let async_body = this.make_async_expr(
                     capture_clause,
-                    closure_hir_id,
                     inner_closure_id,
                     async_ret_ty,
                     body.span,
                     hir::AsyncGeneratorKind::Closure,
                     |this| this.with_new_scopes(|this| this.lower_expr_mut(body)),
-                )
+                );
+                let hir_id = this.lower_node_id(inner_closure_id);
+                this.maybe_forward_track_caller(body.span, closure_hir_id, hir_id);
+                hir::Expr { hir_id, kind: async_body, span: this.lower_span(body.span) }
             });
             body_id
         });
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 9a117ac9a3c..cc879982abc 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1146,7 +1146,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
             let async_expr = this.make_async_expr(
                 CaptureBy::Value,
-                fn_id,
                 closure_id,
                 None,
                 body.span,
@@ -1180,7 +1179,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 },
             );
 
-            (this.arena.alloc_from_iter(parameters), async_expr)
+            let hir_id = this.lower_node_id(closure_id);
+            this.maybe_forward_track_caller(body.span, fn_id, hir_id);
+            let expr = hir::Expr { hir_id, kind: async_expr, span: this.lower_span(body.span) };
+
+            (this.arena.alloc_from_iter(parameters), expr)
         })
     }
 
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index e2f63641ffa..776bf54244e 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -439,7 +439,7 @@ impl<'a> State<'a> {
                 self.ibox(0);
                 self.print_block_with_attrs(blk, attrs);
             }
-            ast::ExprKind::Async(capture_clause, _, blk) => {
+            ast::ExprKind::Async(capture_clause, blk) => {
                 self.word_nbsp("async");
                 self.print_capture_clause(*capture_clause);
                 // cbox/ibox in analogy to the `ExprKind::Block` arm above
diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs
index 5d8f4db76f9..c9e3cd486f8 100644
--- a/compiler/rustc_builtin_macros/src/assert/context.rs
+++ b/compiler/rustc_builtin_macros/src/assert/context.rs
@@ -287,7 +287,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
             // sync with the `rfc-2011-nicer-assert-messages/all-expr-kinds.rs` test.
             ExprKind::Assign(_, _, _)
             | ExprKind::AssignOp(_, _, _)
-            | ExprKind::Async(_, _, _)
+            | ExprKind::Async(_, _)
             | ExprKind::Await(_)
             | ExprKind::Block(_, _)
             | ExprKind::Break(_, _)
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index 9b0d8d6c072..65607d71805 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -224,8 +224,7 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
             ast::ExprKind::Closure(box ast::Closure {
                 asyncness: ast::Async::Yes { closure_id, .. },
                 ..
-            })
-            | ast::ExprKind::Async(_, closure_id, ..) => self.check_id(closure_id),
+            }) => self.check_id(closure_id),
             _ => {}
         }
     }
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 8b69b3cb036..c4605e63cf3 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2911,7 +2911,7 @@ impl<'a> Parser<'a> {
         self.expect_keyword(kw::Async)?;
         let capture_clause = self.parse_capture_clause()?;
         let (attrs, body) = self.parse_inner_attrs_and_block()?;
-        let kind = ExprKind::Async(capture_clause, DUMMY_NODE_ID, body);
+        let kind = ExprKind::Async(capture_clause, body);
         Ok(self.mk_expr_with_attrs(lo.to(self.prev_token.span), kind, attrs))
     }
 
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index e7ff236f846..356d7f365fe 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -260,9 +260,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
                     Async::No => closure_def,
                 }
             }
-            ExprKind::Async(_, async_id, _) => {
-                self.create_def(async_id, DefPathData::ClosureExpr, expr.span)
-            }
+            ExprKind::Async(_, _) => self.create_def(expr.id, DefPathData::ClosureExpr, expr.span),
             _ => self.parent_def,
         };
 
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index a50c91579fa..9b812bbfc23 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -414,7 +414,7 @@ impl isize {
     }
 }
 
-/// If 6th bit set ascii is upper case.
+/// If 6th bit is set ascii is lower case.
 const ASCII_CASE_MASK: u8 = 0b0010_0000;
 
 impl u8 {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index c00fa5994bf..5f5521caf68 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -32,6 +32,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{self, ExpnKind};
 
 use std::assert_matches::assert_matches;
+use std::borrow::Cow;
 use std::collections::hash_map::Entry;
 use std::collections::BTreeMap;
 use std::default::Default;
@@ -39,7 +40,6 @@ use std::hash::Hash;
 use std::mem;
 use thin_vec::ThinVec;
 
-use crate::clean::inline::merge_attrs;
 use crate::core::{self, DocContext, ImplTraitParam};
 use crate::formats::item_type::ItemType;
 use crate::visit_ast::Module as DocModule;
@@ -2168,32 +2168,39 @@ impl<'hir> hir::intravisit::Visitor<'hir> for OneLevelVisitor<'hir> {
 /// documentation. Otherwise, we repeat the same operation until we find the "end item".
 fn get_all_import_attributes<'hir>(
     mut item: &hir::Item<'hir>,
-    tcx: TyCtxt<'hir>,
+    cx: &mut DocContext<'hir>,
     target_def_id: LocalDefId,
-    attributes: &mut Vec<ast::Attribute>,
     is_inline: bool,
-) {
+    mut prev_import: LocalDefId,
+) -> Vec<(Cow<'hir, ast::Attribute>, Option<DefId>)> {
+    let mut attributes: Vec<(Cow<'hir, ast::Attribute>, Option<DefId>)> = Vec::new();
     let mut first = true;
-    let hir_map = tcx.hir();
+    let hir_map = cx.tcx.hir();
     let mut visitor = OneLevelVisitor::new(hir_map, target_def_id);
     let mut visited = FxHashSet::default();
 
     // If the item is an import and has at least a path with two parts, we go into it.
     while let hir::ItemKind::Use(path, _) = item.kind && visited.insert(item.hir_id()) {
+        let import_parent = cx.tcx.opt_local_parent(prev_import).map(|def_id| def_id.to_def_id());
         if first {
             // This is the "original" reexport so we get all its attributes without filtering them.
-            attributes.extend_from_slice(hir_map.attrs(item.hir_id()));
+            attributes = hir_map.attrs(item.hir_id())
+                .iter()
+                .map(|attr| (Cow::Borrowed(attr), import_parent))
+                .collect::<Vec<_>>();
             first = false;
         } else {
-            add_without_unwanted_attributes(attributes, hir_map.attrs(item.hir_id()), is_inline);
+            add_without_unwanted_attributes(&mut attributes, hir_map.attrs(item.hir_id()), is_inline, import_parent);
         }
 
-        if let Some(i) = visitor.find_target(tcx, item.owner_id.def_id.to_def_id(), path) {
+        if let Some(i) = visitor.find_target(cx.tcx, item.owner_id.def_id.to_def_id(), path) {
             item = i;
         } else {
             break;
         }
+        prev_import = item.owner_id.def_id;
     }
+    attributes
 }
 
 fn filter_tokens_from_list(
@@ -2239,17 +2246,24 @@ fn filter_tokens_from_list(
 /// * `doc(inline)`
 /// * `doc(no_inline)`
 /// * `doc(hidden)`
-fn add_without_unwanted_attributes(
-    attrs: &mut Vec<ast::Attribute>,
-    new_attrs: &[ast::Attribute],
+fn add_without_unwanted_attributes<'hir>(
+    attrs: &mut Vec<(Cow<'hir, ast::Attribute>, Option<DefId>)>,
+    new_attrs: &'hir [ast::Attribute],
     is_inline: bool,
+    import_parent: Option<DefId>,
 ) {
-    // If it's `#[doc(inline)]`, we don't want all attributes, otherwise we keep everything.
+    // If it's not `#[doc(inline)]`, we don't want all attributes, otherwise we keep everything.
     if !is_inline {
-        attrs.extend_from_slice(new_attrs);
+        for attr in new_attrs {
+            attrs.push((Cow::Borrowed(attr), import_parent));
+        }
         return;
     }
     for attr in new_attrs {
+        if matches!(attr.kind, ast::AttrKind::DocComment(..)) {
+            attrs.push((Cow::Borrowed(attr), import_parent));
+            continue;
+        }
         let mut attr = attr.clone();
         match attr.kind {
             ast::AttrKind::Normal(ref mut normal) => {
@@ -2276,18 +2290,15 @@ fn add_without_unwanted_attributes(
                                     )
                                 });
                             args.tokens = TokenStream::new(tokens);
-                            attrs.push(attr);
+                            attrs.push((Cow::Owned(attr), import_parent));
                         }
                         ast::AttrArgs::Empty | ast::AttrArgs::Eq(..) => {
-                            attrs.push(attr);
-                            continue;
+                            attrs.push((Cow::Owned(attr), import_parent));
                         }
                     }
                 }
             }
-            ast::AttrKind::DocComment(..) => {
-                attrs.push(attr);
-            }
+            _ => unreachable!(),
         }
     }
 }
@@ -2374,26 +2385,43 @@ fn clean_maybe_renamed_item<'tcx>(
             _ => unreachable!("not yet converted"),
         };
 
-        let mut import_attrs = Vec::new();
-        let mut target_attrs = Vec::new();
-        if let Some(import_id) = import_id &&
+        let attrs = if let Some(import_id) = import_id &&
             let Some(hir::Node::Item(use_node)) = cx.tcx.hir().find_by_def_id(import_id)
         {
-            let is_inline = inline::load_attrs(cx, import_id.to_def_id()).lists(sym::doc).get_word_attr(sym::inline).is_some();
+            let is_inline = inline::load_attrs(cx, import_id.to_def_id())
+                .lists(sym::doc)
+                .get_word_attr(sym::inline)
+                .is_some();
             // Then we get all the various imports' attributes.
-            get_all_import_attributes(use_node, cx.tcx, item.owner_id.def_id, &mut import_attrs, is_inline);
-            add_without_unwanted_attributes(&mut target_attrs, inline::load_attrs(cx, def_id), is_inline);
+            let mut attrs = get_all_import_attributes(
+                use_node,
+                cx,
+                item.owner_id.def_id,
+                is_inline,
+                import_id,
+            );
+
+            add_without_unwanted_attributes(
+                &mut attrs,
+                inline::load_attrs(cx, def_id),
+                is_inline,
+                None
+            );
+            attrs
         } else {
             // We only keep the item's attributes.
-            target_attrs.extend_from_slice(inline::load_attrs(cx, def_id));
-        }
+            inline::load_attrs(cx, def_id).iter().map(|attr| (Cow::Borrowed(attr), None)).collect::<Vec<_>>()
+        };
 
-        let import_id = import_id.map(|def_id| def_id.to_def_id());
-        let (attrs, cfg) =  merge_attrs(cx, &target_attrs, Some((&import_attrs, import_id)));
+        let cfg = attrs.cfg(cx.tcx, &cx.cache.hidden_cfg);
+        let attrs = Attributes::from_ast_iter(attrs.iter().map(|(attr, did)| match attr {
+            Cow::Borrowed(attr) => (*attr, *did),
+            Cow::Owned(attr) => (attr, *did)
+        }), false);
 
         let mut item =
             Item::from_def_id_and_attrs_and_parts(def_id, Some(name), kind, Box::new(attrs), cfg);
-        item.inline_stmt_id = import_id;
+        item.inline_stmt_id = import_id.map(|local| local.to_def_id());
         vec![item]
     })
 }
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 7dbb3f76a0a..9019a6c49ec 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1,3 +1,4 @@
+use std::borrow::Cow;
 use std::cell::RefCell;
 use std::default::Default;
 use std::hash::Hash;
@@ -869,28 +870,13 @@ pub(crate) trait AttributesExt {
     type AttributeIterator<'a>: Iterator<Item = ast::NestedMetaItem>
     where
         Self: 'a;
+    type Attributes<'a>: Iterator<Item = &'a ast::Attribute>
+    where
+        Self: 'a;
 
     fn lists<'a>(&'a self, name: Symbol) -> Self::AttributeIterator<'a>;
 
-    fn span(&self) -> Option<rustc_span::Span>;
-
-    fn cfg(&self, tcx: TyCtxt<'_>, hidden_cfg: &FxHashSet<Cfg>) -> Option<Arc<Cfg>>;
-}
-
-impl AttributesExt for [ast::Attribute] {
-    type AttributeIterator<'a> = impl Iterator<Item = ast::NestedMetaItem> + 'a;
-
-    fn lists<'a>(&'a self, name: Symbol) -> Self::AttributeIterator<'a> {
-        self.iter()
-            .filter(move |attr| attr.has_name(name))
-            .filter_map(ast::Attribute::meta_item_list)
-            .flatten()
-    }
-
-    /// Return the span of the first doc-comment, if it exists.
-    fn span(&self) -> Option<rustc_span::Span> {
-        self.iter().find(|attr| attr.doc_str().is_some()).map(|attr| attr.span)
-    }
+    fn iter<'a>(&'a self) -> Self::Attributes<'a>;
 
     fn cfg(&self, tcx: TyCtxt<'_>, hidden_cfg: &FxHashSet<Cfg>) -> Option<Arc<Cfg>> {
         let sess = tcx.sess;
@@ -980,6 +966,43 @@ impl AttributesExt for [ast::Attribute] {
     }
 }
 
+impl AttributesExt for [ast::Attribute] {
+    type AttributeIterator<'a> = impl Iterator<Item = ast::NestedMetaItem> + 'a;
+    type Attributes<'a> = impl Iterator<Item = &'a ast::Attribute> + 'a;
+
+    fn lists<'a>(&'a self, name: Symbol) -> Self::AttributeIterator<'a> {
+        self.iter()
+            .filter(move |attr| attr.has_name(name))
+            .filter_map(ast::Attribute::meta_item_list)
+            .flatten()
+    }
+
+    fn iter<'a>(&'a self) -> Self::Attributes<'a> {
+        self.into_iter()
+    }
+}
+
+impl AttributesExt for [(Cow<'_, ast::Attribute>, Option<DefId>)] {
+    type AttributeIterator<'a> = impl Iterator<Item = ast::NestedMetaItem> + 'a
+        where Self: 'a;
+    type Attributes<'a> = impl Iterator<Item = &'a ast::Attribute> + 'a
+        where Self: 'a;
+
+    fn lists<'a>(&'a self, name: Symbol) -> Self::AttributeIterator<'a> {
+        AttributesExt::iter(self)
+            .filter(move |attr| attr.has_name(name))
+            .filter_map(ast::Attribute::meta_item_list)
+            .flatten()
+    }
+
+    fn iter<'a>(&'a self) -> Self::Attributes<'a> {
+        self.into_iter().map(move |(attr, _)| match attr {
+            Cow::Borrowed(attr) => *attr,
+            Cow::Owned(attr) => attr,
+        })
+    }
+}
+
 pub(crate) trait NestedAttributesExt {
     /// Returns `true` if the attribute list contains a specific `word`
     fn has_word(self, word: Symbol) -> bool
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index aaa83ecce48..1a896b411ab 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -1239,8 +1239,9 @@ impl<'a, 'hir, 'tcx> HirCollector<'a, 'hir, 'tcx> {
         if let Some(doc) = attrs.collapsed_doc_value() {
             // Use the outermost invocation, so that doctest names come from where the docs were written.
             let span = ast_attrs
-                .span()
-                .map(|span| span.ctxt().outer_expn().expansion_cause().unwrap_or(span))
+                .iter()
+                .find(|attr| attr.doc_str().is_some())
+                .map(|attr| attr.span.ctxt().outer_expn().expansion_cause().unwrap_or(attr.span))
                 .unwrap_or(DUMMY_SP);
             self.collector.set_position(span);
             markdown::find_testable_code(
diff --git a/src/tools/clippy/clippy_lints/src/redundant_async_block.rs b/src/tools/clippy/clippy_lints/src/redundant_async_block.rs
index 2d30e77d55d..5ac203665d0 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_async_block.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_async_block.rs
@@ -42,7 +42,7 @@ impl EarlyLintPass for RedundantAsyncBlock {
         if expr.span.from_expansion() {
             return;
         }
-        if let ExprKind::Async(_, _, block) = &expr.kind && block.stmts.len() == 1 &&
+        if let ExprKind::Async(_, block) = &expr.kind && block.stmts.len() == 1 &&
             let Some(Stmt { kind: StmtKind::Expr(last), .. }) = block.stmts.last() &&
             let ExprKind::Await(future) = &last.kind &&
             !future.span.from_expansion() &&
diff --git a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
index 8aa47b62ebf..fab8e9c2ec1 100644
--- a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
+++ b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
@@ -578,7 +578,7 @@ fn ident_difference_expr_with_base_location(
         | (Assign(_, _, _), Assign(_, _, _))
         | (TryBlock(_), TryBlock(_))
         | (Await(_), Await(_))
-        | (Async(_, _, _), Async(_, _, _))
+        | (Async(_, _), Async(_, _))
         | (Block(_, _), Block(_, _))
         | (Closure(_), Closure(_))
         | (Match(_, _), Match(_, _))
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index 809d654603a..d2dedc20439 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -209,7 +209,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
                 && eq_fn_decl(lf, rf)
                 && eq_expr(le, re)
         },
-        (Async(lc, _, lb), Async(rc, _, rb)) => lc == rc && eq_block(lb, rb),
+        (Async(lc, lb), Async(rc, rb)) => lc == rc && eq_block(lb, rb),
         (Range(lf, lt, ll), Range(rf, rt, rl)) => ll == rl && eq_expr_opt(lf, rf) && eq_expr_opt(lt, rt),
         (AddrOf(lbk, lm, le), AddrOf(rbk, rm, re)) => lbk == rbk && lm == rm && eq_expr(le, re),
         (Path(lq, lp), Path(rq, rp)) => both(lq, rq, eq_qself) && eq_path(lp, rp),
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 7691f5c32b2..28c045f8382 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -384,6 +384,8 @@ pub struct Config {
     pub only_modified: bool,
 
     pub target_cfg: LazyCell<TargetCfg>,
+
+    pub nocapture: bool,
 }
 
 impl Config {
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index cbaa599f793..bce61c55c3d 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -152,6 +152,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         )
         .optflag("", "force-rerun", "rerun tests even if the inputs are unchanged")
         .optflag("", "only-modified", "only run tests that result been modified")
+        .optflag("", "nocapture", "")
         .optflag("h", "help", "show this message")
         .reqopt("", "channel", "current Rust channel", "CHANNEL")
         .optopt("", "edition", "default Rust edition", "EDITION");
@@ -310,6 +311,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
         force_rerun: matches.opt_present("force-rerun"),
 
         target_cfg: LazyCell::new(),
+
+        nocapture: matches.opt_present("nocapture"),
     }
 }
 
@@ -502,6 +505,13 @@ fn configure_lldb(config: &Config) -> Option<Config> {
 }
 
 pub fn test_opts(config: &Config) -> test::TestOpts {
+    if env::var("RUST_TEST_NOCAPTURE").is_ok() {
+        eprintln!(
+            "WARNING: RUST_TEST_NOCAPTURE is no longer used. \
+                   Use the `--nocapture` flag instead."
+        );
+    }
+
     test::TestOpts {
         exclude_should_panic: false,
         filters: config.filters.clone(),
@@ -511,10 +521,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
         logfile: config.logfile.clone(),
         run_tests: true,
         bench_benchmarks: true,
-        nocapture: match env::var("RUST_TEST_NOCAPTURE") {
-            Ok(val) => &val != "0",
-            Err(_) => false,
-        },
+        nocapture: config.nocapture,
         color: config.color,
         shuffle: false,
         shuffle_seed: None,
diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs
index 7273402ec76..ac96bedf2fe 100644
--- a/src/tools/rustfmt/src/expr.rs
+++ b/src/tools/rustfmt/src/expr.rs
@@ -366,7 +366,7 @@ pub(crate) fn format_expr(
                 ))
             }
         }
-        ast::ExprKind::Async(capture_by, _node_id, ref block) => {
+        ast::ExprKind::Async(capture_by, ref block) => {
             let mover = if capture_by == ast::CaptureBy::Value {
                 "move "
             } else {
diff --git a/tests/rustdoc-ui/issue-109282-import-inline-merge.rs b/tests/rustdoc-ui/issue-109282-import-inline-merge.rs
new file mode 100644
index 00000000000..0ec8523222f
--- /dev/null
+++ b/tests/rustdoc-ui/issue-109282-import-inline-merge.rs
@@ -0,0 +1,14 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/109282>.
+// Import for `ValueEnum` is inlined and doc comments on the import and `ValueEnum` itself are
+// merged. After the merge they still have correct parent scopes to resolve both `[ValueEnum]`.
+
+// check-pass
+
+mod m {
+    pub enum ValueEnum {}
+}
+mod m2 {
+    /// [`ValueEnum`]
+    pub use crate::m::ValueEnum;
+}
+pub use m2::ValueEnum;
diff --git a/tests/ui/simple_global_asm.rs b/tests/ui/simple_global_asm.rs
index 3c69379ff14..c3b2f2e0bc4 100644
--- a/tests/ui/simple_global_asm.rs
+++ b/tests/ui/simple_global_asm.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-asm-support
 
 #![feature(naked_functions)]
 #![allow(dead_code)]