diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:36 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:36 +0000 |
commit | e02c5b5930c2c9ba3e5423fe12e2ef0155017297 (patch) | |
tree | fd60ebbbb5299e16e5fca8c773ddb74f764760db /src/librustdoc/passes | |
parent | Adding debian version 1.73.0+dfsg1-1. (diff) | |
download | rustc-e02c5b5930c2c9ba3e5423fe12e2ef0155017297.tar.xz rustc-e02c5b5930c2c9ba3e5423fe12e2ef0155017297.zip |
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/librustdoc/passes')
-rw-r--r-- | src/librustdoc/passes/calculate_doc_coverage.rs | 9 | ||||
-rw-r--r-- | src/librustdoc/passes/check_custom_code_classes.rs | 92 | ||||
-rw-r--r-- | src/librustdoc/passes/check_doc_test_visibility.rs | 11 | ||||
-rw-r--r-- | src/librustdoc/passes/collect_intra_doc_links.rs | 48 | ||||
-rw-r--r-- | src/librustdoc/passes/lint/bare_urls.rs | 7 | ||||
-rw-r--r-- | src/librustdoc/passes/lint/check_code_block_syntax.rs | 20 | ||||
-rw-r--r-- | src/librustdoc/passes/lint/html_tags.rs | 7 | ||||
-rw-r--r-- | src/librustdoc/passes/lint/redundant_explicit_links.rs | 34 | ||||
-rw-r--r-- | src/librustdoc/passes/lint/unescaped_backticks.rs | 13 | ||||
-rw-r--r-- | src/librustdoc/passes/mod.rs | 96 | ||||
-rw-r--r-- | src/librustdoc/passes/stripper.rs | 2 |
11 files changed, 191 insertions, 148 deletions
diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 592dd0a14..60def4058 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -208,7 +208,14 @@ impl<'a, 'b> DocVisitor for CoverageCalculator<'a, 'b> { let has_docs = !i.attrs.doc_strings.is_empty(); let mut tests = Tests { found_tests: 0 }; - find_testable_code(&i.doc_value(), &mut tests, ErrorCodes::No, false, None); + find_testable_code( + &i.doc_value(), + &mut tests, + ErrorCodes::No, + false, + None, + self.ctx.tcx.features().custom_code_classes_in_docs, + ); let has_doc_example = tests.found_tests != 0; let hir_id = DocContext::as_local_hir_id(self.ctx.tcx, i.item_id).unwrap(); diff --git a/src/librustdoc/passes/check_custom_code_classes.rs b/src/librustdoc/passes/check_custom_code_classes.rs new file mode 100644 index 000000000..6266d3ff5 --- /dev/null +++ b/src/librustdoc/passes/check_custom_code_classes.rs @@ -0,0 +1,92 @@ +//! NIGHTLY & UNSTABLE CHECK: custom_code_classes_in_docs +//! +//! This pass will produce errors when finding custom classes outside of +//! nightly + relevant feature active. + +use super::Pass; +use crate::clean::{Crate, Item}; +use crate::core::DocContext; +use crate::fold::DocFolder; +use crate::html::markdown::{find_codes, ErrorCodes, LangString}; + +use rustc_errors::StashKey; +use rustc_feature::GateIssue; +use rustc_session::parse::add_feature_diagnostics_for_issue; +use rustc_span::symbol::sym; + +pub(crate) const CHECK_CUSTOM_CODE_CLASSES: Pass = Pass { + name: "check-custom-code-classes", + run: check_custom_code_classes, + description: "check for custom code classes without the feature-gate enabled", +}; + +pub(crate) fn check_custom_code_classes(krate: Crate, cx: &mut DocContext<'_>) -> Crate { + if cx.tcx.features().custom_code_classes_in_docs { + // Nothing to check here if the feature is enabled. + return krate; + } + let mut coll = CustomCodeClassLinter { cx }; + + coll.fold_crate(krate) +} + +struct CustomCodeClassLinter<'a, 'tcx> { + cx: &'a DocContext<'tcx>, +} + +impl<'a, 'tcx> DocFolder for CustomCodeClassLinter<'a, 'tcx> { + fn fold_item(&mut self, item: Item) -> Option<Item> { + look_for_custom_classes(&self.cx, &item); + Some(self.fold_item_recur(item)) + } +} + +#[derive(Debug)] +struct TestsWithCustomClasses { + custom_classes_found: Vec<String>, +} + +impl crate::doctest::Tester for TestsWithCustomClasses { + fn add_test(&mut self, _: String, config: LangString, _: usize) { + self.custom_classes_found.extend(config.added_classes.into_iter()); + } +} + +pub(crate) fn look_for_custom_classes<'tcx>(cx: &DocContext<'tcx>, item: &Item) { + if !item.item_id.is_local() { + // If non-local, no need to check anything. + return; + } + + let mut tests = TestsWithCustomClasses { custom_classes_found: vec![] }; + + let dox = item.attrs.doc_value(); + find_codes(&dox, &mut tests, ErrorCodes::No, false, None, true, true); + + if !tests.custom_classes_found.is_empty() { + let span = item.attr_span(cx.tcx); + let sess = &cx.tcx.sess.parse_sess; + let mut err = sess + .span_diagnostic + .struct_span_warn(span, "custom classes in code blocks will change behaviour"); + add_feature_diagnostics_for_issue( + &mut err, + sess, + sym::custom_code_classes_in_docs, + GateIssue::Language, + false, + ); + + err.note( + // This will list the wrong items to make them more easily searchable. + // To ensure the most correct hits, it adds back the 'class:' that was stripped. + format!( + "found these custom classes: class={}", + tests.custom_classes_found.join(",class=") + ), + ); + + // A later feature_err call can steal and cancel this warning. + err.stash(span, StashKey::EarlySyntaxWarning); + } +} diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index e732a4057..d1c4cc1f5 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -60,7 +60,7 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) - | clean::VariantItem(_) | clean::AssocConstItem(..) | clean::AssocTypeItem(..) - | clean::TypedefItem(_) + | clean::TypeAliasItem(_) | clean::StaticItem(_) | clean::ConstantItem(_) | clean::ExternCrateItem { .. } @@ -113,7 +113,14 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item let mut tests = Tests { found_tests: 0 }; - find_testable_code(dox, &mut tests, ErrorCodes::No, false, None); + find_testable_code( + dox, + &mut tests, + ErrorCodes::No, + false, + None, + cx.tcx.features().custom_code_classes_in_docs, + ); if tests.found_tests == 0 && cx.tcx.features().rustdoc_missing_doc_code_examples { if should_have_doc_example(cx, item) { diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 7b0a7a90d..d216305e6 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -16,7 +16,9 @@ use rustc_hir::Mutability; use rustc_middle::ty::{Ty, TyCtxt}; use rustc_middle::{bug, span_bug, ty}; use rustc_resolve::rustdoc::{has_primitive_or_keyword_docs, prepare_to_doc_link_resolution}; -use rustc_resolve::rustdoc::{strip_generics_from_path, MalformedGenerics}; +use rustc_resolve::rustdoc::{ + source_span_for_markdown_range, strip_generics_from_path, MalformedGenerics, +}; use rustc_session::lint::Lint; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{sym, Ident, Symbol}; @@ -520,8 +522,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { ty::Alias(..) | ty::Closure(..) | ty::Generator(..) - | ty::GeneratorWitness(_) - | ty::GeneratorWitnessMIR(..) + | ty::GeneratorWitness(..) | ty::Dynamic(..) | ty::Param(_) | ty::Bound(..) @@ -592,7 +593,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { .unwrap_or(Vec::new()) } } - Res::Def(DefKind::TyAlias { .. }, did) => { + Res::Def(DefKind::TyAlias, did) => { // Resolve the link on the type the alias points to. // FIXME: if the associated item is defined directly on the type alias, // it will show up on its documentation page, we should link there instead. @@ -1211,11 +1212,11 @@ impl LinkCollector<'_, '_> { ori_link: &MarkdownLinkRange, item: &Item, ) { - let span = super::source_span_for_markdown_range( + let span = source_span_for_markdown_range( self.cx.tcx, dox, ori_link.inner_range(), - &item.attrs, + &item.attrs.doc_strings, ) .unwrap_or_else(|| item.attr_span(self.cx.tcx)); rustc_session::parse::feature_err( @@ -1702,26 +1703,27 @@ fn report_diagnostic( let (span, link_range) = match link_range { MarkdownLinkRange::Destination(md_range) => { let mut md_range = md_range.clone(); - let sp = super::source_span_for_markdown_range(tcx, dox, &md_range, &item.attrs) - .map(|mut sp| { - while dox.as_bytes().get(md_range.start) == Some(&b' ') - || dox.as_bytes().get(md_range.start) == Some(&b'`') - { - md_range.start += 1; - sp = sp.with_lo(sp.lo() + BytePos(1)); - } - while dox.as_bytes().get(md_range.end - 1) == Some(&b' ') - || dox.as_bytes().get(md_range.end - 1) == Some(&b'`') - { - md_range.end -= 1; - sp = sp.with_hi(sp.hi() - BytePos(1)); - } - sp - }); + let sp = + source_span_for_markdown_range(tcx, dox, &md_range, &item.attrs.doc_strings) + .map(|mut sp| { + while dox.as_bytes().get(md_range.start) == Some(&b' ') + || dox.as_bytes().get(md_range.start) == Some(&b'`') + { + md_range.start += 1; + sp = sp.with_lo(sp.lo() + BytePos(1)); + } + while dox.as_bytes().get(md_range.end - 1) == Some(&b' ') + || dox.as_bytes().get(md_range.end - 1) == Some(&b'`') + { + md_range.end -= 1; + sp = sp.with_hi(sp.hi() - BytePos(1)); + } + sp + }); (sp, MarkdownLinkRange::Destination(md_range)) } MarkdownLinkRange::WholeLink(md_range) => ( - super::source_span_for_markdown_range(tcx, dox, &md_range, &item.attrs), + source_span_for_markdown_range(tcx, dox, &md_range, &item.attrs.doc_strings), link_range.clone(), ), }; diff --git a/src/librustdoc/passes/lint/bare_urls.rs b/src/librustdoc/passes/lint/bare_urls.rs index 97078a5cb..0c5cfffe1 100644 --- a/src/librustdoc/passes/lint/bare_urls.rs +++ b/src/librustdoc/passes/lint/bare_urls.rs @@ -4,11 +4,11 @@ use crate::clean::*; use crate::core::DocContext; use crate::html::markdown::main_body_opts; -use crate::passes::source_span_for_markdown_range; use core::ops::Range; use pulldown_cmark::{Event, Parser, Tag}; use regex::Regex; use rustc_errors::Applicability; +use rustc_resolve::rustdoc::source_span_for_markdown_range; use std::mem; use std::sync::LazyLock; @@ -21,8 +21,9 @@ pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item) { if !dox.is_empty() { let report_diag = |cx: &DocContext<'_>, msg: &'static str, url: &str, range: Range<usize>| { - let sp = source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs) - .unwrap_or_else(|| item.attr_span(cx.tcx)); + let sp = + source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs.doc_strings) + .unwrap_or_else(|| item.attr_span(cx.tcx)); cx.tcx.struct_span_lint_hir(crate::lint::BARE_URLS, hir_id, sp, msg, |lint| { lint.note("bare URLs are not automatically turned into clickable links") .span_suggestion( diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs index 37e28e1fb..ac8a75a4f 100644 --- a/src/librustdoc/passes/lint/check_code_block_syntax.rs +++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs @@ -6,6 +6,7 @@ use rustc_errors::{ Applicability, Diagnostic, Handler, LazyFallbackBundle, }; use rustc_parse::parse_stream_from_source_str; +use rustc_resolve::rustdoc::source_span_for_markdown_range; use rustc_session::parse::ParseSess; use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId}; use rustc_span::source_map::{FilePathMapping, SourceMap}; @@ -14,13 +15,14 @@ use rustc_span::{FileName, InnerSpan, DUMMY_SP}; use crate::clean; use crate::core::DocContext; use crate::html::markdown::{self, RustCodeBlock}; -use crate::passes::source_span_for_markdown_range; pub(crate) fn visit_item(cx: &DocContext<'_>, item: &clean::Item) { if let Some(dox) = &item.opt_doc_value() { let sp = item.attr_span(cx.tcx); let extra = crate::html::markdown::ExtraInfo::new(cx.tcx, item.item_id.expect_def_id(), sp); - for code_block in markdown::rust_code_blocks(dox, &extra) { + for code_block in + markdown::rust_code_blocks(dox, &extra, cx.tcx.features().custom_code_classes_in_docs) + { check_rust_syntax(cx, item, dox, code_block); } } @@ -77,11 +79,15 @@ fn check_rust_syntax( let is_ignore = code_block.lang_string.ignore != markdown::Ignore::None; // The span and whether it is precise or not. - let (sp, precise_span) = - match source_span_for_markdown_range(cx.tcx, dox, &code_block.range, &item.attrs) { - Some(sp) => (sp, true), - None => (item.attr_span(cx.tcx), false), - }; + let (sp, precise_span) = match source_span_for_markdown_range( + cx.tcx, + dox, + &code_block.range, + &item.attrs.doc_strings, + ) { + Some(sp) => (sp, true), + None => (item.attr_span(cx.tcx), false), + }; let msg = if buffer.has_errors { "could not parse code block as Rust code" diff --git a/src/librustdoc/passes/lint/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs index c135c584c..79fc599e1 100644 --- a/src/librustdoc/passes/lint/html_tags.rs +++ b/src/librustdoc/passes/lint/html_tags.rs @@ -2,9 +2,9 @@ use crate::clean::*; use crate::core::DocContext; use crate::html::markdown::main_body_opts; -use crate::passes::source_span_for_markdown_range; use pulldown_cmark::{BrokenLink, Event, LinkType, Parser, Tag}; +use rustc_resolve::rustdoc::source_span_for_markdown_range; use std::iter::Peekable; use std::ops::Range; @@ -20,7 +20,8 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { let dox = item.doc_value(); if !dox.is_empty() { let report_diag = |msg: String, range: &Range<usize>, is_open_tag: bool| { - let sp = match source_span_for_markdown_range(tcx, &dox, range, &item.attrs) { + let sp = match source_span_for_markdown_range(tcx, &dox, range, &item.attrs.doc_strings) + { Some(sp) => sp, None => item.attr_span(tcx), }; @@ -60,7 +61,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { tcx, &dox, &(generics_start..generics_end), - &item.attrs, + &item.attrs.doc_strings, ) { Some(sp) => sp, None => item.attr_span(tcx), diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs index 67cd2cc97..0c15bf5f7 100644 --- a/src/librustdoc/passes/lint/redundant_explicit_links.rs +++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs @@ -6,6 +6,7 @@ use rustc_errors::SuggestionStyle; use rustc_hir::def::{DefKind, DocLinkResMap, Namespace, Res}; use rustc_hir::HirId; use rustc_lint_defs::Applicability; +use rustc_resolve::rustdoc::source_span_for_markdown_range; use rustc_span::Symbol; use crate::clean::utils::find_nearest_parent_module; @@ -13,7 +14,6 @@ use crate::clean::utils::inherits_doc_hidden; use crate::clean::Item; use crate::core::DocContext; use crate::html::markdown::main_body_opts; -use crate::passes::source_span_for_markdown_range; #[derive(Debug)] struct LinkData { @@ -160,16 +160,21 @@ fn check_inline_or_reference_unknown_redundancy( (find_resolution(resolutions, &dest)?, find_resolution(resolutions, resolvable_link)?); if dest_res == display_res { - let link_span = source_span_for_markdown_range(cx.tcx, &doc, &link_range, &item.attrs) - .unwrap_or(item.attr_span(cx.tcx)); + let link_span = + source_span_for_markdown_range(cx.tcx, &doc, &link_range, &item.attrs.doc_strings) + .unwrap_or(item.attr_span(cx.tcx)); let explicit_span = source_span_for_markdown_range( cx.tcx, &doc, &offset_explicit_range(doc, link_range, open, close), - &item.attrs, + &item.attrs.doc_strings, + )?; + let display_span = source_span_for_markdown_range( + cx.tcx, + &doc, + &resolvable_link_range, + &item.attrs.doc_strings, )?; - let display_span = - source_span_for_markdown_range(cx.tcx, &doc, &resolvable_link_range, &item.attrs)?; cx.tcx.struct_span_lint_hir(crate::lint::REDUNDANT_EXPLICIT_LINKS, hir_id, explicit_span, "redundant explicit link target", |lint| { lint.span_label(explicit_span, "explicit target is redundant") @@ -201,21 +206,26 @@ fn check_reference_redundancy( (find_resolution(resolutions, &dest)?, find_resolution(resolutions, resolvable_link)?); if dest_res == display_res { - let link_span = source_span_for_markdown_range(cx.tcx, &doc, &link_range, &item.attrs) - .unwrap_or(item.attr_span(cx.tcx)); + let link_span = + source_span_for_markdown_range(cx.tcx, &doc, &link_range, &item.attrs.doc_strings) + .unwrap_or(item.attr_span(cx.tcx)); let explicit_span = source_span_for_markdown_range( cx.tcx, &doc, &offset_explicit_range(doc, link_range.clone(), b'[', b']'), - &item.attrs, + &item.attrs.doc_strings, + )?; + let display_span = source_span_for_markdown_range( + cx.tcx, + &doc, + &resolvable_link_range, + &item.attrs.doc_strings, )?; - let display_span = - source_span_for_markdown_range(cx.tcx, &doc, &resolvable_link_range, &item.attrs)?; let def_span = source_span_for_markdown_range( cx.tcx, &doc, &offset_reference_def_range(doc, dest, link_range), - &item.attrs, + &item.attrs.doc_strings, )?; cx.tcx.struct_span_lint_hir(crate::lint::REDUNDANT_EXPLICIT_LINKS, hir_id, explicit_span, "redundant explicit link target", |lint| { diff --git a/src/librustdoc/passes/lint/unescaped_backticks.rs b/src/librustdoc/passes/lint/unescaped_backticks.rs index 256958d71..8b7fdd6ab 100644 --- a/src/librustdoc/passes/lint/unescaped_backticks.rs +++ b/src/librustdoc/passes/lint/unescaped_backticks.rs @@ -3,10 +3,10 @@ use crate::clean::Item; use crate::core::DocContext; use crate::html::markdown::main_body_opts; -use crate::passes::source_span_for_markdown_range; use pulldown_cmark::{BrokenLink, Event, Parser}; use rustc_errors::DiagnosticBuilder; use rustc_lint_defs::Applicability; +use rustc_resolve::rustdoc::source_span_for_markdown_range; use std::ops::Range; pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { @@ -52,7 +52,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { tcx, &dox, &(backtick_index..backtick_index + 1), - &item.attrs, + &item.attrs.doc_strings, ) .unwrap_or_else(|| item.attr_span(tcx)); @@ -378,9 +378,12 @@ fn suggest_insertion( /// Maximum bytes of context to show around the insertion. const CONTEXT_MAX_LEN: usize = 80; - if let Some(span) = - source_span_for_markdown_range(cx.tcx, &dox, &(insert_index..insert_index), &item.attrs) - { + if let Some(span) = source_span_for_markdown_range( + cx.tcx, + &dox, + &(insert_index..insert_index), + &item.attrs.doc_strings, + ) { lint.span_suggestion(span, message, suggestion, Applicability::MaybeIncorrect); } else { let line_start = dox[..insert_index].rfind('\n').map_or(0, |idx| idx + 1); diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 4b1ff68df..4eeaaa2bb 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -1,11 +1,6 @@ //! Contains information about "passes", used to modify crate information during the documentation //! process. -use rustc_middle::ty::TyCtxt; -use rustc_resolve::rustdoc::DocFragmentKind; -use rustc_span::{InnerSpan, Span, DUMMY_SP}; -use std::ops::Range; - use self::Condition::*; use crate::clean; use crate::core::DocContext; @@ -40,6 +35,9 @@ pub(crate) use self::calculate_doc_coverage::CALCULATE_DOC_COVERAGE; mod lint; pub(crate) use self::lint::RUN_LINTS; +mod check_custom_code_classes; +pub(crate) use self::check_custom_code_classes::CHECK_CUSTOM_CODE_CLASSES; + /// A single pass over the cleaned documentation. /// /// Runs in the compiler context, so it has access to types and traits and the like. @@ -71,6 +69,7 @@ pub(crate) enum Condition { /// The full list of passes. pub(crate) const PASSES: &[Pass] = &[ + CHECK_CUSTOM_CODE_CLASSES, CHECK_DOC_TEST_VISIBILITY, STRIP_HIDDEN, STRIP_PRIVATE, @@ -84,6 +83,7 @@ pub(crate) const PASSES: &[Pass] = &[ /// The list of passes run by default. pub(crate) const DEFAULT_PASSES: &[ConditionalPass] = &[ + ConditionalPass::always(CHECK_CUSTOM_CODE_CLASSES), ConditionalPass::always(COLLECT_TRAIT_IMPLS), ConditionalPass::always(CHECK_DOC_TEST_VISIBILITY), ConditionalPass::new(STRIP_HIDDEN, WhenNotDocumentHidden), @@ -115,89 +115,3 @@ impl ConditionalPass { pub(crate) fn defaults(show_coverage: bool) -> &'static [ConditionalPass] { if show_coverage { COVERAGE_PASSES } else { DEFAULT_PASSES } } - -/// Returns a span encompassing all the given attributes. -pub(crate) fn span_of_attrs(attrs: &clean::Attributes) -> Option<Span> { - if attrs.doc_strings.is_empty() { - return None; - } - let start = attrs.doc_strings[0].span; - if start == DUMMY_SP { - return None; - } - let end = attrs.doc_strings.last().expect("no doc strings provided").span; - Some(start.to(end)) -} - -/// Attempts to match a range of bytes from parsed markdown to a `Span` in the source code. -/// -/// This method will return `None` if we cannot construct a span from the source map or if the -/// attributes are not all sugared doc comments. It's difficult to calculate the correct span in -/// that case due to escaping and other source features. -pub(crate) fn source_span_for_markdown_range( - tcx: TyCtxt<'_>, - markdown: &str, - md_range: &Range<usize>, - attrs: &clean::Attributes, -) -> Option<Span> { - let is_all_sugared_doc = - attrs.doc_strings.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc); - - if !is_all_sugared_doc { - return None; - } - - let snippet = tcx.sess.source_map().span_to_snippet(span_of_attrs(attrs)?).ok()?; - - let starting_line = markdown[..md_range.start].matches('\n').count(); - let ending_line = starting_line + markdown[md_range.start..md_range.end].matches('\n').count(); - - // We use `split_terminator('\n')` instead of `lines()` when counting bytes so that we treat - // CRLF and LF line endings the same way. - let mut src_lines = snippet.split_terminator('\n'); - let md_lines = markdown.split_terminator('\n'); - - // The number of bytes from the source span to the markdown span that are not part - // of the markdown, like comment markers. - let mut start_bytes = 0; - let mut end_bytes = 0; - - 'outer: for (line_no, md_line) in md_lines.enumerate() { - loop { - let source_line = src_lines.next()?; - match source_line.find(md_line) { - Some(offset) => { - if line_no == starting_line { - start_bytes += offset; - - if starting_line == ending_line { - break 'outer; - } - } else if line_no == ending_line { - end_bytes += offset; - break 'outer; - } else if line_no < starting_line { - start_bytes += source_line.len() - md_line.len(); - } else { - end_bytes += source_line.len() - md_line.len(); - } - break; - } - None => { - // Since this is a source line that doesn't include a markdown line, - // we have to count the newline that we split from earlier. - if line_no <= starting_line { - start_bytes += source_line.len() + 1; - } else { - end_bytes += source_line.len() + 1; - } - } - } - } - } - - Some(span_of_attrs(attrs)?.from_inner(InnerSpan::new( - md_range.start + start_bytes, - md_range.end + start_bytes + end_bytes, - ))) -} diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index 64a4ace5b..b35618415 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -49,7 +49,7 @@ impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> { } // These items can all get re-exported clean::OpaqueTyItem(..) - | clean::TypedefItem(..) + | clean::TypeAliasItem(..) | clean::StaticItem(..) | clean::StructItem(..) | clean::EnumItem(..) |