@@ -26,6 +26,7 @@ use rustc_span::DUMMY_SP;
2626
2727use std:: cell:: { Cell , RefCell } ;
2828use std:: mem;
29+ use std:: path:: PathBuf ;
2930use std:: rc:: Rc ;
3031
3132use crate :: clean;
@@ -273,6 +274,58 @@ where
273274 ( lint_opts, lint_caps)
274275}
275276
277+ crate fn get_rustdoc_lints (
278+ cfg : FxHashSet < ( String , Option < String > ) > ,
279+ opts : config:: Options ,
280+ ) -> Vec < String > {
281+ let config = interface:: Config {
282+ opts,
283+ crate_cfg : cfg,
284+ input : Input :: File ( PathBuf :: new ( ) ) ,
285+ input_path : None ,
286+ output_file : None ,
287+ output_dir : None ,
288+ file_loader : None ,
289+ diagnostic_output : DiagnosticOutput :: Default ,
290+ stderr : None ,
291+ lint_caps : Default :: default ( ) ,
292+ register_lints : None ,
293+ override_queries : None ,
294+ make_codegen_backend : None ,
295+ registry : rustc_driver:: diagnostics_registry ( ) ,
296+ } ;
297+ let missing_docs_lints = rustc_lint:: builtin:: MISSING_DOCS . name ;
298+ let renamed_and_removed_lints = rustc_lint:: builtin:: RENAMED_AND_REMOVED_LINTS . name ;
299+ let unknown_lints = rustc_lint:: builtin:: UNKNOWN_LINTS . name ;
300+
301+ // Rustdoc silences all lints by default, only warning on lints in the `rustdoc` group.
302+ // These lints aren't in the lint group, but we want to warn on them anyway.
303+ let mut rustdoc_lints = vec ! [
304+ missing_docs_lints. to_owned( ) ,
305+ renamed_and_removed_lints. to_owned( ) ,
306+ unknown_lints. to_owned( ) ,
307+ ] ;
308+
309+ interface:: run_compiler ( config, |compiler| {
310+ let sopts = & compiler. session ( ) . opts ;
311+ let lint_store = rustc_lint:: new_lint_store (
312+ sopts. debugging_opts . no_interleave_lints ,
313+ compiler. session ( ) . unstable_options ( ) ,
314+ ) ;
315+ if let Some ( ( _, lints, _) ) =
316+ lint_store. get_lint_groups ( ) . iter ( ) . find ( |( name, _, _) | * name == "rustdoc" )
317+ {
318+ for lint in lints {
319+ // Funny thing about this: the lints in the compiler are capitalized but the lints
320+ // you get through the `LintStore` are not, which means you have to capitalize them.
321+ rustdoc_lints. push ( lint. to_string ( ) . to_uppercase ( ) ) ;
322+ }
323+ }
324+ } ) ;
325+
326+ rustdoc_lints
327+ }
328+
276329/// Parse, resolve, and typecheck the given crate.
277330crate fn create_config (
278331 RustdocOptions {
@@ -301,51 +354,14 @@ crate fn create_config(
301354 let cpath = Some ( input. clone ( ) ) ;
302355 let input = Input :: File ( input) ;
303356
304- let broken_intra_doc_links = lint:: builtin:: BROKEN_INTRA_DOC_LINKS . name ;
305- let private_intra_doc_links = lint:: builtin:: PRIVATE_INTRA_DOC_LINKS . name ;
306- let missing_docs = rustc_lint:: builtin:: MISSING_DOCS . name ;
307- let missing_doc_example = rustc_lint:: builtin:: MISSING_DOC_CODE_EXAMPLES . name ;
308- let private_doc_tests = rustc_lint:: builtin:: PRIVATE_DOC_TESTS . name ;
309- let no_crate_level_docs = rustc_lint:: builtin:: MISSING_CRATE_LEVEL_DOCS . name ;
310- let invalid_codeblock_attributes_name = rustc_lint:: builtin:: INVALID_CODEBLOCK_ATTRIBUTES . name ;
311- let invalid_html_tags = rustc_lint:: builtin:: INVALID_HTML_TAGS . name ;
312- let renamed_and_removed_lints = rustc_lint:: builtin:: RENAMED_AND_REMOVED_LINTS . name ;
313- let non_autolinks = rustc_lint:: builtin:: NON_AUTOLINKS . name ;
314- let unknown_lints = rustc_lint:: builtin:: UNKNOWN_LINTS . name ;
315-
316- // In addition to those specific lints, we also need to allow those given through
317- // command line, otherwise they'll get ignored and we don't want that.
318- let lints_to_show = vec ! [
319- broken_intra_doc_links. to_owned( ) ,
320- private_intra_doc_links. to_owned( ) ,
321- missing_docs. to_owned( ) ,
322- missing_doc_example. to_owned( ) ,
323- private_doc_tests. to_owned( ) ,
324- no_crate_level_docs. to_owned( ) ,
325- invalid_codeblock_attributes_name. to_owned( ) ,
326- invalid_html_tags. to_owned( ) ,
327- renamed_and_removed_lints. to_owned( ) ,
328- unknown_lints. to_owned( ) ,
329- non_autolinks. to_owned( ) ,
330- ] ;
331-
332- let ( lint_opts, lint_caps) = init_lints ( lints_to_show, lint_opts, |lint| {
333- // FIXME: why is this necessary?
334- if lint. name == broken_intra_doc_links || lint. name == invalid_codeblock_attributes_name {
335- None
336- } else {
337- Some ( ( lint. name_lower ( ) , lint:: Allow ) )
338- }
339- } ) ;
340-
341357 let crate_types =
342358 if proc_macro_crate { vec ! [ CrateType :: ProcMacro ] } else { vec ! [ CrateType :: Rlib ] } ;
343359 // plays with error output here!
344- let sessopts = config:: Options {
360+ let mut sessopts = config:: Options {
345361 maybe_sysroot,
346362 search_paths : libs,
347363 crate_types,
348- lint_opts : if !display_warnings { lint_opts } else { vec ! [ ] } ,
364+ lint_opts : vec ! [ ] ,
349365 lint_cap,
350366 cg : codegen_options,
351367 externs,
@@ -360,9 +376,27 @@ crate fn create_config(
360376 ..Options :: default ( )
361377 } ;
362378
379+ let crate_cfg = interface:: parse_cfgspecs ( cfgs) ;
380+
381+ let invalid_codeblock_attributes_name = rustc_lint:: builtin:: INVALID_CODEBLOCK_ATTRIBUTES . name ;
382+ let broken_intra_doc_links = lint:: builtin:: BROKEN_INTRA_DOC_LINKS . name ;
383+
384+ let lints_to_show = get_rustdoc_lints ( crate_cfg. clone ( ) , sessopts. clone ( ) ) ;
385+ let ( lint_opts, lint_caps) = init_lints ( lints_to_show, lint_opts, |lint| {
386+ // FIXME: why is this necessary?
387+ if lint. name == broken_intra_doc_links || lint. name == invalid_codeblock_attributes_name {
388+ None
389+ } else {
390+ Some ( ( lint. name_lower ( ) , lint:: Allow ) )
391+ }
392+ } ) ;
393+ if !display_warnings {
394+ sessopts. lint_opts = lint_opts;
395+ }
396+
363397 interface:: Config {
364398 opts : sessopts,
365- crate_cfg : interface :: parse_cfgspecs ( cfgs ) ,
399+ crate_cfg,
366400 input,
367401 input_path : cpath,
368402 output_file : None ,
0 commit comments