diff options
| author | bors <bors@rust-lang.org> | 2024-09-05 20:34:38 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-09-05 20:34:38 +0000 |
| commit | 9c01301c52df5d2d7b6fe337707a74e011d68d6f (patch) | |
| tree | 8043def18ff45012546ac3dc52ebec49da75e3b3 /src | |
| parent | eb33b43bab08223fa6b46abacc1e95e859fe375d (diff) | |
| parent | fee6c0a6835b1ade0a1dcff3e2d30dd6a018bc98 (diff) | |
Auto merge of #129994 - matthiaskrgr:rollup-zkj4ekl, r=matthiaskrgr
Rollup of 8 pull requests
Successful merges:
- #128820 (fix: get llvm type of global val)
- #129028 (`impl_trait_overcaptures`: Don't worry about uncaptured contravariant lifetimes if they outlive a captured lifetime)
- #129471 ([rustdoc] Sort impl associated items by kinds and then by appearance)
- #129706 (Rename dump of coroutine by-move-body to be more consistent, fix ICE in dump_mir)
- #129720 (Simplify DestProp memory management)
- #129796 (Unify scraped examples with other code examples)
- #129938 (Elaborate on deriving vs implementing `Copy`)
- #129973 (run_make_support: rename `Command::stdin` to `stdin_buf` and add `std{in,out,err}` config helpers)
r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustdoc/html/render/mod.rs | 86 | ||||
| -rw-r--r-- | src/librustdoc/html/render/print_item.rs | 32 | ||||
| -rw-r--r-- | src/librustdoc/html/render/sidebar.rs | 47 | ||||
| -rw-r--r-- | src/librustdoc/html/sources.rs | 57 | ||||
| -rw-r--r-- | src/librustdoc/html/static/css/noscript.css | 4 | ||||
| -rw-r--r-- | src/librustdoc/html/static/css/rustdoc.css | 150 | ||||
| -rw-r--r-- | src/librustdoc/html/static/js/main.js | 9 | ||||
| -rw-r--r-- | src/librustdoc/html/static/js/scrape-examples.js | 7 | ||||
| -rw-r--r-- | src/librustdoc/html/templates/scraped_source.html | 33 | ||||
| -rw-r--r-- | src/librustdoc/html/templates/source.html | 14 | ||||
| -rw-r--r-- | src/tools/run-make-support/src/command.rs | 85 | ||||
| -rw-r--r-- | src/tools/run-make-support/src/external_deps/llvm.rs | 7 | ||||
| -rw-r--r-- | src/tools/run-make-support/src/external_deps/rustc.rs | 6 | ||||
| -rw-r--r-- | src/tools/run-make-support/src/external_deps/rustdoc.rs | 6 | ||||
| -rw-r--r-- | src/tools/run-make-support/src/lib.rs | 2 |
15 files changed, 354 insertions, 191 deletions
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index dc34c7844bf..f67d006116c 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1794,13 +1794,64 @@ fn render_impl( let mut default_impl_items = Buffer::empty_from(w); let impl_ = i.inner_impl(); + // Impl items are grouped by kinds: + // + // 1. Constants + // 2. Types + // 3. Functions + // + // This order is because you can have associated constants used in associated types (like array + // length), and both in associcated functions. So with this order, when reading from top to + // bottom, you should see items definitions before they're actually used most of the time. + let mut assoc_types = Vec::new(); + let mut methods = Vec::new(); + if !impl_.is_negative_trait_impl() { for trait_item in &impl_.items { + match *trait_item.kind { + clean::MethodItem(..) | clean::TyMethodItem(_) => methods.push(trait_item), + clean::TyAssocTypeItem(..) | clean::AssocTypeItem(..) => { + assoc_types.push(trait_item) + } + clean::TyAssocConstItem(..) | clean::AssocConstItem(_) => { + // We render it directly since they're supposed to come first. + doc_impl_item( + &mut default_impl_items, + &mut impl_items, + cx, + trait_item, + if trait_.is_some() { &i.impl_item } else { parent }, + link, + render_mode, + false, + trait_, + rendering_params, + ); + } + _ => {} + } + } + + for assoc_type in assoc_types { doc_impl_item( &mut default_impl_items, &mut impl_items, cx, - trait_item, + assoc_type, + if trait_.is_some() { &i.impl_item } else { parent }, + link, + render_mode, + false, + trait_, + rendering_params, + ); + } + for method in methods { + doc_impl_item( + &mut default_impl_items, + &mut impl_items, + cx, + method, if trait_.is_some() { &i.impl_item } else { parent }, link, render_mode, @@ -2455,28 +2506,6 @@ fn render_call_locations<W: fmt::Write>(mut w: W, cx: &mut Context<'_>, item: &c let needs_expansion = line_max - line_min > NUM_VISIBLE_LINES; let locations_encoded = serde_json::to_string(&line_ranges).unwrap(); - write!( - &mut w, - "<div class=\"scraped-example {expanded_cls}\" data-locs=\"{locations}\">\ - <div class=\"scraped-example-title\">\ - {name} (<a href=\"{url}\">{title}</a>)\ - </div>\ - <div class=\"code-wrapper\">", - expanded_cls = if needs_expansion { "" } else { "expanded" }, - name = call_data.display_name, - url = init_url, - title = init_title, - // The locations are encoded as a data attribute, so they can be read - // later by the JS for interactions. - locations = Escape(&locations_encoded) - ) - .unwrap(); - - if line_ranges.len() > 1 { - w.write_str(r#"<button class="prev">≺</button> <button class="next">≻</button>"#) - .unwrap(); - } - // Look for the example file in the source map if it exists, otherwise return a dummy span let file_span = (|| { let source_map = tcx.sess.source_map(); @@ -2507,9 +2536,16 @@ fn render_call_locations<W: fmt::Write>(mut w: W, cx: &mut Context<'_>, item: &c cx, &cx.root_path(), highlight::DecorationInfo(decoration_info), - sources::SourceContext::Embedded { offset: line_min, needs_expansion }, + sources::SourceContext::Embedded(sources::ScrapedInfo { + needs_prev_next_buttons: line_ranges.len() > 1, + needs_expansion, + offset: line_min, + name: &call_data.display_name, + url: init_url, + title: init_title, + locations: locations_encoded, + }), ); - w.write_str("</div></div>").unwrap(); true }; diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index a0a72d59d12..cda5409a460 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -843,55 +843,55 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: } } - if !required_types.is_empty() { + if !required_consts.is_empty() { write_section_heading( w, - "Required Associated Types", - "required-associated-types", + "Required Associated Constants", + "required-associated-consts", None, "<div class=\"methods\">", ); - for t in required_types { + for t in required_consts { trait_item(w, cx, t, it); } w.write_str("</div>"); } - if !provided_types.is_empty() { + if !provided_consts.is_empty() { write_section_heading( w, - "Provided Associated Types", - "provided-associated-types", + "Provided Associated Constants", + "provided-associated-consts", None, "<div class=\"methods\">", ); - for t in provided_types { + for t in provided_consts { trait_item(w, cx, t, it); } w.write_str("</div>"); } - if !required_consts.is_empty() { + if !required_types.is_empty() { write_section_heading( w, - "Required Associated Constants", - "required-associated-consts", + "Required Associated Types", + "required-associated-types", None, "<div class=\"methods\">", ); - for t in required_consts { + for t in required_types { trait_item(w, cx, t, it); } w.write_str("</div>"); } - if !provided_consts.is_empty() { + if !provided_types.is_empty() { write_section_heading( w, - "Provided Associated Constants", - "provided-associated-consts", + "Provided Associated Types", + "provided-associated-types", None, "<div class=\"methods\">", ); - for t in provided_consts { + for t in provided_types { trait_item(w, cx, t, it); } w.write_str("</div>"); diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index c75c28ef0a3..06cc57b2a55 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -302,10 +302,10 @@ fn sidebar_trait<'a>( blocks.extend( [ - ("required-associated-types", "Required Associated Types", req_assoc), - ("provided-associated-types", "Provided Associated Types", prov_assoc), ("required-associated-consts", "Required Associated Constants", req_assoc_const), ("provided-associated-consts", "Provided Associated Constants", prov_assoc_const), + ("required-associated-types", "Required Associated Types", req_assoc), + ("provided-associated-types", "Provided Associated Types", prov_assoc), ("required-methods", "Required Methods", req_method), ("provided-methods", "Provided Methods", prov_method), ("foreign-impls", "Implementations on Foreign Types", foreign_impls), @@ -394,6 +394,7 @@ fn sidebar_assoc_items<'a>( let cache = cx.cache(); let mut assoc_consts = Vec::new(); + let mut assoc_types = Vec::new(); let mut methods = Vec::new(); if let Some(v) = cache.impls.get(&did) { let mut used_links = FxHashSet::default(); @@ -401,22 +402,14 @@ fn sidebar_assoc_items<'a>( { let used_links_bor = &mut used_links; - assoc_consts.extend( - v.iter() - .filter(|i| i.inner_impl().trait_.is_none()) - .flat_map(|i| get_associated_constants(i.inner_impl(), used_links_bor)), - ); + for impl_ in v.iter().map(|i| i.inner_impl()).filter(|i| i.trait_.is_none()) { + assoc_consts.extend(get_associated_constants(impl_, used_links_bor)); + assoc_types.extend(get_associated_types(impl_, used_links_bor)); + methods.extend(get_methods(impl_, false, used_links_bor, false, cx.tcx())); + } // We want links' order to be reproducible so we don't use unstable sort. assoc_consts.sort(); - - #[rustfmt::skip] // rustfmt makes the pipeline less readable - methods.extend( - v.iter() - .filter(|i| i.inner_impl().trait_.is_none()) - .flat_map(|i| get_methods(i.inner_impl(), false, used_links_bor, false, cx.tcx())), - ); - - // We want links' order to be reproducible so we don't use unstable sort. + assoc_types.sort(); methods.sort(); } @@ -426,6 +419,11 @@ fn sidebar_assoc_items<'a>( "associatedconstant", assoc_consts, ), + LinkBlock::new( + Link::new("implementations", "Associated Types"), + "associatedtype", + assoc_types, + ), LinkBlock::new(Link::new("implementations", "Methods"), "method", methods), ]; @@ -452,6 +450,7 @@ fn sidebar_assoc_items<'a>( &mut blocks, ); } + links.append(&mut blocks); } } @@ -715,3 +714,19 @@ fn get_associated_constants<'a>( }) .collect::<Vec<_>>() } + +fn get_associated_types<'a>( + i: &'a clean::Impl, + used_links: &mut FxHashSet<String>, +) -> Vec<Link<'a>> { + i.items + .iter() + .filter_map(|item| match item.name { + Some(ref name) if !name.is_empty() && item.is_associated_type() => Some(Link::new( + get_next_url(used_links, format!("{typ}.{name}", typ = ItemType::AssocType)), + name.as_str(), + )), + _ => None, + }) + .collect::<Vec<_>>() +} diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index ae65dd76b5f..551bb56685c 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -290,9 +290,34 @@ where } } -pub(crate) enum SourceContext { +pub(crate) struct ScrapedInfo<'a> { + pub(crate) offset: usize, + pub(crate) needs_prev_next_buttons: bool, + pub(crate) name: &'a str, + pub(crate) url: &'a str, + pub(crate) title: &'a str, + pub(crate) locations: String, + pub(crate) needs_expansion: bool, +} + +#[derive(Template)] +#[template(path = "scraped_source.html")] +struct ScrapedSource<'a, Code: std::fmt::Display> { + info: ScrapedInfo<'a>, + lines: RangeInclusive<usize>, + code_html: Code, +} + +#[derive(Template)] +#[template(path = "source.html")] +struct Source<Code: std::fmt::Display> { + lines: RangeInclusive<usize>, + code_html: Code, +} + +pub(crate) enum SourceContext<'a> { Standalone, - Embedded { offset: usize, needs_expansion: bool }, + Embedded(ScrapedInfo<'a>), } /// Wrapper struct to render the source code of a file. This will do things like @@ -304,23 +329,8 @@ pub(crate) fn print_src( context: &Context<'_>, root_path: &str, decoration_info: highlight::DecorationInfo, - source_context: SourceContext, + source_context: SourceContext<'_>, ) { - #[derive(Template)] - #[template(path = "source.html")] - struct Source<Code: std::fmt::Display> { - embedded: bool, - needs_expansion: bool, - lines: RangeInclusive<usize>, - code_html: Code, - } - let lines = s.lines().count(); - let (embedded, needs_expansion, lines) = match source_context { - SourceContext::Standalone => (false, false, 1..=lines), - SourceContext::Embedded { offset, needs_expansion } => { - (true, needs_expansion, (1 + offset)..=(lines + offset)) - } - }; let current_href = context .href_from_span(clean::Span::new(file_span), false) .expect("only local crates should have sources emitted"); @@ -333,5 +343,14 @@ pub(crate) fn print_src( ); Ok(()) }); - Source { embedded, needs_expansion, lines, code_html: code }.render_into(&mut writer).unwrap(); + let lines = s.lines().count(); + match source_context { + SourceContext::Standalone => { + Source { lines: (1..=lines), code_html: code }.render_into(&mut writer).unwrap() + } + SourceContext::Embedded(info) => { + let lines = (1 + info.offset)..=(lines + info.offset); + ScrapedSource { info, lines, code_html: code }.render_into(&mut writer).unwrap(); + } + }; } diff --git a/src/librustdoc/html/static/css/noscript.css b/src/librustdoc/html/static/css/noscript.css index 86e8edad703..e62b16267f1 100644 --- a/src/librustdoc/html/static/css/noscript.css +++ b/src/librustdoc/html/static/css/noscript.css @@ -59,6 +59,8 @@ nav.sub { --copy-path-button-color: #999; --copy-path-img-filter: invert(50%); --copy-path-img-hover-filter: invert(35%); + --code-example-button-color: #7f7f7f; + --code-example-button-hover-color: #595959; --codeblock-error-hover-color: rgb(255, 0, 0); --codeblock-error-color: rgba(255, 0, 0, .5); --codeblock-ignore-hover-color: rgb(255, 142, 0); @@ -162,6 +164,8 @@ nav.sub { --copy-path-button-color: #999; --copy-path-img-filter: invert(50%); --copy-path-img-hover-filter: invert(65%); + --code-example-button-color: #7f7f7f; + --code-example-button-hover-color: #a5a5a5; --codeblock-error-hover-color: rgb(255, 0, 0); --codeblock-error-color: rgba(255, 0, 0, .5); --codeblock-ignore-hover-color: rgb(255, 142, 0); diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 271de1b1ccf..38154dee3e2 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -378,7 +378,7 @@ pre.item-decl { .src .content pre { padding: 20px; } -.rustdoc.src .example-wrap pre.src-line-numbers { +.rustdoc.src .example-wrap .src-line-numbers { padding: 20px 0 20px 4px; } @@ -757,10 +757,32 @@ ul.block, .block li, .block ul { margin-bottom: 10px; } -.rustdoc .example-wrap > pre { +.rustdoc .example-wrap > pre, +.rustdoc .scraped-example .src-line-numbers, +.rustdoc .scraped-example .src-line-numbers > pre { border-radius: 6px; } +/* +If the code example line numbers are displayed, there will be a weird radius in the middle from +both the code example and the line numbers, so we need to remove the radius in this case. +*/ +.rustdoc .example-wrap > .example-line-numbers, +.rustdoc .scraped-example .src-line-numbers, +.rustdoc .scraped-example .src-line-numbers > pre { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.rustdoc .example-wrap > .example-line-numbers + pre, +.rustdoc .scraped-example .rust { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.rustdoc .scraped-example { + position: relative; +} + /* For the last child of a div, the margin will be taken care of by the margin-top of the next item. */ .rustdoc .example-wrap:last-child { @@ -772,15 +794,36 @@ ul.block, .block li, .block ul { flex-grow: 1; } -.rustdoc:not(.src) .example-wrap pre { +.scraped-example:not(.expanded) .example-wrap { + /* scrape-examples.js has a constant DEFAULT_MAX_LINES (call it N) for the number + * of lines shown in the un-expanded example code viewer. This pre needs to have + * a max-height equal to line-height * N. The line-height is currently 1.5em, + * and we include additional 10px for padding. */ + max-height: calc(1.5em * 5 + 10px); +} + +.rustdoc:not(.src) .scraped-example:not(.expanded) .src-line-numbers, +.rustdoc:not(.src) .scraped-example:not(.expanded) .src-line-numbers > pre, +.rustdoc:not(.src) .scraped-example:not(.expanded) pre.rust { + padding-bottom: 0; + /* See above comment, should be the same max-height. */ overflow: auto hidden; } +.rustdoc:not(.src) .scraped-example .src-line-numbers { + padding-top: 0; +} +.rustdoc:not(.src) .scraped-example.expanded .src-line-numbers { + padding-bottom: 0; +} + +.rustdoc:not(.src) .example-wrap pre { + overflow: auto; +} .rustdoc .example-wrap pre.example-line-numbers, -.rustdoc .example-wrap pre.src-line-numbers { - flex-grow: 0; +.rustdoc .example-wrap .src-line-numbers { min-width: fit-content; /* prevent collapsing into nothing in truncated scraped examples */ - overflow: initial; + flex-grow: 0; text-align: right; -webkit-user-select: none; user-select: none; @@ -788,7 +831,7 @@ ul.block, .block li, .block ul { color: var(--src-line-numbers-span-color); } -.rustdoc .example-wrap pre.src-line-numbers { +.rustdoc .scraped-example .src-line-numbers { padding: 14px 0; } .src-line-numbers a, .src-line-numbers span { @@ -1500,17 +1543,23 @@ instead, we check that it's not a "finger" cursor. .example-wrap .button-holder.keep-visible { visibility: visible; } -.example-wrap .button-holder .copy-button, .example-wrap .test-arrow { +.example-wrap .button-holder > * { background: var(--main-background-color); cursor: pointer; border-radius: var(--button-border-radius); height: var(--copy-path-height); width: var(--copy-path-width); + border: 0; + color: var(--code-example-button-color); } -.example-wrap .button-holder .copy-button { +.example-wrap .button-holder > *:hover { + color: var(--code-example-button-hover-color); +} +.example-wrap .button-holder > *:not(:first-child) { margin-left: var(--button-left-margin); +} +.example-wrap .button-holder .copy-button { padding: 2px 0 0 4px; - border: 0; } .example-wrap .button-holder .copy-button::before, .example-wrap .test-arrow::before { @@ -2254,6 +2303,7 @@ in src-script.js and main.js } } + /* Should have min-width: (N + 1)px where N is the mobile breakpoint above. */ @media (min-width: 701px) { /* Places file-link for a scraped example on top of the example to save space. @@ -2356,99 +2406,41 @@ in src-script.js and main.js color: var(--scrape-example-help-hover-color); } -.scraped-example { - /* So .scraped-example-title can be positioned absolutely */ - position: relative; -} - -.scraped-example .code-wrapper { - position: relative; - display: flex; - flex-direction: row; - flex-wrap: wrap; - width: 100%; -} - -.scraped-example:not(.expanded) .code-wrapper { - /* scrape-examples.js has a constant DEFAULT_MAX_LINES (call it N) for the number - * of lines shown in the un-expanded example code viewer. This pre needs to have - * a max-height equal to line-height * N. The line-height is currently 1.5em, - * and we include additional 10px for padding. */ - max-height: calc(1.5em * 5 + 10px); -} - -.scraped-example:not(.expanded) .code-wrapper pre { - overflow-y: hidden; - padding-bottom: 0; - /* See above comment, should be the same max-height. */ - max-height: calc(1.5em * 5 + 10px); -} - -.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper, -.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper pre { - /* See above comment, except this height is based on HIDDEN_MAX_LINES. */ - max-height: calc(1.5em * 10 + 10px); -} - -.scraped-example .code-wrapper .next, -.scraped-example .code-wrapper .prev, -.scraped-example .code-wrapper .expand { - color: var(--main-color); - position: absolute; - top: 0.25em; - z-index: 1; - padding: 0; - background: none; - border: none; - /* iOS button gradient: https://stackoverflow.com/q/5438567 */ - -webkit-appearance: none; - opacity: 1; -} -.scraped-example .code-wrapper .prev { - right: 2.25em; -} -.scraped-example .code-wrapper .next { - right: 1.25em; -} -.scraped-example .code-wrapper .expand { - right: 0.25em; -} - -.scraped-example:not(.expanded) .code-wrapper::before, -.scraped-example:not(.expanded) .code-wrapper::after { +.scraped-example:not(.expanded) .example-wrap::before, +.scraped-example:not(.expanded) .example-wrap::after { content: " "; width: 100%; height: 5px; position: absolute; z-index: 1; } -.scraped-example:not(.expanded) .code-wrapper::before { +.scraped-example:not(.expanded) .example-wrap::before { top: 0; background: linear-gradient(to bottom, var(--scrape-example-code-wrapper-background-start), var(--scrape-example-code-wrapper-background-end)); } -.scraped-example:not(.expanded) .code-wrapper::after { +.scraped-example:not(.expanded) .example-wrap::after { bottom: 0; background: linear-gradient(to top, var(--scrape-example-code-wrapper-background-start), var(--scrape-example-code-wrapper-background-end)); } -.scraped-example .code-wrapper .example-wrap { +.scraped-example:not(.expanded) { width: 100%; overflow-y: hidden; margin-bottom: 0; } -.scraped-example:not(.expanded) .code-wrapper .example-wrap { +.scraped-example:not(.expanded) { overflow-x: hidden; } -.scraped-example .example-wrap .rust span.highlight { +.scraped-example .rust span.highlight { background: var(--scrape-example-code-line-highlight); } -.scraped-example .example-wrap .rust span.highlight.focus { +.scraped-example .rust span.highlight.focus { background: var(--scrape-example-code-line-highlight-focus); } @@ -2542,6 +2534,8 @@ by default. --copy-path-button-color: #999; --copy-path-img-filter: invert(50%); --copy-path-img-hover-filter: invert(35%); + --code-example-button-color: #7f7f7f; + --code-example-button-hover-color: #595959; --codeblock-error-hover-color: rgb(255, 0, 0); --codeblock-error-color: rgba(255, 0, 0, .5); --codeblock-ignore-hover-color: rgb(255, 142, 0); @@ -2644,6 +2638,8 @@ by default. --copy-path-button-color: #999; --copy-path-img-filter: invert(50%); --copy-path-img-hover-filter: invert(65%); + --code-example-button-color: #7f7f7f; + --code-example-button-hover-color: #a5a5a5; --codeblock-error-hover-color: rgb(255, 0, 0); --codeblock-error-color: rgba(255, 0, 0, .5); --codeblock-ignore-hover-color: rgb(255, 142, 0); @@ -2753,6 +2749,8 @@ Original by Dempfi (https://github.com/dempfi/ayu) --copy-path-button-color: #fff; --copy-path-img-filter: invert(70%); --copy-path-img-hover-filter: invert(100%); + --code-example-button-color: #b2b2b2; + --code-example-button-hover-color: #fff; --codeblock-error-hover-color: rgb(255, 0, 0); --codeblock-error-color: rgba(255, 0, 0, .5); --codeblock-ignore-hover-color: rgb(255, 142, 0); diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 0291b6ed6f5..858753a1917 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1855,8 +1855,13 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm // Since the button will be added, no need to keep this listener around. elem.removeEventListener("mouseover", addCopyButton); - const parent = document.createElement("div"); - parent.className = "button-holder"; + // If this is a scrapped example, there will already be a "button-holder" element. + let parent = elem.querySelector(".button-holder"); + if (!parent) { + parent = document.createElement("div"); + parent.className = "button-holder"; + } + const runButton = elem.querySelector(".test-arrow"); if (runButton !== null) { // If there is a run button, we move it into the same div. diff --git a/src/librustdoc/html/static/js/scrape-examples.js b/src/librustdoc/html/static/js/scrape-examples.js index 7a3a9c5f340..06e42814d33 100644 --- a/src/librustdoc/html/static/js/scrape-examples.js +++ b/src/librustdoc/html/static/js/scrape-examples.js @@ -13,7 +13,7 @@ // Scroll code block to the given code location function scrollToLoc(elt, loc, isHidden) { - const lines = elt.querySelector(".src-line-numbers"); + const lines = elt.querySelector(".src-line-numbers > pre"); let scrollOffset; // If the block is greater than the size of the viewer, @@ -24,8 +24,7 @@ const line = Math.max(0, loc[0] - 1); scrollOffset = lines.children[line].offsetTop; } else { - const wrapper = elt.querySelector(".code-wrapper"); - const halfHeight = wrapper.offsetHeight / 2; + const halfHeight = elt.offsetHeight / 2; const offsetTop = lines.children[loc[0]].offsetTop; const lastLine = lines.children[loc[1]]; const offsetBot = lastLine.offsetTop + lastLine.offsetHeight; @@ -33,7 +32,7 @@ scrollOffset = offsetMid - halfHeight; } - lines.scrollTo(0, scrollOffset); + lines.parentElement.scrollTo(0, scrollOffset); elt.querySelector(".rust").scrollTo(0, scrollOffset); } diff --git a/src/librustdoc/html/templates/scraped_source.html b/src/librustdoc/html/templates/scraped_source.html new file mode 100644 index 00000000000..e1fc2e69378 --- /dev/null +++ b/src/librustdoc/html/templates/scraped_source.html @@ -0,0 +1,33 @@ +<div class="scraped-example{% if !info.needs_expansion +%} expanded{% endif %}" data-locs="{{info.locations}}"> {# #} + <div class="scraped-example-title"> + {{info.name +}} (<a href="{{info.url}}">{{info.title}}</a>) {# #} + </div> + <div class="example-wrap"> {# #} + {# https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr + Do not show "1 2 3 4 5 ..." in web search results. #} + <div class="src-line-numbers" data-nosnippet> {# #} + <pre> + {% for line in lines.clone() %} + {# ~#} + <span>{{line|safe}}</span> + {% endfor %} + </pre> {# #} + </div> {# #} + <pre class="rust"> {# #} + <code> + {{code_html|safe}} + </code> {# #} + </pre> {# #} + {% if info.needs_prev_next_buttons || info.needs_expansion %} + <div class="button-holder"> + {% if info.needs_prev_next_buttons %} + <button class="prev">≺</button> {# #} + <button class="next">≻</button> + {% endif %} + {% if info.needs_expansion %} + <button class="expand">↕</button> + {% endif %} + </div> + {% endif %} + </div> {# #} +</div> {# #} diff --git a/src/librustdoc/html/templates/source.html b/src/librustdoc/html/templates/source.html index 42d01277db2..60a47f1b5de 100644 --- a/src/librustdoc/html/templates/source.html +++ b/src/librustdoc/html/templates/source.html @@ -1,21 +1,15 @@ -<div class="example-wrap"> {# #} +<div class="example-wrap"> {# https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr Do not show "1 2 3 4 5 ..." in web search results. #} <div data-nosnippet><pre class="src-line-numbers"> {% for line in lines.clone() %} - {% if embedded %} - <span>{{line|safe}}</span> - {%~ else %} - <a href="#{{line|safe}}" id="{{line|safe}}">{{line|safe}}</a> - {%~ endif %} + {# ~#} + <a href="#{{line|safe}}" id="{{line|safe}}">{{line|safe}}</a> {% endfor %} </pre></div> {# #} <pre class="rust"> {# #} <code> - {% if needs_expansion %} - <button class="expand">↕</button> - {% endif %} {{code_html|safe}} </code> {# #} </pre> {# #} -</div> +</div> {# #} diff --git a/src/tools/run-make-support/src/command.rs b/src/tools/run-make-support/src/command.rs index a0b96e25a0c..6b58173b343 100644 --- a/src/tools/run-make-support/src/command.rs +++ b/src/tools/run-make-support/src/command.rs @@ -15,7 +15,7 @@ use crate::{ /// This is a custom command wrapper that simplifies working with commands and makes it easier to /// ensure that we check the exit status of executed processes. /// -/// # A [`Command`] must be executed +/// # A [`Command`] must be executed exactly once /// /// A [`Command`] is armed by a [`DropBomb`] on construction to enforce that it will be executed. If /// a [`Command`] is constructed but never executed, the drop bomb will explode and cause the test @@ -23,26 +23,73 @@ use crate::{ /// containing constructed but never executed commands is dangerous because it can give a false /// sense of confidence. /// +/// Each [`Command`] invocation can also only be executed once, because we want to enforce +/// `std{in,out,err}` config via [`std::process::Stdio`] but [`std::process::Stdio`] is not +/// cloneable. +/// +/// In this sense, [`Command`] exhibits linear type semantics but enforced at run-time. +/// /// [`run`]: Self::run /// [`run_fail`]: Self::run_fail /// [`run_unchecked`]: Self::run_unchecked #[derive(Debug)] pub struct Command { cmd: StdCommand, - stdin: Option<Box<[u8]>>, + // Convience for providing a quick stdin buffer. + stdin_buf: Option<Box<[u8]>>, + + // Configurations for child process's std{in,out,err} handles. + stdin: Option<Stdio>, + stdout: Option<Stdio>, + stderr: Option<Stdio>, + + // Emulate linear type semantics. drop_bomb: DropBomb, + already_executed: bool, } impl Command { #[track_caller] pub fn new<P: AsRef<OsStr>>(program: P) -> Self { let program = program.as_ref(); - Self { cmd: StdCommand::new(program), stdin: None, drop_bomb: DropBomb::arm(program) } + Self { + cmd: StdCommand::new(program), + stdin_buf: None, + drop_bomb: DropBomb::arm(program), + stdin: None, + stdout: None, + stderr: None, + already_executed: false, + } } - /// Specify a stdin input - pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self { - self.stdin = Some(input.as_ref().to_vec().into_boxed_slice()); + /// Specify a stdin input buffer. This is a convenience helper, + pub fn stdin_buf<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self { + self.stdin_buf = Some(input.as_ref().to_vec().into_boxed_slice()); + self + } + + /// Configuration for the child process’s standard input (stdin) handle. + /// + /// See [`std::process::Command::stdin`]. + pub fn stdin<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Self { + self.stdin = Some(cfg.into()); + self + } + + /// Configuration for the child process’s standard output (stdout) handle. + /// + /// See [`std::process::Command::stdout`]. + pub fn stdout<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Self { + self.stdout = Some(cfg.into()); + self + } + + /// Configuration for the child process’s standard error (stderr) handle. + /// + /// See [`std::process::Command::stderr`]. + pub fn stderr<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Self { + self.stderr = Some(cfg.into()); self } @@ -105,6 +152,8 @@ impl Command { } /// Run the constructed command and assert that it is successfully run. + /// + /// By default, std{in,out,err} are [`Stdio::piped()`]. #[track_caller] pub fn run(&mut self) -> CompletedProcess { let output = self.command_output(); @@ -115,6 +164,8 @@ impl Command { } /// Run the constructed command and assert that it does not successfully run. + /// + /// By default, std{in,out,err} are [`Stdio::piped()`]. #[track_caller] pub fn run_fail(&mut self) -> CompletedProcess { let output = self.command_output(); @@ -124,10 +175,10 @@ impl Command { output } - /// Run the command but do not check its exit status. - /// Only use if you explicitly don't care about the exit status. - /// Prefer to use [`Self::run`] and [`Self::run_fail`] - /// whenever possible. + /// Run the command but do not check its exit status. Only use if you explicitly don't care + /// about the exit status. + /// + /// Prefer to use [`Self::run`] and [`Self::run_fail`] whenever possible. #[track_caller] pub fn run_unchecked(&mut self) -> CompletedProcess { self.command_output() @@ -135,13 +186,19 @@ impl Command { #[track_caller] fn command_output(&mut self) -> CompletedProcess { + if self.already_executed { + panic!("command was already executed"); + } else { + self.already_executed = true; + } + self.drop_bomb.defuse(); // let's make sure we piped all the input and outputs - self.cmd.stdin(Stdio::piped()); - self.cmd.stdout(Stdio::piped()); - self.cmd.stderr(Stdio::piped()); + self.cmd.stdin(self.stdin.take().unwrap_or(Stdio::piped())); + self.cmd.stdout(self.stdout.take().unwrap_or(Stdio::piped())); + self.cmd.stderr(self.stderr.take().unwrap_or(Stdio::piped())); - let output = if let Some(input) = &self.stdin { + let output = if let Some(input) = &self.stdin_buf { let mut child = self.cmd.spawn().unwrap(); { diff --git a/src/tools/run-make-support/src/external_deps/llvm.rs b/src/tools/run-make-support/src/external_deps/llvm.rs index e9315856cd7..2522c4aeb93 100644 --- a/src/tools/run-make-support/src/external_deps/llvm.rs +++ b/src/tools/run-make-support/src/external_deps/llvm.rs @@ -227,9 +227,10 @@ impl LlvmFilecheck { Self { cmd } } - /// Pipe a read file into standard input containing patterns that will be matched against the .patterns(path) call. - pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self { - self.cmd.stdin(input); + /// Provide a buffer representing standard input containing patterns that will be matched + /// against the `.patterns(path)` call. + pub fn stdin_buf<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self { + self.cmd.stdin_buf(input); self } diff --git a/src/tools/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs index cece58d2956..f60ea972839 100644 --- a/src/tools/run-make-support/src/external_deps/rustc.rs +++ b/src/tools/run-make-support/src/external_deps/rustc.rs @@ -291,9 +291,9 @@ impl Rustc { self } - /// Specify a stdin input - pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self { - self.cmd.stdin(input); + /// Specify a stdin input buffer. + pub fn stdin_buf<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self { + self.cmd.stdin_buf(input); self } diff --git a/src/tools/run-make-support/src/external_deps/rustdoc.rs b/src/tools/run-make-support/src/external_deps/rustdoc.rs index 96b1c719e2e..df5e5d8a2e8 100644 --- a/src/tools/run-make-support/src/external_deps/rustdoc.rs +++ b/src/tools/run-make-support/src/external_deps/rustdoc.rs @@ -85,9 +85,9 @@ impl Rustdoc { self } - /// Specify a stdin input - pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self { - self.cmd.stdin(input); + /// Specify a stdin input buffer. + pub fn stdin_buf<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self { + self.cmd.stdin_buf(input); self } diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 989d00d4c2f..fefafb95b33 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -34,6 +34,7 @@ pub mod rfs { } // Re-exports of third-party library crates. +// tidy-alphabetical-start pub use bstr; pub use gimli; pub use libc; @@ -41,6 +42,7 @@ pub use object; pub use regex; pub use serde_json; pub use wasmparser; +// tidy-alphabetical-end // Re-exports of external dependencies. pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rustdoc}; |
