Skip to content

Commit 34f5815

Browse files
committed
Auto merge of #149872 - jhpratt:rollup-lhzly2q, r=jhpratt
Rollup of 4 pull requests Successful merges: - #142380 (Put negative implementors first and apply same ordering logic to foreign implementors) - #149807 (Use ubuntu:24.04 for the `x86_64-gnu-miri` job) - #149850 (Remove "tidy" tool for `tests/rustdoc` testsuite) - #149867 (only resolve main in bin crates) r? `@ghost` `@rustbot` modify labels: rollup
2 parents f520900 + ed11741 commit 34f5815

File tree

22 files changed

+200
-299
lines changed

22 files changed

+200
-299
lines changed

compiler/rustc_resolve/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ use rustc_middle::ty::{
7373
ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility,
7474
};
7575
use rustc_query_system::ich::StableHashingContext;
76+
use rustc_session::config::CrateType;
7677
use rustc_session::lint::builtin::PRIVATE_MACRO_USE;
7778
use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency};
7879
use rustc_span::{DUMMY_SP, Ident, Macros20NormalizedIdent, Span, Symbol, kw, sym};
@@ -2430,6 +2431,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
24302431
}
24312432

24322433
fn resolve_main(&mut self) {
2434+
let any_exe = self.tcx.crate_types().contains(&CrateType::Executable);
2435+
// Don't try to resolve main unless it's an executable
2436+
if !any_exe {
2437+
return;
2438+
}
2439+
24332440
let module = self.graph_root;
24342441
let ident = Ident::with_dummy_span(sym::main);
24352442
let parent_scope = &ParentScope::module(module, self.arenas);

src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM ubuntu:22.04
1+
FROM ghcr.io/rust-lang/ubuntu:24.04
22

33
ARG DEBIAN_FRONTEND=noninteractive
44
RUN apt-get update && apt-get install -y --no-install-recommends \

src/ci/docker/host-x86_64/x86_64-gnu-miri/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM ghcr.io/rust-lang/ubuntu:22.04
1+
FROM ghcr.io/rust-lang/ubuntu:24.04
22

33
ARG DEBIAN_FRONTEND=noninteractive
44
RUN apt-get update && apt-get install -y --no-install-recommends \

src/librustdoc/formats/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,8 @@ impl Impl {
7676
};
7777
true
7878
}
79+
80+
pub(crate) fn is_negative_trait_impl(&self) -> bool {
81+
self.inner_impl().is_negative_trait_impl()
82+
}
7983
}

src/librustdoc/html/render/print_item.rs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,27 @@ fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> imp
646646
})
647647
}
648648

