Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit d56a1a2

Browse files
committedSep 5, 2024
Auto merge of #129985 - matthiaskrgr:rollup-trpflqk, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #129529 (Add test to build crates used by r-a on stable) - #129624 (Adjust `memchr` pinning and run `cargo update`) - #129720 (Simplify DestProp memory management) - #129796 (Unify scraped examples with other code examples) - #129891 (Do not request sanitizers for naked functions) - #129938 (Elaborate on deriving vs implementing `Copy`) Failed merges: - #129471 ([rustdoc] Sort impl associated items by kinds and then by appearance) r? `@ghost` `@rustbot` modify labels: rollup
2 parents eb33b43 + e835f22 commit d56a1a2

File tree

30 files changed

+941
-620
lines changed

30 files changed

+941
-620
lines changed
 

‎Cargo.lock

Lines changed: 153 additions & 131 deletions
Large diffs are not rendered by default.

‎compiler/rustc_ast/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ version = "0.0.0"
44
edition = "2021"
55

66
[dependencies]
7-
# FIXME: bumping memchr to 2.7.1 causes linker errors in MSVC thin-lto
87
# tidy-alphabetical-start
98
bitflags = "2.4.1"
10-
memchr = "=2.5.0"
9+
memchr = "2.7.4"
1110
rustc_ast_ir = { path = "../rustc_ast_ir" }
1211
rustc_data_structures = { path = "../rustc_data_structures" }
1312
rustc_index = { path = "../rustc_index" }

‎compiler/rustc_codegen_llvm/src/attributes.rs

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -411,26 +411,31 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
411411
// the string "false". Now it is disabled by absence of the attribute.
412412
to_add.push(llvm::CreateAttrStringValue(cx.llcx, "branch-target-enforcement", "false"));
413413
}
414-
} else if llvm_util::get_version() >= (19, 0, 0) {
415-
// For non-naked functions, set branch protection attributes on aarch64.
416-
if let Some(BranchProtection { bti, pac_ret }) =
417-
cx.sess().opts.unstable_opts.branch_protection
418-
{
419-
assert!(cx.sess().target.arch == "aarch64");
420-
if bti {
421-
to_add.push(llvm::CreateAttrString(cx.llcx, "branch-target-enforcement"));
422-
}
423-
if let Some(PacRet { leaf, key }) = pac_ret {
424-
to_add.push(llvm::CreateAttrStringValue(
425-
cx.llcx,
426-
"sign-return-address",
427-
if leaf { "all" } else { "non-leaf" },
428-
));
429-
to_add.push(llvm::CreateAttrStringValue(
430-
cx.llcx,
431-
"sign-return-address-key",
432-
if key == PAuthKey::A { "a_key" } else { "b_key" },
433-
));
414+
} else {
415+
// Do not set sanitizer attributes for naked functions.
416+
to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize));
417+
418+
if llvm_util::get_version() >= (19, 0, 0) {
419+
// For non-naked functions, set branch protection attributes on aarch64.
420+
if let Some(BranchProtection { bti, pac_ret }) =
421+
cx.sess().opts.unstable_opts.branch_protection
422+
{
423+
assert!(cx.sess().target.arch == "aarch64");
424+
if bti {
425+
to_add.push(llvm::CreateAttrString(cx.llcx, "branch-target-enforcement"));
426+
}
427+
if let Some(PacRet { leaf, key }) = pac_ret {
428+
to_add.push(llvm::CreateAttrStringValue(
429+
cx.llcx,
430+
"sign-return-address",
431+
if leaf { "all" } else { "non-leaf" },
432+
));
433+
to_add.push(llvm::CreateAttrStringValue(
434+
cx.llcx,
435+
"sign-return-address-key",
436+
if key == PAuthKey::A { "a_key" } else { "b_key" },
437+
));
438+
}
434439
}
435440
}
436441
}
@@ -485,7 +490,6 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
485490
if let Some(backchain) = backchain_attr(cx) {
486491
to_add.push(backchain);
487492
}
488-
to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize));
489493
to_add.extend(patchable_function_entry_attrs(cx, codegen_fn_attrs.patchable_function_entry));
490494

491495
// Always annotate functions with the target-cpu they are compiled for.

‎compiler/rustc_mir_transform/src/dest_prop.rs

Lines changed: 46 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
163163

164164
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
165165
let def_id = body.source.def_id();
166-
let mut allocations = Allocations::default();
166+
let mut candidates = Candidates::default();
167+
let mut write_info = WriteInfo::default();
167168
trace!(func = ?tcx.def_path_str(def_id));
168169

169170
let borrowed = rustc_mir_dataflow::impls::borrowed_locals(body);
@@ -191,20 +192,15 @@ impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
191192
loop {
192193
// PERF: Can we do something smarter than recalculating the candidates and liveness
193194
// results?
194-
let mut candidates = find_candidates(
195-
body,
196-
&borrowed,
197-
&mut allocations.candidates,
198-
&mut allocations.candidates_reverse,
199-
);
195+
candidates.reset_and_find(body, &borrowed);
200196
trace!(?candidates);
201197
dest_prop_mir_dump(tcx, body, &points, &live, round_count);
202198

203199
FilterInformation::filter_liveness(
204200
&mut candidates,
205201
&points,
206202
&live,
207-
&mut allocations.write_info,
203+
&mut write_info,
208204
body,
209205
);
210206

@@ -253,20 +249,8 @@ impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
253249
}
254250
}
255251

256-
/// Container for the various allocations that we need.
257-
///
258-
/// We store these here and hand out `&mut` access to them, instead of dropping and recreating them
259-
/// frequently. Everything with a `&'alloc` lifetime points into here.
260-
#[derive(Default)]
261-
struct Allocations {
262-
candidates: FxIndexMap<Local, Vec<Local>>,
263-
candidates_reverse: FxIndexMap<Local, Vec<Local>>,
264-
write_info: WriteInfo,
265-
// PERF: Do this for `MaybeLiveLocals` allocations too.
266-
}
267-
268-
#[derive(Debug)]
269-
struct Candidates<'alloc> {
252+
#[derive(Debug, Default)]
253+
struct Candidates {
270254
/// The set of candidates we are considering in this optimization.
271255
///
272256
/// We will always merge the key into at most one of its values.
@@ -281,11 +265,12 @@ struct Candidates<'alloc> {
281265
///
282266
/// We will still report that we would like to merge `_1` and `_2` in an attempt to allow us to
283267
/// remove that assignment.
284-
c: &'alloc mut FxIndexMap<Local, Vec<Local>>,
268+
c: FxIndexMap<Local, Vec<Local>>,
269+
285270
/// A reverse index of the `c` set; if the `c` set contains `a => Place { local: b, proj }`,
286271
/// then this contains `b => a`.
287272
// PERF: Possibly these should be `SmallVec`s?
288-
reverse: &'alloc mut FxIndexMap<Local, Vec<Local>>,
273+
reverse: FxIndexMap<Local, Vec<Local>>,
289274
}
290275

