Auto merge of #102915 - JohnTitor:rollup-5ht99y1, r=JohnTitor

Rollup of 7 pull requests

Successful merges:

 - #102258 (Remove unused variable in float formatting.)
 - #102277 (Consistently write `RwLock`)
 - #102412 (Never panic in `thread::park` and `thread::park_timeout`)
 - #102589 (scoped threads: pass closure through MaybeUninit to avoid invalid dangling references)
 - #102625 (fix backtrace small typo)
 - #102859 (Move lifetime resolution module to rustc_hir_analysis.)
 - #102898 (rustdoc: remove unneeded `<div>` wrapper from sidebar DOM)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-10-11 11:03:12 +00:00
commit bb93450ec4
16 changed files with 128 additions and 109 deletions

View File

@ -46,6 +46,7 @@ use std::iter;
mod generics_of;
mod item_bounds;
mod lifetimes;
mod predicates_of;
mod type_of;
@ -57,6 +58,7 @@ fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
}
pub fn provide(providers: &mut Providers) {
lifetimes::provide(providers);
*providers = Providers {
opt_const_param_of: type_of::opt_const_param_of,
type_of: type_of::type_of,

View File

@ -32,8 +32,6 @@ trait RegionExt {
fn id(&self) -> Option<DefId>;
fn shifted(self, amount: u32) -> Region;
fn shifted_out_to_binder(self, binder: ty::DebruijnIndex) -> Region;
}
impl RegionExt for Region {
@ -69,15 +67,6 @@ impl RegionExt for Region {
_ => self,
}
}
fn shifted_out_to_binder(self, binder: ty::DebruijnIndex) -> Region {
match self {
Region::LateBound(debruijn, index, id) => {
Region::LateBound(debruijn.shifted_out_to_binder(binder), index, id)
}
_ => self,
}
}
}
/// Maps the id of each lifetime reference to the lifetime decl
@ -101,8 +90,8 @@ struct NamedRegionMap {
late_bound_vars: HirIdMap<Vec<ty::BoundVariableKind>>,
}
pub(crate) struct LifetimeContext<'a, 'tcx> {
pub(crate) tcx: TyCtxt<'tcx>,
struct LifetimeContext<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
map: &'a mut NamedRegionMap,
scope: ScopeRef<'a>,
@ -234,7 +223,7 @@ type ScopeRef<'a> = &'a Scope<'a>;
const ROOT_SCOPE: ScopeRef<'static> = &Scope::Root;
pub fn provide(providers: &mut ty::query::Providers) {
pub(crate) fn provide(providers: &mut ty::query::Providers) {
*providers = ty::query::Providers {
resolve_lifetimes_trait_definition,
resolve_lifetimes,

View File

@ -739,7 +739,6 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
ty::provide(providers);
traits::provide(providers);
rustc_passes::provide(providers);
rustc_resolve::provide(providers);
rustc_traits::provide(providers);
rustc_ty_utils::provide(providers);
rustc_metadata::provide(providers);

View File

@ -34,7 +34,6 @@ use std::collections::{hash_map::Entry, BTreeSet};
use std::mem::{replace, take};
mod diagnostics;
pub(crate) mod lifetimes;
type Res = def::Res<NodeId>;

View File

@ -42,7 +42,6 @@ use rustc_metadata::creader::{CStore, CrateLoader};
use rustc_middle::metadata::ModChild;
use rustc_middle::middle::privacy::AccessLevels;
use rustc_middle::span_bug;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, DefIdTree, MainDefinition, RegisteredTools, ResolverOutputs};
use rustc_query_system::ich::StableHashingContext;
use rustc_session::cstore::{CrateStore, CrateStoreDyn, MetadataLoaderDyn};
@ -2082,7 +2081,3 @@ impl Finalize {
Finalize { node_id, path_span, root_span, report_private: true }
}
}
pub fn provide(providers: &mut Providers) {
late::lifetimes::provide(providers);
}

View File

@ -253,7 +253,6 @@ pub fn format_shortest_opt<'a>(
let delta1frac = delta1 & ((1 << e) - 1);
// render integral parts, while checking for the accuracy at each step.
let mut kappa = max_kappa as i16;
let mut ten_kappa = max_ten_kappa; // 10^kappa
let mut remainder = plus1int; // digits yet to be rendered
loop {
@ -290,12 +289,10 @@ pub fn format_shortest_opt<'a>(
// the exact number of digits is `max_kappa + 1` as `plus1 < 10^(max_kappa+1)`.
if i > max_kappa as usize {
debug_assert_eq!(ten_kappa, 1);
debug_assert_eq!(kappa, 0);
break;
}
// restore invariants
kappa -= 1;
ten_kappa /= 10;
remainder = r;
}
@ -338,7 +335,6 @@ pub fn format_shortest_opt<'a>(
}
// restore invariants
kappa -= 1;
remainder = r;
}

View File

@ -14,8 +14,8 @@
//! Backtraces are attempted to be as accurate as possible, but no guarantees
//! are provided about the exact accuracy of a backtrace. Instruction pointers,
//! symbol names, filenames, line numbers, etc, may all be incorrect when
//! reported. Accuracy is attempted on a best-effort basis, however, and bugs
//! are always welcome to indicate areas of improvement!
//! reported. Accuracy is attempted on a best-effort basis, however, any bug
//! reports are always welcome to indicate areas of improvement!
//!
//! For most platforms a backtrace with a filename/line number requires that
//! programs be compiled with debug information. Without debug information
@ -39,7 +39,7 @@
//! default. Its behavior is governed by two environment variables:
//!
//! * `RUST_LIB_BACKTRACE` - if this is set to `0` then `Backtrace::capture`
//! will never capture a backtrace. Any other value this is set to will enable
//! will never capture a backtrace. Any other value set will enable
//! `Backtrace::capture`.
//!
//! * `RUST_BACKTRACE` - if `RUST_LIB_BACKTRACE` is not set, then this variable

View File

@ -167,7 +167,7 @@ impl<T> RwLock<T> {
}
impl<T: ?Sized> RwLock<T> {
/// Locks this rwlock with shared read access, blocking the current thread
/// Locks this `RwLock` with shared read access, blocking the current thread
/// until it can be acquired.
///
/// The calling thread will be blocked until there are no more writers which
@ -181,9 +181,10 @@ impl<T: ?Sized> RwLock<T> {
///
/// # Errors
///
/// This function will return an error if the RwLock is poisoned. An RwLock
/// is poisoned whenever a writer panics while holding an exclusive lock.
/// The failure will occur immediately after the lock has been acquired.
/// This function will return an error if the `RwLock` is poisoned. An
/// `RwLock` is poisoned whenever a writer panics while holding an exclusive
/// lock. The failure will occur immediately after the lock has been
/// acquired.
///
/// # Panics
///
@ -215,7 +216,7 @@ impl<T: ?Sized> RwLock<T> {
}
}
/// Attempts to acquire this rwlock with shared read access.
/// Attempts to acquire this `RwLock` with shared read access.
///
/// If the access could not be granted at this time, then `Err` is returned.
/// Otherwise, an RAII guard is returned which will release the shared access
@ -228,13 +229,13 @@ impl<T: ?Sized> RwLock<T> {
///
/// # Errors
///
/// This function will return the [`Poisoned`] error if the RwLock is poisoned.
/// An RwLock is poisoned whenever a writer panics while holding an exclusive
/// lock. `Poisoned` will only be returned if the lock would have otherwise been
/// acquired.
/// This function will return the [`Poisoned`] error if the `RwLock` is
/// poisoned. An `RwLock` is poisoned whenever a writer panics while holding
/// an exclusive lock. `Poisoned` will only be returned if the lock would
/// have otherwise been acquired.
///
/// This function will return the [`WouldBlock`] error if the RwLock could not
/// be acquired because it was already locked exclusively.
/// This function will return the [`WouldBlock`] error if the `RwLock` could
/// not be acquired because it was already locked exclusively.
///
/// [`Poisoned`]: TryLockError::Poisoned
/// [`WouldBlock`]: TryLockError::WouldBlock
@ -263,20 +264,20 @@ impl<T: ?Sized> RwLock<T> {
}
}
/// Locks this rwlock with exclusive write access, blocking the current
/// Locks this `RwLock` with exclusive write access, blocking the current
/// thread until it can be acquired.
///
/// This function will not return while other writers or other readers
/// currently have access to the lock.
///
/// Returns an RAII guard which will drop the write access of this rwlock
/// Returns an RAII guard which will drop the write access of this `RwLock`
/// when dropped.
///
/// # Errors
///
/// This function will return an error if the RwLock is poisoned. An RwLock
/// is poisoned whenever a writer panics while holding an exclusive lock.
/// An error will be returned when the lock is acquired.
/// This function will return an error if the `RwLock` is poisoned. An
/// `RwLock` is poisoned whenever a writer panics while holding an exclusive
/// lock. An error will be returned when the lock is acquired.
///
/// # Panics
///
@ -303,7 +304,7 @@ impl<T: ?Sized> RwLock<T> {
}
}
/// Attempts to lock this rwlock with exclusive write access.
/// Attempts to lock this `RwLock` with exclusive write access.
///
/// If the lock could not be acquired at this time, then `Err` is returned.
/// Otherwise, an RAII guard is returned which will release the lock when
@ -316,13 +317,13 @@ impl<T: ?Sized> RwLock<T> {
///
/// # Errors
///
/// This function will return the [`Poisoned`] error if the RwLock is
/// poisoned. An RwLock is poisoned whenever a writer panics while holding
/// an exclusive lock. `Poisoned` will only be returned if the lock would have
/// otherwise been acquired.
/// This function will return the [`Poisoned`] error if the `RwLock` is
/// poisoned. An `RwLock` is poisoned whenever a writer panics while holding
/// an exclusive lock. `Poisoned` will only be returned if the lock would
/// have otherwise been acquired.
///
/// This function will return the [`WouldBlock`] error if the RwLock could not
/// be acquired because it was already locked exclusively.
/// This function will return the [`WouldBlock`] error if the `RwLock` could
/// not be acquired because it was already locked exclusively.
///
/// [`Poisoned`]: TryLockError::Poisoned
/// [`WouldBlock`]: TryLockError::WouldBlock
@ -422,10 +423,10 @@ impl<T: ?Sized> RwLock<T> {
///
/// # Errors
///
/// This function will return an error if the RwLock is poisoned. An RwLock
/// is poisoned whenever a writer panics while holding an exclusive lock. An
/// error will only be returned if the lock would have otherwise been
/// acquired.
/// This function will return an error if the `RwLock` is poisoned. An
/// `RwLock` is poisoned whenever a writer panics while holding an exclusive
/// lock. An error will only be returned if the lock would have otherwise
/// been acquired.
///
/// # Examples
///
@ -455,10 +456,10 @@ impl<T: ?Sized> RwLock<T> {
///
/// # Errors
///
/// This function will return an error if the RwLock is poisoned. An RwLock
/// is poisoned whenever a writer panics while holding an exclusive lock. An
/// error will only be returned if the lock would have otherwise been
/// acquired.
/// This function will return an error if the `RwLock` is poisoned. An
/// `RwLock` is poisoned whenever a writer panics while holding an exclusive
/// lock. An error will only be returned if the lock would have otherwise
/// been acquired.
///
/// # Examples
///

View File

@ -160,7 +160,7 @@ use crate::ffi::{CStr, CString};
use crate::fmt;
use crate::io;
use crate::marker::PhantomData;
use crate::mem;
use crate::mem::{self, forget};
use crate::num::NonZeroU64;
use crate::num::NonZeroUsize;
use crate::panic;
@ -499,6 +499,31 @@ impl Builder {
let output_capture = crate::io::set_output_capture(None);
crate::io::set_output_capture(output_capture.clone());
// Pass `f` in `MaybeUninit` because actually that closure might *run longer than the lifetime of `F`*.
// See <https://github.com/rust-lang/rust/issues/101983> for more details.
// To prevent leaks we use a wrapper that drops its contents.
#[repr(transparent)]
struct MaybeDangling<T>(mem::MaybeUninit<T>);
impl<T> MaybeDangling<T> {
fn new(x: T) -> Self {
MaybeDangling(mem::MaybeUninit::new(x))
}
fn into_inner(self) -> T {
// SAFETY: we are always initiailized.
let ret = unsafe { self.0.assume_init_read() };
// Make sure we don't drop.
mem::forget(self);
ret
}
}
impl<T> Drop for MaybeDangling<T> {
fn drop(&mut self) {
// SAFETY: we are always initiailized.
unsafe { self.0.assume_init_drop() };
}
}
let f = MaybeDangling::new(f);
let main = move || {
if let Some(name) = their_thread.cname() {
imp::Thread::set_name(name);
@ -506,6 +531,8 @@ impl Builder {
crate::io::set_output_capture(output_capture);
// SAFETY: we constructed `f` initialized.
let f = f.into_inner();
// SAFETY: the stack guard passed is the one for the current thread.
// This means the current thread's stack and the new thread's stack
// are properly set and protected from each other.
@ -518,6 +545,12 @@ impl Builder {
// same `JoinInner` as this closure meaning the mutation will be
// safe (not modify it and affect a value far away).
unsafe { *their_packet.result.get() = Some(try_result) };
// Here `their_packet` gets dropped, and if this is the last `Arc` for that packet that
// will call `decrement_num_running_threads` and therefore signal that this thread is
// done.
drop(their_packet);
// Here, the lifetime `'a` and even `'scope` can end. `main` keeps running for a bit
// after that before returning itself.
};
if let Some(scope_data) = &my_packet.scope {
@ -851,10 +884,22 @@ pub fn sleep(dur: Duration) {
imp::Thread::sleep(dur)
}
/// Used to ensure that `park` and `park_timeout` do not unwind, as that can
/// cause undefined behaviour if not handled correctly (see #102398 for context).
struct PanicGuard;
impl Drop for PanicGuard {
fn drop(&mut self) {
rtabort!("an irrecoverable error occurred while synchronizing threads")
}
}
/// Blocks unless or until the current thread's token is made available.
///
/// A call to `park` does not guarantee that the thread will remain parked
/// forever, and callers should be prepared for this possibility.
/// forever, and callers should be prepared for this possibility. However,
/// it is guaranteed that this function will not panic (it may abort the
/// process if the implementation encounters some rare errors).
///
/// # park and unpark
///
@ -939,10 +984,13 @@ pub fn sleep(dur: Duration) {
/// [`thread::park_timeout`]: park_timeout
#[stable(feature = "rust1", since = "1.0.0")]
pub fn park() {
let guard = PanicGuard;
// SAFETY: park_timeout is called on the parker owned by this thread.
unsafe {
current().inner.as_ref().parker().park();
}
// No panic occurred, do not abort.
forget(guard);
}
/// Use [`park_timeout`].
@ -1003,10 +1051,13 @@ pub fn park_timeout_ms(ms: u32) {
/// ```
#[stable(feature = "park_timeout", since = "1.4.0")]
pub fn park_timeout(dur: Duration) {
let guard = PanicGuard;
// SAFETY: park_timeout is called on the parker owned by this thread.
unsafe {
current().inner.as_ref().parker().park_timeout(dur);
}
// No panic occurred, do not abort.
forget(guard);
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -1853,12 +1853,12 @@ fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer) {
buffer.write_str("<div class=\"sidebar-elems\">");
if it.is_crate() {
write!(buffer, "<div class=\"block\"><ul>");
write!(buffer, "<ul class=\"block\">");
if let Some(ref version) = cx.cache().crate_version {
write!(buffer, "<li class=\"version\">Version {}</li>", Escape(version));
}
write!(buffer, "<li><a id=\"all-types\" href=\"all.html\">All Items</a></li>");
buffer.write_str("</ul></div>");
buffer.write_str("</ul>");
}
match *it.kind {
@ -2258,8 +2258,7 @@ fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String
}
}
/// Don't call this function directly!!! Use `print_sidebar_title` or `print_sidebar_block` instead!
fn print_sidebar_title_inner(buf: &mut Buffer, id: &str, title: &str) {
fn print_sidebar_title(buf: &mut Buffer, id: &str, title: &str) {
write!(
buf,
"<h3 class=\"sidebar-title\">\
@ -2269,25 +2268,18 @@ fn print_sidebar_title_inner(buf: &mut Buffer, id: &str, title: &str) {
);
}
fn print_sidebar_title(buf: &mut Buffer, id: &str, title: &str) {
buf.push_str("<div class=\"block\">");
print_sidebar_title_inner(buf, id, title);
buf.push_str("</div>");
}
fn print_sidebar_block(
buf: &mut Buffer,
id: &str,
title: &str,
items: impl Iterator<Item = impl fmt::Display>,
) {
buf.push_str("<div class=\"block\">");
print_sidebar_title_inner(buf, id, title);
buf.push_str("<ul>");
print_sidebar_title(buf, id, title);
buf.push_str("<ul class=\"block\">");
for item in items {
write!(buf, "<li>{}</li>", item);
}
buf.push_str("</ul></div>");
buf.push_str("</ul>");
}
fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean::Trait) {
@ -2676,9 +2668,7 @@ pub(crate) fn sidebar_module_like(buf: &mut Buffer, item_sections_in_use: FxHash
write!(
buf,
"<section>\
<div class=\"block\">\
<ul>{}</ul>\
</div>\
<ul class=\"block\">{}</ul>\
</section>",
sidebar
);

View File

@ -501,13 +501,14 @@ img {
width: 100px;
}
.block ul, .block li {
ul.block, .block li {
padding: 0;
margin: 0;
list-style: none;
}
.block a,
.sidebar h3 a,
h2.location a {
display: block;
padding: 0.25rem;
@ -767,7 +768,7 @@ h2.small-section-header > .anchor {
text-decoration: underline;
}
.block a.current.crate { font-weight: 500; }
.crate.block a.current { font-weight: 500; }
/* In most contexts we use `overflow-wrap: anywhere` to ensure that we can wrap
as much as needed on mobile (see

View File

@ -442,12 +442,10 @@ function loadCss(cssFileName) {
return;
}
const div = document.createElement("div");
div.className = "block " + shortty;
const h3 = document.createElement("h3");
h3.innerHTML = `<a href="index.html#${id}">${longty}</a>`;
div.appendChild(h3);
const ul = document.createElement("ul");
ul.className = "block " + shortty;
for (const item of filtered) {
const name = item[0];
@ -473,8 +471,8 @@ function loadCss(cssFileName) {
li.appendChild(link);
ul.appendChild(li);
}
div.appendChild(ul);
sidebar.appendChild(div);
sidebar.appendChild(h3);
sidebar.appendChild(ul);
}
if (sidebar) {
@ -592,27 +590,25 @@ function loadCss(cssFileName) {
return;
}
// Draw a convenient sidebar of known crates if we have a listing
const div = document.createElement("div");
div.className = "block crate";
div.innerHTML = "<h3>Crates</h3>";
const h3 = document.createElement("h3");
h3.innerHTML = "Crates";
const ul = document.createElement("ul");
div.appendChild(ul);
ul.className = "block crate";
for (const crate of window.ALL_CRATES) {
let klass = "crate";
if (window.rootPath !== "./" && crate === window.currentCrate) {
klass += " current";
}
const link = document.createElement("a");
link.href = window.rootPath + crate + "/index.html";
link.className = klass;
if (window.rootPath !== "./" && crate === window.currentCrate) {
link.className = "current";
}
link.textContent = crate;
const li = document.createElement("li");
li.appendChild(link);
ul.appendChild(li);
}
sidebarElems.appendChild(div);
sidebarElems.appendChild(h3);
sidebarElems.appendChild(ul);
}

View File

@ -106,8 +106,8 @@ assert-css: ("h6#sub-heading-for-enum-impl-item-doc", {"border-bottom-width": "0
assert-css: ("h6#sub-sub-heading-for-enum-impl-item-doc", {"font-size": "14px"})
assert-css: ("h6#sub-sub-heading-for-enum-impl-item-doc", {"border-bottom-width": "0px"})
assert-text: (".sidebar .mod h3", "Modules")
assert-css: (".sidebar .mod h3", {"border-bottom-width": "0px"}, ALL)
assert-text: ("//ul[@class='block mod']/preceding-sibling::h3", "Modules")
assert-css: ("//ul[@class='block mod']/preceding-sibling::h3", {"border-bottom-width": "0px"}, ALL)
goto: "file://" + |DOC_PATH| + "/test_docs/union.HeavilyDocumentedUnion.html"

View File

@ -12,7 +12,7 @@ assert-count: (".sidebar .location", 1)
assert-text: ("#all-types", "All Items")
assert-css: ("#all-types", {"color": "rgb(53, 109, 164)"})
// We check that we have the crates list and that the "current" on is "test_docs".
assert-text: (".sidebar-elems .crate > ul > li > a.current", "test_docs")
assert-text: (".sidebar-elems ul.crate > li > a.current", "test_docs")
// And we're also supposed to have the list of items in the current module.
assert-text: (".sidebar-elems section ul > li:nth-child(1)", "Re-exports")
assert-text: (".sidebar-elems section ul > li:nth-child(2)", "Modules")
@ -41,21 +41,21 @@ assert-property: ("html", {"scrollTop": "0"})
// We now go back to the crate page to click on the "lib2" crate link.
goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
assert-property: (".sidebar", {"clientWidth": "200"})
assert-css: (".sidebar-elems .crate > ul > li:first-child > a", {"color": "rgb(53, 109, 164)"})
click: ".sidebar-elems .crate > ul > li:first-child > a"
assert-css: (".sidebar-elems ul.crate > li:first-child > a", {"color": "rgb(53, 109, 164)"})
click: ".sidebar-elems ul.crate > li:first-child > a"
// PAGE: lib2/index.html
goto: "file://" + |DOC_PATH| + "/lib2/index.html"
assert-property: (".sidebar", {"clientWidth": "200"})
assert-text: (".sidebar > .location", "Crate lib2")
// We check that we have the crates list and that the "current" on is now "lib2".
assert-text: (".sidebar-elems .crate > ul > li > a.current", "lib2")
assert-text: (".sidebar-elems ul.crate > li > a.current", "lib2")
// We now go to the "foobar" function page.
assert-text: (".sidebar-elems > section .block ul > li:nth-child(1)", "Modules")
assert-text: (".sidebar-elems > section .block ul > li:nth-child(2)", "Structs")
assert-text: (".sidebar-elems > section .block ul > li:nth-child(3)", "Traits")
assert-text: (".sidebar-elems > section .block ul > li:nth-child(4)", "Functions")
assert-text: (".sidebar-elems > section .block ul > li:nth-child(5)", "Type Definitions")
assert-text: (".sidebar-elems > section ul.block > li:nth-child(1)", "Modules")
assert-text: (".sidebar-elems > section ul.block > li:nth-child(2)", "Structs")
assert-text: (".sidebar-elems > section ul.block > li:nth-child(3)", "Traits")
assert-text: (".sidebar-elems > section ul.block > li:nth-child(4)", "Functions")
assert-text: (".sidebar-elems > section ul.block > li:nth-child(5)", "Type Definitions")
assert-text: ("#functions + .item-table .item-left > a", "foobar")
click: "#functions + .item-table .item-left > a"
@ -90,7 +90,7 @@ assert-property: (".sidebar-elems section .block li > a", {"offsetHeight": 29})
// appropriate anchor in index.html.
goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
assert-property: (".sidebar", {"clientWidth": "200"})
click: ".block.mod h3 a"
click: "//ul[@class='block mod']/preceding-sibling::h3/a"
// PAGE: index.html
assert-css: ("#modules", {"background-color": "rgb(253, 255, 211)"})

View File

@ -1 +1 @@
<ul><li><a href="#variant.Shown">Shown</a></li></ul>
<ul class="block"><li><a href="#variant.Shown">Shown</a></li></ul>

View File

@ -3,7 +3,7 @@
// @!has - '//code' 'NotShown'
// @has - '//code' '// some variants omitted'
// Also check that `NotShown` isn't displayed in the sidebar.
// @snapshot no-not-shown - '//*[@class="sidebar-elems"]/section/*[@class="block"][1]/ul'
// @snapshot no-not-shown - '//*[@class="sidebar-elems"]/section/*[@class="block"][1]'
pub enum MyThing {
Shown,
#[doc(hidden)]