From c28de27a73521c0814e771120bd0aeecde67d93b Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 29 Nov 2023 10:11:37 -0700 Subject: [PATCH 1/8] rustdoc-search: allow `:: ` and ` ::` This restriction made sense back when spaces separated function parameters, but now that they separate path components, there's no real ambiguity any more. Additionally, the Rust language allows it. --- src/librustdoc/html/static/js/search.js | 13 +++---- tests/rustdoc-js-std/parser-errors.js | 27 +++++--------- tests/rustdoc-js-std/parser-paths.js | 48 +++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 26 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 979aebdb7bed1..dc6cdcd569aa5 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -512,18 +512,15 @@ function initSearch(rawSearchIndex) { bindingName, }; } + const quadcolon = /::\s*::/.exec(path); if (path.startsWith("::")) { throw ["Paths cannot start with ", "::"]; } else if (path.endsWith("::")) { throw ["Paths cannot end with ", "::"]; - } else if (path.includes("::::")) { - throw ["Unexpected ", "::::"]; - } else if (path.includes(" ::")) { - throw ["Unexpected ", " ::"]; - } else if (path.includes(":: ")) { - throw ["Unexpected ", ":: "]; - } - const pathSegments = path.split(/::|\s+/); + } else if (quadcolon !== null) { + throw ["Unexpected ", quadcolon[0]]; + } + const pathSegments = path.split(/(?:::\s*)|(?:\s+(?:::\s*)?)/); // In case we only have something like `

