diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 671e082556722..3df5ad0c33b55 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -19,7 +19,7 @@ pub const CALCULATE_DOC_COVERAGE: Pass = Pass { }; fn calculate_doc_coverage(krate: clean::Crate, ctx: &DocContext<'_>) -> clean::Crate { - let mut calc = CoverageCalculator::new(); + let mut calc = CoverageCalculator::new(ctx); let krate = calc.fold_crate(krate); calc.print_results(ctx.renderinfo.borrow().output_format); @@ -94,8 +94,9 @@ impl ops::AddAssign for ItemCount { } } -struct CoverageCalculator { +struct CoverageCalculator<'a, 'tcx> { items: BTreeMap, + cx: &'a DocContext<'tcx>, } fn limit_filename_len(filename: String) -> String { @@ -108,9 +109,9 @@ fn limit_filename_len(filename: String) -> String { } } -impl CoverageCalculator { - fn new() -> CoverageCalculator { - CoverageCalculator { items: Default::default() } +impl<'a, 'tcx> CoverageCalculator<'a, 'tcx> { + fn new(cx: &'a DocContext<'tcx>) -> CoverageCalculator<'a, 'tcx> { + CoverageCalculator { cx, items: Default::default() } } fn to_json(&self) -> String { @@ -178,7 +179,7 @@ impl CoverageCalculator { } } -impl fold::DocFolder for CoverageCalculator { +impl<'a, 'tcx> fold::DocFolder for CoverageCalculator<'a, 'tcx> { fn fold_item(&mut self, i: clean::Item) -> Option { match i.inner { _ if !i.def_id.is_local() => { @@ -244,7 +245,7 @@ impl fold::DocFolder for CoverageCalculator { self.items.entry(i.source.filename.clone()).or_default().count_item( has_docs, has_doc_example, - should_have_doc_example(&i.inner), + should_have_doc_example(self.cx, &i), ); } } diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/doc_test_lints.rs index cbbe86dc433f3..b28dcecb34fd7 100644 --- a/src/librustdoc/passes/doc_test_lints.rs +++ b/src/librustdoc/passes/doc_test_lints.rs @@ -60,8 +60,8 @@ impl crate::doctest::Tester for Tests { } } -pub fn should_have_doc_example(item_kind: &clean::ItemEnum) -> bool { - !matches!(item_kind, +pub fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool { + !matches!(item.inner, clean::StructFieldItem(_) | clean::VariantItem(_) | clean::AssocConstItem(_, _) @@ -73,7 +73,8 @@ pub fn should_have_doc_example(item_kind: &clean::ItemEnum) -> bool { | clean::ImportItem(_) | clean::PrimitiveItem(_) | clean::KeywordItem(_) - ) + ) && (cx.renderinfo.borrow().access_levels.is_public(item.def_id) + || cx.render_options.document_private) } pub fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { @@ -89,10 +90,22 @@ pub fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { find_testable_code(&dox, &mut tests, ErrorCodes::No, false, None); + if cx.render_options.document_private + && dox.is_empty() + && !matches!(item.inner, clean::ImportItem(..)) + { + let sp = span_of_attrs(&item.attrs).unwrap_or(item.source.span()); + if !sp.is_dummy() { + cx.tcx.struct_span_lint_hir(rustc_lint::builtin::MISSING_DOCS, hir_id, sp, |lint| { + lint.build("missing documentation").emit() + }); + } + } + if tests.found_tests == 0 && rustc_feature::UnstableFeatures::from_environment().is_nightly_build() { - if should_have_doc_example(&item.inner) { + if should_have_doc_example(cx, &item) { debug!("reporting error for {:?} (hir_id={:?})", item, hir_id); let sp = span_of_attrs(&item.attrs).unwrap_or(item.source.span()); cx.tcx.struct_span_lint_hir( @@ -102,7 +115,9 @@ pub fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { |lint| lint.build("missing code example in this documentation").emit(), ); } - } else if tests.found_tests > 0 && !cx.renderinfo.borrow().access_levels.is_public(item.def_id) + } else if tests.found_tests > 0 + && !cx.renderinfo.borrow().access_levels.is_public(item.def_id) + && !cx.render_options.document_private { cx.tcx.struct_span_lint_hir( lint::builtin::PRIVATE_DOC_TESTS, diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 75a659666673f..c62129958a43b 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -148,6 +148,7 @@ struct Stripper<'a> { retained: &'a mut DefIdSet, access_levels: &'a AccessLevels, update_retained: bool, + document_private: bool, } impl<'a> DocFolder for Stripper<'a> { @@ -181,7 +182,7 @@ impl<'a> DocFolder for Stripper<'a> { | clean::TraitAliasItem(..) | clean::ForeignTypeItem => { if i.def_id.is_local() { - if !self.access_levels.is_exported(i.def_id) { + if !self.access_levels.is_exported(i.def_id) && !self.document_private { debug!("Stripper: stripping {:?} {:?}", i.type_(), i.name); return None; } @@ -189,13 +190,13 @@ impl<'a> DocFolder for Stripper<'a> { } clean::StructFieldItem(..) => { - if i.visibility != clean::Public { + if i.visibility != clean::Public && !self.document_private { return StripItem(i).strip(); } } clean::ModuleItem(..) => { - if i.def_id.is_local() && i.visibility != clean::Public { + if i.def_id.is_local() && i.visibility != clean::Public && !self.document_private { debug!("Stripper: stripping module {:?}", i.name); let old = mem::replace(&mut self.update_retained, false); let ret = StripItem(self.fold_item_recur(i).unwrap()).strip(); diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs index 9173d8e96058e..343c6ace5f98e 100644 --- a/src/librustdoc/passes/strip_private.rs +++ b/src/librustdoc/passes/strip_private.rs @@ -18,6 +18,7 @@ pub fn strip_private(mut krate: clean::Crate, cx: &DocContext<'_>) -> clean::Cra // This stripper collects all *retained* nodes. let mut retained = DefIdSet::default(); let access_levels = cx.renderinfo.borrow().access_levels.clone(); + let document_private = cx.render_options.document_private; // strip all private items { @@ -25,6 +26,7 @@ pub fn strip_private(mut krate: clean::Crate, cx: &DocContext<'_>) -> clean::Cra retained: &mut retained, access_levels: &access_levels, update_retained: true, + document_private, }; krate = ImportStripper.fold_crate(stripper.fold_crate(krate)); } diff --git a/src/test/rustdoc-ui/lint-missing-doc-code-example-private.rs b/src/test/rustdoc-ui/lint-missing-doc-code-example-private.rs new file mode 100644 index 0000000000000..a7479d6df1696 --- /dev/null +++ b/src/test/rustdoc-ui/lint-missing-doc-code-example-private.rs @@ -0,0 +1,14 @@ +// compile-flags: --document-private-items + +#![deny(missing_docs)] +#![deny(missing_doc_code_examples)] + +//! hello +//! +//! ``` +//! let x = 0; +//! ``` + +fn private_fn() {} +//~^ ERROR +//~^^ ERROR diff --git a/src/test/rustdoc-ui/lint-missing-doc-code-example-private.stderr b/src/test/rustdoc-ui/lint-missing-doc-code-example-private.stderr new file mode 100644 index 0000000000000..f31c1b93ad2b4 --- /dev/null +++ b/src/test/rustdoc-ui/lint-missing-doc-code-example-private.stderr @@ -0,0 +1,26 @@ +error: missing documentation + --> $DIR/lint-missing-doc-code-example-private.rs:12:1 + | +LL | fn private_fn() {} + | ^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/lint-missing-doc-code-example-private.rs:3:9 + | +LL | #![deny(missing_docs)] + | ^^^^^^^^^^^^ + +error: missing code example in this documentation + --> $DIR/lint-missing-doc-code-example-private.rs:12:1 + | +LL | fn private_fn() {} + | ^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/lint-missing-doc-code-example-private.rs:4:9 + | +LL | #![deny(missing_doc_code_examples)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/rustdoc-ui/lint-missing-doc-code-example.rs b/src/test/rustdoc-ui/lint-missing-doc-code-example.rs index ebe7a242211bf..7b51946a1f2ac 100644 --- a/src/test/rustdoc-ui/lint-missing-doc-code-example.rs +++ b/src/test/rustdoc-ui/lint-missing-doc-code-example.rs @@ -16,7 +16,7 @@ fn test() { } #[allow(missing_docs)] -mod module1 { //~ ERROR +pub mod module1 { //~ ERROR } #[allow(missing_doc_code_examples)] @@ -63,9 +63,13 @@ pub enum Enum { /// Doc //~^ ERROR #[repr(C)] -union Union { +pub union Union { /// Doc, but no code example and it's fine! a: i32, /// Doc, but no code example and it's fine! b: f32, } + +mod private { + fn private_fn() {} +} diff --git a/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr b/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr index 32756c99e7f9f..8853a30b6e186 100644 --- a/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr +++ b/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr @@ -25,7 +25,7 @@ LL | /// Doc error: missing code example in this documentation --> $DIR/lint-missing-doc-code-example.rs:19:1 | -LL | / mod module1 { +LL | / pub mod module1 { LL | | } | |_^