diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index e5caf7fdfa235..b1c53ea92b300 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -214,7 +214,7 @@ impl Options { if matches.opt_strs("passes") == ["list"] { println!("Available passes for running rustdoc:"); for pass in passes::PASSES { - println!("{:>20} - {}", pass.name(), pass.description()); + println!("{:>20} - {}", pass.name, pass.description); } println!("\nDefault passes for rustdoc:"); for &name in passes::DEFAULT_PASSES { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 226924c41c541..4dce4e86cc449 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -603,10 +603,12 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt passes::defaults(default_passes).iter().map(|p| p.to_string()).collect(); passes.extend(manual_passes); + info!("Executing passes"); + for pass in &passes { - // the "unknown pass" error will be reported when late passes are run - if let Some(pass) = passes::find_pass(pass).and_then(|p| p.early_fn()) { - krate = pass(krate, &ctxt); + match passes::find_pass(pass).map(|p| p.pass) { + Some(pass) => krate = pass(krate, &ctxt), + None => error!("unknown pass {}, skipping", *pass), } } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 5e9f9ee9f80af..39e504951d1c6 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -441,28 +441,6 @@ where R: 'static + Send, krate.version = crate_version; - info!("Executing passes"); - - for pass in &passes { - // determine if we know about this pass - let pass = match passes::find_pass(pass) { - Some(pass) => if let Some(pass) = pass.late_fn() { - pass - } else { - // not a late pass, but still valid so don't report the error - continue - } - None => { - error!("unknown pass {}, skipping", *pass); - - continue - }, - }; - - // run it - krate = pass(krate); - } - tx.send(f(Output { krate: krate, renderinfo: renderinfo, diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs index f960374370e04..88d9c87c52898 100644 --- a/src/librustdoc/passes/check_code_block_syntax.rs +++ b/src/librustdoc/passes/check_code_block_syntax.rs @@ -10,9 +10,11 @@ use crate::fold::DocFolder; use crate::html::markdown::{self, RustCodeBlock}; use crate::passes::Pass; -pub const CHECK_CODE_BLOCK_SYNTAX: Pass = - Pass::early("check-code-block-syntax", check_code_block_syntax, - "validates syntax inside Rust code blocks"); +pub const CHECK_CODE_BLOCK_SYNTAX: Pass = Pass { + name: "check-code-block-syntax", + pass: check_code_block_syntax, + description: "validates syntax inside Rust code blocks", +}; pub fn check_code_block_syntax(krate: clean::Crate, cx: &DocContext<'_, '_, '_>) -> clean::Crate { SyntaxChecker { cx }.fold_crate(krate) diff --git a/src/librustdoc/passes/collapse_docs.rs b/src/librustdoc/passes/collapse_docs.rs index e5e60cbe71700..088a6ea77c73f 100644 --- a/src/librustdoc/passes/collapse_docs.rs +++ b/src/librustdoc/passes/collapse_docs.rs @@ -1,13 +1,16 @@ use crate::clean::{self, DocFragment, Item}; +use crate::core::DocContext; use crate::fold; use crate::fold::{DocFolder}; use crate::passes::Pass; use std::mem::replace; -pub const COLLAPSE_DOCS: Pass = - Pass::late("collapse-docs", collapse_docs, - "concatenates all document attributes into one document attribute"); +pub const COLLAPSE_DOCS: Pass = Pass { + name: "collapse-docs", + pass: collapse_docs, + description: "concatenates all document attributes into one document attribute", +}; #[derive(Copy, Clone, Debug, PartialEq, Eq)] enum DocFragmentKind { @@ -26,7 +29,7 @@ impl DocFragment { } } -pub fn collapse_docs(krate: clean::Crate) -> clean::Crate { +pub fn collapse_docs(krate: clean::Crate, _: &DocContext<'_, '_, '_>) -> clean::Crate { Collapser.fold_crate(krate) } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 42fa3e2006b42..67f291285c447 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -19,9 +19,11 @@ use crate::passes::{look_for_tests, Pass}; use super::span_of_attrs; -pub const COLLECT_INTRA_DOC_LINKS: Pass = - Pass::early("collect-intra-doc-links", collect_intra_doc_links, - "reads a crate's documentation to resolve intra-doc-links"); +pub const COLLECT_INTRA_DOC_LINKS: Pass = Pass { + name: "collect-intra-doc-links", + pass: collect_intra_doc_links, + description: "reads a crate's documentation to resolve intra-doc-links", +}; pub fn collect_intra_doc_links(krate: Crate, cx: &DocContext<'_, '_, '_>) -> Crate { if !UnstableFeatures::from_environment().is_nightly_build() { diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 903cce3bc032a..4c90540871d2e 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -6,9 +6,11 @@ use super::Pass; use rustc::util::nodemap::FxHashSet; use rustc::hir::def_id::DefId; -pub const COLLECT_TRAIT_IMPLS: Pass = - Pass::early("collect-trait-impls", collect_trait_impls, - "retrieves trait impls for items in the crate"); +pub const COLLECT_TRAIT_IMPLS: Pass = Pass { + name: "collect-trait-impls", + pass: collect_trait_impls, + description: "retrieves trait impls for items in the crate", +}; pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_, '_, '_>) -> Crate { let mut synth = SyntheticImplCollector::new(cx); diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 4d7fef7a76a9f..3a9d8ef20ce84 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -6,7 +6,6 @@ use rustc::lint as lint; use rustc::middle::privacy::AccessLevels; use rustc::util::nodemap::DefIdSet; use std::mem; -use std::fmt; use syntax::ast::NodeId; use syntax_pos::{DUMMY_SP, Span}; use std::ops::Range; @@ -46,84 +45,14 @@ pub use self::collect_trait_impls::COLLECT_TRAIT_IMPLS; mod check_code_block_syntax; pub use self::check_code_block_syntax::CHECK_CODE_BLOCK_SYNTAX; -/// Represents a single pass. +/// A single pass over the cleaned documentation. +/// +/// Runs in the compiler context, so it has access to types and traits and the like. #[derive(Copy, Clone)] -pub enum Pass { - /// An "early pass" is run in the compiler context, and can gather information about types and - /// traits and the like. - EarlyPass { - name: &'static str, - pass: fn(clean::Crate, &DocContext<'_, '_, '_>) -> clean::Crate, - description: &'static str, - }, - /// A "late pass" is run between crate cleaning and page generation. - LatePass { - name: &'static str, - pass: fn(clean::Crate) -> clean::Crate, - description: &'static str, - }, -} - -impl fmt::Debug for Pass { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut dbg = match *self { - Pass::EarlyPass { .. } => f.debug_struct("EarlyPass"), - Pass::LatePass { .. } => f.debug_struct("LatePass"), - }; - - dbg.field("name", &self.name()) - .field("pass", &"...") - .field("description", &self.description()) - .finish() - } -} - -impl Pass { - /// Constructs a new early pass. - pub const fn early(name: &'static str, - pass: fn(clean::Crate, &DocContext<'_, '_, '_>) -> clean::Crate, - description: &'static str) -> Pass { - Pass::EarlyPass { name, pass, description } - } - - /// Constructs a new late pass. - pub const fn late(name: &'static str, - pass: fn(clean::Crate) -> clean::Crate, - description: &'static str) -> Pass { - Pass::LatePass { name, pass, description } - } - - /// Returns the name of this pass. - pub fn name(self) -> &'static str { - match self { - Pass::EarlyPass { name, .. } | - Pass::LatePass { name, .. } => name, - } - } - - /// Returns the description of this pass. - pub fn description(self) -> &'static str { - match self { - Pass::EarlyPass { description, .. } | - Pass::LatePass { description, .. } => description, - } - } - - /// If this pass is an early pass, returns the pointer to its function. - pub fn early_fn(self) -> Option) -> clean::Crate> { - match self { - Pass::EarlyPass { pass, .. } => Some(pass), - _ => None, - } - } - - /// If this pass is a late pass, returns the pointer to its function. - pub fn late_fn(self) -> Option clean::Crate> { - match self { - Pass::LatePass { pass, .. } => Some(pass), - _ => None, - } - } +pub struct Pass { + pub name: &'static str, + pub pass: fn(clean::Crate, &DocContext<'_, '_, '_>) -> clean::Crate, + pub description: &'static str, } /// The full list of passes. @@ -141,27 +70,27 @@ pub const PASSES: &'static [Pass] = &[ ]; /// The list of passes run by default. -pub const DEFAULT_PASSES: &'static [&'static str] = &[ +pub const DEFAULT_PASSES: &[&str] = &[ "collect-trait-impls", + "collapse-docs", + "unindent-comments", "check-private-items-doc-tests", "strip-hidden", "strip-private", "collect-intra-doc-links", "check-code-block-syntax", - "collapse-docs", - "unindent-comments", "propagate-doc-cfg", ]; /// The list of default passes run with `--document-private-items` is passed to rustdoc. -pub const DEFAULT_PRIVATE_PASSES: &'static [&'static str] = &[ +pub const DEFAULT_PRIVATE_PASSES: &[&str] = &[ "collect-trait-impls", + "collapse-docs", + "unindent-comments", "check-private-items-doc-tests", "strip-priv-imports", "collect-intra-doc-links", "check-code-block-syntax", - "collapse-docs", - "unindent-comments", "propagate-doc-cfg", ]; @@ -184,8 +113,8 @@ pub fn defaults(default_set: DefaultPassOption) -> &'static [&'static str] { } /// If the given name matches a known pass, returns its information. -pub fn find_pass(pass_name: &str) -> Option { - PASSES.iter().find(|p| p.name() == pass_name).cloned() +pub fn find_pass(pass_name: &str) -> Option<&'static Pass> { + PASSES.iter().find(|p| p.name == pass_name) } struct Stripper<'a> { @@ -438,11 +367,11 @@ crate fn source_span_for_markdown_range( .span_to_snippet(span_of_attrs(attrs)) .ok()?; - let starting_line = markdown[..md_range.start].lines().count() - 1; - let ending_line = markdown[..md_range.end].lines().count() - 1; + 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 only - // we can treat CRLF and LF line endings the same way. + // 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'); diff --git a/src/librustdoc/passes/private_items_doc_tests.rs b/src/librustdoc/passes/private_items_doc_tests.rs index 819d15f65e8ef..1c3977c4f85cd 100644 --- a/src/librustdoc/passes/private_items_doc_tests.rs +++ b/src/librustdoc/passes/private_items_doc_tests.rs @@ -3,10 +3,11 @@ use crate::core::DocContext; use crate::fold::DocFolder; use crate::passes::{look_for_tests, Pass}; - -pub const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = - Pass::early("check-private-items-doc-tests", check_private_items_doc_tests, - "check private items doc tests"); +pub const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = Pass { + name: "check-private-items-doc-tests", + pass: check_private_items_doc_tests, + description: "check private items doc tests", +}; struct PrivateItemDocTestLinter<'a, 'tcx: 'a, 'rcx: 'a> { cx: &'a DocContext<'a, 'tcx, 'rcx>, diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs index 9ba0b22728691..aed80b5ba86fd 100644 --- a/src/librustdoc/passes/propagate_doc_cfg.rs +++ b/src/librustdoc/passes/propagate_doc_cfg.rs @@ -2,14 +2,17 @@ use std::sync::Arc; use crate::clean::{Crate, Item}; use crate::clean::cfg::Cfg; +use crate::core::DocContext; use crate::fold::DocFolder; use crate::passes::Pass; -pub const PROPAGATE_DOC_CFG: Pass = - Pass::late("propagate-doc-cfg", propagate_doc_cfg, - "propagates `#[doc(cfg(...))]` to child items"); +pub const PROPAGATE_DOC_CFG: Pass = Pass { + name: "propagate-doc-cfg", + pass: propagate_doc_cfg, + description: "propagates `#[doc(cfg(...))]` to child items", +}; -pub fn propagate_doc_cfg(cr: Crate) -> Crate { +pub fn propagate_doc_cfg(cr: Crate, _: &DocContext<'_, '_, '_>) -> Crate { CfgPropagator { parent_cfg: None }.fold_crate(cr) } diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index b3d50e06816c5..330057e53843b 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -7,9 +7,11 @@ use crate::core::DocContext; use crate::fold::{DocFolder, StripItem}; use crate::passes::{ImplStripper, Pass}; -pub const STRIP_HIDDEN: Pass = - Pass::early("strip-hidden", strip_hidden, - "strips all doc(hidden) items from the output"); +pub const STRIP_HIDDEN: Pass = Pass { + name: "strip-hidden", + pass: strip_hidden, + description: "strips all doc(hidden) items from the output", +}; /// Strip items marked `#[doc(hidden)]` pub fn strip_hidden(krate: clean::Crate, _: &DocContext<'_, '_, '_>) -> clean::Crate { diff --git a/src/librustdoc/passes/strip_priv_imports.rs b/src/librustdoc/passes/strip_priv_imports.rs index 3af1403e8749c..479f0877bd7d2 100644 --- a/src/librustdoc/passes/strip_priv_imports.rs +++ b/src/librustdoc/passes/strip_priv_imports.rs @@ -3,8 +3,11 @@ use crate::fold::{DocFolder}; use crate::core::DocContext; use crate::passes::{ImportStripper, Pass}; -pub const STRIP_PRIV_IMPORTS: Pass = Pass::early("strip-priv-imports", strip_priv_imports, - "strips all private import statements (`use`, `extern crate`) from a crate"); +pub const STRIP_PRIV_IMPORTS: Pass = Pass { + name: "strip-priv-imports", + pass: strip_priv_imports, + description: "strips all private import statements (`use`, `extern crate`) from a crate", +}; pub fn strip_priv_imports(krate: clean::Crate, _: &DocContext<'_, '_, '_>) -> clean::Crate { ImportStripper.fold_crate(krate) diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs index e553d792eb697..1ac3a90f38d35 100644 --- a/src/librustdoc/passes/strip_private.rs +++ b/src/librustdoc/passes/strip_private.rs @@ -5,10 +5,12 @@ use crate::fold::{DocFolder}; use crate::core::DocContext; use crate::passes::{ImplStripper, ImportStripper, Stripper, Pass}; -pub const STRIP_PRIVATE: Pass = - Pass::early("strip-private", strip_private, - "strips all private items from a crate which cannot be seen externally, \ - implies strip-priv-imports"); +pub const STRIP_PRIVATE: Pass = Pass { + name: "strip-private", + pass: strip_private, + description: "strips all private items from a crate which cannot be seen externally, \ + implies strip-priv-imports", +}; /// Strip private items from the point of view of a crate or externally from a /// crate, specified by the `xcrate` flag. diff --git a/src/librustdoc/passes/unindent_comments.rs b/src/librustdoc/passes/unindent_comments.rs index 269e4cbe65f8b..b77cf68d7c63f 100644 --- a/src/librustdoc/passes/unindent_comments.rs +++ b/src/librustdoc/passes/unindent_comments.rs @@ -3,14 +3,17 @@ use std::string::String; use std::usize; use crate::clean::{self, DocFragment, Item}; +use crate::core::DocContext; use crate::fold::{self, DocFolder}; use crate::passes::Pass; -pub const UNINDENT_COMMENTS: Pass = - Pass::late("unindent-comments", unindent_comments, - "removes excess indentation on comments in order for markdown to like it"); +pub const UNINDENT_COMMENTS: Pass = Pass { + name: "unindent-comments", + pass: unindent_comments, + description: "removes excess indentation on comments in order for markdown to like it", +}; -pub fn unindent_comments(krate: clean::Crate) -> clean::Crate { +pub fn unindent_comments(krate: clean::Crate, _: &DocContext<'_, '_, '_>) -> clean::Crate { CommentCleaner.fold_crate(krate) } diff --git a/src/test/rustdoc-ui/intra-links-warning.stderr b/src/test/rustdoc-ui/intra-links-warning.stderr index e5409c042056c..60fc131dbda17 100644 --- a/src/test/rustdoc-ui/intra-links-warning.stderr +++ b/src/test/rustdoc-ui/intra-links-warning.stderr @@ -105,8 +105,8 @@ LL | | /// [error] | = note: the link appears in this line: - [error] - ^^^^^ + [error] + ^^^^^ = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` warning: `[error1]` cannot be resolved, ignoring it... diff --git a/src/test/rustdoc-ui/issue-58473-2.rs b/src/test/rustdoc-ui/issue-58473-2.rs new file mode 100644 index 0000000000000..5e5ddebe10884 --- /dev/null +++ b/src/test/rustdoc-ui/issue-58473-2.rs @@ -0,0 +1,12 @@ +// compile-pass + +#![deny(private_doc_tests)] + +mod foo { + /** + Does nothing, returns `()` + + yadda-yadda-yadda + */ + fn foo() {} +} diff --git a/src/test/rustdoc-ui/issue-58473.rs b/src/test/rustdoc-ui/issue-58473.rs new file mode 100644 index 0000000000000..0e5be3292c053 --- /dev/null +++ b/src/test/rustdoc-ui/issue-58473.rs @@ -0,0 +1,10 @@ +// compile-pass + +pub trait Foo { + /** + Does nothing, returns `()` + + yadda-yadda-yadda + */ + fn foo() {} +}