Skip to content

Commit 0d13f6a

Browse files
committed
Auto merge of rust-lang#96015 - Dylan-DPC:rollup-vhdprid, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - rust-lang#93217 (Improve Rustdoc UI for scraped examples with multiline arguments, fix overflow in line numbers) - rust-lang#95885 (Improve error message in case of missing checksum) - rust-lang#95962 (Document that DirEntry holds the directory open) - rust-lang#95991 (fix: wrong trait import suggestion for T:) - rust-lang#96005 (Add missing article to fix "few" to "a few".) - rust-lang#96006 (Add a missing article) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents ab33f71 + e95f2db commit 0d13f6a

File tree

19 files changed

+391
-93
lines changed

19 files changed

+391
-93
lines changed

Diff for: compiler/rustc_typeck/src/check/method/suggest.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1880,9 +1880,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18801880
};
18811881
let sp = hir.span(id);
18821882
let sp = if let Some(first_bound) = has_bounds {
1883-
// `sp` only covers `T`, change it so that it covers
1884-
// `T:` when appropriate
18851883
sp.until(first_bound.span())
1884+
} else if let Some(colon_sp) =
1885+
// If the generic param is declared with a colon but without bounds:
1886+
// fn foo<T:>(t: T) { ... }
1887+
param.colon_span_for_suggestions(
1888+
self.inh.tcx.sess.source_map(),
1889+
)
1890+
{
1891+
sp.to(colon_sp)
18861892
} else {
18871893
sp
18881894
};

