From adf0dff10c5cfb213eacb026566952874d69cb16 Mon Sep 17 00:00:00 2001 From: mu001999 Date: Wed, 24 Jul 2024 00:18:36 +0800 Subject: [PATCH 01/12] Not lint pub structs without pub constructors if containing fields of unit, never type, PhantomData and positional ZST --- compiler/rustc_passes/src/dead.rs | 36 ++++++++++--------- ...lone-debug-dead-code-in-the-same-struct.rs | 4 +-- ...-debug-dead-code-in-the-same-struct.stderr | 16 +++++++-- .../dead-code/unconstructible-pub-struct.rs | 35 ++++++++++++++++++ .../unconstructible-pub-struct.stderr | 14 ++++++++ 5 files changed, 83 insertions(+), 22 deletions(-) create mode 100644 tests/ui/lint/dead-code/unconstructible-pub-struct.rs create mode 100644 tests/ui/lint/dead-code/unconstructible-pub-struct.stderr diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 239bc8e7accfc..bbe4493e874c0 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -72,24 +72,26 @@ fn adt_of<'tcx>(ty: &hir::Ty<'tcx>) -> Option<(LocalDefId, DefKind)> { } fn struct_all_fields_are_public(tcx: TyCtxt<'_>, id: LocalDefId) -> bool { - // treat PhantomData and positional ZST as public, - // we don't want to lint types which only have them, - // cause it's a common way to use such types to check things like well-formedness - tcx.adt_def(id).all_fields().all(|field| { + let adt_def = tcx.adt_def(id); + + // skip types contain fields of unit and never type, + // it's usually intentional to make the type not constructible + let not_require_constructor = adt_def.all_fields().any(|field| { let field_type = tcx.type_of(field.did).instantiate_identity(); - if field_type.is_phantom_data() { - return true; - } - let is_positional = field.name.as_str().starts_with(|c: char| c.is_ascii_digit()); - if is_positional - && tcx - .layout_of(tcx.param_env(field.did).and(field_type)) - .map_or(true, |layout| layout.is_zst()) - { - return true; - } - field.vis.is_public() - }) + field_type.is_unit() || field_type.is_never() + }); + + not_require_constructor + || adt_def.all_fields().all(|field| { + let field_type = tcx.type_of(field.did).instantiate_identity(); + // skip fields of PhantomData, + // cause it's a common way to check things like well-formedness + if field_type.is_phantom_data() { + return true; + } + + field.vis.is_public() + }) } /// check struct and its fields are public or not, diff --git a/tests/ui/derives/clone-debug-dead-code-in-the-same-struct.rs b/tests/ui/derives/clone-debug-dead-code-in-the-same-struct.rs index 885dacc727af6..6ab1fb7b039bd 100644 --- a/tests/ui/derives/clone-debug-dead-code-in-the-same-struct.rs +++ b/tests/ui/derives/clone-debug-dead-code-in-the-same-struct.rs @@ -1,9 +1,9 @@ #![forbid(dead_code)] #[derive(Debug)] -pub struct Whatever { //~ ERROR struct `Whatever` is never constructed +pub struct Whatever { pub field0: (), - field1: (), + field1: (), //~ ERROR fields `field1`, `field2`, `field3`, and `field4` are never read field2: (), field3: (), field4: (), diff --git a/tests/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr b/tests/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr index e10d28ad03a4e..e9b757b6bae72 100644 --- a/tests/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr +++ b/tests/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr @@ -1,9 +1,19 @@ -error: struct `Whatever` is never constructed - --> $DIR/clone-debug-dead-code-in-the-same-struct.rs:4:12 +error: fields `field1`, `field2`, `field3`, and `field4` are never read + --> $DIR/clone-debug-dead-code-in-the-same-struct.rs:6:5 | LL | pub struct Whatever { - | ^^^^^^^^ + | -------- fields in this struct +LL | pub field0: (), +LL | field1: (), + | ^^^^^^ +LL | field2: (), + | ^^^^^^ +LL | field3: (), + | ^^^^^^ +LL | field4: (), + | ^^^^^^ | + = note: `Whatever` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis note: the lint level is defined here --> $DIR/clone-debug-dead-code-in-the-same-struct.rs:1:11 | diff --git a/tests/ui/lint/dead-code/unconstructible-pub-struct.rs b/tests/ui/lint/dead-code/unconstructible-pub-struct.rs new file mode 100644 index 0000000000000..2202cbb673098 --- /dev/null +++ b/tests/ui/lint/dead-code/unconstructible-pub-struct.rs @@ -0,0 +1,35 @@ +#![feature(never_type)] +#![deny(dead_code)] + +pub struct T1(!); +pub struct T2(()); +pub struct T3(std::marker::PhantomData); + +pub struct T4 { + _x: !, +} + +pub struct T5 { + _x: !, + _y: X, +} + +pub struct T6 { + _x: (), +} + +pub struct T7 { + _x: (), + _y: X, +} + +pub struct T8 { + _x: std::marker::PhantomData, +} + +pub struct T9 { //~ ERROR struct `T9` is never constructed + _x: std::marker::PhantomData, + _y: i32, +} + +fn main() {} diff --git a/tests/ui/lint/dead-code/unconstructible-pub-struct.stderr b/tests/ui/lint/dead-code/unconstructible-pub-struct.stderr new file mode 100644 index 0000000000000..a3dde042bbe15 --- /dev/null +++ b/tests/ui/lint/dead-code/unconstructible-pub-struct.stderr @@ -0,0 +1,14 @@ +error: struct `T9` is never constructed + --> $DIR/unconstructible-pub-struct.rs:30:12 + | +LL | pub struct T9 { + | ^^ + | +note: the lint level is defined here + --> $DIR/unconstructible-pub-struct.rs:2:9 + | +LL | #![deny(dead_code)] + | ^^^^^^^^^ + +error: aborting due to 1 previous error + From 06d64ea4c413c94e158a167020b4a5fb57958710 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Mon, 29 Jul 2024 16:31:21 +0300 Subject: [PATCH 02/12] simplify the use of `CiEnv` Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/test.rs | 2 +- src/bootstrap/src/core/builder.rs | 2 +- src/bootstrap/src/core/config/config.rs | 2 +- src/bootstrap/src/lib.rs | 4 +--- src/bootstrap/src/utils/exec.rs | 4 ++-- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 79b7dd78810d2..aa0c76ab15753 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2087,7 +2087,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the let git_config = builder.config.git_config(); cmd.arg("--git-repository").arg(git_config.git_repository); cmd.arg("--nightly-branch").arg(git_config.nightly_branch); - cmd.force_coloring_in_ci(builder.ci_env); + cmd.force_coloring_in_ci(); #[cfg(feature = "build-metrics")] builder.metrics.begin_test_suite( diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 9eb4ca033a80f..84c23c059e97e 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -2157,7 +2157,7 @@ impl<'a> Builder<'a> { // Try to use a sysroot-relative bindir, in case it was configured absolutely. cargo.env("RUSTC_INSTALL_BINDIR", self.config.bindir_relative()); - cargo.force_coloring_in_ci(self.ci_env); + cargo.force_coloring_in_ci(); // When we build Rust dylibs they're all intended for intermediate // usage, so make sure we pass the -Cprefer-dynamic flag instead of diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index b0a967d756b64..1343e257efe08 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -2092,7 +2092,7 @@ impl Config { // CI should always run stage 2 builds, unless it specifically states otherwise #[cfg(not(test))] - if flags.stage.is_none() && crate::CiEnv::current() != crate::CiEnv::None { + if flags.stage.is_none() && build_helper::ci::CiEnv::is_ci() { match config.cmd { Subcommand::Test { .. } | Subcommand::Miri { .. } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index d2f5d1667189c..453fb39327d63 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -26,7 +26,7 @@ use std::sync::OnceLock; use std::time::SystemTime; use std::{env, io, str}; -use build_helper::ci::{gha, CiEnv}; +use build_helper::ci::gha; use build_helper::exit; use sha2::digest::Digest; use termcolor::{ColorChoice, StandardStream, WriteColor}; @@ -168,7 +168,6 @@ pub struct Build { crates: HashMap, crate_paths: HashMap, is_sudo: bool, - ci_env: CiEnv, delayed_failures: RefCell>, prerelease_version: Cell>, @@ -400,7 +399,6 @@ impl Build { crates: HashMap::new(), crate_paths: HashMap::new(), is_sudo, - ci_env: CiEnv::current(), delayed_failures: RefCell::new(Vec::new()), prerelease_version: Cell::new(None), diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index e1387bbbd35d7..9f0d0b7e9691f 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -175,8 +175,8 @@ impl BootstrapCommand { } /// If in a CI environment, forces the command to run with colors. - pub fn force_coloring_in_ci(&mut self, ci_env: CiEnv) { - if ci_env != CiEnv::None { + pub fn force_coloring_in_ci(&mut self) { + if CiEnv::is_ci() { // Due to use of stamp/docker, the output stream of bootstrap is not // a TTY in CI, so coloring is by-default turned off. // The explicit `TERM=xterm` environment is needed for From f3661dce09bc715a46c01f7ea57694e06b587f29 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 10 Jun 2024 15:01:31 -0700 Subject: [PATCH 03/12] rustdoc: word wrap CamelCase in the item list table This is an alternative to ee6459d6521cf6a4c2e08b6e13ce3c6ce5d55ed0. That is, it fixes the issue that affects the very long type names in https://docs.rs/async-stripe/0.31.0/stripe/index.html#structs. This is, necessarily, a pile of nasty heuristics. We need to balance a few issues: - Sometimes, there's no real word break. For example, `BTreeMap` should be `BTreeMap`, not `BTreeMap`. - Sometimes, there's a legit word break, but the name is tiny and the HTML overhead isn't worth it. For example, if we're typesetting `TyCtx`, writing `TyCtx` would have an HTML overhead of 50%. Line breaking inside it makes no sense. --- Cargo.lock | 1 + src/librustdoc/Cargo.toml | 1 + src/librustdoc/html/escape.rs | 44 ++++++++++++++ src/librustdoc/html/escape/tests.rs | 57 +++++++++++++++++++ src/librustdoc/html/format.rs | 3 +- src/librustdoc/html/render/print_item.rs | 6 +- ...long_typename.extremely_long_typename.html | 1 + tests/rustdoc/extremely_long_typename.rs | 7 +++ .../item-desc-list-at-start.item-table.html | 2 +- 9 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 src/librustdoc/html/escape/tests.rs create mode 100644 tests/rustdoc/extremely_long_typename.extremely_long_typename.html create mode 100644 tests/rustdoc/extremely_long_typename.rs diff --git a/Cargo.lock b/Cargo.lock index 281599a21fc14..1a7d7e3f5d7d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4826,6 +4826,7 @@ dependencies = [ "tracing", "tracing-subscriber", "tracing-tree", + "unicode-segmentation", ] [[package]] diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index fe531f0ff5985..dfd7414652fa7 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -23,6 +23,7 @@ tempfile = "3" tracing = "0.1" tracing-tree = "0.3.0" threadpool = "1.8.1" +unicode-segmentation = "1.9" [dependencies.tracing-subscriber] version = "0.3.3" diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs index ea4b573aeb955..9441491316345 100644 --- a/src/librustdoc/html/escape.rs +++ b/src/librustdoc/html/escape.rs @@ -5,6 +5,8 @@ use std::fmt; +use unicode_segmentation::UnicodeSegmentation; + /// Wrapper struct which will emit the HTML-escaped version of the contained /// string when passed to a format string. pub(crate) struct Escape<'a>(pub &'a str); @@ -74,3 +76,45 @@ impl<'a> fmt::Display for EscapeBodyText<'a> { Ok(()) } } + +/// Wrapper struct which will emit the HTML-escaped version of the contained +/// string when passed to a format string. This function also word-breaks +/// CamelCase and snake_case word names. +/// +/// This is only safe to use for text nodes. If you need your output to be +/// safely contained in an attribute, use [`Escape`]. If you don't know the +/// difference, use [`Escape`]. +pub(crate) struct EscapeBodyTextWithWbr<'a>(pub &'a str); + +impl<'a> fmt::Display for EscapeBodyTextWithWbr<'a> { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + let EscapeBodyTextWithWbr(text) = *self; + if text.len() < 8 { + return EscapeBodyText(text).fmt(fmt); + } + let mut last = 0; + let mut it = text.grapheme_indices(true).peekable(); + let _ = it.next(); // don't insert wbr before first char + while let Some((i, s)) = it.next() { + let pk = it.peek(); + let is_uppercase = || s.chars().any(|c| c.is_uppercase()); + let next_is_uppercase = + || pk.map_or(true, |(_, t)| t.chars().any(|c| c.is_uppercase())); + let next_is_underscore = || pk.map_or(true, |(_, t)| t.contains('_')); + if (i - last > 3 && is_uppercase() && !next_is_uppercase()) + || (s.contains('_') && !next_is_underscore()) + { + EscapeBodyText(&text[last..i]).fmt(fmt)?; + fmt.write_str("")?; + last = i; + } + } + if last < text.len() { + EscapeBodyText(&text[last..]).fmt(fmt)?; + } + Ok(()) + } +} + +#[cfg(test)] +mod tests; diff --git a/src/librustdoc/html/escape/tests.rs b/src/librustdoc/html/escape/tests.rs new file mode 100644 index 0000000000000..f99a2a693a628 --- /dev/null +++ b/src/librustdoc/html/escape/tests.rs @@ -0,0 +1,57 @@ +// basic examples +#[test] +fn escape_body_text_with_wbr() { + use super::EscapeBodyTextWithWbr as E; + // extreme corner cases + assert_eq!(&E("").to_string(), ""); + assert_eq!(&E("a").to_string(), "a"); + assert_eq!(&E("A").to_string(), "A"); + // real(istic) examples + assert_eq!(&E("FirstSecond").to_string(), "FirstSecond"); + assert_eq!(&E("First_Second").to_string(), "First_Second"); + assert_eq!(&E("First_Second").to_string(), "First<T>_Second"); + assert_eq!(&E("first_second").to_string(), "first_second"); + assert_eq!(&E("MY_CONSTANT").to_string(), "MY_CONSTANT"); + assert_eq!(&E("___________").to_string(), "___________"); + // a string won't get wrapped if it's less than 8 bytes + assert_eq!(&E("HashSet").to_string(), "HashSet"); + // an individual word won't get wrapped if it's less than 4 bytes + assert_eq!(&E("VecDequeue").to_string(), "VecDequeue"); + assert_eq!(&E("VecDequeueSet").to_string(), "VecDequeueSet"); + // how to handle acronyms + assert_eq!(&E("BTreeMap").to_string(), "BTreeMap"); + assert_eq!(&E("HTTPSProxy").to_string(), "HTTPSProxy"); + // more corners + assert_eq!(&E("ṼẽçÑñéå").to_string(), "ṼẽçÑñéå"); + assert_eq!(&E("V\u{0300}e\u{0300}c\u{0300}D\u{0300}e\u{0300}q\u{0300}u\u{0300}e\u{0300}u\u{0300}e\u{0300}").to_string(), "V\u{0300}e\u{0300}c\u{0300}D\u{0300}e\u{0300}q\u{0300}u\u{0300}e\u{0300}u\u{0300}e\u{0300}"); + assert_eq!(&E("LPFNACCESSIBLEOBJECTFROMWINDOW").to_string(), "LPFNACCESSIBLEOBJECTFROMWINDOW"); +} +// property test +#[test] +fn escape_body_text_with_wbr_makes_sense() { + use itertools::Itertools as _; + + use super::EscapeBodyTextWithWbr as E; + const C: [u8; 3] = [b'a', b'A', b'_']; + for chars in [ + C.into_iter(), + C.into_iter(), + C.into_iter(), + C.into_iter(), + C.into_iter(), + C.into_iter(), + C.into_iter(), + C.into_iter(), + ] + .into_iter() + .multi_cartesian_product() + { + let s = String::from_utf8(chars).unwrap(); + assert_eq!(s.len(), 8); + let esc = E(&s).to_string(); + assert!(!esc.contains("")); + assert!(!esc.ends_with("")); + assert!(!esc.starts_with("")); + assert_eq!(&esc.replace("", ""), &s); + } +} diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index d6aed75103dc4..bb5ac303ffd63 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -32,7 +32,7 @@ use crate::clean::utils::find_nearest_parent_module; use crate::clean::{self, ExternalCrate, PrimitiveType}; use crate::formats::cache::Cache; use crate::formats::item_type::ItemType; -use crate::html::escape::Escape; +use crate::html::escape::{Escape, EscapeBodyText}; use crate::html::render::Context; use crate::passes::collect_intra_doc_links::UrlFragment; @@ -988,6 +988,7 @@ pub(crate) fn anchor<'a, 'cx: 'a>( f, r#"{text}"#, path = join_with_double_colon(&fqp), + text = EscapeBodyText(text.as_str()), ) } else { f.write_str(text.as_str()) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 24476e80778e1..3f01c082ba914 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -29,7 +29,7 @@ use crate::clean; use crate::config::ModuleSorting; use crate::formats::item_type::ItemType; use crate::formats::Impl; -use crate::html::escape::Escape; +use crate::html::escape::{Escape, EscapeBodyTextWithWbr}; use crate::html::format::{ display_fn, join_with_double_colon, print_abi_with_space, print_constness_with_space, print_where_clause, visibility_print_with_space, Buffer, Ending, PrintWithSpace, @@ -423,7 +423,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: "
{}extern crate {} as {};", visibility_print_with_space(myitem, cx), anchor(myitem.item_id.expect_def_id(), src, cx), - myitem.name.unwrap(), + EscapeBodyTextWithWbr(myitem.name.unwrap().as_str()), ), None => write!( w, @@ -520,7 +520,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: {stab_tags}\
\ {docs_before}{docs}{docs_after}", - name = myitem.name.unwrap(), + name = EscapeBodyTextWithWbr(myitem.name.unwrap().as_str()), visibility_and_hidden = visibility_and_hidden, stab_tags = extra_info_tags(myitem, item, tcx), class = myitem.type_(), diff --git a/tests/rustdoc/extremely_long_typename.extremely_long_typename.html b/tests/rustdoc/extremely_long_typename.extremely_long_typename.html new file mode 100644 index 0000000000000..b20e59866dac6 --- /dev/null +++ b/tests/rustdoc/extremely_long_typename.extremely_long_typename.html @@ -0,0 +1 @@ +
  • \ No newline at end of file diff --git a/tests/rustdoc/extremely_long_typename.rs b/tests/rustdoc/extremely_long_typename.rs new file mode 100644 index 0000000000000..212afe2d11033 --- /dev/null +++ b/tests/rustdoc/extremely_long_typename.rs @@ -0,0 +1,7 @@ +// ignore-tidy-linelength +// Make sure that, if an extremely long type name is named, +// the item table has it line wrapped. +// There should be some reasonably-placed `` tags in the snapshot file. + +// @snapshot extremely_long_typename "extremely_long_typename/index.html" '//ul[@class="item-table"]/li' +pub struct CreateSubscriptionPaymentSettingsPaymentMethodOptionsCustomerBalanceBankTransferEuBankTransfer; diff --git a/tests/rustdoc/item-desc-list-at-start.item-table.html b/tests/rustdoc/item-desc-list-at-start.item-table.html index 72bde573cead3..ab8b1508b5519 100644 --- a/tests/rustdoc/item-desc-list-at-start.item-table.html +++ b/tests/rustdoc/item-desc-list-at-start.item-table.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From 583bf1e5bf8ee78c60f5db5b3bb85f032545239c Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 10 Jun 2024 16:28:51 -0700 Subject: [PATCH 04/12] Fix tidy call in runtest with custom HTML element --- src/tools/compiletest/src/runtest.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index f6e8fdd624434..1f15605d8beed 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2731,6 +2731,7 @@ impl<'test> TestCx<'test> { #[rustfmt::skip] let tidy_args = [ + "--new-blocklevel-tags", "rustdoc-search", "--indent", "yes", "--indent-spaces", "2", "--wrap", "0", From 0d0e18e7f6e5f3278d897123e78271cce95de863 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 6 Jul 2024 17:12:53 -0700 Subject: [PATCH 05/12] rustdoc: use ``-tolerant function to check text contents --- .../rustdoc-gui/duplicate-macro-reexport.goml | 4 ++-- tests/rustdoc-gui/font-weight.goml | 4 ++-- tests/rustdoc-gui/item-info.goml | 4 ++-- tests/rustdoc-gui/label-next-to-symbol.goml | 18 +++++++++--------- tests/rustdoc-gui/notable-trait.goml | 8 ++++---- tests/rustdoc-gui/search-result-color.goml | 12 ++++++------ tests/rustdoc-gui/sidebar-macro-reexport.goml | 2 +- tests/rustdoc-gui/sidebar-mobile.goml | 7 +++++-- tests/rustdoc-gui/sidebar-source-code.goml | 8 ++++---- tests/rustdoc-gui/source-anchor-scroll.goml | 2 +- 10 files changed, 36 insertions(+), 33 deletions(-) diff --git a/tests/rustdoc-gui/duplicate-macro-reexport.goml b/tests/rustdoc-gui/duplicate-macro-reexport.goml index 7d01c88f31ba5..a838d99c4bffc 100644 --- a/tests/rustdoc-gui/duplicate-macro-reexport.goml +++ b/tests/rustdoc-gui/duplicate-macro-reexport.goml @@ -4,11 +4,11 @@ go-to: "file://" + |DOC_PATH| + "/test_docs/macro.a.html" wait-for: ".sidebar-elems .macro" // Check there is only one macro named "a" listed in the sidebar. assert-count: ( - "//*[@class='sidebar-elems']//*[@class='block macro']//li/a[text()='a']", + "//*[@class='sidebar-elems']//*[@class='block macro']//li/a[normalize-space()='a']", 1, ) // Check there is only one macro named "b" listed in the sidebar. assert-count: ( - "//*[@class='sidebar-elems']//*[@class='block macro']//li/a[text()='b']", + "//*[@class='sidebar-elems']//*[@class='block macro']//li/a[normalize-space()='b']", 1, ) diff --git a/tests/rustdoc-gui/font-weight.goml b/tests/rustdoc-gui/font-weight.goml index 602b8d6f5b34c..26e9bf515a3ff 100644 --- a/tests/rustdoc-gui/font-weight.goml +++ b/tests/rustdoc-gui/font-weight.goml @@ -1,8 +1,8 @@ // This test checks that the font weight is correctly applied. go-to: "file://" + |DOC_PATH| + "/lib2/struct.Foo.html" -assert-css: ("//*[@class='rust item-decl']//a[text()='Alias']", {"font-weight": "400"}) +assert-css: ("//*[@class='rust item-decl']//a[normalize-space()='Alias']", {"font-weight": "400"}) assert-css: ( - "//*[@class='structfield section-header']//a[text()='Alias']", + "//*[@class='structfield section-header']//a[normalize-space()='Alias']", {"font-weight": "400"}, ) assert-css: ("#method\.a_method > .code-header", {"font-weight": "600"}) diff --git a/tests/rustdoc-gui/item-info.goml b/tests/rustdoc-gui/item-info.goml index 1eb46e832b70b..7a0194c6cc1f6 100644 --- a/tests/rustdoc-gui/item-info.goml +++ b/tests/rustdoc-gui/item-info.goml @@ -12,11 +12,11 @@ assert-position: (".item-info .stab", {"x": 245}) // test for . set-window-size: (850, 800) store-position: ( - "//*[@class='stab portability']//code[text()='Win32_System']", + "//*[@class='stab portability']//code[normalize-space()='Win32_System']", {"x": first_line_x, "y": first_line_y}, ) store-position: ( - "//*[@class='stab portability']//code[text()='Win32_System_Diagnostics']", + "//*[@class='stab portability']//code[normalize-space()='Win32_System_Diagnostics']", {"x": second_line_x, "y": second_line_y}, ) assert: |first_line_x| != |second_line_x| && |first_line_x| == 516 && |second_line_x| == 272 diff --git a/tests/rustdoc-gui/label-next-to-symbol.goml b/tests/rustdoc-gui/label-next-to-symbol.goml index 0582bd2cad36e..1fa0a120adaec 100644 --- a/tests/rustdoc-gui/label-next-to-symbol.goml +++ b/tests/rustdoc-gui/label-next-to-symbol.goml @@ -23,7 +23,7 @@ assert-css: ( // table like view assert-css: (".desc.docblock-short", { "padding-left": "0px" }) compare-elements-position-near: ( - "//*[@class='item-name']//a[text()='replaced_function']", + "//*[@class='item-name']//a[normalize-space()='replaced_function']", ".item-name .stab.deprecated", {"y": 2}, ) @@ -35,8 +35,8 @@ compare-elements-position: ( // Ensure no wrap compare-elements-position: ( - "//*[@class='item-name']//a[text()='replaced_function']/..", - "//*[@class='desc docblock-short'][text()='a thing with a label']", + "//*[@class='item-name']//a[normalize-space()='replaced_function']/..", + "//*[@class='desc docblock-short'][normalize-space()='a thing with a label']", ["y"], ) @@ -45,7 +45,7 @@ set-window-size: (600, 600) // staggered layout with 2em spacing assert-css: (".desc.docblock-short", { "padding-left": "32px" }) compare-elements-position-near: ( - "//*[@class='item-name']//a[text()='replaced_function']", + "//*[@class='item-name']//a[normalize-space()='replaced_function']", ".item-name .stab.deprecated", {"y": 2}, ) @@ -57,13 +57,13 @@ compare-elements-position: ( // Ensure wrap compare-elements-position-false: ( - "//*[@class='item-name']//a[text()='replaced_function']/..", - "//*[@class='desc docblock-short'][text()='a thing with a label']", + "//*[@class='item-name']//a[normalize-space()='replaced_function']/..", + "//*[@class='desc docblock-short'][normalize-space()='a thing with a label']", ["y"], ) compare-elements-position-false: ( ".item-name .stab.deprecated", - "//*[@class='desc docblock-short'][text()='a thing with a label']", + "//*[@class='desc docblock-short'][normalize-space()='a thing with a label']", ["y"], ) @@ -73,7 +73,7 @@ go-to: "file://" + |DOC_PATH| + "/test_docs/cfgs/index.html" // This part of the tags should not be on the same line as the beginning since the width // is too small for that. compare-elements-position-false: ( - "//*[@class='stab portability']/code[text()='appservice-api-c']", - "//*[@class='stab portability']/code[text()='server']", + "//*[@class='stab portability']/code[normalize-space()='appservice-api-c']", + "//*[@class='stab portability']/code[normalize-space()='server']", ["y"], ) diff --git a/tests/rustdoc-gui/notable-trait.goml b/tests/rustdoc-gui/notable-trait.goml index 6ee810c5768c2..e2a8a43007eb0 100644 --- a/tests/rustdoc-gui/notable-trait.goml +++ b/tests/rustdoc-gui/notable-trait.goml @@ -9,19 +9,19 @@ define-function: ( block { // Checking they have the same y position. compare-elements-position: ( - "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", + "//*[@id='method.create_an_iterator_from_read']//a[normalize-space()='NotableStructWithLongName']", "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", ["y"], ) // Checking they don't have the same x position. compare-elements-position-false: ( - "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", + "//*[@id='method.create_an_iterator_from_read']//a[normalize-space()='NotableStructWithLongName']", "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", ["x"], ) // The `i` should be *after* the type. assert-position: ( - "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", + "//*[@id='method.create_an_iterator_from_read']//a[normalize-space()='NotableStructWithLongName']", {"x": |x|}, ) assert-position: ( @@ -70,7 +70,7 @@ call-function: ("check-notable-tooltip-position-complete", { // Now only the `i` should be on the next line. set-window-size: (1055, 600) compare-elements-position-false: ( - "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", + "//*[@id='method.create_an_iterator_from_read']//a[normalize-space()='NotableStructWithLongName']", "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", ["y", "x"], ) diff --git a/tests/rustdoc-gui/search-result-color.goml b/tests/rustdoc-gui/search-result-color.goml index 9825f92b45351..e8da43eb896bc 100644 --- a/tests/rustdoc-gui/search-result-color.goml +++ b/tests/rustdoc-gui/search-result-color.goml @@ -20,11 +20,11 @@ define-function: ( ALL, ) assert-css: ( - "//*[@class='desc'][text()='Just a normal struct.']", + "//*[@class='desc'][normalize-space()='Just a normal struct.']", {"color": |desc_color|}, ) assert-css: ( - "//*[@class='result-name']//*[text()='test_docs::']", + "//*[@class='result-name']//*[normalize-space()='test_docs::']", {"color": |path_color|}, ) @@ -85,19 +85,19 @@ define-function: ( move-cursor-to: ".search-input" focus: ".search-input" // To ensure the `` container isn't focused or hovered. assert-css: ( - "//*[@class='result-name']//*[text()='test_docs::']/ancestor::a", + "//*[@class='result-name']//*[normalize-space()='test_docs::']/ancestor::a", {"color": |path_color|, "background-color": "transparent"}, ALL, ) // Checking color and background on hover. - move-cursor-to: "//*[@class='desc'][text()='Just a normal struct.']" + move-cursor-to: "//*[@class='desc'][normalize-space()='Just a normal struct.']" assert-css: ( - "//*[@class='result-name']//*[text()='test_docs::']", + "//*[@class='result-name']//*[normalize-space()='test_docs::']", {"color": |hover_path_color|}, ) assert-css: ( - "//*[@class='result-name']//*[text()='test_docs::']/ancestor::a", + "//*[@class='result-name']//*[normalize-space()='test_docs::']/ancestor::a", {"color": |hover_path_color|, "background-color": |hover_background|}, ) } diff --git a/tests/rustdoc-gui/sidebar-macro-reexport.goml b/tests/rustdoc-gui/sidebar-macro-reexport.goml index 0f7ef6c355828..cad25507fbbd6 100644 --- a/tests/rustdoc-gui/sidebar-macro-reexport.goml +++ b/tests/rustdoc-gui/sidebar-macro-reexport.goml @@ -2,4 +2,4 @@ // displayed twice in the sidebar. go-to: "file://" + |DOC_PATH| + "/test_docs/macro.repro.html" wait-for: ".sidebar-elems .block.macro a" -assert-count: ("//*[@class='sidebar-elems']//*[@class='block macro']//a[text()='repro']", 1) +assert-count: ("//*[@class='sidebar-elems']//*[@class='block macro']//a[normalize-space()='repro']", 1) diff --git a/tests/rustdoc-gui/sidebar-mobile.goml b/tests/rustdoc-gui/sidebar-mobile.goml index b4ff483c18097..4ada4837a5774 100644 --- a/tests/rustdoc-gui/sidebar-mobile.goml +++ b/tests/rustdoc-gui/sidebar-mobile.goml @@ -25,9 +25,12 @@ click: ".sidebar-menu-toggle" assert-css: (".sidebar", {"left": "0px"}) // Make sure the "struct Foo" header is hidden, since the mobile topbar already does it. -assert-css: ("//nav[contains(@class, 'sidebar')]//h2/a[text()='Foo']/parent::h2", {"display": "none"}) +assert-css: ("//nav[contains(@class, 'sidebar')]//h2/a[normalize-space()='Foo']/parent::h2", {"display": "none"}) // Make sure the global navigation is still here. -assert-css: ("//nav[contains(@class, 'sidebar')]//h2/a[text()='In crate test_docs']/parent::h2", {"display": "block"}) +assert-css: ( + "//nav[contains(@class, 'sidebar')]//h2/a[normalize-space()='In crate test_docs']/parent::h2", + {"display": "block"} +) // Click elsewhere. click: "body" diff --git a/tests/rustdoc-gui/sidebar-source-code.goml b/tests/rustdoc-gui/sidebar-source-code.goml index ef0b5ab38b138..6afccf6a95fe2 100644 --- a/tests/rustdoc-gui/sidebar-source-code.goml +++ b/tests/rustdoc-gui/sidebar-source-code.goml @@ -66,12 +66,12 @@ click: "#sidebar-button" // We wait for the sidebar to be expanded. wait-for-css: (".src-sidebar-expanded nav.sidebar", {"width": "300px"}) assert: "//*[@class='dir-entry' and @open]/*[text()='lib2']" -assert: "//*[@class='dir-entry' and @open]/*[text()='another_folder']" -assert: "//*[@class='dir-entry' and @open]/*[text()='sub_mod']" +assert: "//*[@class='dir-entry' and @open]/*[normalize-space()='another_folder']" +assert: "//*[@class='dir-entry' and @open]/*[normalize-space()='sub_mod']" // Only "another_folder" should be "open" in "lib2". -assert: "//*[@class='dir-entry' and not(@open)]/*[text()='another_mod']" +assert: "//*[@class='dir-entry' and not(@open)]/*[normalize-space()='another_mod']" // All other trees should be collapsed. -assert-count: ("//*[@id='src-sidebar']/details[not(text()='lib2') and not(@open)]", 11) +assert-count: ("//*[@id='src-sidebar']/details[not(normalize-space()='lib2') and not(@open)]", 11) // We now switch to mobile mode. set-window-size: (600, 600) diff --git a/tests/rustdoc-gui/source-anchor-scroll.goml b/tests/rustdoc-gui/source-anchor-scroll.goml index 940851ea14632..3508b26a0bf24 100644 --- a/tests/rustdoc-gui/source-anchor-scroll.goml +++ b/tests/rustdoc-gui/source-anchor-scroll.goml @@ -11,7 +11,7 @@ click: '//a[text() = "barbar" and @href="#5-7"]' assert-property: ("html", {"scrollTop": "123"}) click: '//a[text() = "bar" and @href="#28-36"]' assert-property: ("html", {"scrollTop": "154"}) -click: '//a[text() = "sub_fn" and @href="#2-4"]' +click: '//a[normalize-space() = "sub_fn" and @href="#2-4"]' assert-property: ("html", {"scrollTop": "51"}) // We now check that clicking on lines doesn't change the scroll From 9186001f3491c0eb996de6f61a457cecfb089333 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 6 Jul 2024 19:05:28 -0700 Subject: [PATCH 06/12] rustdoc: avoid redundant HTML when there's already line breaks --- src/librustdoc/html/escape.rs | 6 ++++++ src/librustdoc/html/escape/tests.rs | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs index 9441491316345..3e20c5b322b4a 100644 --- a/src/librustdoc/html/escape.rs +++ b/src/librustdoc/html/escape.rs @@ -97,6 +97,12 @@ impl<'a> fmt::Display for EscapeBodyTextWithWbr<'a> { let _ = it.next(); // don't insert wbr before first char while let Some((i, s)) = it.next() { let pk = it.peek(); + if s.chars().all(|c| c.is_whitespace()) { + // don't need "First Second"; the space is enough + EscapeBodyText(&text[last..i]).fmt(fmt)?; + last = i; + continue; + } let is_uppercase = || s.chars().any(|c| c.is_uppercase()); let next_is_uppercase = || pk.map_or(true, |(_, t)| t.chars().any(|c| c.is_uppercase())); diff --git a/src/librustdoc/html/escape/tests.rs b/src/librustdoc/html/escape/tests.rs index f99a2a693a628..7933f23eb7474 100644 --- a/src/librustdoc/html/escape/tests.rs +++ b/src/librustdoc/html/escape/tests.rs @@ -9,6 +9,10 @@ fn escape_body_text_with_wbr() { // real(istic) examples assert_eq!(&E("FirstSecond").to_string(), "FirstSecond"); assert_eq!(&E("First_Second").to_string(), "First_Second"); + assert_eq!(&E("First Second").to_string(), "First Second"); + assert_eq!(&E("First HSecond").to_string(), "First HSecond"); + assert_eq!(&E("First HTTPSecond").to_string(), "First HTTPSecond"); + assert_eq!(&E("First SecondThird").to_string(), "First SecondThird"); assert_eq!(&E("First_Second").to_string(), "First<T>_Second"); assert_eq!(&E("first_second").to_string(), "first_second"); assert_eq!(&E("MY_CONSTANT").to_string(), "MY_CONSTANT"); From f990239b34d4cc81999d62e3f2271c7c53c72fb7 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 24 Jul 2024 15:58:34 -0400 Subject: [PATCH 07/12] Stop using MoveDataParamEnv for places that don't need a param-env --- compiler/rustc_borrowck/src/lib.rs | 16 +++-- .../src/drop_flag_effects.rs | 7 +-- .../src/impls/initialized.rs | 60 ++++++++----------- compiler/rustc_mir_dataflow/src/rustc_peek.rs | 9 ++- .../src/elaborate_drops.rs | 16 +++-- .../src/remove_uninit_drops.rs | 9 ++- 6 files changed, 53 insertions(+), 64 deletions(-) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 74d9f9d8f81b8..9c2a0036befa8 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -45,7 +45,7 @@ use rustc_mir_dataflow::impls::{ use rustc_mir_dataflow::move_paths::{ InitIndex, InitLocation, LookupResult, MoveData, MoveOutIndex, MovePathIndex, }; -use rustc_mir_dataflow::{Analysis, MoveDataParamEnv}; +use rustc_mir_dataflow::Analysis; use rustc_session::lint::builtin::UNUSED_MUT; use rustc_span::{Span, Symbol}; use rustc_target::abi::FieldIdx; @@ -194,9 +194,7 @@ fn do_mir_borrowck<'tcx>( .iter_enumerated() .map(|(idx, body)| (idx, MoveData::gather_moves(body, tcx, param_env, |_| true))); - let mdpe = MoveDataParamEnv { move_data, param_env }; - - let mut flow_inits = MaybeInitializedPlaces::new(tcx, body, &mdpe) + let mut flow_inits = MaybeInitializedPlaces::new(tcx, body, &move_data) .into_engine(tcx, body) .pass_name("borrowck") .iterate_to_fixpoint() @@ -204,7 +202,7 @@ fn do_mir_borrowck<'tcx>( let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(def).is_fn_or_closure(); let borrow_set = - Rc::new(BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &mdpe.move_data)); + Rc::new(BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &move_data)); // Compute non-lexical lifetimes. let nll::NllOutput { @@ -222,7 +220,7 @@ fn do_mir_borrowck<'tcx>( &location_table, param_env, &mut flow_inits, - &mdpe.move_data, + &move_data, &borrow_set, tcx.closure_captures(def), consumer_options, @@ -254,11 +252,11 @@ fn do_mir_borrowck<'tcx>( .into_engine(tcx, body) .pass_name("borrowck") .iterate_to_fixpoint(); - let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &mdpe) + let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &move_data) .into_engine(tcx, body) .pass_name("borrowck") .iterate_to_fixpoint(); - let flow_ever_inits = EverInitializedPlaces::new(body, &mdpe) + let flow_ever_inits = EverInitializedPlaces::new(body, &move_data) .into_engine(tcx, body) .pass_name("borrowck") .iterate_to_fixpoint(); @@ -324,7 +322,7 @@ fn do_mir_borrowck<'tcx>( infcx: &infcx, param_env, body, - move_data: &mdpe.move_data, + move_data: &move_data, location_table: &location_table, movable_coroutine, locals_are_invalidated_at_exit, diff --git a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs index 4f67a0fa09541..bb53eaf6cbd1c 100644 --- a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs +++ b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs @@ -3,7 +3,6 @@ use rustc_target::abi::VariantIdx; use tracing::debug; use super::move_paths::{InitKind, LookupResult, MoveData, MovePathIndex}; -use super::MoveDataParamEnv; use crate::elaborate_drops::DropFlagState; pub fn move_path_children_matching<'tcx, F>( @@ -70,12 +69,11 @@ pub fn on_all_children_bits<'tcx, F>( pub fn drop_flag_effects_for_function_entry<'tcx, F>( body: &Body<'tcx>, - ctxt: &MoveDataParamEnv<'tcx>, + move_data: &MoveData<'tcx>, mut callback: F, ) where F: FnMut(MovePathIndex, DropFlagState), { - let move_data = &ctxt.move_data; for arg in body.args_iter() { let place = mir::Place::from(arg); let lookup_result = move_data.rev_lookup.find(place.as_ref()); @@ -87,13 +85,12 @@ pub fn drop_flag_effects_for_function_entry<'tcx, F>( pub fn drop_flag_effects_for_location<'tcx, F>( body: &Body<'tcx>, - ctxt: &MoveDataParamEnv<'tcx>, + move_data: &MoveData<'tcx>, loc: Location, mut callback: F, ) where F: FnMut(MovePathIndex, DropFlagState), { - let move_data = &ctxt.move_data; debug!("drop_flag_effects_for_location({:?})", loc); // first, move out of the RHS diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs index 77f4dcf892a39..e9e8ddefa020b 100644 --- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs +++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs @@ -11,7 +11,7 @@ use crate::move_paths::{HasMoveData, InitIndex, InitKind, LookupResult, MoveData use crate::{ drop_flag_effects, drop_flag_effects_for_function_entry, drop_flag_effects_for_location, lattice, on_all_children_bits, on_lookup_result_bits, AnalysisDomain, GenKill, GenKillAnalysis, - MaybeReachable, MoveDataParamEnv, + MaybeReachable, }; /// `MaybeInitializedPlaces` tracks all places that might be @@ -52,17 +52,13 @@ use crate::{ pub struct MaybeInitializedPlaces<'a, 'mir, 'tcx> { tcx: TyCtxt<'tcx>, body: &'mir Body<'tcx>, - mdpe: &'a MoveDataParamEnv<'tcx>, + move_data: &'a MoveData<'tcx>, skip_unreachable_unwind: bool, } impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> { - pub fn new( - tcx: TyCtxt<'tcx>, - body: &'mir Body<'tcx>, - mdpe: &'a MoveDataParamEnv<'tcx>, - ) -> Self { - MaybeInitializedPlaces { tcx, body, mdpe, skip_unreachable_unwind: false } + pub fn new(tcx: TyCtxt<'tcx>, body: &'mir Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self { + MaybeInitializedPlaces { tcx, body, move_data, skip_unreachable_unwind: false } } pub fn skipping_unreachable_unwind(mut self) -> Self { @@ -89,7 +85,7 @@ impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> { impl<'a, 'mir, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'mir, 'tcx> { fn move_data(&self) -> &MoveData<'tcx> { - &self.mdpe.move_data + self.move_data } } @@ -131,22 +127,18 @@ impl<'a, 'mir, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'mir, 'tcx pub struct MaybeUninitializedPlaces<'a, 'mir, 'tcx> { tcx: TyCtxt<'tcx>, body: &'mir Body<'tcx>, - mdpe: &'a MoveDataParamEnv<'tcx>, + move_data: &'a MoveData<'tcx>, mark_inactive_variants_as_uninit: bool, skip_unreachable_unwind: BitSet, } impl<'a, 'mir, 'tcx> MaybeUninitializedPlaces<'a, 'mir, 'tcx> { - pub fn new( - tcx: TyCtxt<'tcx>, - body: &'mir Body<'tcx>, - mdpe: &'a MoveDataParamEnv<'tcx>, - ) -> Self { + pub fn new(tcx: TyCtxt<'tcx>, body: &'mir Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self { MaybeUninitializedPlaces { tcx, body, - mdpe, + move_data, mark_inactive_variants_as_uninit: false, skip_unreachable_unwind: BitSet::new_empty(body.basic_blocks.len()), } @@ -173,7 +165,7 @@ impl<'a, 'mir, 'tcx> MaybeUninitializedPlaces<'a, 'mir, 'tcx> { impl<'a, 'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'a, '_, 'tcx> { fn move_data(&self) -> &MoveData<'tcx> { - &self.mdpe.move_data + self.move_data } } @@ -213,18 +205,18 @@ impl<'a, 'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'a, '_, 'tcx> { /// that would require a dynamic drop-flag at that statement. pub struct DefinitelyInitializedPlaces<'a, 'tcx> { body: &'a Body<'tcx>, - mdpe: &'a MoveDataParamEnv<'tcx>, + move_data: &'a MoveData<'tcx>, } impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> { - pub fn new(body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self { - DefinitelyInitializedPlaces { body, mdpe } + pub fn new(body: &'a Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self { + DefinitelyInitializedPlaces { body, move_data } } } impl<'a, 'tcx> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> { fn move_data(&self) -> &MoveData<'tcx> { - &self.mdpe.move_data + self.move_data } } @@ -259,18 +251,18 @@ impl<'a, 'tcx> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> { /// ``` pub struct EverInitializedPlaces<'a, 'mir, 'tcx> { body: &'mir Body<'tcx>, - mdpe: &'a MoveDataParamEnv<'tcx>, + move_data: &'a MoveData<'tcx>, } impl<'a, 'mir, 'tcx> EverInitializedPlaces<'a, 'mir, 'tcx> { - pub fn new(body: &'mir Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self { - EverInitializedPlaces { body, mdpe } + pub fn new(body: &'mir Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self { + EverInitializedPlaces { body, move_data } } } impl<'a, 'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'a, '_, 'tcx> { fn move_data(&self) -> &MoveData<'tcx> { - &self.mdpe.move_data + self.move_data } } @@ -328,7 +320,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> { fn initialize_start_block(&self, _: &mir::Body<'tcx>, state: &mut Self::Domain) { *state = MaybeReachable::Reachable(ChunkedBitSet::new_empty(self.move_data().move_paths.len())); - drop_flag_effects_for_function_entry(self.body, self.mdpe, |path, s| { + drop_flag_effects_for_function_entry(self.body, self.move_data, |path, s| { assert!(s == DropFlagState::Present); state.gen_(path); }); @@ -348,7 +340,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> { statement: &mir::Statement<'tcx>, location: Location, ) { - drop_flag_effects_for_location(self.body, self.mdpe, location, |path, s| { + drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| { Self::update_bits(trans, path, s) }); @@ -380,7 +372,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> { { edges = TerminatorEdges::Single(target); } - drop_flag_effects_for_location(self.body, self.mdpe, location, |path, s| { + drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| { Self::update_bits(state, path, s) }); edges @@ -465,7 +457,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, '_, 'tcx> { // set all bits to 1 (uninit) before gathering counter-evidence state.insert_all(); - drop_flag_effects_for_function_entry(self.body, self.mdpe, |path, s| { + drop_flag_effects_for_function_entry(self.body, self.move_data, |path, s| { assert!(s == DropFlagState::Present); state.remove(path); }); @@ -485,7 +477,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, '_, 'tcx> { _statement: &mir::Statement<'tcx>, location: Location, ) { - drop_flag_effects_for_location(self.body, self.mdpe, location, |path, s| { + drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| { Self::update_bits(trans, path, s) }); @@ -499,7 +491,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, '_, 'tcx> { terminator: &'mir mir::Terminator<'tcx>, location: Location, ) -> TerminatorEdges<'mir, 'tcx> { - drop_flag_effects_for_location(self.body, self.mdpe, location, |path, s| { + drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| { Self::update_bits(trans, path, s) }); if self.skip_unreachable_unwind.contains(location.block) { @@ -592,7 +584,7 @@ impl<'a, 'tcx> AnalysisDomain<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> { fn initialize_start_block(&self, _: &mir::Body<'tcx>, state: &mut Self::Domain) { state.0.clear(); - drop_flag_effects_for_function_entry(self.body, self.mdpe, |path, s| { + drop_flag_effects_for_function_entry(self.body, self.move_data, |path, s| { assert!(s == DropFlagState::Present); state.0.insert(path); }); @@ -612,7 +604,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> { _statement: &mir::Statement<'tcx>, location: Location, ) { - drop_flag_effects_for_location(self.body, self.mdpe, location, |path, s| { + drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| { Self::update_bits(trans, path, s) }) } @@ -623,7 +615,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> { terminator: &'mir mir::Terminator<'tcx>, location: Location, ) -> TerminatorEdges<'mir, 'tcx> { - drop_flag_effects_for_location(self.body, self.mdpe, location, |path, s| { + drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| { Self::update_bits(trans, path, s) }); terminator.edges() diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs index 23bf35b30cae0..0171cc8591809 100644 --- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs +++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs @@ -16,7 +16,7 @@ use crate::impls::{ DefinitelyInitializedPlaces, MaybeInitializedPlaces, MaybeLiveLocals, MaybeUninitializedPlaces, }; use crate::move_paths::{HasMoveData, LookupResult, MoveData, MovePathIndex}; -use crate::{Analysis, JoinSemiLattice, MoveDataParamEnv, ResultsCursor}; +use crate::{Analysis, JoinSemiLattice, ResultsCursor}; pub struct SanityCheck; @@ -46,10 +46,9 @@ impl<'tcx> MirPass<'tcx> for SanityCheck { let param_env = tcx.param_env(def_id); let move_data = MoveData::gather_moves(body, tcx, param_env, |_| true); - let mdpe = MoveDataParamEnv { move_data, param_env }; if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_init).is_some() { - let flow_inits = MaybeInitializedPlaces::new(tcx, body, &mdpe) + let flow_inits = MaybeInitializedPlaces::new(tcx, body, &move_data) .into_engine(tcx, body) .iterate_to_fixpoint(); @@ -57,7 +56,7 @@ impl<'tcx> MirPass<'tcx> for SanityCheck { } if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_uninit).is_some() { - let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &mdpe) + let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &move_data) .into_engine(tcx, body) .iterate_to_fixpoint(); @@ -65,7 +64,7 @@ impl<'tcx> MirPass<'tcx> for SanityCheck { } if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_definite_init).is_some() { - let flow_def_inits = DefinitelyInitializedPlaces::new(body, &mdpe) + let flow_def_inits = DefinitelyInitializedPlaces::new(body, &move_data) .into_engine(tcx, body) .iterate_to_fixpoint(); diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index 026812852dd31..5a22ef7790349 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -62,7 +62,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops { let elaborate_patch = { let env = MoveDataParamEnv { move_data, param_env }; - let mut inits = MaybeInitializedPlaces::new(tcx, body, &env) + let mut inits = MaybeInitializedPlaces::new(tcx, body, &env.move_data) .skipping_unreachable_unwind() .into_engine(tcx, body) .pass_name("elaborate_drops") @@ -70,7 +70,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops { .into_results_cursor(body); let dead_unwinds = compute_dead_unwinds(body, &mut inits); - let uninits = MaybeUninitializedPlaces::new(tcx, body, &env) + let uninits = MaybeUninitializedPlaces::new(tcx, body, &env.move_data) .mark_inactive_variants_as_uninit() .skipping_unreachable_unwind(dead_unwinds) .into_engine(tcx, body) @@ -443,9 +443,13 @@ impl<'b, 'mir, 'tcx> ElaborateDropsCtxt<'b, 'mir, 'tcx> { fn drop_flags_for_args(&mut self) { let loc = Location::START; - rustc_mir_dataflow::drop_flag_effects_for_function_entry(self.body, self.env, |path, ds| { - self.set_drop_flag(loc, path, ds); - }) + rustc_mir_dataflow::drop_flag_effects_for_function_entry( + self.body, + &self.env.move_data, + |path, ds| { + self.set_drop_flag(loc, path, ds); + }, + ) } fn drop_flags_for_locs(&mut self) { @@ -478,7 +482,7 @@ impl<'b, 'mir, 'tcx> ElaborateDropsCtxt<'b, 'mir, 'tcx> { let loc = Location { block: bb, statement_index: i }; rustc_mir_dataflow::drop_flag_effects_for_location( self.body, - self.env, + &self.env.move_data, loc, |path, ds| self.set_drop_flag(loc, path, ds), ) diff --git a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs index d642c307a3f37..fae1cb5f7d8a5 100644 --- a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs +++ b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs @@ -3,7 +3,7 @@ use rustc_middle::mir::{Body, TerminatorKind}; use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt, VariantDef}; use rustc_mir_dataflow::impls::MaybeInitializedPlaces; use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex}; -use rustc_mir_dataflow::{move_path_children_matching, Analysis, MaybeReachable, MoveDataParamEnv}; +use rustc_mir_dataflow::{move_path_children_matching, Analysis, MaybeReachable}; use rustc_target::abi::FieldIdx; use crate::MirPass; @@ -24,8 +24,7 @@ impl<'tcx> MirPass<'tcx> for RemoveUninitDrops { let move_data = MoveData::gather_moves(body, tcx, param_env, |ty| ty.needs_drop(tcx, param_env)); - let mdpe = MoveDataParamEnv { move_data, param_env }; - let mut maybe_inits = MaybeInitializedPlaces::new(tcx, body, &mdpe) + let mut maybe_inits = MaybeInitializedPlaces::new(tcx, body, &move_data) .into_engine(tcx, body) .pass_name("remove_uninit_drops") .iterate_to_fixpoint() @@ -40,7 +39,7 @@ impl<'tcx> MirPass<'tcx> for RemoveUninitDrops { let MaybeReachable::Reachable(maybe_inits) = maybe_inits.get() else { continue }; // If there's no move path for the dropped place, it's probably a `Deref`. Let it alone. - let LookupResult::Exact(mpi) = mdpe.move_data.rev_lookup.find(place.as_ref()) else { + let LookupResult::Exact(mpi) = move_data.rev_lookup.find(place.as_ref()) else { continue; }; @@ -48,7 +47,7 @@ impl<'tcx> MirPass<'tcx> for RemoveUninitDrops { tcx, param_env, maybe_inits, - &mdpe.move_data, + &move_data, place.ty(body, tcx).ty, mpi, ); From 23f46e5b9944f35d2726d583f18d8e387f1556f4 Mon Sep 17 00:00:00 2001 From: George Bateman Date: Mon, 29 Jul 2024 17:50:12 +0100 Subject: [PATCH 08/12] Stabilize offset_of_nested --- .../src/error_codes/E0795.md | 4 +- compiler/rustc_feature/src/accepted.rs | 2 + compiler/rustc_feature/src/unstable.rs | 2 - compiler/rustc_hir_typeck/src/expr.rs | 12 -- library/core/src/lib.rs | 2 +- library/core/src/mem/mod.rs | 3 +- library/core/tests/lib.rs | 110 +++++++++--------- tests/mir-opt/const_prop/offset_of.rs | 2 +- .../mir-opt/dataflow-const-prop/offset_of.rs | 2 - .../feature-gate-offset-of-enum.rs | 2 - .../feature-gate-offset-of-enum.stderr | 8 +- .../feature-gate-offset-of-nested.rs | 28 ----- .../feature-gate-offset-of-nested.stderr | 60 ---------- .../dead-code/offset-of-correct-param-env.rs | 1 - tests/ui/lint/dead-code/offset-of.rs | 1 - tests/ui/lint/dead-code/offset-of.stderr | 12 +- tests/ui/offset-of/offset-of-enum.rs | 2 +- tests/ui/offset-of/offset-of-private.rs | 2 +- tests/ui/offset-of/offset-of-self.rs | 2 - tests/ui/offset-of/offset-of-self.stderr | 14 +-- tests/ui/offset-of/offset-of-slice.rs | 2 +- tests/ui/offset-of/offset-of-tuple-nested.rs | 2 - tests/ui/offset-of/offset-of-tuple.rs | 1 - tests/ui/offset-of/offset-of-tuple.stderr | 66 +++++------ .../offset-of-unstable-with-feature.rs | 2 +- tests/ui/offset-of/offset-of-unstable.rs | 2 - tests/ui/offset-of/offset-of-unstable.stderr | 16 +-- 27 files changed, 126 insertions(+), 236 deletions(-) delete mode 100644 tests/ui/feature-gates/feature-gate-offset-of-nested.rs delete mode 100644 tests/ui/feature-gates/feature-gate-offset-of-nested.stderr diff --git a/compiler/rustc_error_codes/src/error_codes/E0795.md b/compiler/rustc_error_codes/src/error_codes/E0795.md index ad77d72c913a8..69e61f7738f79 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0795.md +++ b/compiler/rustc_error_codes/src/error_codes/E0795.md @@ -3,7 +3,7 @@ Invalid argument for the `offset_of!` macro. Erroneous code example: ```compile_fail,E0795 -#![feature(offset_of_enum, offset_of_nested)] +#![feature(offset_of_enum)] let x = std::mem::offset_of!(Option, Some); ``` @@ -16,7 +16,7 @@ The offset of the contained `u8` in the `Option` can be found by specifying the field name `0`: ``` -#![feature(offset_of_enum, offset_of_nested)] +#![feature(offset_of_enum)] let x: usize = std::mem::offset_of!(Option, Some.0); ``` diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 46992347f839d..99fcc66a4adc1 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -292,6 +292,8 @@ declare_features! ( (accepted, non_exhaustive, "1.40.0", Some(44109)), /// Allows `foo.rs` as an alternative to `foo/mod.rs`. (accepted, non_modrs_mods, "1.30.0", Some(44660)), + /// Allows using multiple nested field accesses in offset_of! + (accepted, offset_of_nested, "CURRENT_RUSTC_VERSION", Some(120140)), /// Allows the use of or-patterns (e.g., `0 | 1`). (accepted, or_patterns, "1.53.0", Some(54883)), /// Allows using `+bundle,+whole-archive` link modifiers with native libs. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 7d0ca3a1d0faf..a57ff3f7b006f 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -560,8 +560,6 @@ declare_features! ( (unstable, object_safe_for_dispatch, "1.40.0", Some(43561)), /// Allows using enums in offset_of! (unstable, offset_of_enum, "1.75.0", Some(120141)), - /// Allows using multiple nested field accesses in offset_of! - (unstable, offset_of_nested, "1.77.0", Some(120140)), /// Allows using fields with slice type in offset_of! (unstable, offset_of_slice, "CURRENT_RUSTC_VERSION", Some(126151)), /// Allows using `#[optimize(X)]`. diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index f3266e04f8194..d75a5f8806bc9 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3338,18 +3338,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Ty<'tcx> { let container = self.lower_ty(container).normalized; - if let Some(ident_2) = fields.get(1) - && !self.tcx.features().offset_of_nested - { - rustc_session::parse::feature_err( - &self.tcx.sess, - sym::offset_of_nested, - ident_2.span, - "only a single ident or integer is stable as the field in offset_of", - ) - .emit(); - } - let mut field_indices = Vec::with_capacity(fields.len()); let mut current_container = container; let mut fields = fields.into_iter(); diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index a3eca34a35cfc..d9c7a0877399b 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -107,6 +107,7 @@ // // Library features: // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(offset_of_nested))] #![feature(array_ptr_get)] #![feature(asm_experimental_arch)] #![feature(char_indices_offset)] @@ -172,7 +173,6 @@ #![feature(isqrt)] #![feature(link_cfg)] #![feature(offset_of_enum)] -#![feature(offset_of_nested)] #![feature(panic_internals)] #![feature(ptr_alignment_type)] #![feature(ptr_metadata)] diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index b8e9f606a9ad6..ea2dcdce6e89e 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1321,7 +1321,8 @@ impl SizedTypeProperties for T {} /// # Examples /// /// ``` -/// #![feature(offset_of_enum, offset_of_nested)] +/// # #![cfg_attr(bootstrap, feature(offset_of_nested))] +/// #![feature(offset_of_enum)] /// /// use std::mem; /// #[repr(C)] diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 5dad5937a603d..1e336bf96b8fa 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -1,6 +1,11 @@ +// tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(offset_of_nested))] +#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))] +#![cfg_attr(test, feature(cfg_match))] #![feature(alloc_layout_extra)] #![feature(array_chunks)] #![feature(array_ptr_get)] +#![feature(array_try_from_fn)] #![feature(array_windows)] #![feature(ascii_char)] #![feature(ascii_char_variants)] @@ -9,112 +14,109 @@ #![feature(bigint_helper_methods)] #![feature(cell_update)] #![feature(clone_to_uninit)] -#![feature(const_align_offset)] #![feature(const_align_of_val_raw)] +#![feature(const_align_offset)] +#![feature(const_array_from_ref)] #![feature(const_black_box)] #![feature(const_cell_into_inner)] #![feature(const_hash)] #![feature(const_heap)] #![feature(const_intrinsic_copy)] +#![feature(const_ip)] +#![feature(const_ipv4)] +#![feature(const_ipv6)] +#![feature(const_likely)] #![feature(const_maybe_uninit_as_mut_ptr)] +#![feature(const_mut_refs)] #![feature(const_nonnull_new)] +#![feature(const_option)] +#![feature(const_option_ext)] +#![feature(const_pin)] #![feature(const_pointer_is_aligned)] #![feature(const_ptr_as_ref)] #![feature(const_ptr_write)] +#![feature(const_result)] +#![feature(const_slice_from_ref)] #![feature(const_three_way_compare)] #![feature(const_trait_impl)] -#![feature(const_likely)] #![feature(core_intrinsics)] #![feature(core_io_borrowed_buf)] #![feature(core_private_bignum)] #![feature(core_private_diy_float)] #![feature(dec2flt)] -#![feature(duration_consts_float)] #![feature(duration_constants)] #![feature(duration_constructors)] +#![feature(duration_consts_float)] +#![feature(error_generic_member_access)] #![feature(exact_size_is_empty)] #![feature(extern_types)] -#![feature(freeze)] +#![feature(float_minimum_maximum)] #![feature(flt2dec)] #![feature(fmt_internals)] -#![feature(float_minimum_maximum)] +#![feature(freeze)] #![feature(future_join)] #![feature(generic_assert_internals)] -#![feature(array_try_from_fn)] +#![feature(get_many_mut)] #![feature(hasher_prefixfree_extras)] #![feature(hashmap_internals)] -#![feature(try_find)] -#![feature(layout_for_ptr)] -#![feature(pattern)] -#![feature(slice_take)] -#![feature(slice_from_ptr_range)] -#![feature(slice_split_once)] -#![feature(split_as_slice)] -#![feature(maybe_uninit_fill)] -#![feature(maybe_uninit_write_slice)] -#![feature(maybe_uninit_uninit_array_transpose)] -#![feature(min_specialization)] -#![feature(noop_waker)] -#![feature(numfmt)] -#![feature(num_midpoint)] -#![feature(offset_of_nested)] -#![feature(isqrt)] -#![feature(unsigned_is_multiple_of)] -#![feature(step_trait)] -#![feature(str_internals)] -#![feature(std_internals)] -#![feature(test)] -#![feature(trusted_len)] -#![feature(try_blocks)] -#![feature(try_trait_v2)] -#![feature(slice_internals)] -#![feature(slice_partition_dedup)] +#![feature(int_roundings)] #![feature(ip)] +#![feature(is_ascii_octdigit)] +#![feature(isqrt)] #![feature(iter_advance_by)] #![feature(iter_array_chunks)] #![feature(iter_chain)] #![feature(iter_collect_into)] -#![feature(iter_partition_in_place)] #![feature(iter_intersperse)] #![feature(iter_is_partitioned)] +#![feature(iter_map_windows)] #![feature(iter_next_chunk)] #![feature(iter_order_by)] +#![feature(iter_partition_in_place)] #![feature(iter_repeat_n)] #![feature(iterator_try_collect)] #![feature(iterator_try_reduce)] -#![feature(const_ip)] -#![feature(const_ipv4)] -#![feature(const_ipv6)] -#![feature(const_mut_refs)] -#![feature(const_pin)] +#![feature(layout_for_ptr)] +#![feature(maybe_uninit_fill)] +#![feature(maybe_uninit_uninit_array_transpose)] +#![feature(maybe_uninit_write_slice)] +#![feature(min_specialization)] #![feature(never_type)] -#![feature(unwrap_infallible)] +#![feature(noop_waker)] +#![feature(num_midpoint)] +#![feature(numfmt)] +#![feature(pattern)] #![feature(pointer_is_aligned_to)] #![feature(portable_simd)] #![feature(ptr_metadata)] -#![feature(unsized_tuple_coercion)] -#![feature(const_option)] -#![feature(const_option_ext)] -#![feature(const_result)] -#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))] -#![cfg_attr(test, feature(cfg_match))] -#![feature(int_roundings)] +#![feature(slice_from_ptr_range)] +#![feature(slice_internals)] +#![feature(slice_partition_dedup)] +#![feature(slice_split_once)] +#![feature(slice_take)] #![feature(split_array)] +#![feature(split_as_slice)] +#![feature(std_internals)] +#![feature(step_trait)] +#![feature(str_internals)] #![feature(strict_provenance)] #![feature(strict_provenance_atomic_ptr)] +#![feature(test)] +#![feature(trait_upcasting)] +#![feature(trusted_len)] #![feature(trusted_random_access)] +#![feature(try_blocks)] +#![feature(try_find)] +#![feature(try_trait_v2)] +#![feature(unsigned_is_multiple_of)] #![feature(unsize)] -#![feature(const_array_from_ref)] -#![feature(const_slice_from_ref)] +#![feature(unsized_tuple_coercion)] +#![feature(unwrap_infallible)] #![feature(waker_getters)] -#![feature(error_generic_member_access)] -#![feature(trait_upcasting)] -#![feature(is_ascii_octdigit)] -#![feature(get_many_mut)] -#![feature(iter_map_windows)] +// tidy-alphabetical-end #![allow(internal_features)] -#![deny(unsafe_op_in_unsafe_fn)] #![deny(fuzzy_provenance_casts)] +#![deny(unsafe_op_in_unsafe_fn)] mod alloc; mod any; diff --git a/tests/mir-opt/const_prop/offset_of.rs b/tests/mir-opt/const_prop/offset_of.rs index 264c8a3d21cdc..c2f5e83d6868f 100644 --- a/tests/mir-opt/const_prop/offset_of.rs +++ b/tests/mir-opt/const_prop/offset_of.rs @@ -2,7 +2,7 @@ //@ test-mir-pass: GVN // EMIT_MIR_FOR_EACH_PANIC_STRATEGY -#![feature(offset_of_enum, offset_of_nested)] +#![feature(offset_of_enum)] use std::marker::PhantomData; use std::mem::offset_of; diff --git a/tests/mir-opt/dataflow-const-prop/offset_of.rs b/tests/mir-opt/dataflow-const-prop/offset_of.rs index 12396b31ed0e9..bb4a74d3712a0 100644 --- a/tests/mir-opt/dataflow-const-prop/offset_of.rs +++ b/tests/mir-opt/dataflow-const-prop/offset_of.rs @@ -1,8 +1,6 @@ //@ test-mir-pass: DataflowConstProp // EMIT_MIR_FOR_EACH_PANIC_STRATEGY -#![feature(offset_of_nested)] - use std::marker::PhantomData; use std::mem::offset_of; diff --git a/tests/ui/feature-gates/feature-gate-offset-of-enum.rs b/tests/ui/feature-gates/feature-gate-offset-of-enum.rs index 1f2f7ee1e1919..cc9efeb67f31d 100644 --- a/tests/ui/feature-gates/feature-gate-offset-of-enum.rs +++ b/tests/ui/feature-gates/feature-gate-offset-of-enum.rs @@ -1,5 +1,3 @@ -#![feature(offset_of_nested)] - use std::mem::offset_of; enum Alpha { diff --git a/tests/ui/feature-gates/feature-gate-offset-of-enum.stderr b/tests/ui/feature-gates/feature-gate-offset-of-enum.stderr index fc7dd7923f7a8..8a73abc8cadbe 100644 --- a/tests/ui/feature-gates/feature-gate-offset-of-enum.stderr +++ b/tests/ui/feature-gates/feature-gate-offset-of-enum.stderr @@ -1,5 +1,5 @@ error[E0573]: expected type, found variant `Alpha::One` - --> $DIR/feature-gate-offset-of-enum.rs:11:16 + --> $DIR/feature-gate-offset-of-enum.rs:9:16 | LL | offset_of!(Alpha::One, 0); | ^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | offset_of!(Alpha::One, 0); | help: try using the variant's enum: `Alpha` error[E0658]: using enums in offset_of is experimental - --> $DIR/feature-gate-offset-of-enum.rs:12:23 + --> $DIR/feature-gate-offset-of-enum.rs:10:23 | LL | offset_of!(Alpha, One); | ^^^ @@ -18,13 +18,13 @@ LL | offset_of!(Alpha, One); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0795]: `One` is an enum variant; expected field at end of `offset_of` - --> $DIR/feature-gate-offset-of-enum.rs:12:23 + --> $DIR/feature-gate-offset-of-enum.rs:10:23 | LL | offset_of!(Alpha, One); | ^^^ enum variant error[E0658]: using enums in offset_of is experimental - --> $DIR/feature-gate-offset-of-enum.rs:14:23 + --> $DIR/feature-gate-offset-of-enum.rs:12:23 | LL | offset_of!(Alpha, Two.0); | ^^^ diff --git a/tests/ui/feature-gates/feature-gate-offset-of-nested.rs b/tests/ui/feature-gates/feature-gate-offset-of-nested.rs deleted file mode 100644 index c4eb4720fde5e..0000000000000 --- a/tests/ui/feature-gates/feature-gate-offset-of-nested.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![feature(offset_of_enum)] - -use std::mem::offset_of; - -struct S { - a: u8, - b: (u8, u8), - c: T, -} - -struct T { - t: &'static str, -} - -enum Alpha { - One(u8), - Two(u8), -} - -fn main() { - offset_of!(Alpha, Two.0); //~ ERROR only a single ident or integer is stable as the field in offset_of - offset_of!(S, a); - offset_of!((u8, S), 1); - offset_of!((u32, (S, T)), 1.1); //~ ERROR only a single ident or integer is stable as the field in offset_of - offset_of!(S, b.0); //~ ERROR only a single ident or integer is stable as the field in offset_of - offset_of!((S, ()), 0.c); //~ ERROR only a single ident or integer is stable as the field in offset_of - offset_of!(S, c.t); //~ ERROR only a single ident or integer is stable as the field in offset_of -} diff --git a/tests/ui/feature-gates/feature-gate-offset-of-nested.stderr b/tests/ui/feature-gates/feature-gate-offset-of-nested.stderr deleted file mode 100644 index f367fc9fa0dd4..0000000000000 --- a/tests/ui/feature-gates/feature-gate-offset-of-nested.stderr +++ /dev/null @@ -1,60 +0,0 @@ -error[E0658]: only a single ident or integer is stable as the field in offset_of - --> $DIR/feature-gate-offset-of-nested.rs:21:27 - | -LL | offset_of!(Alpha, Two.0); - | ^ - | - = note: see issue #120140 for more information - = help: add `#![feature(offset_of_nested)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: only a single ident or integer is stable as the field in offset_of - --> $DIR/feature-gate-offset-of-nested.rs:24:33 - | -LL | offset_of!((u32, (S, T)), 1.1); - | _____----------------------------^- - | | | - | | in this macro invocation -LL | | offset_of!(S, b.0); -LL | | offset_of!((S, ()), 0.c); -LL | | offset_of!(S, c.t); -... | - | - = note: see issue #120140 for more information - = help: add `#![feature(offset_of_nested)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0658]: only a single ident or integer is stable as the field in offset_of - --> $DIR/feature-gate-offset-of-nested.rs:25:21 - | -LL | offset_of!(S, b.0); - | ^ - | - = note: see issue #120140 for more information - = help: add `#![feature(offset_of_nested)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: only a single ident or integer is stable as the field in offset_of - --> $DIR/feature-gate-offset-of-nested.rs:26:27 - | -LL | offset_of!((S, ()), 0.c); - | ^ - | - = note: see issue #120140 for more information - = help: add `#![feature(offset_of_nested)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: only a single ident or integer is stable as the field in offset_of - --> $DIR/feature-gate-offset-of-nested.rs:27:21 - | -LL | offset_of!(S, c.t); - | ^ - | - = note: see issue #120140 for more information - = help: add `#![feature(offset_of_nested)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 5 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/lint/dead-code/offset-of-correct-param-env.rs b/tests/ui/lint/dead-code/offset-of-correct-param-env.rs index 61babdeb28b5b..8cb242f82822a 100644 --- a/tests/ui/lint/dead-code/offset-of-correct-param-env.rs +++ b/tests/ui/lint/dead-code/offset-of-correct-param-env.rs @@ -1,6 +1,5 @@ //@ check-pass -#![feature(offset_of_nested)] #![deny(dead_code)] // This struct contains a projection that can only be normalized after getting the field type. diff --git a/tests/ui/lint/dead-code/offset-of.rs b/tests/ui/lint/dead-code/offset-of.rs index 5269426d2ff3a..89e9fd910cb64 100644 --- a/tests/ui/lint/dead-code/offset-of.rs +++ b/tests/ui/lint/dead-code/offset-of.rs @@ -1,4 +1,3 @@ -#![feature(offset_of_nested)] #![deny(dead_code)] use std::mem::offset_of; diff --git a/tests/ui/lint/dead-code/offset-of.stderr b/tests/ui/lint/dead-code/offset-of.stderr index ed2916461cde8..4a903a9d6e899 100644 --- a/tests/ui/lint/dead-code/offset-of.stderr +++ b/tests/ui/lint/dead-code/offset-of.stderr @@ -1,5 +1,5 @@ error: field `b` is never read - --> $DIR/offset-of.rs:8:5 + --> $DIR/offset-of.rs:7:5 | LL | struct Alpha { | ----- field in this struct @@ -8,13 +8,13 @@ LL | b: (), | ^ | note: the lint level is defined here - --> $DIR/offset-of.rs:2:9 + --> $DIR/offset-of.rs:1:9 | LL | #![deny(dead_code)] | ^^^^^^^^^ error: field `a` is never read - --> $DIR/offset-of.rs:13:5 + --> $DIR/offset-of.rs:12:5 | LL | struct Beta { | ---- field in this struct @@ -22,7 +22,7 @@ LL | a: (), | ^ error: field `a` is never read - --> $DIR/offset-of.rs:18:5 + --> $DIR/offset-of.rs:17:5 | LL | struct Gamma { | ----- field in this struct @@ -30,7 +30,7 @@ LL | a: (), | ^ error: field `b` is never read - --> $DIR/offset-of.rs:24:5 + --> $DIR/offset-of.rs:23:5 | LL | struct Delta { | ----- field in this struct @@ -39,7 +39,7 @@ LL | b: (), | ^ error: field `a` is never read - --> $DIR/offset-of.rs:35:5 + --> $DIR/offset-of.rs:34:5 | LL | struct Project { | ------- field in this struct diff --git a/tests/ui/offset-of/offset-of-enum.rs b/tests/ui/offset-of/offset-of-enum.rs index cb2f04786ac5c..64850e4782335 100644 --- a/tests/ui/offset-of/offset-of-enum.rs +++ b/tests/ui/offset-of/offset-of-enum.rs @@ -1,4 +1,4 @@ -#![feature(offset_of_enum, offset_of_nested)] +#![feature(offset_of_enum)] use std::mem::offset_of; diff --git a/tests/ui/offset-of/offset-of-private.rs b/tests/ui/offset-of/offset-of-private.rs index 1c326b5c79a5e..8b8ffb5e08e90 100644 --- a/tests/ui/offset-of/offset-of-private.rs +++ b/tests/ui/offset-of/offset-of-private.rs @@ -1,4 +1,4 @@ -#![feature(offset_of_enum, offset_of_nested)] +#![feature(offset_of_enum)] use std::mem::offset_of; diff --git a/tests/ui/offset-of/offset-of-self.rs b/tests/ui/offset-of/offset-of-self.rs index 1558e13b53095..e5730b8cf6cdb 100644 --- a/tests/ui/offset-of/offset-of-self.rs +++ b/tests/ui/offset-of/offset-of-self.rs @@ -1,5 +1,3 @@ -#![feature(offset_of_nested)] - use std::mem::offset_of; struct C { diff --git a/tests/ui/offset-of/offset-of-self.stderr b/tests/ui/offset-of/offset-of-self.stderr index 7c7576e066b6f..5bbb4ecf091a7 100644 --- a/tests/ui/offset-of/offset-of-self.stderr +++ b/tests/ui/offset-of/offset-of-self.stderr @@ -1,11 +1,11 @@ error: offset_of expects dot-separated field and variant names - --> $DIR/offset-of-self.rs:20:26 + --> $DIR/offset-of-self.rs:18:26 | LL | offset_of!(Self, Self::v); | ^^^^^^^ error[E0412]: cannot find type `S` in module `self` - --> $DIR/offset-of-self.rs:34:26 + --> $DIR/offset-of-self.rs:32:26 | LL | offset_of!(self::S, v); | ^ not found in `self` @@ -21,7 +21,7 @@ LL + offset_of!(S, v); | error[E0411]: cannot find type `Self` in this scope - --> $DIR/offset-of-self.rs:51:16 + --> $DIR/offset-of-self.rs:49:16 | LL | fn main() { | ---- `Self` not allowed in a function @@ -30,7 +30,7 @@ LL | offset_of!(Self, v); | ^^^^ `Self` is only available in impls, traits, and type definitions error[E0609]: no field `Self` on type `S` - --> $DIR/offset-of-self.rs:21:23 + --> $DIR/offset-of-self.rs:19:23 | LL | offset_of!(S, Self); | ^^^^ @@ -38,13 +38,13 @@ LL | offset_of!(S, Self); = note: available fields are: `v`, `w` error[E0616]: field `v` of struct `T` is private - --> $DIR/offset-of-self.rs:40:30 + --> $DIR/offset-of-self.rs:38:30 | LL | offset_of!(Self, v) | ^ private field error[E0609]: no field `self` on type `S` - --> $DIR/offset-of-self.rs:53:19 + --> $DIR/offset-of-self.rs:51:19 | LL | offset_of!(S, self); | ^^^^ @@ -52,7 +52,7 @@ LL | offset_of!(S, self); = note: available fields are: `v`, `w` error[E0609]: no field `self` on type `u8` - --> $DIR/offset-of-self.rs:54:21 + --> $DIR/offset-of-self.rs:52:21 | LL | offset_of!(S, v.self); | ^^^^ diff --git a/tests/ui/offset-of/offset-of-slice.rs b/tests/ui/offset-of/offset-of-slice.rs index a0fe3198f6869..e6eb12abd7bbc 100644 --- a/tests/ui/offset-of/offset-of-slice.rs +++ b/tests/ui/offset-of/offset-of-slice.rs @@ -1,5 +1,5 @@ //@run-pass -#![feature(offset_of_slice, offset_of_nested)] +#![feature(offset_of_slice)] use std::mem::offset_of; diff --git a/tests/ui/offset-of/offset-of-tuple-nested.rs b/tests/ui/offset-of/offset-of-tuple-nested.rs index 4a58b7167cb7c..210a8b6e897b3 100644 --- a/tests/ui/offset-of/offset-of-tuple-nested.rs +++ b/tests/ui/offset-of/offset-of-tuple-nested.rs @@ -2,8 +2,6 @@ // Test for issue #112204 -- make sure this goes through the entire compilation pipeline, // similar to why `offset-of-unsized.rs` is also build-pass -#![feature(offset_of_nested)] - use std::mem::offset_of; type ComplexTup = ((u8, (u8, (u8, u16), u8)), (u8, u32, u16)); diff --git a/tests/ui/offset-of/offset-of-tuple.rs b/tests/ui/offset-of/offset-of-tuple.rs index 75ba8d77f2fbd..b0822352c9dc6 100644 --- a/tests/ui/offset-of/offset-of-tuple.rs +++ b/tests/ui/offset-of/offset-of-tuple.rs @@ -1,4 +1,3 @@ -#![feature(offset_of_nested)] #![feature(builtin_syntax)] use std::mem::offset_of; diff --git a/tests/ui/offset-of/offset-of-tuple.stderr b/tests/ui/offset-of/offset-of-tuple.stderr index 1e2d9240267da..e6b45c0b6b846 100644 --- a/tests/ui/offset-of/offset-of-tuple.stderr +++ b/tests/ui/offset-of/offset-of-tuple.stderr @@ -1,11 +1,11 @@ error: suffixes on a tuple index are invalid - --> $DIR/offset-of-tuple.rs:19:35 + --> $DIR/offset-of-tuple.rs:18:35 | LL | builtin # offset_of((u8, u8), 1_u8); | ^^^^ invalid suffix `u8` error: leading `+` is not supported - --> $DIR/offset-of-tuple.rs:23:37 + --> $DIR/offset-of-tuple.rs:22:37 | LL | { builtin # offset_of((u8, u8), +1) }; | ^ unexpected `+` @@ -17,67 +17,67 @@ LL + { builtin # offset_of((u8, u8), 1) }; | error: offset_of expects dot-separated field and variant names - --> $DIR/offset-of-tuple.rs:24:38 + --> $DIR/offset-of-tuple.rs:23:38 | LL | { builtin # offset_of((u8, u8), 1.) }; | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:25:40 + --> $DIR/offset-of-tuple.rs:24:40 | LL | { builtin # offset_of((u8, u8), 1 .) }; | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:47:45 + --> $DIR/offset-of-tuple.rs:46:45 | LL | { builtin # offset_of(ComplexTup, 0.0.1.) }; | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:48:46 + --> $DIR/offset-of-tuple.rs:47:46 | LL | { builtin # offset_of(ComplexTup, 0 .0.1.) }; | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:49:47 + --> $DIR/offset-of-tuple.rs:48:47 | LL | { builtin # offset_of(ComplexTup, 0 . 0.1.) }; | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:50:46 + --> $DIR/offset-of-tuple.rs:49:46 | LL | { builtin # offset_of(ComplexTup, 0. 0.1.) }; | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:51:46 + --> $DIR/offset-of-tuple.rs:50:46 | LL | { builtin # offset_of(ComplexTup, 0.0 .1.) }; | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:52:47 + --> $DIR/offset-of-tuple.rs:51:47 | LL | { builtin # offset_of(ComplexTup, 0.0 . 1.) }; | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:53:46 + --> $DIR/offset-of-tuple.rs:52:46 | LL | { builtin # offset_of(ComplexTup, 0.0. 1.) }; | ^ error: suffixes on a tuple index are invalid - --> $DIR/offset-of-tuple.rs:10:26 + --> $DIR/offset-of-tuple.rs:9:26 | LL | offset_of!((u8, u8), 1_u8); | ^^^^ invalid suffix `u8` error: no rules expected the token `+` - --> $DIR/offset-of-tuple.rs:12:26 + --> $DIR/offset-of-tuple.rs:11:26 | LL | offset_of!((u8, u8), +1); | ^ no rules expected this token in macro call @@ -86,115 +86,115 @@ note: while trying to match meta-variable `$fields:expr` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL error: offset_of expects dot-separated field and variant names - --> $DIR/offset-of-tuple.rs:13:26 + --> $DIR/offset-of-tuple.rs:12:26 | LL | offset_of!((u8, u8), -1); | ^^ error: offset_of expects dot-separated field and variant names - --> $DIR/offset-of-tuple.rs:14:27 + --> $DIR/offset-of-tuple.rs:13:27 | LL | offset_of!((u8, u8), 1.); | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:15:29 + --> $DIR/offset-of-tuple.rs:14:29 | LL | offset_of!((u8, u8), 1 .); | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:36:34 + --> $DIR/offset-of-tuple.rs:35:34 | LL | offset_of!(ComplexTup, 0.0.1.); | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:37:35 + --> $DIR/offset-of-tuple.rs:36:35 | LL | offset_of!(ComplexTup, 0 .0.1.); | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:38:36 + --> $DIR/offset-of-tuple.rs:37:36 | LL | offset_of!(ComplexTup, 0 . 0.1.); | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:39:35 + --> $DIR/offset-of-tuple.rs:38:35 | LL | offset_of!(ComplexTup, 0. 0.1.); | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:40:35 + --> $DIR/offset-of-tuple.rs:39:35 | LL | offset_of!(ComplexTup, 0.0 .1.); | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:41:36 + --> $DIR/offset-of-tuple.rs:40:36 | LL | offset_of!(ComplexTup, 0.0 . 1.); | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:42:35 + --> $DIR/offset-of-tuple.rs:41:35 | LL | offset_of!(ComplexTup, 0.0. 1.); | ^ error[E0609]: no field `_0` on type `(u8, u8)` - --> $DIR/offset-of-tuple.rs:7:26 + --> $DIR/offset-of-tuple.rs:6:26 | LL | offset_of!((u8, u8), _0); | ^^ error[E0609]: no field `01` on type `(u8, u8)` - --> $DIR/offset-of-tuple.rs:8:26 + --> $DIR/offset-of-tuple.rs:7:26 | LL | offset_of!((u8, u8), 01); | ^^ error[E0609]: no field `1e2` on type `(u8, u8)` - --> $DIR/offset-of-tuple.rs:9:26 + --> $DIR/offset-of-tuple.rs:8:26 | LL | offset_of!((u8, u8), 1e2); | ^^^ error[E0609]: no field `1_` on type `(u8, u8)` - --> $DIR/offset-of-tuple.rs:10:26 + --> $DIR/offset-of-tuple.rs:9:26 | LL | offset_of!((u8, u8), 1_u8); | ^^^^ error[E0609]: no field `1e2` on type `(u8, u8)` - --> $DIR/offset-of-tuple.rs:16:35 + --> $DIR/offset-of-tuple.rs:15:35 | LL | builtin # offset_of((u8, u8), 1e2); | ^^^ error[E0609]: no field `_0` on type `(u8, u8)` - --> $DIR/offset-of-tuple.rs:17:35 + --> $DIR/offset-of-tuple.rs:16:35 | LL | builtin # offset_of((u8, u8), _0); | ^^ error[E0609]: no field `01` on type `(u8, u8)` - --> $DIR/offset-of-tuple.rs:18:35 + --> $DIR/offset-of-tuple.rs:17:35 | LL | builtin # offset_of((u8, u8), 01); | ^^ error[E0609]: no field `1_` on type `(u8, u8)` - --> $DIR/offset-of-tuple.rs:19:35 + --> $DIR/offset-of-tuple.rs:18:35 | LL | builtin # offset_of((u8, u8), 1_u8); | ^^^^ error[E0609]: no field `2` on type `(u8, u16)` - --> $DIR/offset-of-tuple.rs:31:47 + --> $DIR/offset-of-tuple.rs:30:47 | LL | offset_of!(((u8, u16), (u32, u16, u8)), 0.2); | _____------------------------------------------^- @@ -207,7 +207,7 @@ LL | | offset_of!(((u8, u16), (u32, u16, u8)), 1.2.0); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0609]: no field `0` on type `u8` - --> $DIR/offset-of-tuple.rs:33:49 + --> $DIR/offset-of-tuple.rs:32:49 | LL | offset_of!(((u8, u16), (u32, u16, u8)), 1.2.0); | ^ diff --git a/tests/ui/offset-of/offset-of-unstable-with-feature.rs b/tests/ui/offset-of/offset-of-unstable-with-feature.rs index c9d4f30e99a20..c2614ba3d8af8 100644 --- a/tests/ui/offset-of/offset-of-unstable-with-feature.rs +++ b/tests/ui/offset-of/offset-of-unstable-with-feature.rs @@ -1,7 +1,7 @@ //@ check-pass //@ aux-build:offset-of-staged-api.rs -#![feature(offset_of_nested, unstable_test_feature)] +#![feature(unstable_test_feature)] use std::mem::offset_of; diff --git a/tests/ui/offset-of/offset-of-unstable.rs b/tests/ui/offset-of/offset-of-unstable.rs index ab6f89ce52a53..d249e8871c326 100644 --- a/tests/ui/offset-of/offset-of-unstable.rs +++ b/tests/ui/offset-of/offset-of-unstable.rs @@ -1,7 +1,5 @@ //@ aux-build:offset-of-staged-api.rs -#![feature(offset_of_nested)] - use std::mem::offset_of; extern crate offset_of_staged_api; diff --git a/tests/ui/offset-of/offset-of-unstable.stderr b/tests/ui/offset-of/offset-of-unstable.stderr index 4882dee404226..44ccad3ff39fd 100644 --- a/tests/ui/offset-of/offset-of-unstable.stderr +++ b/tests/ui/offset-of/offset-of-unstable.stderr @@ -1,5 +1,5 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' - --> $DIR/offset-of-unstable.rs:14:9 + --> $DIR/offset-of-unstable.rs:12:9 | LL | Unstable, | ^^^^^^^^ @@ -8,7 +8,7 @@ LL | Unstable, = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature 'unstable_test_feature' - --> $DIR/offset-of-unstable.rs:23:9 + --> $DIR/offset-of-unstable.rs:21:9 | LL | UnstableWithStableFieldType, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | UnstableWithStableFieldType, = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature 'unstable_test_feature' - --> $DIR/offset-of-unstable.rs:28:9 + --> $DIR/offset-of-unstable.rs:26:9 | LL | UnstableWithStableFieldType, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | UnstableWithStableFieldType, = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature 'unstable_test_feature' - --> $DIR/offset-of-unstable.rs:12:5 + --> $DIR/offset-of-unstable.rs:10:5 | LL | / offset_of!( LL | | @@ -40,7 +40,7 @@ LL | | ); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: use of unstable library feature 'unstable_test_feature' - --> $DIR/offset-of-unstable.rs:18:5 + --> $DIR/offset-of-unstable.rs:16:5 | LL | offset_of!(StableWithUnstableField, unstable); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -50,7 +50,7 @@ LL | offset_of!(StableWithUnstableField, unstable); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: use of unstable library feature 'unstable_test_feature' - --> $DIR/offset-of-unstable.rs:20:5 + --> $DIR/offset-of-unstable.rs:18:5 | LL | offset_of!(StableWithUnstableFieldType, stable.unstable); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL | offset_of!(StableWithUnstableFieldType, stable.unstable); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: use of unstable library feature 'unstable_test_feature' - --> $DIR/offset-of-unstable.rs:21:5 + --> $DIR/offset-of-unstable.rs:19:5 | LL | / offset_of!( LL | | @@ -74,7 +74,7 @@ LL | | ); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: use of unstable library feature 'unstable_test_feature' - --> $DIR/offset-of-unstable.rs:26:5 + --> $DIR/offset-of-unstable.rs:24:5 | LL | / offset_of!( LL | | From f4fa80ff5a10e468360f1a5a7090fae8519488a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Mon, 29 Jul 2024 17:01:39 +0000 Subject: [PATCH 09/12] triagebot: make sure Nora is called Nora --- triagebot.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index 5c5aa47538518..2795f93728470 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -852,7 +852,7 @@ cc = ["@Urgau"] cc = ["@Urgau"] [mentions."src/doc/rustc/src/platform-support"] -cc = ["@Nilstrieb"] +cc = ["@Noratrieb"] [mentions."tests/codegen/sanitizer"] cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"] @@ -938,7 +938,7 @@ libs = [ "@cuviper", "@Mark-Simulacrum", "@Amanieu", - "@Nilstrieb", + "@Noratrieb", "@workingjubilee", "@joboet", "@jhpratt", From 1d339b07ca84743710dc87dc0bc4c0597006ed59 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 6 Jul 2024 19:07:22 -0700 Subject: [PATCH 10/12] rustdoc: use `` in sidebar headers This also improves sidebar layout, so instead of BTreeM ap you get this BTree Map --- src/librustdoc/html/layout.rs | 2 ++ src/librustdoc/html/render/mod.rs | 2 +- src/librustdoc/html/render/sidebar.rs | 16 ++++++++++++++++ src/librustdoc/html/templates/page.html | 2 +- src/librustdoc/html/templates/sidebar.html | 6 ++++-- 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 7dfcc88398faf..780cda9b1cdf4 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -69,6 +69,8 @@ struct PageLayout<'a> { display_krate_version_extra: &'a str, } +pub(crate) use crate::html::render::sidebar::filters; + pub(crate) fn render( layout: &Layout, page: &Page<'_>, diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index aaac8678264aa..b5cc495ce41ef 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -30,7 +30,7 @@ mod tests; mod context; mod print_item; -mod sidebar; +pub(crate) mod sidebar; mod span_map; mod type_layout; mod write_shared; diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index 6e826446c0e0e..101cc839f0988 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -77,6 +77,22 @@ impl<'a> Link<'a> { } } +pub(crate) mod filters { + use std::fmt::Display; + + use rinja::filters::Safe; + + use crate::html::escape::EscapeBodyTextWithWbr; + use crate::html::render::display_fn; + pub(crate) fn wrapped(v: T) -> rinja::Result> + where + T: Display, + { + let string = v.to_string(); + Ok(Safe(display_fn(move |f| EscapeBodyTextWithWbr(&string).fmt(f)))) + } +} + pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer) { let blocks: Vec> = match *it.kind { clean::StructItem(ref s) => sidebar_struct(cx, it, s), diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index cdf01fa7a97e8..65c4304e20207 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -98,7 +98,7 @@ {# #} {% endif %}

    {# #} - {{display_krate}} {# #} + {{display_krate|wrapped|safe}} {# #} {% if !display_krate_version_number.is_empty() %} {{+ display_krate_version_number}} {% endif %} diff --git a/src/librustdoc/html/templates/sidebar.html b/src/librustdoc/html/templates/sidebar.html index 3251b4c14c95a..025220ab4159c 100644 --- a/src/librustdoc/html/templates/sidebar.html +++ b/src/librustdoc/html/templates/sidebar.html @@ -1,6 +1,6 @@ {% if !title.is_empty() %}

    {# #} - {{title_prefix}}{{title}} {# #} + {{title_prefix}}{{title|wrapped|safe}} {# #}

    {% endif %} diff --git a/tests/rustdoc-gui/label-next-to-symbol.goml b/tests/rustdoc-gui/label-next-to-symbol.goml index 1fa0a120adaec..a8363f29dd5de 100644 --- a/tests/rustdoc-gui/label-next-to-symbol.goml +++ b/tests/rustdoc-gui/label-next-to-symbol.goml @@ -27,7 +27,8 @@ compare-elements-position-near: ( ".item-name .stab.deprecated", {"y": 2}, ) -compare-elements-position: ( +// "Unix" part is on second line +compare-elements-position-false: ( ".item-name .stab.deprecated", ".item-name .stab.portability", ["y"], From ac303df4e21eabfbf692f2d1959f7403f4887a31 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 22 Jul 2024 09:49:49 -0700 Subject: [PATCH 12/12] rustdoc: move the wbr after the underscore, instead of before --- src/librustdoc/html/escape.rs | 8 ++++---- src/librustdoc/html/escape/tests.rs | 8 ++++---- tests/rustdoc/item-desc-list-at-start.item-table.html | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs index f8199cd6e0e7f..691f86847b56d 100644 --- a/src/librustdoc/html/escape.rs +++ b/src/librustdoc/html/escape.rs @@ -108,13 +108,13 @@ impl<'a> fmt::Display for EscapeBodyTextWithWbr<'a> { || pk.map_or(true, |(_, t)| t.chars().any(|c| c.is_uppercase())); let next_is_underscore = || pk.map_or(true, |(_, t)| t.contains('_')); let next_is_colon = || pk.map_or(true, |(_, t)| t.contains(':')); - if (i - last > 3 && is_uppercase() && !next_is_uppercase()) - || (s.contains('_') && !next_is_underscore()) - { + if i - last > 3 && is_uppercase() && !next_is_uppercase() { EscapeBodyText(&text[last..i]).fmt(fmt)?; fmt.write_str("")?; last = i; - } else if s.contains(':') && !next_is_colon() { + } else if (s.contains(':') && !next_is_colon()) + || (s.contains('_') && !next_is_underscore()) + { EscapeBodyText(&text[last..i + 1]).fmt(fmt)?; fmt.write_str("")?; last = i + 1; diff --git a/src/librustdoc/html/escape/tests.rs b/src/librustdoc/html/escape/tests.rs index e2d81cf5c27aa..a09649e9e18dc 100644 --- a/src/librustdoc/html/escape/tests.rs +++ b/src/librustdoc/html/escape/tests.rs @@ -14,16 +14,16 @@ fn escape_body_text_with_wbr() { assert_eq!(&E(" ").to_string(), " "); // real(istic) examples assert_eq!(&E("FirstSecond").to_string(), "FirstSecond"); - assert_eq!(&E("First_Second").to_string(), "First_Second"); + assert_eq!(&E("First_Second").to_string(), "First_Second"); assert_eq!(&E("First Second").to_string(), "First Second"); assert_eq!(&E("First HSecond").to_string(), "First HSecond"); assert_eq!(&E("First HTTPSecond").to_string(), "First HTTPSecond"); assert_eq!(&E("First SecondThird").to_string(), "First SecondThird"); - assert_eq!(&E("First_Second").to_string(), "First<T>_Second"); - assert_eq!(&E("first_second").to_string(), "first_second"); + assert_eq!(&E("First_Second").to_string(), "First<T>_Second"); + assert_eq!(&E("first_second").to_string(), "first_second"); assert_eq!(&E("first:second").to_string(), "first:second"); assert_eq!(&E("first::second").to_string(), "first::second"); - assert_eq!(&E("MY_CONSTANT").to_string(), "MY_CONSTANT"); + assert_eq!(&E("MY_CONSTANT").to_string(), "MY_CONSTANT"); // a string won't get wrapped if it's less than 8 bytes assert_eq!(&E("HashSet").to_string(), "HashSet"); // an individual word won't get wrapped if it's less than 4 bytes diff --git a/tests/rustdoc/item-desc-list-at-start.item-table.html b/tests/rustdoc/item-desc-list-at-start.item-table.html index ab8b1508b5519..cff4f816529c3 100644 --- a/tests/rustdoc/item-desc-list-at-start.item-table.html +++ b/tests/rustdoc/item-desc-list-at-start.item-table.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file