diff options
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)] |