Diff for: library/core/src/convert/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,11 @@ pub const fn identity<T>(x: T) -> T {
108108
/// If you need to do a costly conversion it is better to implement [`From`] with type
109109
/// `&T` or write a custom function.
110110
///
111-
/// `AsRef` has the same signature as [`Borrow`], but [`Borrow`] is different in few aspects:
111+
/// `AsRef` has the same signature as [`Borrow`], but [`Borrow`] is different in a few aspects:
112112
///
113113
/// - Unlike `AsRef`, [`Borrow`] has a blanket impl for any `T`, and can be used to accept either
114114
/// a reference or a value.
115-
/// - [`Borrow`] also requires that [`Hash`], [`Eq`] and [`Ord`] for borrowed value are
115+
/// - [`Borrow`] also requires that [`Hash`], [`Eq`] and [`Ord`] for a borrowed value are
116116
/// equivalent to those of the owned value. For this reason, if you want to
117117
/// borrow only a single field of a struct you can implement `AsRef`, but not [`Borrow`].
118118
///

Diff for: library/std/src/fs.rs

+10
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,16 @@ pub struct ReadDir(fs_imp::ReadDir);
132132
/// An instance of `DirEntry` represents an entry inside of a directory on the
133133
/// filesystem. Each entry can be inspected via methods to learn about the full
134134
/// path or possibly other metadata through per-platform extension traits.
135+
///
136+
/// # Platform-specific behavior
137+
///
138+
/// On Unix, the `DirEntry` struct contains an internal reference to the open
139+
/// directory. Holding `DirEntry` objects will consume a file handle even
140+
/// after the `ReadDir` iterator is dropped.
141+
///
142+
/// Note that this [may change in the future][changes].
143+
///
144+
/// [changes]: io#platform-specific-behavior
135145
#[stable(feature = "rust1", since = "1.0.0")]
136146
pub struct DirEntry(fs_imp::DirEntry);
137147

Diff for: src/bootstrap/bootstrap.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ def get(base, url, path, checksums, verbose=False, do_verify=True, help_on_error
7070
try:
7171
if do_verify:
7272
if url not in checksums:
73-
raise RuntimeError("src/stage0.json doesn't contain a checksum for {}".format(url))
73+
raise RuntimeError(("src/stage0.json doesn't contain a checksum for {}. "
74+
"Pre-built artifacts might not available for this "
75+
"target at this time, see https://doc.rust-lang.org/nightly"
76+
"/rustc/platform-support.html for more information.")
77+
.format(url))
7478
sha256 = checksums[url]
7579
if os.path.exists(path):
7680
if verify(path, sha256, False):

Diff for: src/doc/rustdoc/src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- [Linking to items by name](write-documentation/linking-to-items-by-name.md)
1010
- [Documentation tests](write-documentation/documentation-tests.md)
1111
- [Rustdoc-specific lints](lints.md)
12+
- [Scraped examples](scraped-examples.md)
1213
- [Advanced features](advanced-features.md)
1314
- [Unstable features](unstable-features.md)
1415
- [Deprecated features](deprecated-features.md)

Diff for: src/doc/rustdoc/src/scraped-examples.md

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Scraped examples
2+
3+
Rustdoc has an unstable feature where it can automatically scrape examples of items being documented from the `examples/` directory of a Cargo workspace. These examples will be included within the generated documentation for that item. For example, if your library contains a public function:
4+
5+
```rust,ignore (needs-other-file)
6+
// a_crate/src/lib.rs
7+
pub fn a_func() {}
8+
```
9+
10+
And you have an example calling this function:
11+
12+
```rust,ignore (needs-other-file)
13+
// a_crate/examples/ex.rs
14+
fn main() {
15+
a_crate::a_func();
16+
}
17+
```
18+
19+
Then this code snippet will be included in the documentation for `a_func`. This documentation is inserted by Rustdoc and cannot be manually edited by the crate author.
20+
21+
22+
## How to use this feature
23+
24+
This feature is unstable, so you can enable it by calling Rustdoc with the unstable `rustdoc-scrape-examples` flag:
25+
26+
```bash
27+
cargo doc -Zunstable-options -Zrustdoc-scrape-examples=examples
28+
```
29+
30+
To enable this feature on [docs.rs](https://docs.rs), add this to your Cargo.toml:
31+
32+
```toml
33+
[package.metadata.docs.rs]
34+
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples=examples"]
35+
```
36+
37+
38+
## How it works
39+
40+
When you run `cargo doc`, Rustdoc will analyze all the crates that match Cargo's `--examples` filter for instances of items being documented. Then Rustdoc will include the source code of these instances in the generated documentation.
41+
42+
Rustdoc has a few techniques to ensure these examples don't overwhelm documentation readers, and that it doesn't blow up the page size:
43+
44+
1. For a given item, a maximum of 5 examples are included in the page. The remaining examples are just links to source code.
45+
2. Only one example is shown by default, and the remaining examples are hidden behind a toggle.
46+
3. For a given file that contains examples, only the item containing the examples will be included in the generated documentation.
47+
48+
For a given item, Rustdoc sorts its examples based on the size of the example &mdash; smaller ones are shown first.
49+
50+
51+
## FAQ
52+
53+
### My example is not showing up in the documentation
54+
55+
This feature uses Cargo's convention for finding examples. You should ensure that `cargo check --examples` includes your example file.

Diff for: src/librustdoc/html/render/context.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use super::print_item::{full_path, item_path, print_item};
1717
use super::search_index::build_index;
1818
use super::write_shared::write_shared;
1919
use super::{
20-
collect_spans_and_sources, print_sidebar, settings, AllTypes, LinkFromSrc, NameDoc, StylePath,
21-
BASIC_KEYWORDS,
20+
collect_spans_and_sources, print_sidebar, scrape_examples_help, settings, AllTypes,
21+
LinkFromSrc, NameDoc, StylePath, BASIC_KEYWORDS,
2222
};
2323

2424
use crate::clean::{self, types::ExternalLocation, ExternalCrate};
@@ -551,6 +551,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
551551
let crate_name = self.tcx().crate_name(LOCAL_CRATE);
552552
let final_file = self.dst.join(crate_name.as_str()).join("all.html");
553553
let settings_file = self.dst.join("settings.html");
554+
let scrape_examples_help_file = self.dst.join("scrape-examples-help.html");
554555

555556
let mut root_path = self.dst.to_str().expect("invalid path").to_owned();
556557
if !root_path.ends_with('/') {
@@ -606,6 +607,20 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
606607
&self.shared.style_files,
607608
);
608609
self.shared.fs.write(settings_file, v)?;
610+
611+
if self.shared.layout.scrape_examples_extension {
612+
page.title = "About scraped examples";
613+
page.description = "How the scraped examples feature works in Rustdoc";
614+
let v = layout::render(
615+
&self.shared.layout,
616+
&page,
617+
"",
618+
scrape_examples_help(&*self.shared),
619+
&self.shared.style_files,
620+
);
621+
self.shared.fs.write(scrape_examples_help_file, v)?;
622+
}
623+
609624
if let Some(ref redirections) = self.shared.redirections {
610625
if !redirections.borrow().is_empty() {
611626
let redirect_map_path =

Diff for: src/librustdoc/html/render/mod.rs

+35-1
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,10 @@ use crate::html::format::{
7575
use crate::html::highlight;
7676
use crate::html::markdown::{HeadingOffset, IdMap, Markdown, MarkdownHtml, MarkdownSummaryLine};
7777
use crate::html::sources;
78+
use crate::html::static_files::SCRAPE_EXAMPLES_HELP_MD;
7879
use crate::scrape_examples::{CallData, CallLocation};
7980
use crate::try_none;
81+
use crate::DOC_RUST_LANG_ORG_CHANNEL;
8082

8183
/// A pair of name and its optional document.
8284
crate type NameDoc = (String, Option<String>);
@@ -460,6 +462,34 @@ fn settings(root_path: &str, suffix: &str, theme_names: Vec<String>) -> Result<S
460462
))
461463
}
462464

465+
fn scrape_examples_help(shared: &SharedContext<'_>) -> String {
466+
let mut content = SCRAPE_EXAMPLES_HELP_MD.to_owned();
467+
content.push_str(&format!(
468+
"## More information\n\n\
469+
If you want more information about this feature, please read the [corresponding chapter in the Rustdoc book]({}/rustdoc/scraped-examples.html).",
470+
DOC_RUST_LANG_ORG_CHANNEL));
471+
472+
let mut ids = IdMap::default();
473+
format!(
474+
"<div class=\"main-heading\">\
475+
<h1 class=\"fqn\">\
476+
<span class=\"in-band\">About scraped examples</span>\
477+
</h1>\
478+
</div>\
479+
<div>{}</div>",
480+
Markdown {
481+
content: &content,
482+
links: &[],
483+
ids: &mut ids,
484+
error_codes: shared.codes,
485+
edition: shared.edition(),
486+
playground: &shared.playground,
487+
heading_offset: HeadingOffset::H1
488+
}
489+
.into_string()
490+
)
491+
}
492+
463493
fn document(
464494
w: &mut Buffer,
465495
cx: &Context<'_>,
@@ -2743,7 +2773,9 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item) {
27432773
<span></span>\
27442774
<h5 id=\"{id}\">\
27452775
<a href=\"#{id}\">Examples found in repository</a>\
2776+
<a class=\"scrape-help\" href=\"{root_path}scrape-examples-help.html\">?</a>\
27462777
</h5>",
2778+
root_path = cx.root_path(),
27472779
id = id
27482780
);
27492781

@@ -2795,9 +2827,10 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item) {
27952827
.locations
27962828
.iter()
27972829
.map(|loc| {
2798-
let (byte_lo, byte_hi) = loc.call_expr.byte_span;
2830+
let (byte_lo, byte_hi) = loc.call_ident.byte_span;
27992831
let (line_lo, line_hi) = loc.call_expr.line_span;
28002832
let byte_range = (byte_lo - byte_min, byte_hi - byte_min);
2833+
28012834
let line_range = (line_lo - line_min, line_hi - line_min);
28022835
let (line_url, line_title) = link_to_loc(call_data, loc);
28032836

@@ -2913,6 +2946,7 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item) {
29132946
<summary class=\"hideme\">\
29142947
<span>More examples</span>\
29152948
</summary>\
2949+
<div class=\"hide-more\">Hide additional examples</div>\
29162950
<div class=\"more-scraped-examples\">\
29172951
<div class=\"toggle-line\"><div class=\"toggle-line-inner\"></div></div>\
29182952
<div class=\"more-scraped-examples-inner\">"

0 commit comments

Comments
 (0)