649+
/// Struct used to handle insertion of "negative impl" marker in the generated DOM.
650+
///
651+
/// This marker appears once in all trait impl lists to divide negative impls from positive impls.
652+
struct NegativeMarker {
653+
inserted: bool,
654+
}
655+
656+
impl NegativeMarker {
657+
fn new() -> Self {
658+
Self { inserted: false }
659+
}
660+
661+
fn insert_if_needed(&mut self, w: &mut fmt::Formatter<'_>, implementor: &Impl) -> fmt::Result {
662+
if !self.inserted && !implementor.is_negative_trait_impl() {
663+
w.write_str("<div class=\"negative-marker\"></div>")?;
664+
self.inserted = true;
665+
}
666+
Ok(())
667+
}
668+
}
669+
649670
fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt::Display {
650671
fmt::from_fn(|w| {
651672
let tcx = cx.tcx();
@@ -1072,7 +1093,9 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt:
10721093
"<div id=\"implementors-list\">",
10731094
)
10741095
)?;
1096+
let mut negative_marker = NegativeMarker::new();
10751097
for implementor in concrete {
1098+
negative_marker.insert_if_needed(w, implementor)?;
10761099
write!(w, "{}", render_implementor(cx, implementor, it, &implementor_dups, &[]))?;
10771100
}
10781101
w.write_str("</div>")?;
@@ -1088,7 +1111,9 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt:
10881111
"<div id=\"synthetic-implementors-list\">",
10891112
)
10901113
)?;
1114+
let mut negative_marker = NegativeMarker::new();
10911115
for implementor in synthetic {
1116+
negative_marker.insert_if_needed(w, implementor)?;
10921117
write!(
10931118
w,
10941119
"{}",
@@ -2302,11 +2327,18 @@ where
23022327
}
23032328

23042329
#[derive(PartialEq, Eq)]
2305-
struct ImplString(String);
2330+
struct ImplString {
2331+
rendered: String,
2332+
is_negative: bool,
2333+
}
23062334

23072335
impl ImplString {
23082336
fn new(i: &Impl, cx: &Context<'_>) -> ImplString {
2309-
ImplString(format!("{}", print_impl(i.inner_impl(), false, cx)))
2337+
let impl_ = i.inner_impl();
2338+
ImplString {
2339+
is_negative: impl_.is_negative_trait_impl(),
2340+
rendered: format!("{}", print_impl(impl_, false, cx)),
2341+
}
23102342
}
23112343
}
23122344

@@ -2318,7 +2350,12 @@ impl PartialOrd for ImplString {
23182350

23192351
impl Ord for ImplString {
23202352
fn cmp(&self, other: &Self) -> Ordering {
2321-
compare_names(&self.0, &other.0)
2353+
// We sort negative impls first.
2354+
match (self.is_negative, other.is_negative) {
2355+
(false, true) => Ordering::Greater,
2356+
(true, false) => Ordering::Less,
2357+
_ => compare_names(&self.rendered, &other.rendered),
2358+
}
23222359
}
23232360
}
23242361

src/librustdoc/html/render/write_shared.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
//! or contains "invocation-specific".
1515
1616
use std::cell::RefCell;
17+
use std::cmp::Ordering;
1718
use std::ffi::{OsStr, OsString};
1819
use std::fs::File;
1920
use std::io::{self, Write as _};
@@ -47,6 +48,7 @@ use crate::formats::item_type::ItemType;
4748
use crate::html::format::{print_impl, print_path};
4849
use crate::html::layout;
4950
use crate::html::render::ordered_json::{EscapedJson, OrderedJson};
51+
use crate::html::render::print_item::compare_names;
5052
use crate::html::render::search_index::{SerializedSearchIndex, build_index};
5153
use crate::html::render::sorted_template::{self, FileFormat, SortedTemplate};
5254
use crate::html::render::{AssocItemLink, ImplRenderingParameters, StylePath};
@@ -667,7 +669,7 @@ impl TraitAliasPart {
667669
fn blank() -> SortedTemplate<<Self as CciPart>::FileFormat> {
668670
SortedTemplate::from_before_after(
669671
r"(function() {
670-
var implementors = Object.fromEntries([",
672+
const implementors = Object.fromEntries([",
671673
r"]);
672674
if (window.register_implementors) {
673675
window.register_implementors(implementors);
@@ -720,10 +722,12 @@ impl TraitAliasPart {
720722
{
721723
None
722724
} else {
725+
let impl_ = imp.inner_impl();
723726
Some(Implementor {
724-
text: print_impl(imp.inner_impl(), false, cx).to_string(),
727+
text: print_impl(impl_, false, cx).to_string(),
725728
synthetic: imp.inner_impl().kind.is_auto(),
726729
types: collect_paths_for_type(&imp.inner_impl().for_, cache),
730+
is_negative: impl_.is_negative_trait_impl(),
727731
})
728732
}
729733
})
@@ -742,8 +746,22 @@ impl TraitAliasPart {
742746
}
743747
path.push(format!("{remote_item_type}.{}.js", remote_path[remote_path.len() - 1]));
744748

745-
let part = OrderedJson::array_sorted(
746-
implementors.map(|implementor| OrderedJson::serialize(implementor).unwrap()),
749+
let mut implementors = implementors.collect::<Vec<_>>();
750+
implementors.sort_unstable_by(|a, b| {
751+
// We sort negative impls first.
752+
match (a.is_negative, b.is_negative) {
753+
(false, true) => Ordering::Greater,
754+
(true, false) => Ordering::Less,
755+
_ => compare_names(&a.text, &b.text),
756+
}
757+
});
758+
759+
let part = OrderedJson::array_unsorted(
760+
implementors
761+
.iter()
762+
.map(OrderedJson::serialize)
763+
.collect::<Result<Vec<_>, _>>()
764+
.unwrap(),
747765
);
748766
path_parts.push(path, OrderedJson::array_unsorted([crate_name_json, &part]));
749767
}
@@ -755,6 +773,7 @@ struct Implementor {
755773
text: String,
756774
synthetic: bool,
757775
types: Vec<String>,
776+
is_negative: bool,
758777
}
759778

760779
impl Serialize for Implementor {
@@ -764,6 +783,7 @@ impl Serialize for Implementor {
764783
{
765784
let mut seq = serializer.serialize_seq(None)?;
766785
seq.serialize_element(&self.text)?;
786+
seq.serialize_element(if self.is_negative { &1 } else { &0 })?;
767787
if self.synthetic {
768788
seq.serialize_element(&1)?;
769789
seq.serialize_element(&self.types)?;

src/librustdoc/html/render/write_shared/tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ fn trait_alias_template() {
6868
assert_eq!(
6969
but_last_line(&template.to_string()),
7070
r#"(function() {
71-
var implementors = Object.fromEntries([]);
71+
const implementors = Object.fromEntries([]);
7272
if (window.register_implementors) {
7373
window.register_implementors(implementors);
7474
} else {
@@ -80,7 +80,7 @@ fn trait_alias_template() {
8080
assert_eq!(
8181
but_last_line(&template.to_string()),
8282
r#"(function() {
83-
var implementors = Object.fromEntries([["a"]]);
83+
const implementors = Object.fromEntries([["a"]]);
8484
if (window.register_implementors) {
8585
window.register_implementors(implementors);
8686
} else {
@@ -92,7 +92,7 @@ fn trait_alias_template() {
9292
assert_eq!(
9393
but_last_line(&template.to_string()),
9494
r#"(function() {
95-
var implementors = Object.fromEntries([["a"],["b"]]);
95+
const implementors = Object.fromEntries([["a"],["b"]]);
9696
if (window.register_implementors) {
9797
window.register_implementors(implementors);
9898
} else {

src/librustdoc/html/static/css/noscript.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ nav.sub {
2929
display: none;
3030
}
3131

32+
#synthetic-implementors-list:not(.loaded), #implementors-list:not(.loaded) {
33+
display: block;
34+
}
35+
3236
/* Begin: styles for themes
3337
Keep the default light and dark themes synchronized with the ones
3438
in rustdoc.css */

src/librustdoc/html/static/css/rustdoc.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,6 +1158,12 @@ div.where {
11581158
margin-left: calc(var(--docblock-indent) + var(--impl-items-indent));
11591159
}
11601160

1161+
#synthetic-implementors-list:not(.loaded), #implementors-list:not(.loaded) {
1162+
/* To prevent layout shift when loading the page with extra implementors being loaded
1163+
from JS, we hide the list until it's complete. */
1164+
display: none;
1165+
}
1166+
11611167
.item-info code {
11621168
font-size: 0.875rem;
11631169
}
@@ -2976,6 +2982,9 @@ in src-script.js and main.js
29762982
{
29772983
margin-bottom: 0.75em;
29782984
}
2985+
.negative-marker {
2986+
display: none;
2987+
}
29792988

29802989
.variants > .docblock,
29812990
.implementors-toggle > .docblock,

src/librustdoc/html/static/js/main.js

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -800,21 +800,34 @@ function preLoadCss(cssUrl) {
800800

801801
// <https://github.com/search?q=repo%3Arust-lang%2Frust+[RUSTDOCIMPL]+trait.impl&type=code>
802802
window.register_implementors = imp => {
803-
const implementors = document.getElementById("implementors-list");
804-
const synthetic_implementors = document.getElementById("synthetic-implementors-list");
803+
/** Takes an ID as input and returns a list of two elements. The first element is the DOM
804+
* element with the given ID and the second is the "negative marker", meaning the location
805+
* between the negative and non-negative impls.
806+
*
807+
* @param {string} id: ID of the DOM element.
808+
*
809+
* @return {[HTMLElement|null, HTMLElement|null]}
810+
*/
811+
function implementorsElems(id) {
812+
const elem = document.getElementById(id);
813+
return [elem, elem ? elem.querySelector(".negative-marker") : null];
814+
}
815+
const implementors = implementorsElems("implementors-list");
816+
const syntheticImplementors = implementorsElems("synthetic-implementors-list");
805817
const inlined_types = new Set();
806818

807819
const TEXT_IDX = 0;
808-
const SYNTHETIC_IDX = 1;
809-
const TYPES_IDX = 2;
820+
const IS_NEG_IDX = 1;
821+
const SYNTHETIC_IDX = 2;
822+
const TYPES_IDX = 3;
810823

811-
if (synthetic_implementors) {
824+
if (syntheticImplementors[0]) {
812825
// This `inlined_types` variable is used to avoid having the same implementation
813826
// showing up twice. For example "String" in the "Sync" doc page.
814827
//
815828
// By the way, this is only used by and useful for traits implemented automatically
816829
// (like "Send" and "Sync").
817-
onEachLazy(synthetic_implementors.getElementsByClassName("impl"), el => {
830+
onEachLazy(syntheticImplementors[0].getElementsByClassName("impl"), el => {
818831
const aliases = el.getAttribute("data-aliases");
819832
if (!aliases) {
820833
return;
@@ -827,7 +840,7 @@ function preLoadCss(cssUrl) {
827840
}
828841

829842
// @ts-expect-error
830-
let currentNbImpls = implementors.getElementsByClassName("impl").length;
843+
let currentNbImpls = implementors[0].getElementsByClassName("impl").length;
831844
// @ts-expect-error
832845
const traitName = document.querySelector(".main-heading h1 > .trait").textContent;
833846
const baseIdName = "impl-" + traitName + "-";
@@ -849,7 +862,7 @@ function preLoadCss(cssUrl) {
849862

850863
struct_loop:
851864
for (const struct of structs) {
852-
const list = struct[SYNTHETIC_IDX] ? synthetic_implementors : implementors;
865+
const list = struct[SYNTHETIC_IDX] ? syntheticImplementors : implementors;
853866

854867
// The types list is only used for synthetic impls.
855868
// If this changes, `main.js` and `write_shared.rs` both need changed.
@@ -884,11 +897,25 @@ function preLoadCss(cssUrl) {
884897
addClass(display, "impl");
885898
display.appendChild(anchor);
886899
display.appendChild(code);
887-
// @ts-expect-error
888-
list.appendChild(display);
900+
901+
// If this is a negative implementor, we put it into the right location (just
902+
// before the negative impl marker).
903+
if (struct[IS_NEG_IDX]) {
904+
// @ts-expect-error
905+
list[1].before(display);
906+
} else {
907+
// @ts-expect-error
908+
list[0].appendChild(display);
909+
}
889910
currentNbImpls += 1;
890911
}
891912
}
913+
if (implementors[0]) {
914+
implementors[0].classList.add("loaded");
915+
}
916+
if (syntheticImplementors[0]) {
917+
syntheticImplementors[0].classList.add("loaded");
918+
}
892919
};
893920
if (window.pending_implementors) {
894921
window.register_implementors(window.pending_implementors);

0 commit comments

Comments
 (0)