diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2025-06-07 22:22:55 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-07 22:22:55 +0200 |
| commit | 2c8a9cccd9497d20d3f2a30c1370dd53c8f21296 (patch) | |
| tree | 5e623e4b7e5944f0e192855b647e710d6b625301 /src | |
| parent | 2f2c8c3512e82e4315db83bbb53eb79e2c566270 (diff) | |
| parent | d96d3bed6fc14fa03b077b1b7acf493815a6ef31 (diff) | |
| download | rust-2c8a9cccd9497d20d3f2a30c1370dd53c8f21296.tar.gz rust-2c8a9cccd9497d20d3f2a30c1370dd53c8f21296.zip | |
Rollup merge of #140560 - Urgau:test_attr-module-level, r=GuillaumeGomez
Allow `#![doc(test(attr(..)))]` everywhere This PR adds the ability to specify [`#![doc(test(attr(..)))]`](https://doc.rust-lang.org/nightly/rustdoc/write-documentation/the-doc-attribute.html#testattr) ~~at module level~~ everywhere in addition to allowing it at crate-root. This is motivated by a recent PR #140323 (by ````@tgross35)```` where we have to duplicate 2 attributes to every single `f16` and `f128` doctests, by allowing `#![doc(test(attr(..)))]` at module level (and everywhere else) we can omit them entirely and just have (in both module): ```rust #![doc(test(attr(feature(cfg_target_has_reliable_f16_f128))))] #![doc(test(attr(expect(internal_features))))] ``` Those new attributes are appended to the one found at crate-root or at a previous module. Those "global" attributes are compatible with merged doctests (they already were before). Given the small addition that this is, I'm proposing to insta-stabilize it, but I can feature-gate it if preferred. Best reviewed commit by commit. r? ````@GuillaumeGomez````
Diffstat (limited to 'src')
| -rw-r--r-- | src/doc/rustdoc/src/write-documentation/the-doc-attribute.md | 32 | ||||
| -rw-r--r-- | src/librustdoc/doctest.rs | 49 | ||||
| -rw-r--r-- | src/librustdoc/doctest/extracted.rs | 5 | ||||
| -rw-r--r-- | src/librustdoc/doctest/make.rs | 21 | ||||
| -rw-r--r-- | src/librustdoc/doctest/markdown.rs | 2 | ||||
| -rw-r--r-- | src/librustdoc/doctest/runner.rs | 11 | ||||
| -rw-r--r-- | src/librustdoc/doctest/rust.rs | 29 | ||||
| -rw-r--r-- | src/librustdoc/doctest/tests.rs | 68 | ||||
| -rw-r--r-- | src/librustdoc/html/markdown.rs | 1 |
9 files changed, 150 insertions, 68 deletions
diff --git a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md index 6ec93d1746c..65e6b417427 100644 --- a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md +++ b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md @@ -143,15 +143,6 @@ But if you include this: it will not. -### `test(attr(...))` - -This form of the `doc` attribute allows you to add arbitrary attributes to all your doctests. For -example, if you want your doctests to fail if they have dead code, you could add this: - -```rust,no_run -#![doc(test(attr(deny(dead_code))))] -``` - ## At the item level These forms of the `#[doc]` attribute are used on individual items, to control how @@ -283,3 +274,26 @@ To get around this limitation, we just add `#[doc(alias = "lib_name_do_something on the `do_something` method and then it's all good! Users can now look for `lib_name_do_something` in our crate directly and find `Obj::do_something`. + +### `test(attr(...))` + +This form of the `doc` attribute allows you to add arbitrary attributes to all your doctests. For +example, if you want your doctests to fail if they have dead code, you could add this: + +```rust,no_run +#![doc(test(attr(deny(dead_code))))] + +mod my_mod { + #![doc(test(attr(allow(dead_code))))] // but allow `dead_code` for this module +} +``` + +`test(attr(..))` attributes are appended to the parent module's, they do not replace the current +list of attributes. In the previous example, both attributes would be present: + +```rust,no_run +// For every doctest in `my_mod` + +#![deny(dead_code)] // from the crate-root +#![allow(dead_code)] // from `my_mod` +``` diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index b2fe24db0a2..a81d6020f71 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -5,6 +5,7 @@ mod runner; mod rust; use std::fs::File; +use std::hash::{Hash, Hasher}; use std::io::{self, Write}; use std::path::{Path, PathBuf}; use std::process::{self, Command, Stdio}; @@ -14,7 +15,7 @@ use std::{panic, str}; pub(crate) use make::{BuildDocTestBuilder, DocTestBuilder}; pub(crate) use markdown::test as test_markdown; -use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; +use rustc_data_structures::fx::{FxHashMap, FxHasher, FxIndexMap, FxIndexSet}; use rustc_errors::emitter::HumanReadableErrorType; use rustc_errors::{ColorConfig, DiagCtxtHandle}; use rustc_hir as hir; @@ -45,8 +46,6 @@ pub(crate) struct GlobalTestOptions { /// Whether inserting extra indent spaces in code block, /// default is `false`, only `true` for generating code link of Rust playground pub(crate) insert_indent_space: bool, - /// Additional crate-level attributes to add to doctests. - pub(crate) attrs: Vec<String>, /// Path to file containing arguments for the invocation of rustc. pub(crate) args_file: PathBuf, } @@ -283,7 +282,7 @@ pub(crate) fn run_tests( rustdoc_options: &Arc<RustdocOptions>, unused_extern_reports: &Arc<Mutex<Vec<UnusedExterns>>>, mut standalone_tests: Vec<test::TestDescAndFn>, - mergeable_tests: FxIndexMap<Edition, Vec<(DocTestBuilder, ScrapedDocTest)>>, + mergeable_tests: FxIndexMap<MergeableTestKey, Vec<(DocTestBuilder, ScrapedDocTest)>>, // We pass this argument so we can drop it manually before using `exit`. mut temp_dir: Option<TempDir>, ) { @@ -298,7 +297,7 @@ pub(crate) fn run_tests( let mut ran_edition_tests = 0; let target_str = rustdoc_options.target.to_string(); - for (edition, mut doctests) in mergeable_tests { + for (MergeableTestKey { edition, global_crate_attrs_hash }, mut doctests) in mergeable_tests { if doctests.is_empty() { continue; } @@ -308,8 +307,8 @@ pub(crate) fn run_tests( let rustdoc_test_options = IndividualTestOptions::new( rustdoc_options, - &Some(format!("merged_doctest_{edition}")), - PathBuf::from(format!("doctest_{edition}.rs")), + &Some(format!("merged_doctest_{edition}_{global_crate_attrs_hash}")), + PathBuf::from(format!("doctest_{edition}_{global_crate_attrs_hash}.rs")), ); for (doctest, scraped_test) in &doctests { @@ -371,12 +370,9 @@ fn scrape_test_config( attrs: &[hir::Attribute], args_file: PathBuf, ) -> GlobalTestOptions { - use rustc_ast_pretty::pprust; - let mut opts = GlobalTestOptions { crate_name, no_crate_inject: false, - attrs: Vec::new(), insert_indent_space: false, args_file, }; @@ -393,13 +389,7 @@ fn scrape_test_config( if attr.has_name(sym::no_crate_inject) { opts.no_crate_inject = true; } - if attr.has_name(sym::attr) - && let Some(l) = attr.meta_item_list() - { - for item in l { - opts.attrs.push(pprust::meta_list_item_to_string(item)); - } - } + // NOTE: `test(attr(..))` is handled when discovering the individual tests } opts @@ -848,6 +838,7 @@ pub(crate) struct ScrapedDocTest { text: String, name: String, span: Span, + global_crate_attrs: Vec<String>, } impl ScrapedDocTest { @@ -858,6 +849,7 @@ impl ScrapedDocTest { langstr: LangString, text: String, span: Span, + global_crate_attrs: Vec<String>, ) -> Self { let mut item_path = logical_path.join("::"); item_path.retain(|c| c != ' '); @@ -867,7 +859,7 @@ impl ScrapedDocTest { let name = format!("{} - {item_path}(line {line})", filename.prefer_remapped_unconditionaly()); - Self { filename, line, langstr, text, name, span } + Self { filename, line, langstr, text, name, span, global_crate_attrs } } fn edition(&self, opts: &RustdocOptions) -> Edition { self.langstr.edition.unwrap_or(opts.edition) @@ -896,9 +888,15 @@ pub(crate) trait DocTestVisitor { fn visit_header(&mut self, _name: &str, _level: u32) {} } +#[derive(Clone, Debug, Hash, Eq, PartialEq)] +pub(crate) struct MergeableTestKey { + edition: Edition, + global_crate_attrs_hash: u64, +} + struct CreateRunnableDocTests { standalone_tests: Vec<test::TestDescAndFn>, - mergeable_tests: FxIndexMap<Edition, Vec<(DocTestBuilder, ScrapedDocTest)>>, + mergeable_tests: FxIndexMap<MergeableTestKey, Vec<(DocTestBuilder, ScrapedDocTest)>>, rustdoc_options: Arc<RustdocOptions>, opts: GlobalTestOptions, @@ -949,6 +947,7 @@ impl CreateRunnableDocTests { let edition = scraped_test.edition(&self.rustdoc_options); let doctest = BuildDocTestBuilder::new(&scraped_test.text) .crate_name(&self.opts.crate_name) + .global_crate_attrs(scraped_test.global_crate_attrs.clone()) .edition(edition) .can_merge_doctests(self.can_merge_doctests) .test_id(test_id) @@ -965,7 +964,17 @@ impl CreateRunnableDocTests { let test_desc = self.generate_test_desc_and_fn(doctest, scraped_test); self.standalone_tests.push(test_desc); } else { - self.mergeable_tests.entry(edition).or_default().push((doctest, scraped_test)); + self.mergeable_tests + .entry(MergeableTestKey { + edition, + global_crate_attrs_hash: { + let mut hasher = FxHasher::default(); + scraped_test.global_crate_attrs.hash(&mut hasher); + hasher.finish() + }, + }) + .or_default() + .push((doctest, scraped_test)); } } diff --git a/src/librustdoc/doctest/extracted.rs b/src/librustdoc/doctest/extracted.rs index 3b17ccc78c7..ebe6bfd22ba 100644 --- a/src/librustdoc/doctest/extracted.rs +++ b/src/librustdoc/doctest/extracted.rs @@ -35,13 +35,16 @@ impl ExtractedDocTests { ) { let edition = scraped_test.edition(options); - let ScrapedDocTest { filename, line, langstr, text, name, .. } = scraped_test; + let ScrapedDocTest { filename, line, langstr, text, name, global_crate_attrs, .. } = + scraped_test; let doctest = BuildDocTestBuilder::new(&text) .crate_name(&opts.crate_name) + .global_crate_attrs(global_crate_attrs) .edition(edition) .lang_str(&langstr) .build(None); + let (full_test_code, size) = doctest.generate_unique_doctest( &text, langstr.test_harness, diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index 66647b88018..5e571613d6f 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -45,6 +45,7 @@ pub(crate) struct BuildDocTestBuilder<'a> { test_id: Option<String>, lang_str: Option<&'a LangString>, span: Span, + global_crate_attrs: Vec<String>, } impl<'a> BuildDocTestBuilder<'a> { @@ -57,6 +58,7 @@ impl<'a> BuildDocTestBuilder<'a> { test_id: None, lang_str: None, span: DUMMY_SP, + global_crate_attrs: Vec::new(), } } @@ -96,6 +98,12 @@ impl<'a> BuildDocTestBuilder<'a> { self } + #[inline] + pub(crate) fn global_crate_attrs(mut self, global_crate_attrs: Vec<String>) -> Self { + self.global_crate_attrs = global_crate_attrs; + self + } + pub(crate) fn build(self, dcx: Option<DiagCtxtHandle<'_>>) -> DocTestBuilder { let BuildDocTestBuilder { source, @@ -106,6 +114,7 @@ impl<'a> BuildDocTestBuilder<'a> { test_id, lang_str, span, + global_crate_attrs, } = self; let can_merge_doctests = can_merge_doctests && lang_str.is_some_and(|lang_str| { @@ -133,6 +142,7 @@ impl<'a> BuildDocTestBuilder<'a> { // If the AST returned an error, we don't want this doctest to be merged with the // others. return DocTestBuilder::invalid( + Vec::new(), String::new(), String::new(), String::new(), @@ -155,6 +165,7 @@ impl<'a> BuildDocTestBuilder<'a> { DocTestBuilder { supports_color, has_main_fn, + global_crate_attrs, crate_attrs, maybe_crate_attrs, crates, @@ -173,6 +184,7 @@ pub(crate) struct DocTestBuilder { pub(crate) supports_color: bool, pub(crate) already_has_extern_crate: bool, pub(crate) has_main_fn: bool, + pub(crate) global_crate_attrs: Vec<String>, pub(crate) crate_attrs: String, /// If this is a merged doctest, it will be put into `everything_else`, otherwise it will /// put into `crate_attrs`. @@ -186,6 +198,7 @@ pub(crate) struct DocTestBuilder { impl DocTestBuilder { fn invalid( + global_crate_attrs: Vec<String>, crate_attrs: String, maybe_crate_attrs: String, crates: String, @@ -195,6 +208,7 @@ impl DocTestBuilder { Self { supports_color: false, has_main_fn: false, + global_crate_attrs, crate_attrs, maybe_crate_attrs, crates, @@ -224,7 +238,8 @@ impl DocTestBuilder { let mut line_offset = 0; let mut prog = String::new(); let everything_else = self.everything_else.trim(); - if opts.attrs.is_empty() { + + if self.global_crate_attrs.is_empty() { // If there aren't any attributes supplied by #![doc(test(attr(...)))], then allow some // lints that are commonly triggered in doctests. The crate-level test attributes are // commonly used to make tests fail in case they trigger warnings, so having this there in @@ -233,8 +248,8 @@ impl DocTestBuilder { line_offset += 1; } - // Next, any attributes that came from the crate root via #![doc(test(attr(...)))]. - for attr in &opts.attrs { + // Next, any attributes that came from #![doc(test(attr(...)))]. + for attr in &self.global_crate_attrs { prog.push_str(&format!("#![{attr}]\n")); line_offset += 1; } diff --git a/src/librustdoc/doctest/markdown.rs b/src/librustdoc/doctest/markdown.rs index e358a7e44e5..7f26605f256 100644 --- a/src/librustdoc/doctest/markdown.rs +++ b/src/librustdoc/doctest/markdown.rs @@ -31,6 +31,7 @@ impl DocTestVisitor for MdCollector { config, test, DUMMY_SP, + Vec::new(), )); } @@ -96,7 +97,6 @@ pub(crate) fn test(input: &Input, options: Options) -> Result<(), String> { crate_name, no_crate_inject: true, insert_indent_space: false, - attrs: vec![], args_file, }; diff --git a/src/librustdoc/doctest/runner.rs b/src/librustdoc/doctest/runner.rs index 39a4f23560a..f0914474c79 100644 --- a/src/librustdoc/doctest/runner.rs +++ b/src/librustdoc/doctest/runner.rs @@ -12,6 +12,7 @@ use crate::html::markdown::{Ignore, LangString}; /// Convenient type to merge compatible doctests into one. pub(crate) struct DocTestRunner { crate_attrs: FxIndexSet<String>, + global_crate_attrs: FxIndexSet<String>, ids: String, output: String, output_merged_tests: String, @@ -23,6 +24,7 @@ impl DocTestRunner { pub(crate) fn new() -> Self { Self { crate_attrs: FxIndexSet::default(), + global_crate_attrs: FxIndexSet::default(), ids: String::new(), output: String::new(), output_merged_tests: String::new(), @@ -46,6 +48,9 @@ impl DocTestRunner { for line in doctest.crate_attrs.split('\n') { self.crate_attrs.insert(line.to_string()); } + for line in &doctest.global_crate_attrs { + self.global_crate_attrs.insert(line.to_string()); + } } self.ids.push_str(&format!( "tests.push({}::TEST);\n", @@ -85,7 +90,7 @@ impl DocTestRunner { code_prefix.push('\n'); } - if opts.attrs.is_empty() { + if self.global_crate_attrs.is_empty() { // If there aren't any attributes supplied by #![doc(test(attr(...)))], then allow some // lints that are commonly triggered in doctests. The crate-level test attributes are // commonly used to make tests fail in case they trigger warnings, so having this there in @@ -93,8 +98,8 @@ impl DocTestRunner { code_prefix.push_str("#![allow(unused)]\n"); } - // Next, any attributes that came from the crate root via #![doc(test(attr(...)))]. - for attr in &opts.attrs { + // Next, any attributes that came from #![doc(test(attr(...)))]. + for attr in &self.global_crate_attrs { code_prefix.push_str(&format!("#![{attr}]\n")); } diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index f9d2aa3d3b4..96975105ac5 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -4,6 +4,7 @@ use std::cell::Cell; use std::env; use std::sync::Arc; +use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; use rustc_hir::{self as hir, CRATE_HIR_ID, intravisit}; @@ -11,7 +12,7 @@ use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; use rustc_resolve::rustdoc::span_of_fragments; use rustc_span::source_map::SourceMap; -use rustc_span::{BytePos, DUMMY_SP, FileName, Pos, Span}; +use rustc_span::{BytePos, DUMMY_SP, FileName, Pos, Span, sym}; use super::{DocTestVisitor, ScrapedDocTest}; use crate::clean::{Attributes, extract_cfg_from_attrs}; @@ -22,6 +23,7 @@ struct RustCollector { tests: Vec<ScrapedDocTest>, cur_path: Vec<String>, position: Span, + global_crate_attrs: Vec<String>, } impl RustCollector { @@ -75,6 +77,7 @@ impl DocTestVisitor for RustCollector { config, test, span, + self.global_crate_attrs.clone(), )); } @@ -94,6 +97,7 @@ impl<'tcx> HirCollector<'tcx> { cur_path: vec![], position: DUMMY_SP, tests: vec![], + global_crate_attrs: Vec::new(), }; Self { codes, tcx, collector } } @@ -123,6 +127,26 @@ impl HirCollector<'_> { return; } + // Try collecting `#[doc(test(attr(...)))]` + let old_global_crate_attrs_len = self.collector.global_crate_attrs.len(); + for doc_test_attrs in ast_attrs + .iter() + .filter(|a| a.has_name(sym::doc)) + .flat_map(|a| a.meta_item_list().unwrap_or_default()) + .filter(|a| a.has_name(sym::test)) + { + let Some(doc_test_attrs) = doc_test_attrs.meta_item_list() else { continue }; + for attr in doc_test_attrs + .iter() + .filter(|a| a.has_name(sym::attr)) + .flat_map(|a| a.meta_item_list().unwrap_or_default()) + .map(|i| pprust::meta_list_item_to_string(i)) + { + // Add the additional attributes to the global_crate_attrs vector + self.collector.global_crate_attrs.push(attr); + } + } + let mut has_name = false; if let Some(name) = name { self.collector.cur_path.push(name); @@ -157,6 +181,9 @@ impl HirCollector<'_> { nested(self); + // Restore global_crate_attrs to it's previous size/content + self.collector.global_crate_attrs.truncate(old_global_crate_attrs_len); + if has_name { self.collector.cur_path.pop(); } diff --git a/src/librustdoc/doctest/tests.rs b/src/librustdoc/doctest/tests.rs index 08248fdf39b..ce2984ced79 100644 --- a/src/librustdoc/doctest/tests.rs +++ b/src/librustdoc/doctest/tests.rs @@ -7,9 +7,11 @@ fn make_test( crate_name: Option<&str>, dont_insert_main: bool, opts: &GlobalTestOptions, + global_crate_attrs: Vec<&str>, test_id: Option<&str>, ) -> (String, usize) { - let mut builder = BuildDocTestBuilder::new(test_code); + let mut builder = BuildDocTestBuilder::new(test_code) + .global_crate_attrs(global_crate_attrs.into_iter().map(|a| a.to_string()).collect()); if let Some(crate_name) = crate_name { builder = builder.crate_name(crate_name); } @@ -28,7 +30,6 @@ fn default_global_opts(crate_name: impl Into<String>) -> GlobalTestOptions { crate_name: crate_name.into(), no_crate_inject: false, insert_indent_space: false, - attrs: vec![], args_file: PathBuf::new(), } } @@ -43,7 +44,7 @@ fn main() { assert_eq!(2+2, 4); }" .to_string(); - let (output, len) = make_test(input, None, false, &opts, None); + let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 2)); } @@ -58,7 +59,7 @@ fn main() { assert_eq!(2+2, 4); }" .to_string(); - let (output, len) = make_test(input, Some("asdf"), false, &opts, None); + let (output, len) = make_test(input, Some("asdf"), false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 2)); } @@ -77,7 +78,7 @@ use asdf::qwop; assert_eq!(2+2, 4); }" .to_string(); - let (output, len) = make_test(input, Some("asdf"), false, &opts, None); + let (output, len) = make_test(input, Some("asdf"), false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 3)); } @@ -94,7 +95,7 @@ use asdf::qwop; assert_eq!(2+2, 4); }" .to_string(); - let (output, len) = make_test(input, Some("asdf"), false, &opts, None); + let (output, len) = make_test(input, Some("asdf"), false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 2)); } @@ -112,7 +113,7 @@ use std::*; assert_eq!(2+2, 4); }" .to_string(); - let (output, len) = make_test(input, Some("std"), false, &opts, None); + let (output, len) = make_test(input, Some("std"), false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 2)); } @@ -131,7 +132,7 @@ use asdf::qwop; assert_eq!(2+2, 4); }" .to_string(); - let (output, len) = make_test(input, Some("asdf"), false, &opts, None); + let (output, len) = make_test(input, Some("asdf"), false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 2)); } @@ -148,7 +149,7 @@ use asdf::qwop; assert_eq!(2+2, 4); }" .to_string(); - let (output, len) = make_test(input, Some("asdf"), false, &opts, None); + let (output, len) = make_test(input, Some("asdf"), false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 2)); } @@ -156,8 +157,7 @@ assert_eq!(2+2, 4); fn make_test_opts_attrs() { // If you supplied some doctest attributes with `#![doc(test(attr(...)))]`, it will use // those instead of the stock `#![allow(unused)]`. - let mut opts = default_global_opts("asdf"); - opts.attrs.push("feature(sick_rad)".to_string()); + let opts = default_global_opts("asdf"); let input = "use asdf::qwop; assert_eq!(2+2, 4);"; let expected = "#![feature(sick_rad)] @@ -168,11 +168,10 @@ use asdf::qwop; assert_eq!(2+2, 4); }" .to_string(); - let (output, len) = make_test(input, Some("asdf"), false, &opts, None); + let (output, len) = + make_test(input, Some("asdf"), false, &opts, vec!["feature(sick_rad)"], None); assert_eq!((output, len), (expected, 3)); - // Adding more will also bump the returned line offset. - opts.attrs.push("feature(hella_dope)".to_string()); let expected = "#![feature(sick_rad)] #![feature(hella_dope)] #[allow(unused_extern_crates)] @@ -182,7 +181,18 @@ use asdf::qwop; assert_eq!(2+2, 4); }" .to_string(); - let (output, len) = make_test(input, Some("asdf"), false, &opts, None); + let (output, len) = make_test( + input, + Some("asdf"), + false, + &opts, + vec![ + "feature(sick_rad)", + // Adding more will also bump the returned line offset. + "feature(hella_dope)", + ], + None, + ); assert_eq!((output, len), (expected, 4)); } @@ -200,7 +210,7 @@ fn main() { assert_eq!(2+2, 4); }" .to_string(); - let (output, len) = make_test(input, None, false, &opts, None); + let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 2)); } @@ -216,7 +226,7 @@ fn main() { assert_eq!(2+2, 4); }" .to_string(); - let (output, len) = make_test(input, None, false, &opts, None); + let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 1)); } @@ -232,7 +242,7 @@ fn main() { assert_eq!(2+2, 4); }" .to_string(); - let (output, len) = make_test(input, None, false, &opts, None); + let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 2)); } @@ -246,7 +256,7 @@ assert_eq!(2+2, 4);"; //Ceci n'est pas une `fn main` assert_eq!(2+2, 4);" .to_string(); - let (output, len) = make_test(input, None, true, &opts, None); + let (output, len) = make_test(input, None, true, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 1)); } @@ -264,7 +274,7 @@ assert_eq!(2+2, 4); }" .to_string(); - let (output, len) = make_test(input, None, false, &opts, None); + let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 2)); } @@ -284,7 +294,7 @@ assert_eq!(asdf::foo, 4); }" .to_string(); - let (output, len) = make_test(input, Some("asdf"), false, &opts, None); + let (output, len) = make_test(input, Some("asdf"), false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 3)); } @@ -302,7 +312,7 @@ test_wrapper! { }" .to_string(); - let (output, len) = make_test(input, Some("my_crate"), false, &opts, None); + let (output, len) = make_test(input, Some("my_crate"), false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 1)); } @@ -322,7 +332,7 @@ io::stdin().read_line(&mut input)?; Ok::<(), io:Error>(()) } _inner().unwrap() }" .to_string(); - let (output, len) = make_test(input, None, false, &opts, None); + let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 2)); } @@ -336,7 +346,7 @@ fn main() { #[allow(non_snake_case)] fn _doctest_main__some_unique_name() { assert_eq!(2+2, 4); } _doctest_main__some_unique_name() }" .to_string(); - let (output, len) = make_test(input, None, false, &opts, Some("_some_unique_name")); + let (output, len) = make_test(input, None, false, &opts, Vec::new(), Some("_some_unique_name")); assert_eq!((output, len), (expected, 2)); } @@ -355,7 +365,7 @@ fn main() { eprintln!(\"hello anan\"); }" .to_string(); - let (output, len) = make_test(input, None, false, &opts, None); + let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 2)); } @@ -375,7 +385,7 @@ fn main() { eprintln!(\"hello anan\"); }" .to_string(); - let (output, len) = make_test(input, None, false, &opts, None); + let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 1)); } @@ -400,7 +410,7 @@ fn main() { }" .to_string(); - let (output, len) = make_test(input, None, false, &opts, None); + let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 2)); // And same, if there is a `main` function provided by the user, we ensure that it's @@ -420,7 +430,7 @@ fn main() {}"; fn main() {}" .to_string(); - let (output, len) = make_test(input, None, false, &opts, None); + let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 1)); } @@ -448,6 +458,6 @@ pub mod outer_module { } }" .to_string(); - let (output, len) = make_test(input, None, false, &opts, None); + let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 2)); } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 68ba1245520..d3701784f9d 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -300,7 +300,6 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> { crate_name: krate.map(String::from).unwrap_or_default(), no_crate_inject: false, insert_indent_space: true, - attrs: vec![], args_file: PathBuf::new(), }; let mut builder = doctest::BuildDocTestBuilder::new(&test).edition(edition); |