291276
//////////////////////////////////////////////////////////
@@ -358,19 +343,40 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Merger<'a, 'tcx> {
358343
//
359344
// This section enforces bullet point 2
360345

361-
struct FilterInformation<'a, 'body, 'alloc, 'tcx> {
362-
body: &'body Body<'tcx>,
346+
struct FilterInformation<'a, 'tcx> {
347+
body: &'a Body<'tcx>,
363348
points: &'a DenseLocationMap,
364349
live: &'a SparseIntervalMatrix<Local, PointIndex>,
365-
candidates: &'a mut Candidates<'alloc>,
366-
write_info: &'alloc mut WriteInfo,
350+
candidates: &'a mut Candidates,
351+
write_info: &'a mut WriteInfo,
367352
at: Location,
368353
}
369354

370355
// We first implement some utility functions which we will expose removing candidates according to
371356
// different needs. Throughout the liveness filtering, the `candidates` are only ever accessed
372357
// through these methods, and not directly.
373-
impl<'alloc> Candidates<'alloc> {
358+
impl Candidates {
359+
/// Collects the candidates for merging.
360+
///
361+
/// This is responsible for enforcing the first and third bullet point.
362+
fn reset_and_find<'tcx>(&mut self, body: &Body<'tcx>, borrowed: &BitSet<Local>) {
363+
self.c.clear();
364+
self.reverse.clear();
365+
let mut visitor = FindAssignments { body, candidates: &mut self.c, borrowed };
366+
visitor.visit_body(body);
367+
// Deduplicate candidates.
368+
for (_, cands) in self.c.iter_mut() {
369+
cands.sort();
370+
cands.dedup();
371+
}
372+
// Generate the reverse map.
373+
for (src, cands) in self.c.iter() {
374+
for dest in cands.iter().copied() {
375+
self.reverse.entry(dest).or_default().push(*src);
376+
}
377+
}
378+
}
379+
374380
/// Just `Vec::retain`, but the condition is inverted and we add debugging output
375381
fn vec_filter_candidates(
376382
src: Local,
@@ -445,7 +451,7 @@ enum CandidateFilter {
445451
Remove,
446452
}
447453

448-
impl<'a, 'body, 'alloc, 'tcx> FilterInformation<'a, 'body, 'alloc, 'tcx> {
454+
impl<'a, 'tcx> FilterInformation<'a, 'tcx> {
449455
/// Filters the set of candidates to remove those that conflict.
450456
///
451457
/// The steps we take are exactly those that are outlined at the top of the file. For each
@@ -463,12 +469,12 @@ impl<'a, 'body, 'alloc, 'tcx> FilterInformation<'a, 'body, 'alloc, 'tcx> {
463469
/// before the statement/terminator will correctly report locals that are read in the
464470
/// statement/terminator to be live. We are additionally conservative by treating all written to
465471
/// locals as also being read from.
466-
fn filter_liveness<'b>(
467-
candidates: &mut Candidates<'alloc>,
472+
fn filter_liveness(
473+
candidates: &mut Candidates,
468474
points: &DenseLocationMap,
469475
live: &SparseIntervalMatrix<Local, PointIndex>,
470-
write_info_alloc: &'alloc mut WriteInfo,
471-
body: &'b Body<'tcx>,
476+
write_info: &mut WriteInfo,
477+
body: &Body<'tcx>,
472478
) {
473479
let mut this = FilterInformation {
474480
body,
@@ -477,7 +483,7 @@ impl<'a, 'body, 'alloc, 'tcx> FilterInformation<'a, 'body, 'alloc, 'tcx> {
477483
candidates,
478484
// We don't actually store anything at this scope, we just keep things here to be able
479485
// to reuse the allocation.
480-
write_info: write_info_alloc,
486+
write_info,
481487
// Doesn't matter what we put here, will be overwritten before being used
482488
at: Location::START,
483489
};
@@ -734,40 +740,13 @@ fn places_to_candidate_pair<'tcx>(
734740
Some((a, b))
735741
}
736742

737-
/// Collects the candidates for merging
738-
///
739-
/// This is responsible for enforcing the first and third bullet point.
740-
fn find_candidates<'alloc, 'tcx>(
741-
body: &Body<'tcx>,
742-
borrowed: &BitSet<Local>,
743-
candidates: &'alloc mut FxIndexMap<Local, Vec<Local>>,
744-
candidates_reverse: &'alloc mut FxIndexMap<Local, Vec<Local>>,
745-
) -> Candidates<'alloc> {
746-
candidates.clear();
747-
candidates_reverse.clear();
748-
let mut visitor = FindAssignments { body, candidates, borrowed };
749-
visitor.visit_body(body);
750-
// Deduplicate candidates
751-
for (_, cands) in candidates.iter_mut() {
752-
cands.sort();
753-
cands.dedup();
754-
}
755-
// Generate the reverse map
756-
for (src, cands) in candidates.iter() {
757-
for dest in cands.iter().copied() {
758-
candidates_reverse.entry(dest).or_default().push(*src);
759-
}
760-
}
761-
Candidates { c: candidates, reverse: candidates_reverse }
762-
}
763-
764-
struct FindAssignments<'a, 'alloc, 'tcx> {
743+
struct FindAssignments<'a, 'tcx> {
765744
body: &'a Body<'tcx>,
766-
candidates: &'alloc mut FxIndexMap<Local, Vec<Local>>,
745+
candidates: &'a mut FxIndexMap<Local, Vec<Local>>,
767746
borrowed: &'a BitSet<Local>,
768747
}
769748

770-
impl<'tcx> Visitor<'tcx> for FindAssignments<'_, '_, 'tcx> {
749+
impl<'tcx> Visitor<'tcx> for FindAssignments<'_, 'tcx> {
771750
fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) {
772751
if let StatementKind::Assign(box (
773752
lhs,
@@ -819,9 +798,9 @@ fn is_local_required(local: Local, body: &Body<'_>) -> bool {
819798
/////////////////////////////////////////////////////////
820799
// MIR Dump
821800

822-
fn dest_prop_mir_dump<'body, 'tcx>(
801+
fn dest_prop_mir_dump<'tcx>(
823802
tcx: TyCtxt<'tcx>,
824-
body: &'body Body<'tcx>,
803+
body: &Body<'tcx>,
825804
points: &DenseLocationMap,
826805
live: &SparseIntervalMatrix<Local, PointIndex>,
827806
round: usize,

‎compiler/rustc_type_ir/src/elaborate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ pub fn supertrait_def_ids<I: Interner>(
237237
cx: I,
238238
trait_def_id: I::DefId,
239239
) -> impl Iterator<Item = I::DefId> {
240-
let mut set: HashSet<I::DefId> = HashSet::default();
240+
let mut set = HashSet::default();
241241
let mut stack = vec![trait_def_id];
242242

243243
set.insert(trait_def_id);

‎library/Cargo.lock

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change

‎library/core/src/marker.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,19 @@ marker_impls! {
288288
/// }
289289
/// ```
290290
///
291-
/// There is a small difference between the two: the `derive` strategy will also place a `Copy`
292-
/// bound on type parameters, which isn't always desired.
291+
/// There is a small difference between the two. The `derive` strategy will also place a `Copy`
292+
/// bound on type parameters:
293+
///
294+
/// ```
295+
/// #[derive(Clone)]
296+
/// struct MyStruct<T>(T);
297+
///
298+
/// impl<T: Copy> Copy for MyStruct<T> { }
299+
/// ```
300+
///
301+
/// This isn't always desired. For example, shared references (`&T`) can be copied regardless of
302+
/// whether `T` is `Copy`. Likewise, a generic struct containing markers such as [`PhantomData`]
303+
/// could potentially be duplicated with a bit-wise copy.
293304
///
294305
/// ## What's the difference between `Copy` and `Clone`?
295306
///

‎library/std/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ unwind = { path = "../unwind" }
2323
hashbrown = { version = "0.14", default-features = false, features = [
2424
'rustc-dep-of-std',
2525
] }
26+
# FIXME(#127890): `object` depends on `memchr`, but `memchr` > v2.5 causes
27+
# issues with LTO. This dependency is not used directly, but pin it here so
28+
# it is resolved 2.5. To be removed once rust-lang/rust#127890 is fixed.
29+
memchr = { version = "=2.5.0", default-features = false, features = ["rustc-dep-of-std"] }
2630
std_detect = { path = "../stdarch/crates/std_detect", default-features = false, features = [
2731
'rustc-dep-of-std',
2832
] }

‎src/librustdoc/html/render/mod.rs

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2455,28 +2455,6 @@ fn render_call_locations<W: fmt::Write>(mut w: W, cx: &mut Context<'_>, item: &c
24552455
let needs_expansion = line_max - line_min > NUM_VISIBLE_LINES;
24562456
let locations_encoded = serde_json::to_string(&line_ranges).unwrap();
24572457

2458-
write!(
2459-
&mut w,
2460-
"<div class=\"scraped-example {expanded_cls}\" data-locs=\"{locations}\">\
2461-
<div class=\"scraped-example-title\">\
2462-
{name} (<a href=\"{url}\">{title}</a>)\
2463-
</div>\
2464-
<div class=\"code-wrapper\">",
2465-
expanded_cls = if needs_expansion { "" } else { "expanded" },
2466-
name = call_data.display_name,
2467-
url = init_url,
2468-
title = init_title,
2469-
// The locations are encoded as a data attribute, so they can be read
2470-
// later by the JS for interactions.
2471-
locations = Escape(&locations_encoded)
2472-
)
2473-
.unwrap();
2474-
2475-
if line_ranges.len() > 1 {
2476-
w.write_str(r#"<button class="prev">&pr;</button> <button class="next">&sc;</button>"#)
2477-
.unwrap();
2478-
}
2479-
24802458
// Look for the example file in the source map if it exists, otherwise return a dummy span
24812459
let file_span = (|| {
24822460
let source_map = tcx.sess.source_map();
@@ -2507,9 +2485,16 @@ fn render_call_locations<W: fmt::Write>(mut w: W, cx: &mut Context<'_>, item: &c
25072485
cx,
25082486
&cx.root_path(),
25092487
highlight::DecorationInfo(decoration_info),
2510-
sources::SourceContext::Embedded { offset: line_min, needs_expansion },
2488+
sources::SourceContext::Embedded(sources::ScrapedInfo {
2489+
needs_prev_next_buttons: line_ranges.len() > 1,
2490+
needs_expansion,
2491+
offset: line_min,
2492+
name: &call_data.display_name,
2493+
url: init_url,
2494+
title: init_title,
2495+
locations: locations_encoded,
2496+
}),
25112497
);
2512-
w.write_str("</div></div>").unwrap();
25132498

25142499
true
25152500
};

‎src/librustdoc/html/sources.rs

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,34 @@ where
290290
}
291291
}
292292

293-
pub(crate) enum SourceContext {
293+
pub(crate) struct ScrapedInfo<'a> {
294+
pub(crate) offset: usize,
295+
pub(crate) needs_prev_next_buttons: bool,
296+
pub(crate) name: &'a str,
297+
pub(crate) url: &'a str,
298+
pub(crate) title: &'a str,
299+
pub(crate) locations: String,
300+
pub(crate) needs_expansion: bool,
301+
}
302+
303+
#[derive(Template)]
304+
#[template(path = "scraped_source.html")]
305+
struct ScrapedSource<'a, Code: std::fmt::Display> {
306+
info: ScrapedInfo<'a>,
307+
lines: RangeInclusive<usize>,
308+
code_html: Code,
309+
}
310+
311+
#[derive(Template)]
312+
#[template(path = "source.html")]
313+
struct Source<Code: std::fmt::Display> {
314+
lines: RangeInclusive<usize>,
315+
code_html: Code,
316+
}
317+
318+
pub(crate) enum SourceContext<'a> {
294319
Standalone,
295-
Embedded { offset: usize, needs_expansion: bool },
320+
Embedded(ScrapedInfo<'a>),
296321
}
297322

298323
/// Wrapper struct to render the source code of a file. This will do things like
@@ -304,23 +329,8 @@ pub(crate) fn print_src(
304329
context: &Context<'_>,
305330
root_path: &str,
306331
decoration_info: highlight::DecorationInfo,
307-
source_context: SourceContext,
332+
source_context: SourceContext<'_>,
308333
) {
309-
#[derive(Template)]
310-
#[template(path = "source.html")]
311-
struct Source<Code: std::fmt::Display> {
312-
embedded: bool,
313-
needs_expansion: bool,
314-
lines: RangeInclusive<usize>,
315-
code_html: Code,
316-
}
317-
let lines = s.lines().count();
318-
let (embedded, needs_expansion, lines) = match source_context {
319-
SourceContext::Standalone => (false, false, 1..=lines),
320-
SourceContext::Embedded { offset, needs_expansion } => {
321-
(true, needs_expansion, (1 + offset)..=(lines + offset))
322-
}
323-
};
324334
let current_href = context
325335
.href_from_span(clean::Span::new(file_span), false)
326336
.expect("only local crates should have sources emitted");
@@ -333,5 +343,14 @@ pub(crate) fn print_src(
333343
);
334344
Ok(())
335345
});
336-
Source { embedded, needs_expansion, lines, code_html: code }.render_into(&mut writer).unwrap();
346+
let lines = s.lines().count();
347+
match source_context {
348+
SourceContext::Standalone => {
349+
Source { lines: (1..=lines), code_html: code }.render_into(&mut writer).unwrap()
350+
}
351+
SourceContext::Embedded(info) => {
352+
let lines = (1 + info.offset)..=(lines + info.offset);
353+
ScrapedSource { info, lines, code_html: code }.render_into(&mut writer).unwrap();
354+
}
355+
};
337356
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ nav.sub {
5959
--copy-path-button-color: #999;
6060
--copy-path-img-filter: invert(50%);
6161
--copy-path-img-hover-filter: invert(35%);
62+
--code-example-button-color: #7f7f7f;
63+
--code-example-button-hover-color: #595959;
6264
--codeblock-error-hover-color: rgb(255, 0, 0);
6365
--codeblock-error-color: rgba(255, 0, 0, .5);
6466
--codeblock-ignore-hover-color: rgb(255, 142, 0);
@@ -162,6 +164,8 @@ nav.sub {
162164
--copy-path-button-color: #999;
163165
--copy-path-img-filter: invert(50%);
164166
--copy-path-img-hover-filter: invert(65%);
167+
--code-example-button-color: #7f7f7f;
168+
--code-example-button-hover-color: #a5a5a5;
165169
--codeblock-error-hover-color: rgb(255, 0, 0);
166170
--codeblock-error-color: rgba(255, 0, 0, .5);
167171
--codeblock-ignore-hover-color: rgb(255, 142, 0);

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

Lines changed: 74 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ pre.item-decl {
378378
.src .content pre {
379379
padding: 20px;
380380
}
381-
.rustdoc.src .example-wrap pre.src-line-numbers {
381+
.rustdoc.src .example-wrap .src-line-numbers {
382382
padding: 20px 0 20px 4px;
383383
}
384384

@@ -757,10 +757,32 @@ ul.block, .block li, .block ul {
757757
margin-bottom: 10px;
758758
}
759759

760-
.rustdoc .example-wrap > pre {
760+
.rustdoc .example-wrap > pre,
761+
.rustdoc .scraped-example .src-line-numbers,
762+
.rustdoc .scraped-example .src-line-numbers > pre {
761763
border-radius: 6px;
762764
}
763765

766+
/*
767+
If the code example line numbers are displayed, there will be a weird radius in the middle from
768+
both the code example and the line numbers, so we need to remove the radius in this case.
769+
*/
770+
.rustdoc .example-wrap > .example-line-numbers,
771+
.rustdoc .scraped-example .src-line-numbers,
772+
.rustdoc .scraped-example .src-line-numbers > pre {
773+
border-top-right-radius: 0;
774+
border-bottom-right-radius: 0;
775+
}
776+
.rustdoc .example-wrap > .example-line-numbers + pre,
777+
.rustdoc .scraped-example .rust {
778+
border-top-left-radius: 0;
779+
border-bottom-left-radius: 0;
780+
}
781+
782+
.rustdoc .scraped-example {
783+
position: relative;
784+
}
785+
764786
/* For the last child of a div, the margin will be taken care of
765787
by the margin-top of the next item. */
766788
.rustdoc .example-wrap:last-child {
@@ -772,23 +794,44 @@ ul.block, .block li, .block ul {
772794
flex-grow: 1;
773795
}
774796

775-
.rustdoc:not(.src) .example-wrap pre {
797+
.scraped-example:not(.expanded) .example-wrap {
798+
/* scrape-examples.js has a constant DEFAULT_MAX_LINES (call it N) for the number
799+
* of lines shown in the un-expanded example code viewer. This pre needs to have
800+
* a max-height equal to line-height * N. The line-height is currently 1.5em,
801+
* and we include additional 10px for padding. */
802+
max-height: calc(1.5em * 5 + 10px);
803+
}
804+
805+
.rustdoc:not(.src) .scraped-example:not(.expanded) .src-line-numbers,
806+
.rustdoc:not(.src) .scraped-example:not(.expanded) .src-line-numbers > pre,
807+
.rustdoc:not(.src) .scraped-example:not(.expanded) pre.rust {
808+
padding-bottom: 0;
809+
/* See above comment, should be the same max-height. */
776810
overflow: auto hidden;
777811
}
812+
.rustdoc:not(.src) .scraped-example .src-line-numbers {
813+
padding-top: 0;
814+
}
815+
.rustdoc:not(.src) .scraped-example.expanded .src-line-numbers {
816+
padding-bottom: 0;
817+
}
818+
819+
.rustdoc:not(.src) .example-wrap pre {
820+
overflow: auto;
821+
}
778822

779823
.rustdoc .example-wrap pre.example-line-numbers,
780-
.rustdoc .example-wrap pre.src-line-numbers {
781-
flex-grow: 0;
824+
.rustdoc .example-wrap .src-line-numbers {
782825
min-width: fit-content; /* prevent collapsing into nothing in truncated scraped examples */
783-
overflow: initial;
826+
flex-grow: 0;
784827
text-align: right;
785828
-webkit-user-select: none;
786829
user-select: none;
787830
padding: 14px 8px;
788831
color: var(--src-line-numbers-span-color);
789832
}
790833

791-
.rustdoc .example-wrap pre.src-line-numbers {
834+
.rustdoc .scraped-example .src-line-numbers {
792835
padding: 14px 0;
793836
}
794837
.src-line-numbers a, .src-line-numbers span {
@@ -1500,17 +1543,23 @@ instead, we check that it's not a "finger" cursor.
15001543
.example-wrap .button-holder.keep-visible {
15011544
visibility: visible;
15021545
}
1503-
.example-wrap .button-holder .copy-button, .example-wrap .test-arrow {
1546+
.example-wrap .button-holder > * {
15041547
background: var(--main-background-color);
15051548
cursor: pointer;
15061549
border-radius: var(--button-border-radius);
15071550
height: var(--copy-path-height);
15081551
width: var(--copy-path-width);
1552+
border: 0;
1553+
color: var(--code-example-button-color);
15091554
}
1510-
.example-wrap .button-holder .copy-button {
1555+
.example-wrap .button-holder > *:hover {
1556+
color: var(--code-example-button-hover-color);
1557+
}
1558+
.example-wrap .button-holder > *:not(:first-child) {
15111559
margin-left: var(--button-left-margin);
1560+
}
1561+
.example-wrap .button-holder .copy-button {
15121562
padding: 2px 0 0 4px;
1513-
border: 0;
15141563
}
15151564
.example-wrap .button-holder .copy-button::before,
15161565
.example-wrap .test-arrow::before {
@@ -2254,6 +2303,7 @@ in src-script.js and main.js
22542303
}
22552304
}
22562305

2306+
22572307
/* Should have min-width: (N + 1)px where N is the mobile breakpoint above. */
22582308
@media (min-width: 701px) {
22592309
/* 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
23562406
color: var(--scrape-example-help-hover-color);
23572407
}
23582408

2359-
.scraped-example {
2360-
/* So .scraped-example-title can be positioned absolutely */
2361-
position: relative;
2362-
}
2363-
2364-
.scraped-example .code-wrapper {
2365-
position: relative;
2366-
display: flex;
2367-
flex-direction: row;
2368-
flex-wrap: wrap;
2369-
width: 100%;
2370-
}
2371-
2372-
.scraped-example:not(.expanded) .code-wrapper {
2373-
/* scrape-examples.js has a constant DEFAULT_MAX_LINES (call it N) for the number
2374-
* of lines shown in the un-expanded example code viewer. This pre needs to have
2375-
* a max-height equal to line-height * N. The line-height is currently 1.5em,
2376-
* and we include additional 10px for padding. */
2377-
max-height: calc(1.5em * 5 + 10px);
2378-
}
2379-
2380-
.scraped-example:not(.expanded) .code-wrapper pre {
2381-
overflow-y: hidden;
2382-
padding-bottom: 0;
2383-
/* See above comment, should be the same max-height. */
2384-
max-height: calc(1.5em * 5 + 10px);
2385-
}
2386-
2387-
.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper,
2388-
.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper pre {
2389-
/* See above comment, except this height is based on HIDDEN_MAX_LINES. */
2390-
max-height: calc(1.5em * 10 + 10px);
2391-
}
2392-
2393-
.scraped-example .code-wrapper .next,
2394-
.scraped-example .code-wrapper .prev,
2395-
.scraped-example .code-wrapper .expand {
2396-
color: var(--main-color);
2397-
position: absolute;
2398-
top: 0.25em;
2399-
z-index: 1;
2400-
padding: 0;
2401-
background: none;
2402-
border: none;
2403-
/* iOS button gradient: https://stackoverflow.com/q/5438567 */
2404-
-webkit-appearance: none;
2405-
opacity: 1;
2406-
}
2407-
.scraped-example .code-wrapper .prev {
2408-
right: 2.25em;
2409-
}
2410-
.scraped-example .code-wrapper .next {
2411-
right: 1.25em;
2412-
}
2413-
.scraped-example .code-wrapper .expand {
2414-
right: 0.25em;
2415-
}
2416-
2417-
.scraped-example:not(.expanded) .code-wrapper::before,
2418-
.scraped-example:not(.expanded) .code-wrapper::after {
2409+
.scraped-example:not(.expanded) .example-wrap::before,
2410+
.scraped-example:not(.expanded) .example-wrap::after {
24192411
content: " ";
24202412
width: 100%;
24212413
height: 5px;
24222414
position: absolute;
24232415
z-index: 1;
24242416
}
2425-
.scraped-example:not(.expanded) .code-wrapper::before {
2417+
.scraped-example:not(.expanded) .example-wrap::before {
24262418
top: 0;
24272419
background: linear-gradient(to bottom,
24282420
var(--scrape-example-code-wrapper-background-start),
24292421
var(--scrape-example-code-wrapper-background-end));
24302422
}
2431-
.scraped-example:not(.expanded) .code-wrapper::after {
2423+
.scraped-example:not(.expanded) .example-wrap::after {
24322424
bottom: 0;
24332425
background: linear-gradient(to top,
24342426
var(--scrape-example-code-wrapper-background-start),
24352427
var(--scrape-example-code-wrapper-background-end));
24362428
}
24372429

2438-
.scraped-example .code-wrapper .example-wrap {
2430+
.scraped-example:not(.expanded) {
24392431
width: 100%;
24402432
overflow-y: hidden;
24412433
margin-bottom: 0;
24422434
}
24432435

2444-
.scraped-example:not(.expanded) .code-wrapper .example-wrap {
2436+
.scraped-example:not(.expanded) {
24452437
overflow-x: hidden;
24462438
}
24472439

2448-
.scraped-example .example-wrap .rust span.highlight {
2440+
.scraped-example .rust span.highlight {
24492441
background: var(--scrape-example-code-line-highlight);
24502442
}
2451-
.scraped-example .example-wrap .rust span.highlight.focus {
2443+
.scraped-example .rust span.highlight.focus {
24522444
background: var(--scrape-example-code-line-highlight-focus);
24532445
}
24542446

@@ -2542,6 +2534,8 @@ by default.
25422534
--copy-path-button-color: #999;
25432535
--copy-path-img-filter: invert(50%);
25442536
--copy-path-img-hover-filter: invert(35%);
2537+
--code-example-button-color: #7f7f7f;
2538+
--code-example-button-hover-color: #595959;
25452539
--codeblock-error-hover-color: rgb(255, 0, 0);
25462540
--codeblock-error-color: rgba(255, 0, 0, .5);
25472541
--codeblock-ignore-hover-color: rgb(255, 142, 0);
@@ -2644,6 +2638,8 @@ by default.
26442638
--copy-path-button-color: #999;
26452639
--copy-path-img-filter: invert(50%);
26462640
--copy-path-img-hover-filter: invert(65%);
2641+
--code-example-button-color: #7f7f7f;
2642+
--code-example-button-hover-color: #a5a5a5;
26472643
--codeblock-error-hover-color: rgb(255, 0, 0);
26482644
--codeblock-error-color: rgba(255, 0, 0, .5);
26492645
--codeblock-ignore-hover-color: rgb(255, 142, 0);
@@ -2753,6 +2749,8 @@ Original by Dempfi (https://github.com/dempfi/ayu)
27532749
--copy-path-button-color: #fff;
27542750
--copy-path-img-filter: invert(70%);
27552751
--copy-path-img-hover-filter: invert(100%);
2752+
--code-example-button-color: #b2b2b2;
2753+
--code-example-button-hover-color: #fff;
27562754
--codeblock-error-hover-color: rgb(255, 0, 0);
27572755
--codeblock-error-color: rgba(255, 0, 0, .5);
27582756
--codeblock-ignore-hover-color: rgb(255, 142, 0);

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1855,8 +1855,13 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
18551855
// Since the button will be added, no need to keep this listener around.
18561856
elem.removeEventListener("mouseover", addCopyButton);
18571857

1858-
const parent = document.createElement("div");
1859-
parent.className = "button-holder";
1858+
// If this is a scrapped example, there will already be a "button-holder" element.
1859+
let parent = elem.querySelector(".button-holder");
1860+
if (!parent) {
1861+
parent = document.createElement("div");
1862+
parent.className = "button-holder";
1863+
}
1864+
18601865
const runButton = elem.querySelector(".test-arrow");
18611866
if (runButton !== null) {
18621867
// If there is a run button, we move it into the same div.

‎src/librustdoc/html/static/js/scrape-examples.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
// Scroll code block to the given code location
1515
function scrollToLoc(elt, loc, isHidden) {
16-
const lines = elt.querySelector(".src-line-numbers");
16+
const lines = elt.querySelector(".src-line-numbers > pre");
1717
let scrollOffset;
1818

1919
// If the block is greater than the size of the viewer,
@@ -24,16 +24,15 @@
2424
const line = Math.max(0, loc[0] - 1);
2525
scrollOffset = lines.children[line].offsetTop;
2626
} else {
27-
const wrapper = elt.querySelector(".code-wrapper");
28-
const halfHeight = wrapper.offsetHeight / 2;
27+
const halfHeight = elt.offsetHeight / 2;
2928
const offsetTop = lines.children[loc[0]].offsetTop;
3029
const lastLine = lines.children[loc[1]];
3130
const offsetBot = lastLine.offsetTop + lastLine.offsetHeight;
3231
const offsetMid = (offsetTop + offsetBot) / 2;
3332
scrollOffset = offsetMid - halfHeight;
3433
}
3534

36-
lines.scrollTo(0, scrollOffset);
35+
lines.parentElement.scrollTo(0, scrollOffset);
3736
elt.querySelector(".rust").scrollTo(0, scrollOffset);
3837
}
3938

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<div class="scraped-example{% if !info.needs_expansion +%} expanded{% endif %}" data-locs="{{info.locations}}"> {# #}
2+
<div class="scraped-example-title">
3+
{{info.name +}} (<a href="{{info.url}}">{{info.title}}</a>) {# #}
4+
</div>
5+
<div class="example-wrap"> {# #}
6+
{# https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr
7+
Do not show "1 2 3 4 5 ..." in web search results. #}
8+
<div class="src-line-numbers" data-nosnippet> {# #}
9+
<pre>
10+
{% for line in lines.clone() %}
11+
{# ~#}
12+
<span>{{line|safe}}</span>
13+
{% endfor %}
14+
</pre> {# #}
15+
</div> {# #}
16+
<pre class="rust"> {# #}
17+
<code>
18+
{{code_html|safe}}
19+
</code> {# #}
20+
</pre> {# #}
21+
{% if info.needs_prev_next_buttons || info.needs_expansion %}
22+
<div class="button-holder">
23+
{% if info.needs_prev_next_buttons %}
24+
<button class="prev">&pr;</button> {# #}
25+
<button class="next">&sc;</button>
26+
{% endif %}
27+
{% if info.needs_expansion %}
28+
<button class="expand">&varr;</button>
29+
{% endif %}
30+
</div>
31+
{% endif %}
32+
</div> {# #}
33+
</div> {# #}
Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,15 @@
1-
<div class="example-wrap"> {# #}
1+
<div class="example-wrap">
22
{# https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr
33
Do not show "1 2 3 4 5 ..." in web search results. #}
44
<div data-nosnippet><pre class="src-line-numbers">
55
{% for line in lines.clone() %}
6-
{% if embedded %}
7-
<span>{{line|safe}}</span>
8-
{%~ else %}
9-
<a href="#{{line|safe}}" id="{{line|safe}}">{{line|safe}}</a>
10-
{%~ endif %}
6+
{# ~#}
7+
<a href="#{{line|safe}}" id="{{line|safe}}">{{line|safe}}</a>
118
{% endfor %}
129
</pre></div> {# #}
1310
<pre class="rust"> {# #}
1411
<code>
15-
{% if needs_expansion %}
16-
<button class="expand">&varr;</button>
17-
{% endif %}
1812
{{code_html|safe}}
1913
</code> {# #}
2014
</pre> {# #}
21-
</div>
15+
</div> {# #}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use crate::command::Command;
2+
use crate::env_var;
3+
4+
/// Returns a command that can be used to invoke Cargo.
5+
pub fn cargo() -> Command {
6+
Command::new(env_var("BOOTSTRAP_CARGO"))
7+
}

‎src/tools/run-make-support/src/external_deps/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
//! such as `cc` or `python`.
33
44
pub mod c_build;
5+
pub mod cargo;
56
pub mod cc;
67
pub mod clang;
78
pub mod htmldocck;

‎src/tools/run-make-support/src/external_deps/rustc.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,13 @@ pub struct Rustc {
3636

3737
crate::macros::impl_common_helpers!(Rustc);
3838

39+
pub fn rustc_path() -> String {
40+
env_var("RUSTC")
41+
}
42+
3943
#[track_caller]
4044
fn setup_common() -> Command {
41-
let rustc = env_var("RUSTC");
42-
let mut cmd = Command::new(rustc);
45+
let mut cmd = Command::new(rustc_path());
4346
set_host_rpath(&mut cmd);
4447
cmd
4548
}

‎src/tools/run-make-support/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rust
4848
// These rely on external dependencies.
4949
pub use cc::{cc, cxx, extra_c_flags, extra_cxx_flags, Cc};
5050
pub use c_build::{build_native_dynamic_lib, build_native_static_lib, build_native_static_lib_optimized, build_native_static_lib_cxx};
51+
pub use cargo::cargo;
5152
pub use clang::{clang, Clang};
5253
pub use htmldocck::htmldocck;
5354
pub use llvm::{
@@ -56,7 +57,7 @@ pub use llvm::{
5657
LlvmProfdata, LlvmReadobj,
5758
};
5859
pub use python::python_command;
59-
pub use rustc::{aux_build, bare_rustc, rustc, Rustc};
60+
pub use rustc::{aux_build, bare_rustc, rustc, rustc_path, Rustc};
6061
pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc};
6162

6263
/// [`diff`][mod@diff] is implemented in terms of the [similar] library.
@@ -96,3 +97,4 @@ pub use assertion_helpers::{
9697
pub use string::{
9798
count_regex_matches_in_files_with_extension, invalid_utf8_contains, invalid_utf8_not_contains,
9899
};
100+
use crate::external_deps::cargo;

‎src/tools/rustbook/Cargo.lock

Lines changed: 202 additions & 206 deletions
Large diffs are not rendered by default.

‎src/tools/tidy/src/deps.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ const PERMITTED_DEPS_LOCATION: &str = concat!(file!(), ":", line!());
242242
/// rustc. Please check with the compiler team before adding an entry.
243243
const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
244244
// tidy-alphabetical-start
245-
"adler",
245+
"adler2",
246246
"ahash",
247247
"aho-corasick",
248248
"allocator-api2", // FIXME: only appears in Cargo.lock due to https://github.com/rust-lang/cargo/issues/10801
@@ -481,6 +481,7 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[
481481
"rand_core",
482482
"rand_xorshift",
483483
"rustc-demangle",
484+
"shlex",
484485
"unicode-width",
485486
"unwinding",
486487
"wasi",

‎tests/codegen/naked-asan.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Make sure we do not request sanitizers for naked functions.
2+
3+
//@ only-x86_64
4+
//@ needs-sanitizer-address
5+
//@ compile-flags: -Zsanitizer=address
6+
7+
#![crate_type = "lib"]
8+
#![no_std]
9+
#![feature(abi_x86_interrupt, naked_functions)]
10+
11+
// CHECK: define x86_intrcc void @page_fault_handler(ptr {{.*}}%0, i64 {{.*}}%1){{.*}}#[[ATTRS:[0-9]+]] {
12+
// CHECK-NOT: memcpy
13+
#[naked]
14+
#[no_mangle]
15+
pub extern "x86-interrupt" fn page_fault_handler(_: u64, _: u64) {
16+
unsafe {
17+
core::arch::asm!("ud2", options(noreturn));
18+
}
19+
}
20+
21+
// CHECK: #[[ATTRS]] =
22+
// CHECK-NOT: sanitize_address
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//! Checks if selected rustc crates can be compiled on the stable channel (or a "simulation" of it).
2+
//! These crates are designed to be used by downstream users.
3+
4+
use run_make_support::{cargo, rustc_path, source_root};
5+
6+
fn main() {
7+
// Use the stage0 beta cargo for the compilation (it shouldn't really matter which cargo we use)
8+
cargo()
9+
// Ensure `proc-macro2`'s nightly detection is disabled
10+
.env("RUSTC_STAGE", "0")
11+
.env("RUSTC", rustc_path())
12+
// We want to disallow all nightly features to simulate a stable build
13+
.env("RUSTFLAGS", "-Zallow-features=")
14+
.arg("build")
15+
.arg("--manifest-path")
16+
.arg(source_root().join("Cargo.toml"))
17+
.args(&[
18+
// Avoid depending on transitive rustc crates
19+
"--no-default-features",
20+
// Emit artifacts in this temporary directory, not in the source_root's `target` folder
21+
"--target-dir",
22+
"target",
23+
])
24+
// Check that these crates can be compiled on "stable"
25+
.args(&[
26+
"-p",
27+
"rustc_type_ir",
28+
"-p",
29+
"rustc_next_trait_solver",
30+
"-p",
31+
"rustc_pattern_analysis",
32+
"-p",
33+
"rustc_lexer",
34+
])
35+
.run();
36+
}

‎tests/rustdoc-gui/code-example-buttons.goml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,24 @@ call-function: ("check-buttons",{
9494
"filter": "invert(0.5)",
9595
"filter_hover": "invert(0.35)",
9696
})
97+
98+
define-function: (
99+
"check-buttons-position",
100+
[pre_selector],
101+
block {
102+
move-cursor-to: |pre_selector| + " .rust:not(.item-decl)"
103+
store-position: (|pre_selector| + " .rust:not(.item-decl)", {"x": x, "y": y})
104+
assert-position: (|pre_selector| + " .rust:not(.item-decl) + .button-holder", {
105+
"y": |y| + 4,
106+
})
107+
}
108+
)
109+
110+
call-function: ("check-buttons-position", {"pre_selector": ".example-wrap"})
111+
112+
go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html"
113+
// We should work as well for scraped examples.
114+
call-function: ("check-buttons-position", {"pre_selector": ".scraped-example .example-wrap"})
115+
// And also when the scraped example "title" goes above.
116+
set-window-size: (600, 600)
117+
call-function: ("check-buttons-position", {"pre_selector": ".scraped-example .example-wrap"})

‎tests/rustdoc-gui/docblock-code-block-line-number.goml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,18 @@ go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html"
55
// We check that without this setting, there is no line number displayed.
66
assert-false: "pre.example-line-numbers"
77

8+
// All corners should be rounded.
9+
assert-css: (
10+
".example-wrap .rust",
11+
{
12+
"border-top-left-radius": "6px",
13+
"border-bottom-left-radius": "6px",
14+
"border-top-right-radius": "6px",
15+
"border-bottom-right-radius": "6px",
16+
},
17+
ALL,
18+
)
19+
820
// We set the setting to show the line numbers on code examples.
921
set-local-storage: {"rustdoc-line-numbers": "true"}
1022
reload:
@@ -29,9 +41,21 @@ define-function: (
2941
"margin": "0px",
3042
"padding": "14px 8px",
3143
"text-align": "right",
44+
// There should not be a radius on the right of the line numbers.
45+
"border-top-left-radius": "6px",
46+
"border-bottom-left-radius": "6px",
47+
"border-top-right-radius": "0px",
48+
"border-bottom-right-radius": "0px",
3249
},
3350
ALL,
3451
)
52+
// There should not be a radius on the left of the line numbers.
53+
assert-css: ("pre.example-line-numbers + .rust", {
54+
"border-top-left-radius": "0px",
55+
"border-bottom-left-radius": "0px",
56+
"border-top-right-radius": "6px",
57+
"border-bottom-right-radius": "6px",
58+
})
3559
},
3660
)
3761
call-function: ("check-colors", {
@@ -64,7 +88,56 @@ wait-for: 100 // wait-for-false does not exist
6488
assert-false: "pre.example-line-numbers"
6589
assert-local-storage: {"rustdoc-line-numbers": "false" }
6690

91+
// Check that the rounded corners are back.
92+
assert-css: (
93+
".example-wrap .rust",
94+
{
95+
"border-top-left-radius": "6px",
96+
"border-bottom-left-radius": "6px",
97+
"border-top-right-radius": "6px",
98+
"border-bottom-right-radius": "6px",
99+
},
100+
ALL,
101+
)
102+
67103
// Finally, turn it on again.
68104
click: "input#line-numbers"
69105
wait-for: "pre.example-line-numbers"
70106
assert-local-storage: {"rustdoc-line-numbers": "true" }
107+
108+
// Same check with scraped examples line numbers.
109+
go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html"
110+
111+
assert-css: (
112+
".scraped-example .src-line-numbers > pre",
113+
{
114+
// There should not be a radius on the right of the line numbers.
115+
"border-top-left-radius": "6px",
116+
"border-bottom-left-radius": "6px",
117+
"border-top-right-radius": "0px",
118+
"border-bottom-right-radius": "0px",
119+
},
120+
ALL,
121+
)
122+
assert-css: (
123+
".scraped-example .src-line-numbers",
124+
{
125+
// There should not be a radius on the right of the line numbers.
126+
"border-top-left-radius": "6px",
127+
"border-bottom-left-radius": "6px",
128+
"border-top-right-radius": "0px",
129+
"border-bottom-right-radius": "0px",
130+
},
131+
ALL,
132+
)
133+
assert-css: (
134+
".scraped-example .rust",
135+
{
136+
// There should not be a radius on the left of the code.
137+
"border-top-left-radius": "0px",
138+
"border-bottom-left-radius": "0px",
139+
"border-top-right-radius": "6px",
140+
"border-bottom-right-radius": "6px",
141+
},
142+
ALL,
143+
)

‎tests/rustdoc-gui/scrape-examples-button-focus.goml

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,53 @@
33
go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test.html"
44

55
// The next/prev buttons vertically scroll the code viewport between examples
6-
store-property: (".scraped-example-list > .scraped-example pre", {"scrollTop": initialScrollTop})
6+
move-cursor-to: ".scraped-example-list > .scraped-example"
7+
store-property: (".scraped-example-list > .scraped-example .src-line-numbers", {
8+
"scrollTop": initialScrollTop,
9+
})
10+
assert-property: (".scraped-example-list > .scraped-example .rust", {
11+
"scrollTop": |initialScrollTop|,
12+
})
713
focus: ".scraped-example-list > .scraped-example .next"
814
press-key: "Enter"
9-
assert-property-false: (".scraped-example-list > .scraped-example pre", {
15+
assert-property-false: (".scraped-example-list > .scraped-example .src-line-numbers", {
16+
"scrollTop": |initialScrollTop|
17+
}, NEAR)
18+
assert-property-false: (".scraped-example-list > .scraped-example .rust", {
1019
"scrollTop": |initialScrollTop|
1120
}, NEAR)
1221
focus: ".scraped-example-list > .scraped-example .prev"
1322
press-key: "Enter"
14-
assert-property: (".scraped-example-list > .scraped-example pre", {
23+
assert-property: (".scraped-example-list > .scraped-example .src-line-numbers", {
24+
"scrollTop": |initialScrollTop|
25+
}, NEAR)
26+
assert-property: (".scraped-example-list > .scraped-example .rust", {
1527
"scrollTop": |initialScrollTop|
1628
}, NEAR)
1729

1830
// The expand button increases the scrollHeight of the minimized code viewport
1931
store-property: (".scraped-example-list > .scraped-example pre", {"offsetHeight": smallOffsetHeight})
20-
assert-property-false: (".scraped-example-list > .scraped-example pre", {
32+
assert-property: (".scraped-example-list > .scraped-example .src-line-numbers", {
33+
"scrollHeight": |smallOffsetHeight|
34+
}, NEAR)
35+
assert-property: (".scraped-example-list > .scraped-example .rust", {
2136
"scrollHeight": |smallOffsetHeight|
2237
}, NEAR)
2338
focus: ".scraped-example-list > .scraped-example .expand"
2439
press-key: "Enter"
25-
assert-property-false: (".scraped-example-list > .scraped-example pre", {
40+
assert-property-false: (".scraped-example-list > .scraped-example .src-line-numbers", {
41+
"offsetHeight": |smallOffsetHeight|
42+
}, NEAR)
43+
assert-property-false: (".scraped-example-list > .scraped-example .rust", {
2644
"offsetHeight": |smallOffsetHeight|
2745
}, NEAR)
28-
store-property: (".scraped-example-list > .scraped-example pre", {"offsetHeight": fullOffsetHeight})
29-
assert-property: (".scraped-example-list > .scraped-example pre", {
46+
store-property: (".scraped-example-list > .scraped-example .src-line-numbers", {
47+
"offsetHeight": fullOffsetHeight,
48+
})
49+
assert-property: (".scraped-example-list > .scraped-example .rust", {
50+
"offsetHeight": |fullOffsetHeight|,
51+
"scrollHeight": |fullOffsetHeight|,
52+
})
53+
assert-property: (".scraped-example-list > .scraped-example .src-line-numbers", {
3054
"scrollHeight": |fullOffsetHeight|
3155
}, NEAR)

‎tests/rustdoc-gui/scrape-examples-color.goml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ define-function: (
1010
block {
1111
call-function: ("switch-theme", {"theme": |theme|})
1212
wait-for: ".more-examples-toggle"
13-
assert-css: (".scraped-example .example-wrap .rust span.highlight:not(.focus)", {
13+
assert-css: (".scraped-example .rust span.highlight:not(.focus)", {
1414
"background-color": |highlight|,
1515
}, ALL)
16-
assert-css: (".scraped-example .example-wrap .rust span.highlight.focus", {
16+
assert-css: (".scraped-example .rust span.highlight.focus", {
1717
"background-color": |highlight_focus|,
1818
}, ALL)
1919

@@ -67,11 +67,11 @@ define-function: (
6767
[theme, background_color_start, background_color_end],
6868
block {
6969
call-function: ("switch-theme", {"theme": |theme|})
70-
assert-css: (".scraped-example:not(.expanded) .code-wrapper::before", {
70+
assert-css: (".scraped-example:not(.expanded) .example-wrap::before", {
7171
"background-image": "linear-gradient(" + |background_color_start| + ", " +
7272
|background_color_end| + ")",
7373
})
74-
assert-css: (".scraped-example:not(.expanded) .code-wrapper::after", {
74+
assert-css: (".scraped-example:not(.expanded) .example-wrap::after", {
7575
"background-image": "linear-gradient(to top, " + |background_color_start| + ", " +
7676
|background_color_end| + ")",
7777
})
Lines changed: 77 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,115 @@
11
// Check that the line number column has the correct layout.
22
go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html"
33

4+
set-window-size: (1000, 1000)
5+
46
// Check that it's not zero.
57
assert-property-false: (
6-
".more-scraped-examples .scraped-example .code-wrapper .src-line-numbers",
8+
".more-scraped-examples .scraped-example .src-line-numbers",
79
{"clientWidth": "0"}
810
)
911

1012
// Check that examples with very long lines have the same width as ones that don't.
1113
store-property: (
12-
".more-scraped-examples .scraped-example:nth-child(2) .code-wrapper .src-line-numbers",
14+
".more-scraped-examples .scraped-example:nth-child(2) .src-line-numbers",
1315
{"clientWidth": clientWidth},
1416
)
1517

1618
assert-property: (
17-
".more-scraped-examples .scraped-example:nth-child(3) .code-wrapper .src-line-numbers",
19+
".more-scraped-examples .scraped-example:nth-child(3) .src-line-numbers",
1820
{"clientWidth": |clientWidth|}
1921
)
2022

2123
assert-property: (
22-
".more-scraped-examples .scraped-example:nth-child(4) .code-wrapper .src-line-numbers",
24+
".more-scraped-examples .scraped-example:nth-child(4) .src-line-numbers",
2325
{"clientWidth": |clientWidth|}
2426
)
2527

2628
assert-property: (
27-
".more-scraped-examples .scraped-example:nth-child(5) .code-wrapper .src-line-numbers",
29+
".more-scraped-examples .scraped-example:nth-child(5) .src-line-numbers",
2830
{"clientWidth": |clientWidth|}
2931
)
3032

3133
assert-property: (
32-
".more-scraped-examples .scraped-example:nth-child(6) .code-wrapper .src-line-numbers",
34+
".more-scraped-examples .scraped-example:nth-child(6) .src-line-numbers",
3335
{"clientWidth": |clientWidth|}
3436
)
3537

38+
// The "title" should be located at the right bottom corner of the code example.
39+
store-position: (".scraped-example .example-wrap", {"x": x, "y": y})
40+
store-size: (".scraped-example .example-wrap", {"width": width, "height": height})
41+
store-size: (".scraped-example .scraped-example-title", {
42+
"width": title_width,
43+
"height": title_height,
44+
})
45+
assert-position: (".scraped-example .scraped-example-title", {
46+
"x": |x| + |width| - |title_width| - 5,
47+
"y": |y| + |height| - |title_height| - 8,
48+
})
49+
50+
// Check that the expand button works and also that line number aligns with code.
51+
move-cursor-to: ".scraped-example .rust"
52+
click: ".scraped-example .button-holder .expand"
53+
wait-for: ".scraped-example.expanded"
54+
// They should have the same y position.
55+
compare-elements-position: (
56+
".scraped-example.expanded .src-line-numbers pre span",
57+
".scraped-example.expanded .rust code",
58+
["y"],
59+
)
60+
// And they should have the same height.
61+
compare-elements-size: (
62+
".scraped-example.expanded .src-line-numbers",
63+
".scraped-example.expanded .rust",
64+
["height"],
65+
)
66+
// Collapse code again.
67+
click: ".scraped-example .button-holder .expand"
68+
3669
// Check that for both mobile and desktop sizes, the buttons in scraped examples are displayed
3770
// correctly.
3871

3972
store-value: (offset_y, 4)
4073

4174
// First with desktop
42-
assert-position: (".scraped-example .code-wrapper", {"y": 226})
43-
assert-position: (".scraped-example .code-wrapper .prev", {"y": 226 + |offset_y|})
75+
assert-position: (".scraped-example", {"y": 226})
76+
assert-position: (".scraped-example .prev", {"y": 226 + |offset_y|})
77+
78+
// Gradient background should be at the top of the code block.
79+
assert-css: (".scraped-example .example-wrap::before", {"top": "0px"})
80+
assert-css: (".scraped-example .example-wrap::after", {"bottom": "0px"})
4481

4582
// Then with mobile
4683
set-window-size: (600, 600)
47-
assert-position: (".scraped-example .code-wrapper", {"y": 308})
48-
assert-position: (".scraped-example .code-wrapper .prev", {"y": 308 + |offset_y|})
84+
store-size: (".scraped-example .scraped-example-title", {"height": title_height})
85+
assert-position: (".scraped-example", {"y": 284})
86+
assert-position: (".scraped-example .prev", {"y": 284 + |offset_y| + |title_height|})
87+
88+
define-function: (
89+
"check_title_and_code_position",
90+
[],
91+
block {
92+
// Title should be above the code.
93+
store-position: (".scraped-example .example-wrap .src-line-numbers", {"x": x, "y": y})
94+
store-size: (".scraped-example .scraped-example-title", { "height": title_height })
95+
96+
assert-position: (".scraped-example .scraped-example-title", {
97+
"x": |x|, // same X position.
98+
"y": |y| - |title_height|,
99+
})
100+
101+
// Line numbers should be right beside the code.
102+
compare-elements-position: (
103+
".scraped-example .example-wrap .src-line-numbers",
104+
".scraped-example .example-wrap .rust",
105+
["y"],
106+
)
107+
}
108+
)
109+
110+
// Check that the title is now above the code.
111+
call-function: ("check_title_and_code_position", {})
112+
113+
// Then with small mobile
114+
set-window-size: (300, 300)
115+
call-function: ("check_title_and_code_position", {})

‎tests/rustdoc-gui/src/theme_css/custom-theme.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
--copy-path-button-color: #999;
2424
--copy-path-img-filter: invert(50%);
2525
--copy-path-img-hover-filter: invert(35%);
26+
--code-example-button-color: #7f7f7f;
27+
--code-example-button-hover-color: #a5a5a5;
2628
--codeblock-error-hover-color: rgb(255, 0, 0);
2729
--codeblock-error-color: rgba(255, 0, 0, .5);
2830
--codeblock-ignore-hover-color: rgb(255, 142, 0);

0 commit comments

Comments
 (0)
Please sign in to comment.