From 4ef35bcaef07871f286330c13783d8cc37f9c209 Mon Sep 17 00:00:00 2001 From: binarycat Date: Sat, 24 May 2025 14:15:20 -0500 Subject: [PATCH 1/2] rustdoc: use descriptive tooltip if doctest is conditionally ignored fixes https://github.com/rust-lang/rust/issues/141092 --- src/librustdoc/html/highlight.rs | 45 +++++++++++++++++++---- src/librustdoc/html/markdown.rs | 6 ++- tests/rustdoc/doctest/ignore-sometimes.rs | 23 ++++++++++++ 3 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 tests/rustdoc/doctest/ignore-sometimes.rs diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 2db1ea8450ce1..f9d355cc0386d 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -6,7 +6,7 @@ //! Use the `render_with_highlighting` to highlight some rust code. use std::collections::VecDeque; -use std::fmt::{Display, Write}; +use std::fmt::{self, Display, Write}; use rustc_data_structures::fx::FxIndexMap; use rustc_lexer::{Cursor, FrontmatterAllowed, LiteralKind, TokenKind}; @@ -36,9 +36,10 @@ pub(crate) struct HrefContext<'a, 'tcx> { #[derive(Default)] pub(crate) struct DecorationInfo(pub(crate) FxIndexMap<&'static str, Vec<(u32, u32)>>); -#[derive(Eq, PartialEq, Clone, Copy)] +#[derive(Eq, PartialEq, Clone)] pub(crate) enum Tooltip { - Ignore, + IgnoreAll, + IgnoreSome(Vec), CompileFail, ShouldPanic, Edition(Edition), @@ -70,7 +71,7 @@ fn write_header( format_args!( "
", match tooltip { - Tooltip::Ignore => " ignore", + Tooltip::IgnoreAll | Tooltip::IgnoreSome(_) => " ignore", Tooltip::CompileFail => " compile_fail", Tooltip::ShouldPanic => " should_panic", Tooltip::Edition(_) => " edition", @@ -80,18 +81,46 @@ fn write_header( ); if tooltip != Tooltip::None { - let edition_code; + // variable for extending lifetimes of temporaries + let tmp; write_str( out, format_args!( "", match tooltip { - Tooltip::Ignore => "This example is not tested", + Tooltip::IgnoreAll => "This example is not tested", + Tooltip::IgnoreSome(platforms) => { + tmp = format!( + "This example is not tested on {}", + fmt::from_fn(|f| { + match platforms.len() { + 0 => unreachable!(), + 1 => f.write_str(&platforms[0]), + 2 => write!(f, "{} or {}", &platforms[0], &platforms[1]), + _ => { + for (i, plat) in platforms.iter().enumerate() { + match (platforms.len() - 2).cmp(&i) { + std::cmp::Ordering::Greater => { + write!(f, "{}, ", plat)? + } + std::cmp::Ordering::Equal => { + write!(f, "{}, or ", plat)? + } + std::cmp::Ordering::Less => f.write_str(&plat)?, + } + } + Ok(()) + } + } + }) + ); + &tmp + } Tooltip::CompileFail => "This example deliberately fails to compile", Tooltip::ShouldPanic => "This example panics", Tooltip::Edition(edition) => { - edition_code = format!("This example runs with edition {edition}"); - &edition_code + tmp = format!("This example runs with edition {edition}"); + &tmp } Tooltip::None => unreachable!(), } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index ad7dfafd90c7d..987b92fa4e231 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -320,8 +320,10 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { )) }); - let tooltip = if ignore != Ignore::None { - highlight::Tooltip::Ignore + let tooltip = if ignore == Ignore::All { + highlight::Tooltip::IgnoreAll + } else if let Ignore::Some(platforms) = ignore { + highlight::Tooltip::IgnoreSome(platforms) } else if compile_fail { highlight::Tooltip::CompileFail } else if should_panic { diff --git a/tests/rustdoc/doctest/ignore-sometimes.rs b/tests/rustdoc/doctest/ignore-sometimes.rs new file mode 100644 index 0000000000000..0f8586d221c15 --- /dev/null +++ b/tests/rustdoc/doctest/ignore-sometimes.rs @@ -0,0 +1,23 @@ +#![crate_name = "foo"] + +// test for https://github.com/rust-lang/rust/issues/141092 + +//@ has 'foo/fn.f.html' '//a[@title="This example is not tested on wasm"]' 'ⓘ' +/// Example +/// +/// ```ignore-wasm +/// let x = 1; +/// ``` +pub fn f() {} + +//@ has 'foo/fn.g.html' '//a[@title="This example is not tested on wasm or windows"]' 'ⓘ' +/// ```ignore-wasm,ignore-windows +/// let x = 1; +/// ``` +pub fn g() {} + +//@ has 'foo/fn.h.html' '//a[@title="This example is not tested on wasm, windows, or unix"]' 'ⓘ' +/// ```ignore-wasm,ignore-windows,ignore-unix +/// let x = 1; +/// ``` +pub fn h() {} From f9931d198cb92b72a0a8f893c380fdf07ebb4800 Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 26 May 2025 11:35:45 -0500 Subject: [PATCH 2/2] rustdoc: refactor Tooltip rendering logic --- src/librustdoc/html/highlight.rs | 64 +++++++++++--------------------- 1 file changed, 21 insertions(+), 43 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index f9d355cc0386d..b2feee36c939c 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -81,51 +81,29 @@ fn write_header( ); if tooltip != Tooltip::None { - // variable for extending lifetimes of temporaries - let tmp; - write_str( - out, - format_args!( - "", - match tooltip { - Tooltip::IgnoreAll => "This example is not tested", - Tooltip::IgnoreSome(platforms) => { - tmp = format!( - "This example is not tested on {}", - fmt::from_fn(|f| { - match platforms.len() { - 0 => unreachable!(), - 1 => f.write_str(&platforms[0]), - 2 => write!(f, "{} or {}", &platforms[0], &platforms[1]), - _ => { - for (i, plat) in platforms.iter().enumerate() { - match (platforms.len() - 2).cmp(&i) { - std::cmp::Ordering::Greater => { - write!(f, "{}, ", plat)? - } - std::cmp::Ordering::Equal => { - write!(f, "{}, or ", plat)? - } - std::cmp::Ordering::Less => f.write_str(&plat)?, - } - } - Ok(()) - } - } - }) - ); - &tmp - } - Tooltip::CompileFail => "This example deliberately fails to compile", - Tooltip::ShouldPanic => "This example panics", - Tooltip::Edition(edition) => { - tmp = format!("This example runs with edition {edition}"); - &tmp + let tooltip = fmt::from_fn(|f| match &tooltip { + Tooltip::IgnoreAll => f.write_str("This example is not tested"), + Tooltip::IgnoreSome(platforms) => { + f.write_str("This example is not tested on ")?; + match &platforms[..] { + [] => unreachable!(), + [platform] => f.write_str(platform)?, + [first, second] => write!(f, "{first} or {second}")?, + [platforms @ .., last] => { + for platform in platforms { + write!(f, "{platform}, ")?; + } + write!(f, "or {last}")?; } - Tooltip::None => unreachable!(), } - ), - ); + Ok(()) + } + Tooltip::CompileFail => f.write_str("This example deliberately fails to compile"), + Tooltip::ShouldPanic => f.write_str("This example panics"), + Tooltip::Edition(edition) => write!(f, "This example runs with edition {edition}"), + Tooltip::None => unreachable!(), + }); + write_str(out, format_args!("")); } if let Some(extra) = extra_content {