`, there is no name. if (pathSegments.length === 0 || (pathSegments.length === 1 && pathSegments[0] === "")) { if (generics.length > 0 || prevIs(parserState, ">")) { diff --git a/tests/rustdoc-js-std/parser-errors.js b/tests/rustdoc-js-std/parser-errors.js index ab8d72bf71b13..410fe11b9cf0a 100644 --- a/tests/rustdoc-js-std/parser-errors.js +++ b/tests/rustdoc-js-std/parser-errors.js @@ -143,6 +143,15 @@ const PARSED = [ userQuery: "a::::b", error: "Unexpected `::::`", }, + { + query: "a:: ::b", + elems: [], + foundElems: 0, + original: "a:: ::b", + returned: [], + userQuery: "a:: ::b", + error: "Unexpected `:: ::`", + }, { query: "a::b::", elems: [], @@ -314,24 +323,6 @@ const PARSED = [ userQuery: 'a<->', error: 'Unexpected `-` after `<`', }, - { - query: "a:: a", - elems: [], - foundElems: 0, - original: 'a:: a', - returned: [], - userQuery: 'a:: a', - error: 'Unexpected `:: `', - }, - { - query: "a ::a", - elems: [], - foundElems: 0, - original: 'a ::a', - returned: [], - userQuery: 'a ::a', - error: 'Unexpected ` ::`', - }, { query: "a:", elems: [], diff --git a/tests/rustdoc-js-std/parser-paths.js b/tests/rustdoc-js-std/parser-paths.js index 8d4dedf3f46c8..774e5d028cc2c 100644 --- a/tests/rustdoc-js-std/parser-paths.js +++ b/tests/rustdoc-js-std/parser-paths.js @@ -15,6 +15,54 @@ const PARSED = [ userQuery: "a::b", error: null, }, + { + query: "a:: a", + elems: [{ + name: "a:: a", + fullPath: ["a", "a"], + pathWithoutLast: ["a"], + pathLast: "a", + generics: [], + typeFilter: -1, + }], + foundElems: 1, + original: 'a:: a', + returned: [], + userQuery: 'a:: a', + error: null, + }, + { + query: "a ::a", + elems: [{ + name: "a ::a", + fullPath: ["a", "a"], + pathWithoutLast: ["a"], + pathLast: "a", + generics: [], + typeFilter: -1, + }], + foundElems: 1, + original: 'a ::a', + returned: [], + userQuery: 'a ::a', + error: null, + }, + { + query: "a :: a", + elems: [{ + name: "a :: a", + fullPath: ["a", "a"], + pathWithoutLast: ["a"], + pathLast: "a", + generics: [], + typeFilter: -1, + }], + foundElems: 1, + original: 'a :: a', + returned: [], + userQuery: 'a :: a', + error: null, + }, { query: 'A::B,C', elems: [ From 93f17117ed50a972bfabea86762241cd9ac5ccbd Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 29 Nov 2023 10:23:42 -0700 Subject: [PATCH 2/8] rustdoc-search: removed dead parser code This is already covered by the normal unexpected char path. --- src/librustdoc/html/static/js/search.js | 2 -- tests/rustdoc-js-std/parser-errors.js | 9 +++++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index dc6cdcd569aa5..37e5276a49494 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -473,8 +473,6 @@ function initSearch(rawSearchIndex) { const path = name.trim(); if (path.length === 0 && generics.length === 0) { throw ["Unexpected ", parserState.userQuery[parserState.pos]]; - } else if (path === "*") { - throw ["Unexpected ", "*"]; } if (query.literalSearch && parserState.totalElems - parserState.genericsElems > 0) { throw ["Cannot have more than one element if you use quotes"]; diff --git a/tests/rustdoc-js-std/parser-errors.js b/tests/rustdoc-js-std/parser-errors.js index 410fe11b9cf0a..cb1654c0fb0ba 100644 --- a/tests/rustdoc-js-std/parser-errors.js +++ b/tests/rustdoc-js-std/parser-errors.js @@ -17,6 +17,15 @@ const PARSED = [ userQuery: "->

", error: "Found generics without a path", }, + { + query: '-> *', + elems: [], + foundElems: 0, + original: "-> *", + returned: [], + userQuery: "-> *", + error: "Unexpected `*`", + }, { query: 'a<"P">', elems: [], From 930cba8061dca5988a58b4e74774489e1b129184 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 29 Nov 2023 10:54:49 -0700 Subject: [PATCH 3/8] rustdoc-search: replace TAB/NL/LF with SP first This way, most of the parsing code doesn't need to be designed to handle it, since they should always be treated exactly the same anyhow. --- src/librustdoc/html/static/js/search.js | 16 ++++++-------- tests/rustdoc-js-std/parser-errors.js | 9 ++++++++ tests/rustdoc-js-std/parser-separators.js | 22 ++++++++++---------- tests/rustdoc-js-std/parser-weird-queries.js | 4 ++-- 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 37e5276a49494..8f68796ad26b8 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -287,10 +287,6 @@ function initSearch(rawSearchIndex) { } } - function isWhitespace(c) { - return " \t\n\r".indexOf(c) !== -1; - } - function isSpecialStartCharacter(c) { return "<\"".indexOf(c) !== -1; } @@ -408,7 +404,7 @@ function initSearch(rawSearchIndex) { * @return {boolean} */ function isPathSeparator(c) { - return c === ":" || isWhitespace(c); + return c === ":" || c === " "; } /** @@ -425,7 +421,7 @@ function initSearch(rawSearchIndex) { const c = parserState.userQuery[pos - 1]; if (c === lookingFor) { return true; - } else if (!isWhitespace(c)) { + } else if (c !== " ") { break; } pos -= 1; @@ -454,7 +450,7 @@ function initSearch(rawSearchIndex) { function skipWhitespace(parserState) { while (parserState.pos < parserState.userQuery.length) { const c = parserState.userQuery[parserState.pos]; - if (!isWhitespace(c)) { + if (c !== " ") { break; } parserState.pos += 1; @@ -599,7 +595,7 @@ function initSearch(rawSearchIndex) { } else { while (parserState.pos + 1 < parserState.length) { const next_c = parserState.userQuery[parserState.pos + 1]; - if (!isWhitespace(next_c)) { + if (next_c !== " ") { break; } parserState.pos += 1; @@ -953,7 +949,7 @@ function initSearch(rawSearchIndex) { query.literalSearch = false; foundStopChar = true; continue; - } else if (isWhitespace(c)) { + } else if (c === " ") { skipWhitespace(parserState); continue; } @@ -1113,7 +1109,7 @@ function initSearch(rawSearchIndex) { } } } - userQuery = userQuery.trim(); + userQuery = userQuery.trim().replace(/\r|\n|\t/g, " "); const parserState = { length: userQuery.length, pos: 0, diff --git a/tests/rustdoc-js-std/parser-errors.js b/tests/rustdoc-js-std/parser-errors.js index cb1654c0fb0ba..f9f9c4f4de8c6 100644 --- a/tests/rustdoc-js-std/parser-errors.js +++ b/tests/rustdoc-js-std/parser-errors.js @@ -161,6 +161,15 @@ const PARSED = [ userQuery: "a:: ::b", error: "Unexpected `:: ::`", }, + { + query: "a::\t::b", + elems: [], + foundElems: 0, + original: "a:: ::b", + returned: [], + userQuery: "a:: ::b", + error: "Unexpected `:: ::`", + }, { query: "a::b::", elems: [], diff --git a/tests/rustdoc-js-std/parser-separators.js b/tests/rustdoc-js-std/parser-separators.js index 00c489b51a6a2..7f95f61b006bb 100644 --- a/tests/rustdoc-js-std/parser-separators.js +++ b/tests/rustdoc-js-std/parser-separators.js @@ -5,7 +5,7 @@ const PARSED = [ query: 'aaaaaa b', elems: [ { - name: 'aaaaaa\tb', + name: 'aaaaaa b', fullPath: ['aaaaaa', 'b'], pathWithoutLast: ['aaaaaa'], pathLast: 'b', @@ -14,9 +14,9 @@ const PARSED = [ }, ], foundElems: 1, - original: "aaaaaa b", + original: "aaaaaa b", returned: [], - userQuery: "aaaaaa b", + userQuery: "aaaaaa b", error: null, }, { @@ -40,9 +40,9 @@ const PARSED = [ }, ], foundElems: 2, - original: "aaaaaa, b", + original: "aaaaaa, b", returned: [], - userQuery: "aaaaaa, b", + userQuery: "aaaaaa, b", error: null, }, { @@ -93,7 +93,7 @@ const PARSED = [ query: 'a\tb', elems: [ { - name: 'a\tb', + name: 'a b', fullPath: ['a', 'b'], pathWithoutLast: ['a'], pathLast: 'b', @@ -102,9 +102,9 @@ const PARSED = [ }, ], foundElems: 1, - original: "a\tb", + original: "a b", returned: [], - userQuery: "a\tb", + userQuery: "a b", error: null, }, { @@ -176,7 +176,7 @@ const PARSED = [ pathLast: 'a', generics: [ { - name: 'b\tc', + name: 'b c', fullPath: ['b', 'c'], pathWithoutLast: ['b'], pathLast: 'c', @@ -187,9 +187,9 @@ const PARSED = [ }, ], foundElems: 1, - original: "a", + original: "a", returned: [], - userQuery: "a", + userQuery: "a", error: null, }, ]; diff --git a/tests/rustdoc-js-std/parser-weird-queries.js b/tests/rustdoc-js-std/parser-weird-queries.js index 720ef66c16525..ba68c9717c51a 100644 --- a/tests/rustdoc-js-std/parser-weird-queries.js +++ b/tests/rustdoc-js-std/parser-weird-queries.js @@ -92,9 +92,9 @@ const PARSED = [ query: 'mod\t:', elems: [], foundElems: 0, - original: 'mod\t:', + original: 'mod :', returned: [], - userQuery: 'mod\t:', + userQuery: 'mod :', error: "Unexpected `:` (expected path after type filter `mod:`)", }, ]; From 4be07075b3651a69f05b9b9f16312fe3a8cf21fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 29 Nov 2023 18:11:57 +0000 Subject: [PATCH 4/8] Tweak message on ADT with private fields building When trying to create an inaccessible ADT due to private fields, handle the case when no fields were passed. ``` error: cannot construct `Foo` with struct literal syntax due to private fields --> $DIR/issue-76077.rs:8:5 | LL | foo::Foo {}; | ^^^^^^^^ | = note: private field `you_cant_use_this_field` that was not provided ``` --- compiler/rustc_hir_typeck/src/expr.rs | 3 ++- tests/ui/issues/issue-76077.stderr | 2 +- tests/ui/privacy/issue-79593.stderr | 2 +- tests/ui/privacy/suggest-box-new.stderr | 4 ++-- .../issue-87872-missing-inaccessible-field-literal.stderr | 2 +- .../ui/typeck/missing-private-fields-in-struct-literal.stderr | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index ed5ac2cea3874..c2a8eb3bc8e00 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2090,7 +2090,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { [] => unreachable!(), }; err.note(format!( - "... and other private field{s} {names}that {were} not provided", + "{}private field{s} {names}that {were} not provided", + if used_fields.is_empty() { "" } else { "...and other " }, s = pluralize!(remaining_private_fields_len), were = pluralize!("was", remaining_private_fields_len), )); diff --git a/tests/ui/issues/issue-76077.stderr b/tests/ui/issues/issue-76077.stderr index 4c510e91ada48..3fef5ffce30dc 100644 --- a/tests/ui/issues/issue-76077.stderr +++ b/tests/ui/issues/issue-76077.stderr @@ -4,7 +4,7 @@ error: cannot construct `Foo` with struct literal syntax due to private fields LL | foo::Foo {}; | ^^^^^^^^ | - = note: ... and other private field `you_cant_use_this_field` that was not provided + = note: private field `you_cant_use_this_field` that was not provided error: aborting due to 1 previous error diff --git a/tests/ui/privacy/issue-79593.stderr b/tests/ui/privacy/issue-79593.stderr index 21ba760ad0bcc..5bb69836f609f 100644 --- a/tests/ui/privacy/issue-79593.stderr +++ b/tests/ui/privacy/issue-79593.stderr @@ -16,7 +16,7 @@ error: cannot construct `Pub` with struct literal syntax due to private fields LL | foo::Pub {}; | ^^^^^^^^ | - = note: ... and other private field `private` that was not provided + = note: private field `private` that was not provided error[E0063]: missing field `y` in initializer of `Enum` --> $DIR/issue-79593.rs:23:5 diff --git a/tests/ui/privacy/suggest-box-new.stderr b/tests/ui/privacy/suggest-box-new.stderr index 2224f1c60d63c..8b01e8c3c10ef 100644 --- a/tests/ui/privacy/suggest-box-new.stderr +++ b/tests/ui/privacy/suggest-box-new.stderr @@ -56,7 +56,7 @@ error: cannot construct `HashMap<_, _, _>` with struct literal syntax due to pri LL | let _ = std::collections::HashMap {}; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: ... and other private field `base` that was not provided + = note: private field `base` that was not provided help: you might have meant to use an associated function to build this type | LL | let _ = std::collections::HashMap::new(); @@ -78,7 +78,7 @@ error: cannot construct `Box<_, _>` with struct literal syntax due to private fi LL | let _ = Box {}; | ^^^ | - = note: ... and other private fields `0` and `1` that were not provided + = note: private fields `0` and `1` that were not provided help: you might have meant to use an associated function to build this type | LL | let _ = Box::new(_); diff --git a/tests/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr b/tests/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr index eab494ffbdf29..899dd02583a71 100644 --- a/tests/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr +++ b/tests/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr @@ -4,7 +4,7 @@ error: cannot construct `Foo` with struct literal syntax due to private fields LL | foo::Foo {}; | ^^^^^^^^ | - = note: ... and other private field `you_cant_use_this_field` that was not provided + = note: private field `you_cant_use_this_field` that was not provided error: aborting due to 1 previous error diff --git a/tests/ui/typeck/missing-private-fields-in-struct-literal.stderr b/tests/ui/typeck/missing-private-fields-in-struct-literal.stderr index 96998ca244d22..003eaa405924a 100644 --- a/tests/ui/typeck/missing-private-fields-in-struct-literal.stderr +++ b/tests/ui/typeck/missing-private-fields-in-struct-literal.stderr @@ -9,7 +9,7 @@ LL | a: (), LL | b: (), | ----- private field | - = note: ... and other private fields `c`, `d` and `e` that were not provided + = note: ...and other private fields `c`, `d` and `e` that were not provided error: aborting due to 1 previous error From 32c035c8c8f8581a412dc3251a7e4e90a4fee08e Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Wed, 29 Nov 2023 20:15:13 +0000 Subject: [PATCH 5/8] rustc_span: Remove unused symbols. --- compiler/rustc_span/src/symbol.rs | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9a2fe01229ddb..46545416b5e1b 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -128,13 +128,11 @@ symbols! { AcqRel, Acquire, AddToDiagnostic, - Alignment, Any, Arc, ArcWeak, Argument, ArgumentMethods, - Arguments, ArrayIntoIter, AsMut, AsRef, @@ -164,7 +162,6 @@ symbols! { Break, C, CStr, - CString, Capture, Center, Cleanup, @@ -174,7 +171,6 @@ symbols! { Context, Continue, Copy, - Count, Cow, Debug, DebugStruct, @@ -199,7 +195,6 @@ symbols! { Fn, FnMut, FnOnce, - FormatSpec, Formatter, From, FromIterator, @@ -208,8 +203,6 @@ symbols! { FsPermissions, Future, FutureOutput, - FxHashMap, - FxHashSet, GlobalAlloc, Hash, HashMap, @@ -253,7 +246,6 @@ symbols! { NonZeroI32, NonZeroI64, NonZeroI8, - NonZeroIsize, NonZeroU128, NonZeroU16, NonZeroU32, @@ -275,7 +267,6 @@ symbols! { Path, PathBuf, Pending, - Pin, Pointer, Poll, ProcMacro, @@ -333,7 +324,6 @@ symbols! { TyCtxt, TyKind, Unknown, - UnsafeArg, Vec, VecDeque, Wrapper, @@ -389,7 +379,6 @@ symbols! { allow_fail, allow_internal_unsafe, allow_internal_unstable, - allowed, alu32, always, and, @@ -405,8 +394,6 @@ symbols! { arm, arm_target_feature, array, - arrays, - as_mut_ptr, as_ptr, as_ref, as_str, @@ -589,7 +576,6 @@ symbols! { const_try, constant, constructor, - context, convert_identity, copy, copy_closures, @@ -776,8 +762,6 @@ symbols! { field, field_init_shorthand, file, - fill, - flags, float, float_to_int_unchecked, floorf32, @@ -1059,7 +1043,6 @@ symbols! { mir_unwind_unreachable, mir_variant, miri, - misc, mmx_reg, modifiers, module, @@ -1157,9 +1140,7 @@ symbols! { omit_gdb_pretty_printer_section, on, on_unimplemented, - oom, opaque, - ops, opt_out_copy, optimize, optimize_attribute, @@ -1217,7 +1198,6 @@ symbols! { pointer, pointer_like, poll, - position, post_dash_lto: "post-lto", powerpc_target_feature, powf32, @@ -1226,7 +1206,6 @@ symbols! { powif64, pre_dash_lto: "pre-lto", precise_pointer_size_matching, - precision, pref_align_of, prefetch_read_data, prefetch_read_instruction, @@ -1236,7 +1215,6 @@ symbols! { prelude, prelude_import, preserves_flags, - primitive, print_macro, println_macro, proc_dash_macro: "proc-macro", @@ -1260,7 +1238,6 @@ symbols! { ptr_const_is_null, ptr_copy, ptr_copy_nonoverlapping, - ptr_drop_in_place, ptr_eq, ptr_from_ref, ptr_guaranteed_cmp, @@ -1622,7 +1599,6 @@ symbols! { structural_match, structural_peq, structural_teq, - sty, sub, sub_assign, sub_with_overflow, @@ -1744,7 +1720,6 @@ symbols! { unrestricted_attribute_tokens, unsafe_block_in_unsafe_fn, unsafe_cell, - unsafe_cell_from_mut, unsafe_cell_raw_get, unsafe_no_drop_flag, unsafe_pin_internals, @@ -1769,7 +1744,6 @@ symbols! { used_with_arg, using, usize, - v1, va_arg, va_copy, va_end, @@ -1801,7 +1775,6 @@ symbols! { wasm_import_module, wasm_target_feature, while_let, - width, windows, windows_subsystem, with_negative_coherence, From c910a49b05ed2edac0a989efa53e6468148bf0f7 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 29 Nov 2023 13:38:56 -0700 Subject: [PATCH 6/8] rustdoc: remove small from `small-section-header` There's no such thing as a big section header, so I don't know why the name was used. --- src/librustdoc/html/render/mod.rs | 2 +- src/librustdoc/html/render/print_item.rs | 14 +++++++------- src/librustdoc/html/static/css/rustdoc.css | 10 +++++----- src/librustdoc/html/templates/item_union.html | 4 ++-- src/librustdoc/html/templates/type_layout.html | 2 +- tests/rustdoc-gui/font-weight.goml | 2 +- tests/rustdoc-gui/headers-color.goml | 2 +- tests/rustdoc/async-fn-opaque-item.rs | 4 ++-- tests/rustdoc/compiler-derive-proc-macro.rs | 6 +++--- ...ine-private-with-intermediate-doc-hidden.rs | 4 ++-- .../issue-105735-overlapping-reexport-2.rs | 6 +++--- .../issue-105735-overlapping-reexport.rs | 6 +++--- .../issue-109258-missing-private-inlining.rs | 10 +++++----- .../issue-109449-doc-hidden-reexports.rs | 12 ++++++------ tests/rustdoc/issue-110422-inner-private.rs | 18 +++++++++--------- .../issue-60522-duplicated-glob-reexport.rs | 4 ++-- tests/rustdoc/nested-items-issue-111415.rs | 8 ++++---- .../pub-reexport-of-pub-reexport-46506.rs | 8 ++++---- tests/rustdoc/typedef-inner-variants.rs | 4 ++-- 19 files changed, 63 insertions(+), 63 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 348d546c2361e..51ec33bd832d3 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1145,7 +1145,7 @@ impl<'a> AssocItemLink<'a> { fn write_impl_section_heading(mut w: impl fmt::Write, title: &str, id: &str) { write!( w, - "

\ + "

\ {title}\ §\

" diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 2dac943f6951c..e4309c782f6a3 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -430,7 +430,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: last_section = Some(my_section); write!( w, - "

\ + "

\ {name}\

{ITEM_TABLE_OPEN}", id = cx.derive_id(my_section.id()), @@ -827,7 +827,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: fn write_small_section_header(w: &mut Buffer, id: &str, title: &str, extra_content: &str) { write!( w, - "

\ + "

\ {1}§\

{2}", id, title, extra_content @@ -1260,7 +1260,7 @@ fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &c if let Some(inner_type) = &t.inner_type { write!( w, - "

\ + "

\ Aliased Type§

" ); @@ -1685,7 +1685,7 @@ fn item_variants( let tcx = cx.tcx(); write!( w, - "

\ + "

\ Variants{}§\

\ {}\ @@ -1772,7 +1772,7 @@ fn item_variants( write!( w, "
\ - \ + \ §\ {f}: {t}\ ", @@ -1929,7 +1929,7 @@ fn item_fields( if fields.peek().is_some() { write!( w, - "

\ + "

\ {}{}§\

\ {}", @@ -1943,7 +1943,7 @@ fn item_fields( let id = cx.derive_id(format!("{typ}.{field_name}", typ = ItemType::StructField)); write!( w, - "\ + "\ §\ {field_name}: {ty}\ ", diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 9efdcd601170e..d8250c273b0b6 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -205,7 +205,7 @@ ul.all-items { #toggle-all-docs, a.anchor, -.small-section-header a, +.section-header a, #src-sidebar a, .rust a, .sidebar h2 a, @@ -742,13 +742,13 @@ nav.sub { margin: 0 0 15px 0; } -.small-section-header { +.section-header { /* fields use tags, but should get their own lines */ display: block; position: relative; } -.small-section-header:hover > .anchor, .impl:hover > .anchor, +.section-header:hover > .anchor, .impl:hover > .anchor, .trait-impl:hover > .anchor, .variant:hover > .anchor { display: initial; } @@ -761,11 +761,11 @@ nav.sub { .anchor.field { left: -5px; } -.small-section-header > .anchor { +.section-header > .anchor { left: -15px; padding-right: 8px; } -h2.small-section-header > .anchor { +h2.section-header > .anchor { padding-right: 6px; } diff --git a/src/librustdoc/html/templates/item_union.html b/src/librustdoc/html/templates/item_union.html index f6d2fa3489081..8db7986fa7506 100644 --- a/src/librustdoc/html/templates/item_union.html +++ b/src/librustdoc/html/templates/item_union.html @@ -4,13 +4,13 @@ {{ self.document() | safe }} {% if self.fields_iter().peek().is_some() %} -

{# #} +

{# #} Fields§ {# #}

{% for (field, ty) in self.fields_iter() %} {% let name = field.name.expect("union field name") %} {# #} + class="{{ ItemType::StructField +}} section-header"> {# #} § {# #} {{ name }}: {{+ self.print_ty(ty) | safe }} {# #} diff --git a/src/librustdoc/html/templates/type_layout.html b/src/librustdoc/html/templates/type_layout.html index c75fc34a9dfe7..e0516bb42fe40 100644 --- a/src/librustdoc/html/templates/type_layout.html +++ b/src/librustdoc/html/templates/type_layout.html @@ -1,4 +1,4 @@ -

{# #} +

{# #} Layout§ {# #}

{# #}
{# #} diff --git a/tests/rustdoc-gui/font-weight.goml b/tests/rustdoc-gui/font-weight.goml index 6fad128dab8c3..602b8d6f5b34c 100644 --- a/tests/rustdoc-gui/font-weight.goml +++ b/tests/rustdoc-gui/font-weight.goml @@ -2,7 +2,7 @@ go-to: "file://" + |DOC_PATH| + "/lib2/struct.Foo.html" assert-css: ("//*[@class='rust item-decl']//a[text()='Alias']", {"font-weight": "400"}) assert-css: ( - "//*[@class='structfield small-section-header']//a[text()='Alias']", + "//*[@class='structfield section-header']//a[text()='Alias']", {"font-weight": "400"}, ) assert-css: ("#method\.a_method > .code-header", {"font-weight": "600"}) diff --git a/tests/rustdoc-gui/headers-color.goml b/tests/rustdoc-gui/headers-color.goml index a7ac94c4943cc..19185818f407e 100644 --- a/tests/rustdoc-gui/headers-color.goml +++ b/tests/rustdoc-gui/headers-color.goml @@ -31,7 +31,7 @@ define-function: ( ALL, ) go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" - assert-css: (".small-section-header a", {"color": |color|}, ALL) + assert-css: (".section-header a", {"color": |color|}, ALL) go-to: "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html" // We select headings (h2, h3, h...). assert-css: (".docblock > :not(p) > a", {"color": |headings_color|}, ALL) diff --git a/tests/rustdoc/async-fn-opaque-item.rs b/tests/rustdoc/async-fn-opaque-item.rs index a73e84f3fdc4e..2c030824fe7ba 100644 --- a/tests/rustdoc/async-fn-opaque-item.rs +++ b/tests/rustdoc/async-fn-opaque-item.rs @@ -9,7 +9,7 @@ // Checking there is only a "Functions" header and no "Opaque types". // @has async_fn_opaque_item/index.html -// @count - '//*[@class="small-section-header"]' 1 -// @has - '//*[@class="small-section-header"]' 'Functions' +// @count - '//*[@class="section-header"]' 1 +// @has - '//*[@class="section-header"]' 'Functions' pub async fn test() {} diff --git a/tests/rustdoc/compiler-derive-proc-macro.rs b/tests/rustdoc/compiler-derive-proc-macro.rs index 489ec924c1fcf..1c3867ced9b9a 100644 --- a/tests/rustdoc/compiler-derive-proc-macro.rs +++ b/tests/rustdoc/compiler-derive-proc-macro.rs @@ -5,9 +5,9 @@ // @has 'foo/index.html' // Each compiler builtin proc-macro has a trait equivalent so we should have // a trait section as well. -// @count - '//*[@id="main-content"]//*[@class="small-section-header"]' 2 -// @has - '//*[@id="main-content"]//*[@class="small-section-header"]' 'Traits' -// @has - '//*[@id="main-content"]//*[@class="small-section-header"]' 'Derive Macros' +// @count - '//*[@id="main-content"]//*[@class="section-header"]' 2 +// @has - '//*[@id="main-content"]//*[@class="section-header"]' 'Traits' +// @has - '//*[@id="main-content"]//*[@class="section-header"]' 'Derive Macros' // Now checking the correct file is generated as well. // @has 'foo/derive.Clone.html' diff --git a/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs b/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs index e382940a47eb8..ae830c03ea3c5 100644 --- a/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs +++ b/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs @@ -6,8 +6,8 @@ // @has 'foo/index.html' // There should only be one struct displayed. -// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1 -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs' +// @count - '//*[@id="main-content"]/*[@class="section-header"]' 1 +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Structs' // @has - '//*[@id="main-content"]//a[@href="struct.Reexport.html"]' 'Reexport' // @has - '//*[@id="main-content"]//*[@class="desc docblock-short"]' 'Visible. Original.' diff --git a/tests/rustdoc/issue-105735-overlapping-reexport-2.rs b/tests/rustdoc/issue-105735-overlapping-reexport-2.rs index 5d2c553d8a51e..2905e7d44bcd3 100644 --- a/tests/rustdoc/issue-105735-overlapping-reexport-2.rs +++ b/tests/rustdoc/issue-105735-overlapping-reexport-2.rs @@ -7,9 +7,9 @@ // @has - '//*[@class="item-name"]/a[@class="type"]' 'AtomicU8' // @has - '//*[@class="item-name"]/a[@class="constant"]' 'AtomicU8' // We also ensure we don't have another item displayed. -// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 2 -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Type Aliases' -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Constants' +// @count - '//*[@id="main-content"]/*[@class="section-header"]' 2 +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Type Aliases' +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Constants' mod other { pub type AtomicU8 = (); diff --git a/tests/rustdoc/issue-105735-overlapping-reexport.rs b/tests/rustdoc/issue-105735-overlapping-reexport.rs index 50f2450b90a0b..7fa7df7701a24 100644 --- a/tests/rustdoc/issue-105735-overlapping-reexport.rs +++ b/tests/rustdoc/issue-105735-overlapping-reexport.rs @@ -7,9 +7,9 @@ // @has - '//*[@class="item-name"]/a[@class="struct"]' 'AtomicU8' // @has - '//*[@class="item-name"]/a[@class="constant"]' 'AtomicU8' // We also ensure we don't have another item displayed. -// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 2 -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs' -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Constants' +// @count - '//*[@id="main-content"]/*[@class="section-header"]' 2 +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Structs' +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Constants' mod thing { pub use core::sync::atomic::AtomicU8; diff --git a/tests/rustdoc/issue-109258-missing-private-inlining.rs b/tests/rustdoc/issue-109258-missing-private-inlining.rs index 96f606368b27d..12c5556f13266 100644 --- a/tests/rustdoc/issue-109258-missing-private-inlining.rs +++ b/tests/rustdoc/issue-109258-missing-private-inlining.rs @@ -4,9 +4,9 @@ // @has 'foo/index.html' // We should only have a "Re-exports" and a "Modules" headers. -// @count - '//*[@id="main-content"]/h2[@class="small-section-header"]' 2 -// @has - '//*[@id="main-content"]/h2[@class="small-section-header"]' 'Re-exports' -// @has - '//*[@id="main-content"]/h2[@class="small-section-header"]' 'Modules' +// @count - '//*[@id="main-content"]/h2[@class="section-header"]' 2 +// @has - '//*[@id="main-content"]/h2[@class="section-header"]' 'Re-exports' +// @has - '//*[@id="main-content"]/h2[@class="section-header"]' 'Modules' // @has - '//*[@id="reexport.Foo"]' 'pub use crate::issue_109258::Foo;' // @has - '//*[@id="reexport.Foo"]//a[@href="issue_109258/struct.Foo.html"]' 'Foo' @@ -15,8 +15,8 @@ pub use crate::issue_109258::Foo; // @has 'foo/issue_109258/index.html' // We should only have a "Structs" header. -// @count - '//*[@id="main-content"]/h2[@class="small-section-header"]' 1 -// @has - '//*[@id="main-content"]/h2[@class="small-section-header"]' 'Structs' +// @count - '//*[@id="main-content"]/h2[@class="section-header"]' 1 +// @has - '//*[@id="main-content"]/h2[@class="section-header"]' 'Structs' // @has - '//*[@id="main-content"]//a[@href="struct.Foo.html"]' 'Foo' // @has 'foo/issue_109258/struct.Foo.html' pub mod issue_109258 { diff --git a/tests/rustdoc/issue-109449-doc-hidden-reexports.rs b/tests/rustdoc/issue-109449-doc-hidden-reexports.rs index 3b836a219312c..9fb2f7c7c05b0 100644 --- a/tests/rustdoc/issue-109449-doc-hidden-reexports.rs +++ b/tests/rustdoc/issue-109449-doc-hidden-reexports.rs @@ -66,8 +66,8 @@ pub mod single_reexport_inherit_hidden { pub mod single_reexport_no_inline { // First we ensure that we only have re-exports and no inlined items. // @has 'foo/single_reexport_no_inline/index.html' - // @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1 - // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Re-exports' + // @count - '//*[@id="main-content"]/*[@class="section-header"]' 1 + // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Re-exports' // Now we check that we don't have links to the items, just `pub use`. // @has - '//*[@id="main-content"]//*' 'pub use crate::private_module::Public as XFoo;' @@ -101,10 +101,10 @@ pub mod glob_reexport { // With glob re-exports, we don't inline `#[doc(hidden)]` items so only `module` items // should be inlined. // @has 'foo/glob_reexport/index.html' - // @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 3 - // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Re-exports' - // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs' - // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Type Aliases' + // @count - '//*[@id="main-content"]/*[@class="section-header"]' 3 + // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Re-exports' + // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Structs' + // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Type Aliases' // Now we check we have 1 re-export and 2 inlined items. // If not item from a glob re-export is visible, we don't show the re-export. diff --git a/tests/rustdoc/issue-110422-inner-private.rs b/tests/rustdoc/issue-110422-inner-private.rs index ee8ed5cc6e17f..43dc929ab074c 100644 --- a/tests/rustdoc/issue-110422-inner-private.rs +++ b/tests/rustdoc/issue-110422-inner-private.rs @@ -8,11 +8,11 @@ // @has 'foo/index.html' // Checking there is no "trait" entry. -// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 4 -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs' -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Constants' -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Functions' -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Macros' +// @count - '//*[@id="main-content"]/*[@class="section-header"]' 4 +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Structs' +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Constants' +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Functions' +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Macros' // @has - '//a[@href="fn.foo.html"]' 'foo' fn foo() { @@ -50,11 +50,11 @@ const BAR: i32 = { // @has 'foo/struct.Bar.html' // @has - '//*[@id="method.foo"]/*[@class="code-header"]' 'pub(crate) fn foo()' - // @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 3 + // @count - '//*[@id="main-content"]/*[@class="section-header"]' 3 // We now check that the `Foo` trait is not documented nor visible on `Bar` page. - // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Implementations' - // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Auto Trait Implementations' - // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Blanket Implementations' + // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Implementations' + // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Auto Trait Implementations' + // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Blanket Implementations' // @!has - '//*[@href="trait.Foo.html#method.babar"]/*[@class="code-header"]' 'fn babar()' impl Bar { fn foo() {} diff --git a/tests/rustdoc/issue-60522-duplicated-glob-reexport.rs b/tests/rustdoc/issue-60522-duplicated-glob-reexport.rs index 1429b5e474100..50def2c3cd983 100644 --- a/tests/rustdoc/issue-60522-duplicated-glob-reexport.rs +++ b/tests/rustdoc/issue-60522-duplicated-glob-reexport.rs @@ -5,8 +5,8 @@ #![crate_name = "foo"] // @has 'foo/index.html' -// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1 -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Modules' +// @count - '//*[@id="main-content"]/*[@class="section-header"]' 1 +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Modules' // @count - '//*[@id="main-content"]/*[@class="item-table"]//*[@class="mod"]' 2 // @has - '//*[@id="main-content"]//*[@class="mod"]' 'banana' // @has - '//*[@id="main-content"]//*[@href="banana/index.html"]' 'banana' diff --git a/tests/rustdoc/nested-items-issue-111415.rs b/tests/rustdoc/nested-items-issue-111415.rs index 9b7688c332c44..c117569d9b468 100644 --- a/tests/rustdoc/nested-items-issue-111415.rs +++ b/tests/rustdoc/nested-items-issue-111415.rs @@ -5,10 +5,10 @@ // @has 'foo/index.html' // Checking there are only three sections. -// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 3 -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs' -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Functions' -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Traits' +// @count - '//*[@id="main-content"]/*[@class="section-header"]' 3 +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Structs' +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Functions' +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Traits' // Checking that there are only three items. // @count - '//*[@id="main-content"]//*[@class="item-name"]' 3 // @has - '//*[@id="main-content"]//a[@href="struct.Bar.html"]' 'Bar' diff --git a/tests/rustdoc/pub-reexport-of-pub-reexport-46506.rs b/tests/rustdoc/pub-reexport-of-pub-reexport-46506.rs index d8953eaf5970a..ae0aead244b31 100644 --- a/tests/rustdoc/pub-reexport-of-pub-reexport-46506.rs +++ b/tests/rustdoc/pub-reexport-of-pub-reexport-46506.rs @@ -4,8 +4,8 @@ #![crate_name = "foo"] // @has 'foo/associations/index.html' -// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1 -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Traits' +// @count - '//*[@id="main-content"]/*[@class="section-header"]' 1 +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Traits' // @has - '//*[@id="main-content"]//a[@href="trait.GroupedBy.html"]' 'GroupedBy' // @has 'foo/associations/trait.GroupedBy.html' pub mod associations { @@ -16,8 +16,8 @@ pub mod associations { } // @has 'foo/prelude/index.html' -// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1 -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Re-exports' +// @count - '//*[@id="main-content"]/*[@class="section-header"]' 1 +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Re-exports' // @has - '//*[@id="main-content"]//*[@id="reexport.GroupedBy"]' 'pub use associations::GroupedBy;' pub mod prelude { pub use associations::GroupedBy; diff --git a/tests/rustdoc/typedef-inner-variants.rs b/tests/rustdoc/typedef-inner-variants.rs index b734714fd6432..4d0ff85551ce9 100644 --- a/tests/rustdoc/typedef-inner-variants.rs +++ b/tests/rustdoc/typedef-inner-variants.rs @@ -65,7 +65,7 @@ pub union OneOr { // @count - '//*[@id="aliased-type"]' 1 // @count - '//*[@id="variants"]' 0 // @count - '//*[@id="fields"]' 1 -// @count - '//*[@class="structfield small-section-header"]' 2 +// @count - '//*[@class="structfield section-header"]' 2 // @matches - '//pre[@class="rust item-decl"]//code' "union OneOrF64" pub type OneOrF64 = OneOr; @@ -81,7 +81,7 @@ pub struct One { // @count - '//*[@id="aliased-type"]' 1 // @count - '//*[@id="variants"]' 0 // @count - '//*[@id="fields"]' 1 -// @count - '//*[@class="structfield small-section-header"]' 1 +// @count - '//*[@class="structfield section-header"]' 1 // @matches - '//pre[@class="rust item-decl"]//code' "struct OneU64" // @matches - '//pre[@class="rust item-decl"]//code' "pub val" pub type OneU64 = One; From 3323e4dc04e57cc64ac77dbff2f6bf50ac6832f0 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Wed, 29 Nov 2023 17:36:45 -0600 Subject: [PATCH 7/8] Dispose llvm::TargetMachines prior to llvm::Context being disposed If the TargetMachine is disposed after the Context is disposed, it can lead to use after frees in some cases. I've observed this happening occasionally on code compiled for aarch64-pc-windows-msvc using `-Zstack-protector=strong` but other users have reported AVs from host aarch64-pc-windows-msvc compilers as well. --- compiler/rustc_codegen_llvm/src/back/lto.rs | 3 ++- compiler/rustc_codegen_llvm/src/lib.rs | 21 ++++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 8655aeec13dd6..db297425b03bf 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -25,6 +25,7 @@ use std::ffi::{CStr, CString}; use std::fs::File; use std::io; use std::iter; +use std::mem::ManuallyDrop; use std::path::Path; use std::slice; use std::sync::Arc; @@ -734,7 +735,7 @@ pub unsafe fn optimize_thin_module( let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names); let llmod_raw = parse_module(llcx, module_name, thin_module.data(), &diag_handler)? as *const _; let mut module = ModuleCodegen { - module_llvm: ModuleLlvm { llmod_raw, llcx, tm }, + module_llvm: ModuleLlvm { llmod_raw, llcx, tm: ManuallyDrop::new(tm) }, name: thin_module.name().to_string(), kind: ModuleKind::Regular, }; diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index f8a0423e9b104..09c01eeb69cff 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -52,6 +52,7 @@ use rustc_span::symbol::Symbol; use std::any::Any; use std::ffi::CStr; use std::io::Write; +use std::mem::ManuallyDrop; mod back { pub mod archive; @@ -407,8 +408,9 @@ pub struct ModuleLlvm { llcx: &'static mut llvm::Context, llmod_raw: *const llvm::Module, - // independent from llcx and llmod_raw, resources get disposed by drop impl - tm: OwnedTargetMachine, + // This field is `ManuallyDrop` because it is important that the `TargetMachine` + // is disposed prior to the `Context` being disposed otherwise UAFs can occur. + tm: ManuallyDrop, } unsafe impl Send for ModuleLlvm {} @@ -419,7 +421,11 @@ impl ModuleLlvm { unsafe { let llcx = llvm::LLVMRustContextCreate(tcx.sess.fewer_names()); let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _; - ModuleLlvm { llmod_raw, llcx, tm: create_target_machine(tcx, mod_name) } + ModuleLlvm { + llmod_raw, + llcx, + tm: ManuallyDrop::new(create_target_machine(tcx, mod_name)), + } } } @@ -427,7 +433,11 @@ impl ModuleLlvm { unsafe { let llcx = llvm::LLVMRustContextCreate(tcx.sess.fewer_names()); let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _; - ModuleLlvm { llmod_raw, llcx, tm: create_informational_target_machine(tcx.sess) } + ModuleLlvm { + llmod_raw, + llcx, + tm: ManuallyDrop::new(create_informational_target_machine(tcx.sess)), + } } } @@ -448,7 +458,7 @@ impl ModuleLlvm { } }; - Ok(ModuleLlvm { llmod_raw, llcx, tm }) + Ok(ModuleLlvm { llmod_raw, llcx, tm: ManuallyDrop::new(tm) }) } } @@ -460,6 +470,7 @@ impl ModuleLlvm { impl Drop for ModuleLlvm { fn drop(&mut self) { unsafe { + drop(ManuallyDrop::take(&mut self.tm)); llvm::LLVMContextDispose(&mut *(self.llcx as *mut _)); } } From 10110787154154cddfaaacdeebd7a4406223a25b Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Wed, 29 Nov 2023 18:00:41 -0600 Subject: [PATCH 8/8] Update compiler/rustc_codegen_llvm/src/lib.rs Co-authored-by: Josh Stone --- compiler/rustc_codegen_llvm/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 09c01eeb69cff..915cf31de08fb 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -470,7 +470,7 @@ impl ModuleLlvm { impl Drop for ModuleLlvm { fn drop(&mut self) { unsafe { - drop(ManuallyDrop::take(&mut self.tm)); + ManuallyDrop::drop(&mut self.tm); llvm::LLVMContextDispose(&mut *(self.llcx as *mut _)); } }