Skip to content

Commit 3487be1

Browse files
committed
Auto merge of rust-lang#86545 - JohnTitor:rollup-7sqdhpa, r=JohnTitor
Rollup of 6 pull requests Successful merges: - rust-lang#86393 (Add regression test for issue rust-lang#52025) - rust-lang#86402 (rustdoc: add optional woff2 versions of Source Serif and Source Code) - rust-lang#86451 (Resolve intra-doc links in summary desc) - rust-lang#86501 (Cleanup handling of `crate_name` for doctests) - rust-lang#86517 (Fix `unused_unsafe` around `await`) - rust-lang#86537 (Mark some edition tests as check-pass) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 75ed342 + 00a7d5c commit 3487be1

40 files changed

+279
-100
lines changed

compiler/rustc_middle/src/mir/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,8 @@ impl<'tcx> Body<'tcx> {
494494
#[derive(Copy, Clone, PartialEq, Eq, Debug, TyEncodable, TyDecodable, HashStable)]
495495
pub enum Safety {
496496
Safe,
497+
/// Unsafe because of compiler-generated unsafe code, like `await` desugaring
498+
BuiltinUnsafe,
497499
/// Unsafe because of an unsafe fn
498500
FnUnsafe,
499501
/// Unsafe because of an `unsafe` block

compiler/rustc_middle/src/thir.rs

+1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ pub struct Adt<'tcx> {
114114
#[derive(Copy, Clone, Debug, HashStable)]
115115
pub enum BlockSafety {
116116
Safe,
117+
BuiltinUnsafe,
117118
ExplicitUnsafe(hir::HirId),
118119
}
119120

compiler/rustc_mir/src/transform/check_unsafety.rs

+1
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
321321
}
322322
false
323323
}
324+
Safety::BuiltinUnsafe => true,
324325
Safety::ExplicitUnsafe(hir_id) => {
325326
// mark unsafe block as used if there are any unsafe operations inside
326327
if !violations.is_empty() {

compiler/rustc_mir_build/src/build/block.rs

+1
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
214214
debug!("update_source_scope_for({:?}, {:?})", span, safety_mode);
215215
let new_unsafety = match safety_mode {
216216
BlockSafety::Safe => None,
217+
BlockSafety::BuiltinUnsafe => Some(Safety::BuiltinUnsafe),
217218
BlockSafety::ExplicitUnsafe(hir_id) => {
218219
match self.in_scope_unsafe {
219220
Safety::Safe => {}

compiler/rustc_mir_build/src/check_unsafety.rs

+20-13
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,7 @@ struct UnsafetyVisitor<'a, 'tcx> {
2929
}
3030

3131
impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
32-
fn in_safety_context<R>(
33-
&mut self,
34-
safety_context: SafetyContext,
35-
f: impl FnOnce(&mut Self) -> R,
36-
) {
32+
fn in_safety_context(&mut self, safety_context: SafetyContext, f: impl FnOnce(&mut Self)) {
3733
if let (
3834
SafetyContext::UnsafeBlock { span: enclosing_span, .. },
3935
SafetyContext::UnsafeBlock { span: block_span, hir_id, .. },
@@ -63,14 +59,14 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
6359
);
6460
}
6561
self.safety_context = prev_context;
66-
return;
6762
}
6863
}
6964

7065
fn requires_unsafe(&mut self, span: Span, kind: UnsafeOpKind) {
7166
let (description, note) = kind.description_and_note();
7267
let unsafe_op_in_unsafe_fn_allowed = self.unsafe_op_in_unsafe_fn_allowed();
7368
match self.safety_context {
69+
SafetyContext::BuiltinUnsafeBlock => {}
7470
SafetyContext::UnsafeBlock { ref mut used, .. } => {
7571
if !self.body_unsafety.is_unsafe() || !unsafe_op_in_unsafe_fn_allowed {
7672
// Mark this block as useful
@@ -142,13 +138,23 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
142138
}
143139

144140
fn visit_block(&mut self, block: &Block) {
145-
if let BlockSafety::ExplicitUnsafe(hir_id) = block.safety_mode {
146-
self.in_safety_context(
147-
SafetyContext::UnsafeBlock { span: block.span, hir_id, used: false },
148-
|this| visit::walk_block(this, block),
149-
);
150-
} else {
151-
visit::walk_block(self, block);
141+
match block.safety_mode {
142+
// compiler-generated unsafe code should not count towards the usefulness of
143+
// an outer unsafe block
144+
BlockSafety::BuiltinUnsafe => {
145+
self.in_safety_context(SafetyContext::BuiltinUnsafeBlock, |this| {
146+
visit::walk_block(this, block)
147+
});
148+
}
149+
BlockSafety::ExplicitUnsafe(hir_id) => {
150+
self.in_safety_context(
151+
SafetyContext::UnsafeBlock { span: block.span, hir_id, used: false },
152+
|this| visit::walk_block(this, block),
153+
);
154+
}
155+
BlockSafety::Safe => {
156+
visit::walk_block(self, block);
157+
}
152158
}
153159
}
154160

@@ -250,6 +256,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
250256
#[derive(Clone, Copy)]
251257
enum SafetyContext {
252258
Safe,
259+
BuiltinUnsafeBlock,
253260
UnsafeFn,
254261
UnsafeBlock { span: Span, hir_id: hir::HirId, used: bool },
255262
}

compiler/rustc_mir_build/src/thir/cx/block.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ impl<'tcx> Cx<'tcx> {
2626
expr: block.expr.map(|expr| self.mirror_expr(expr)),
2727
safety_mode: match block.rules {
2828
hir::BlockCheckMode::DefaultBlock => BlockSafety::Safe,
29-
hir::BlockCheckMode::UnsafeBlock(..) => BlockSafety::ExplicitUnsafe(block.hir_id),
29+
hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::CompilerGenerated) => {
30+
BlockSafety::BuiltinUnsafe
31+
}
32+
hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::UserProvided) => {
33+
BlockSafety::ExplicitUnsafe(block.hir_id)
34+
}
3035
},
3136
}
3237
}

src/librustdoc/clean/types.rs

+27
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,33 @@ impl Item {
523523
.collect()
524524
}
525525

526+
/// Find a list of all link names, without finding their href.
527+
///
528+
/// This is used for generating summary text, which does not include
529+
/// the link text, but does need to know which `[]`-bracketed names
530+
/// are actually links.
531+
crate fn link_names(&self, cache: &Cache) -> Vec<RenderedLink> {
532+
cache
533+
.intra_doc_links
534+
.get(&self.def_id)
535+
.map_or(&[][..], |v| v.as_slice())
536+
.iter()
537+
.filter_map(|ItemLink { link: s, link_text, did, fragment }| {
538+
// FIXME(83083): using fragments as a side-channel for
539+
// primitive names is very unfortunate
540+
if did.is_some() || fragment.is_some() {
541+
Some(RenderedLink {
542+
original_text: s.clone(),
543+
new_text: link_text.clone(),
544+
href: String::new(),
545+
})
546+
} else {
547+
None
548+
}
549+
})
550+
.collect()
551+
}
552+
526553
crate fn is_crate(&self) -> bool {
527554
self.is_mod() && self.def_id.as_real().map_or(false, |did| did.index == CRATE_DEF_INDEX)
528555
}

src/librustdoc/doctest.rs

+20-20
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
33
use rustc_data_structures::sync::Lrc;
44
use rustc_errors::{ColorConfig, ErrorReported};
55
use rustc_hir as hir;
6+
use rustc_hir::def_id::LOCAL_CRATE;
67
use rustc_hir::intravisit;
78
use rustc_hir::{HirId, CRATE_HIR_ID};
89
use rustc_interface::interface;
@@ -13,6 +14,7 @@ use rustc_session::{lint, DiagnosticOutput, Session};
1314
use rustc_span::edition::Edition;
1415
use rustc_span::source_map::SourceMap;
1516
use rustc_span::symbol::sym;
17+
use rustc_span::Symbol;
1618
use rustc_span::{BytePos, FileName, Pos, Span, DUMMY_SP};
1719
use rustc_target::spec::TargetTriple;
1820
use tempfile::Builder as TempFileBuilder;
@@ -111,8 +113,6 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
111113
let res = interface::run_compiler(config, |compiler| {
112114
compiler.enter(|queries| {
113115
let _lower_to_hir = queries.lower_to_hir()?;
114-
115-
let crate_name = queries.crate_name()?.peek().to_string();
116116
let mut global_ctxt = queries.global_ctxt()?.take();
117117

118118
let collector = global_ctxt.enter(|tcx| {
@@ -123,7 +123,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
123123
opts.display_warnings |= options.display_warnings;
124124
let enable_per_target_ignores = options.enable_per_target_ignores;
125125
let mut collector = Collector::new(
126-
crate_name,
126+
tcx.crate_name(LOCAL_CRATE),
127127
options,
128128
false,
129129
opts,
@@ -293,7 +293,7 @@ struct UnusedExterns {
293293

294294
fn run_test(
295295
test: &str,
296-
cratename: &str,
296+
crate_name: &str,
297297
line: usize,
298298
options: Options,
299299
should_panic: bool,
@@ -312,7 +312,7 @@ fn run_test(
312312
report_unused_externs: impl Fn(UnusedExterns),
313313
) -> Result<(), TestFailure> {
314314
let (test, line_offset, supports_color) =
315-
make_test(test, Some(cratename), as_test_harness, opts, edition, Some(test_id));
315+
make_test(test, Some(crate_name), as_test_harness, opts, edition, Some(test_id));
316316

317317
let output_file = outdir.path().join("rust_out");
318318

@@ -479,7 +479,7 @@ fn run_test(
479479
/// lines before the test code begins as well as if the output stream supports colors or not.
480480
crate fn make_test(
481481
s: &str,
482-
cratename: Option<&str>,
482+
crate_name: Option<&str>,
483483
dont_insert_main: bool,
484484
opts: &TestOptions,
485485
edition: Edition,
@@ -540,7 +540,7 @@ crate fn make_test(
540540
let sess = ParseSess::with_span_handler(handler, sm);
541541

542542
let mut found_main = false;
543-
let mut found_extern_crate = cratename.is_none();
543+
let mut found_extern_crate = crate_name.is_none();
544544
let mut found_macro = false;
545545

546546
let mut parser = match maybe_new_parser_from_source_str(&sess, filename, source) {
@@ -567,13 +567,13 @@ crate fn make_test(
567567

568568
if !found_extern_crate {
569569
if let ast::ItemKind::ExternCrate(original) = item.kind {
570-
// This code will never be reached if `cratename` is none because
570+
// This code will never be reached if `crate_name` is none because
571571
// `found_extern_crate` is initialized to `true` if it is none.
572-
let cratename = cratename.unwrap();
572+
let crate_name = crate_name.unwrap();
573573

574574
match original {
575-
Some(name) => found_extern_crate = name.as_str() == cratename,
576-
None => found_extern_crate = item.ident.as_str() == cratename,
575+
Some(name) => found_extern_crate = name.as_str() == crate_name,
576+
None => found_extern_crate = item.ident.as_str() == crate_name,
577577
}
578578
}
579579
}
@@ -631,14 +631,14 @@ crate fn make_test(
631631

632632
// Don't inject `extern crate std` because it's already injected by the
633633
// compiler.
634-
if !already_has_extern_crate && !opts.no_crate_inject && cratename != Some("std") {
635-
if let Some(cratename) = cratename {
634+
if !already_has_extern_crate && !opts.no_crate_inject && crate_name != Some("std") {
635+
if let Some(crate_name) = crate_name {
636636
// Don't inject `extern crate` if the crate is never used.
637637
// NOTE: this is terribly inaccurate because it doesn't actually
638638
// parse the source, but only has false positives, not false
639639
// negatives.
640-
if s.contains(cratename) {
641-
prog.push_str(&format!("extern crate r#{};\n", cratename));
640+
if s.contains(crate_name) {
641+
prog.push_str(&format!("extern crate r#{};\n", crate_name));
642642
line_offset += 1;
643643
}
644644
}
@@ -797,7 +797,7 @@ crate struct Collector {
797797
options: Options,
798798
use_headers: bool,
799799
enable_per_target_ignores: bool,
800-
cratename: String,
800+
crate_name: Symbol,
801801
opts: TestOptions,
802802
position: Span,
803803
source_map: Option<Lrc<SourceMap>>,
@@ -809,7 +809,7 @@ crate struct Collector {
809809

810810
impl Collector {
811811
crate fn new(
812-
cratename: String,
812+
crate_name: Symbol,
813813
options: Options,
814814
use_headers: bool,
815815
opts: TestOptions,
@@ -823,7 +823,7 @@ impl Collector {
823823
options,
824824
use_headers,
825825
enable_per_target_ignores,
826-
cratename,
826+
crate_name,
827827
opts,
828828
position: DUMMY_SP,
829829
source_map,
@@ -871,7 +871,7 @@ impl Tester for Collector {
871871
fn add_test(&mut self, test: String, config: LangString, line: usize) {
872872
let filename = self.get_filename();
873873
let name = self.generate_name(line, &filename);
874-
let cratename = self.cratename.to_string();
874+
let crate_name = self.crate_name.to_string();
875875
let opts = self.opts.clone();
876876
let edition = config.edition.unwrap_or(self.options.edition);
877877
let options = self.options.clone();
@@ -954,7 +954,7 @@ impl Tester for Collector {
954954
};
955955
let res = run_test(
956956
&test,
957-
&cratename,
957+
&crate_name,
958958
line,
959959
options,
960960
config.should_panic,

src/librustdoc/formats/cache.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -292,13 +292,14 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
292292
// which should not be indexed. The crate-item itself is
293293
// inserted later on when serializing the search-index.
294294
if item.def_id.index().map_or(false, |idx| idx != CRATE_DEF_INDEX) {
295+
let desc = item.doc_value().map_or_else(String::new, |x| {
296+
short_markdown_summary(&x.as_str(), &item.link_names(&self.cache))
297+
});
295298
self.cache.search_index.push(IndexItem {
296299
ty: item.type_(),
297300
name: s.to_string(),
298301
path: path.join("::"),
299-
desc: item
300-
.doc_value()
301-
.map_or_else(String::new, |x| short_markdown_summary(&x.as_str())),
302+
desc,
302303
parent,
303304
parent_idx: None,
304305
search_type: get_index_search_type(&item, &self.empty_cache, self.tcx),

src/librustdoc/html/markdown.rs

+21-4
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,11 @@ impl MarkdownSummaryLine<'_> {
10511051
///
10521052
/// Returns a tuple of the rendered HTML string and whether the output was shortened
10531053
/// due to the provided `length_limit`.
1054-
fn markdown_summary_with_limit(md: &str, length_limit: usize) -> (String, bool) {
1054+
fn markdown_summary_with_limit(
1055+
md: &str,
1056+
link_names: &[RenderedLink],
1057+
length_limit: usize,
1058+
) -> (String, bool) {
10551059
if md.is_empty() {
10561060
return (String::new(), false);
10571061
}
@@ -1065,7 +1069,20 @@ fn markdown_summary_with_limit(md: &str, length_limit: usize) -> (String, bool)
10651069
*text_length += text.len();
10661070
}
10671071

1068-
'outer: for event in Parser::new_ext(md, summary_opts()) {
1072+
let mut replacer = |broken_link: BrokenLink<'_>| {
1073+
if let Some(link) =
1074+
link_names.iter().find(|link| &*link.original_text == broken_link.reference)
1075+
{
1076+
Some((link.href.as_str().into(), link.new_text.as_str().into()))
1077+
} else {
1078+
None
1079+
}
1080+
};
1081+
1082+
let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut replacer));
1083+
let p = LinkReplacer::new(p, link_names);
1084+
1085+
'outer: for event in p {
10691086
match &event {
10701087
Event::Text(text) => {
10711088
for word in text.split_inclusive(char::is_whitespace) {
@@ -1121,8 +1138,8 @@ fn markdown_summary_with_limit(md: &str, length_limit: usize) -> (String, bool)
11211138
/// Will shorten to 59 or 60 characters, including an ellipsis (…) if it was shortened.
11221139
///
11231140
/// See [`markdown_summary_with_limit`] for details about what is rendered and what is not.
1124-
crate fn short_markdown_summary(markdown: &str) -> String {
1125-
let (mut s, was_shortened) = markdown_summary_with_limit(markdown, 59);
1141+
crate fn short_markdown_summary(markdown: &str, link_names: &[RenderedLink]) -> String {
1142+
let (mut s, was_shortened) = markdown_summary_with_limit(markdown, link_names, 59);
11261143

11271144
if was_shortened {
11281145
s.push('…');

src/librustdoc/html/markdown/tests.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ fn test_header_ids_multiple_blocks() {
221221
#[test]
222222
fn test_short_markdown_summary() {
223223
fn t(input: &str, expect: &str) {
224-
let output = short_markdown_summary(input);
224+
let output = short_markdown_summary(input, &[][..]);
225225
assert_eq!(output, expect, "original: {}", input);
226226
}
227227

@@ -232,6 +232,7 @@ fn test_short_markdown_summary() {
232232
t("Hard-break \nsummary", "Hard-break summary");
233233
t("hello [Rust] :)\n\n[Rust]: https://www.rust-lang.org", "hello Rust :)");
234234
t("hello [Rust](https://www.rust-lang.org \"Rust\") :)", "hello Rust :)");
235+
t("dud [link]", "dud [link]");
235236
t("code `let x = i32;` ...", "code <code>let x = i32;</code> …");
236237
t("type `Type<'static>` ...", "type <code>Type<'static></code> …");
237238
t("# top header", "top header");
@@ -259,6 +260,7 @@ fn test_plain_text_summary() {
259260
t("Hard-break \nsummary", "Hard-break summary");
260261
t("hello [Rust] :)\n\n[Rust]: https://www.rust-lang.org", "hello Rust :)");
261262
t("hello [Rust](https://www.rust-lang.org \"Rust\") :)", "hello Rust :)");
263+
t("dud [link]", "dud [link]");
262264
t("code `let x = i32;` ...", "code `let x = i32;` …");
263265
t("type `Type<'static>` ...", "type `Type<'static>` …");
264266
t("# top header", "top header");

0 commit comments

Comments
 (0)