88use clippy_utils:: attrs:: is_doc_hidden;
99use clippy_utils:: diagnostics:: span_lint;
1010use clippy_utils:: is_from_proc_macro;
11+ use hir:: def_id:: LocalDefId ;
1112use if_chain:: if_chain;
1213use rustc_ast:: ast:: { self , MetaItem , MetaItemKind } ;
1314use rustc_hir as hir;
1415use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
15- use rustc_middle:: ty:: DefIdTree ;
16+ use rustc_middle:: ty:: { DefIdTree , Visibility } ;
1617use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
1718use rustc_span:: def_id:: CRATE_DEF_ID ;
1819use rustc_span:: source_map:: Span ;
@@ -35,6 +36,9 @@ declare_clippy_lint! {
3536}
3637
3738pub struct MissingDoc {
39+ /// Whether to **only** check for missing documentation in items visible within the current
40+ /// crate. For example, `pub(crate)` items.
41+ crate_items_only : bool ,
3842 /// Stack of whether #[doc(hidden)] is set
3943 /// at each level which has lint attributes.
4044 doc_hidden_stack : Vec < bool > ,
@@ -43,14 +47,15 @@ pub struct MissingDoc {
4347impl Default for MissingDoc {
4448 #[ must_use]
4549 fn default ( ) -> Self {
46- Self :: new ( )
50+ Self :: new ( false )
4751 }
4852}
4953
5054impl MissingDoc {
5155 #[ must_use]
52- pub fn new ( ) -> Self {
56+ pub fn new ( crate_items_only : bool ) -> Self {
5357 Self {
58+ crate_items_only,
5459 doc_hidden_stack : vec ! [ false ] ,
5560 }
5661 }
@@ -76,6 +81,7 @@ impl MissingDoc {
7681 fn check_missing_docs_attrs (
7782 & self ,
7883 cx : & LateContext < ' _ > ,
84+ def_id : LocalDefId ,
7985 attrs : & [ ast:: Attribute ] ,
8086 sp : Span ,
8187 article : & ' static str ,
@@ -96,6 +102,13 @@ impl MissingDoc {
96102 return ;
97103 }
98104
105+ if self . crate_items_only && def_id != CRATE_DEF_ID {
106+ let vis = cx. tcx . visibility ( def_id) ;
107+ if vis == Visibility :: Public || vis != Visibility :: Restricted ( CRATE_DEF_ID . into ( ) ) {
108+ return ;
109+ }
110+ }
111+
99112 let has_doc = attrs
100113 . iter ( )
101114 . any ( |a| a. doc_str ( ) . is_some ( ) || Self :: has_include ( a. meta ( ) ) ) ;
@@ -124,7 +137,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
124137
125138 fn check_crate ( & mut self , cx : & LateContext < ' tcx > ) {
126139 let attrs = cx. tcx . hir ( ) . attrs ( hir:: CRATE_HIR_ID ) ;
127- self . check_missing_docs_attrs ( cx, attrs, cx. tcx . def_span ( CRATE_DEF_ID ) , "the" , "crate" ) ;
140+ self . check_missing_docs_attrs ( cx, CRATE_DEF_ID , attrs, cx. tcx . def_span ( CRATE_DEF_ID ) , "the" , "crate" ) ;
128141 }
129142
130143 fn check_item ( & mut self , cx : & LateContext < ' tcx > , it : & ' tcx hir:: Item < ' _ > ) {
@@ -160,7 +173,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
160173
161174 let attrs = cx. tcx . hir ( ) . attrs ( it. hir_id ( ) ) ;
162175 if !is_from_proc_macro ( cx, it) {
163- self . check_missing_docs_attrs ( cx, attrs, it. span , article, desc) ;
176+ self . check_missing_docs_attrs ( cx, it . owner_id . def_id , attrs, it. span , article, desc) ;
164177 }
165178 }
166179
@@ -169,7 +182,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
169182
170183 let attrs = cx. tcx . hir ( ) . attrs ( trait_item. hir_id ( ) ) ;
171184 if !is_from_proc_macro ( cx, trait_item) {
172- self . check_missing_docs_attrs ( cx, attrs, trait_item. span , article, desc) ;
185+ self . check_missing_docs_attrs ( cx, trait_item . owner_id . def_id , attrs, trait_item. span , article, desc) ;
173186 }
174187 }
175188
@@ -186,23 +199,23 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
186199 let ( article, desc) = cx. tcx . article_and_description ( impl_item. owner_id . to_def_id ( ) ) ;
187200 let attrs = cx. tcx . hir ( ) . attrs ( impl_item. hir_id ( ) ) ;
188201 if !is_from_proc_macro ( cx, impl_item) {
189- self . check_missing_docs_attrs ( cx, attrs, impl_item. span , article, desc) ;
202+ self . check_missing_docs_attrs ( cx, impl_item . owner_id . def_id , attrs, impl_item. span , article, desc) ;
190203 }
191204 }
192205
193206 fn check_field_def ( & mut self , cx : & LateContext < ' tcx > , sf : & ' tcx hir:: FieldDef < ' _ > ) {
194207 if !sf. is_positional ( ) {
195208 let attrs = cx. tcx . hir ( ) . attrs ( sf. hir_id ) ;
196209 if !is_from_proc_macro ( cx, sf) {
197- self . check_missing_docs_attrs ( cx, attrs, sf. span , "a" , "struct field" ) ;
210+ self . check_missing_docs_attrs ( cx, sf . def_id , attrs, sf. span , "a" , "struct field" ) ;
198211 }
199212 }
200213 }
201214
202215 fn check_variant ( & mut self , cx : & LateContext < ' tcx > , v : & ' tcx hir:: Variant < ' _ > ) {
203216 let attrs = cx. tcx . hir ( ) . attrs ( v. hir_id ) ;
204217 if !is_from_proc_macro ( cx, v) {
205- self . check_missing_docs_attrs ( cx, attrs, v. span , "a" , "variant" ) ;
218+ self . check_missing_docs_attrs ( cx, v . def_id , attrs, v. span , "a" , "variant" ) ;
206219 }
207220 }
208221}
0 commit comments