Skip to content

Commit 7ae31e9

Browse files
committed
Auto merge of #49451 - QuietMisdreavus:epoch-doctests, r=GuillaumeGomez
rustdoc: add an --edition flag to compile docs/doctests with a certain edition To correspond with the 2018 edition, this adds a (currently unstable) `--edition` flag to rustdoc that makes it compile crates and doctests with the given edition. Once this lands, Cargo should be updated to pass this flag when the edition configuration option is given.
2 parents 80785a5 + 97aead0 commit 7ae31e9

File tree

5 files changed

+70
-17
lines changed

5 files changed

+70
-17
lines changed

src/doc/rustdoc/src/unstable-features.md

+13
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,19 @@ details.
348348

349349
[issue-display-warnings]: https://github.com/rust-lang/rust/issues/41574
350350

351+
### `--edition`: control the edition of docs and doctests
352+
353+
Using this flag looks like this:
354+
355+
```bash
356+
$ rustdoc src/lib.rs -Z unstable-options --edition 2018
357+
$ rustdoc --test src/lib.rs -Z unstable-options --edition 2018
358+
```
359+
360+
This flag allows rustdoc to treat your rust code as the given edition. It will compile doctests with
361+
the given edition as well. As with `rustc`, the default edition that `rustdoc` will use is `2015`
362+
(the first edition).
363+
351364
### `-Z force-unstable-if-unmarked`
352365

353366
Using this flag looks like this:

src/librustdoc/core.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use rustc_back::target::TargetTriple;
2626

2727
use syntax::ast::NodeId;
2828
use syntax::codemap;
29+
use syntax::edition::Edition;
2930
use syntax::feature_gate::UnstableFeatures;
3031
use errors;
3132
use errors::emitter::ColorConfig;
@@ -123,7 +124,8 @@ pub fn run_core(search_paths: SearchPaths,
123124
maybe_sysroot: Option<PathBuf>,
124125
allow_warnings: bool,
125126
crate_name: Option<String>,
126-
force_unstable_if_unmarked: bool) -> (clean::Crate, RenderInfo)
127+
force_unstable_if_unmarked: bool,
128+
edition: Edition) -> (clean::Crate, RenderInfo)
127129
{
128130
// Parse, resolve, and typecheck the given crate.
129131

@@ -148,6 +150,7 @@ pub fn run_core(search_paths: SearchPaths,
148150
actually_rustdoc: true,
149151
debugging_opts: config::DebuggingOptions {
150152
force_unstable_if_unmarked,
153+
edition,
151154
..config::basic_debugging_options()
152155
},
153156
..config::basic_options().clone()

src/librustdoc/lib.rs

+30-8
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ use std::path::{Path, PathBuf};
6161
use std::process;
6262
use std::sync::mpsc::channel;
6363

64+
use syntax::edition::Edition;
6465
use externalfiles::ExternalHtml;
6566
use rustc::session::search_paths::SearchPaths;
6667
use rustc::session::config::{ErrorOutputType, RustcOptGroup, nightly_options, Externs};
@@ -271,6 +272,11 @@ pub fn opts() -> Vec<RustcOptGroup> {
271272
\"light-suffix.css\"",
272273
"PATH")
273274
}),
275+
unstable("edition", |o| {
276+
o.optopt("", "edition",
277+
"edition to use when compiling rust code (default: 2015)",
278+
"EDITION")
279+
}),
274280
]
275281
}
276282

@@ -429,14 +435,23 @@ pub fn main_args(args: &[String]) -> isize {
429435
let sort_modules_alphabetically = !matches.opt_present("sort-modules-by-appearance");
430436
let resource_suffix = matches.opt_str("resource-suffix");
431437

438+
let edition = matches.opt_str("edition").unwrap_or("2015".to_string());
439+
let edition = match edition.parse() {
440+
Ok(e) => e,
441+
Err(_) => {
442+
print_error("could not parse edition");
443+
return 1;
444+
}
445+
};
446+
432447
match (should_test, markdown_input) {
433448
(true, true) => {
434449
return markdown::test(input, cfgs, libs, externs, test_args, maybe_sysroot,
435-
display_warnings, linker)
450+
display_warnings, linker, edition)
436451
}
437452
(true, false) => {
438453
return test::run(Path::new(input), cfgs, libs, externs, test_args, crate_name,
439-
maybe_sysroot, display_warnings, linker)
454+
maybe_sysroot, display_warnings, linker, edition)
440455
}
441456
(false, true) => return markdown::render(Path::new(input),
442457
output.unwrap_or(PathBuf::from("doc")),
@@ -446,7 +461,7 @@ pub fn main_args(args: &[String]) -> isize {
446461
}
447462

448463
let output_format = matches.opt_str("w");
449-
let res = acquire_input(PathBuf::from(input), externs, &matches, move |out| {
464+
let res = acquire_input(PathBuf::from(input), externs, edition, &matches, move |out| {
450465
let Output { krate, passes, renderinfo } = out;
451466
info!("going to format");
452467
match output_format.as_ref().map(|s| &**s) {
@@ -487,14 +502,15 @@ fn print_error<T>(error_message: T) where T: Display {
487502
/// and files and then generates the necessary rustdoc output for formatting.
488503
fn acquire_input<R, F>(input: PathBuf,
489504
externs: Externs,
505+
edition: Edition,
490506
matches: &getopts::Matches,
491507
f: F)
492508
-> Result<R, String>
493509
where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R {
494510
match matches.opt_str("r").as_ref().map(|s| &**s) {
495-
Some("rust") => Ok(rust_input(input, externs, matches, f)),
511+
Some("rust") => Ok(rust_input(input, externs, edition, matches, f)),
496512
Some(s) => Err(format!("unknown input format: {}", s)),
497-
None => Ok(rust_input(input, externs, matches, f))
513+
None => Ok(rust_input(input, externs, edition, matches, f))
498514
}
499515
}
500516

@@ -520,8 +536,14 @@ fn parse_externs(matches: &getopts::Matches) -> Result<Externs, String> {
520536
/// generated from the cleaned AST of the crate.
521537
///
522538
/// This form of input will run all of the plug/cleaning passes
523-
fn rust_input<R, F>(cratefile: PathBuf, externs: Externs, matches: &getopts::Matches, f: F) -> R
524-
where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R {
539+
fn rust_input<R, F>(cratefile: PathBuf,
540+
externs: Externs,
541+
edition: Edition,
542+
matches: &getopts::Matches,
543+
f: F) -> R
544+
where R: 'static + Send,
545+
F: 'static + Send + FnOnce(Output) -> R
546+
{
525547
let mut default_passes = !matches.opt_present("no-defaults");
526548
let mut passes = matches.opt_strs("passes");
527549
let mut plugins = matches.opt_strs("plugins");
@@ -570,7 +592,7 @@ where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R {
570592
let (mut krate, renderinfo) =
571593
core::run_core(paths, cfgs, externs, Input::File(cratefile), triple, maybe_sysroot,
572594
display_warnings, crate_name.clone(),
573-
force_unstable_if_unmarked);
595+
force_unstable_if_unmarked, edition);
574596

575597
info!("finished with rustc");
576598

src/librustdoc/markdown.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use testing;
1818
use rustc::session::search_paths::SearchPaths;
1919
use rustc::session::config::Externs;
2020
use syntax::codemap::DUMMY_SP;
21+
use syntax::edition::Edition;
2122

2223
use externalfiles::{ExternalHtml, LoadStringError, load_string};
2324

@@ -139,7 +140,7 @@ pub fn render(input: &Path, mut output: PathBuf, matches: &getopts::Matches,
139140
/// Run any tests/code examples in the markdown file `input`.
140141
pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
141142
mut test_args: Vec<String>, maybe_sysroot: Option<PathBuf>,
142-
display_warnings: bool, linker: Option<PathBuf>) -> isize {
143+
display_warnings: bool, linker: Option<PathBuf>, edition: Edition) -> isize {
143144
let input_str = match load_string(input) {
144145
Ok(s) => s,
145146
Err(LoadStringError::ReadFail) => return 1,
@@ -151,7 +152,7 @@ pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
151152
let mut collector = Collector::new(input.to_owned(), cfgs, libs, externs,
152153
true, opts, maybe_sysroot, None,
153154
Some(PathBuf::from(input)),
154-
linker);
155+
linker, edition);
155156
find_testable_code(&input_str, &mut collector, DUMMY_SP, None);
156157
test_args.insert(0, "rustdoctest".to_string());
157158
testing::test_main(&test_args, collector.tests,

src/librustdoc/test.rs

+20-6
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use rustc_metadata::cstore::CStore;
3434
use rustc_resolve::MakeGlobMap;
3535
use syntax::ast;
3636
use syntax::codemap::CodeMap;
37+
use syntax::edition::Edition;
3738
use syntax::feature_gate::UnstableFeatures;
3839
use syntax::with_globals;
3940
use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName};
@@ -57,7 +58,8 @@ pub fn run(input_path: &Path,
5758
crate_name: Option<String>,
5859
maybe_sysroot: Option<PathBuf>,
5960
display_warnings: bool,
60-
linker: Option<PathBuf>)
61+
linker: Option<PathBuf>,
62+
edition: Edition)
6163
-> isize {
6264
let input = config::Input::File(input_path.to_owned());
6365

@@ -70,6 +72,10 @@ pub fn run(input_path: &Path,
7072
unstable_features: UnstableFeatures::from_environment(),
7173
lint_cap: Some(::rustc::lint::Level::Allow),
7274
actually_rustdoc: true,
75+
debugging_opts: config::DebuggingOptions {
76+
edition,
77+
..config::basic_debugging_options()
78+
},
7379
..config::basic_options().clone()
7480
};
7581

@@ -117,7 +123,8 @@ pub fn run(input_path: &Path,
117123
maybe_sysroot,
118124
Some(codemap),
119125
None,
120-
linker);
126+
linker,
127+
edition);
121128

122129
{
123130
let map = hir::map::map_crate(&sess, &cstore, &mut hir_forest, &defs);
@@ -177,8 +184,7 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
177184
externs: Externs,
178185
should_panic: bool, no_run: bool, as_test_harness: bool,
179186
compile_fail: bool, mut error_codes: Vec<String>, opts: &TestOptions,
180-
maybe_sysroot: Option<PathBuf>,
181-
linker: Option<PathBuf>) {
187+
maybe_sysroot: Option<PathBuf>, linker: Option<PathBuf>, edition: Edition) {
182188
// the test harness wants its own `main` & top level functions, so
183189
// never wrap the test in `fn main() { ... }`
184190
let (test, line_offset) = make_test(test, Some(cratename), as_test_harness, opts);
@@ -204,6 +210,10 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
204210
},
205211
test: as_test_harness,
206212
unstable_features: UnstableFeatures::from_environment(),
213+
debugging_opts: config::DebuggingOptions {
214+
edition,
215+
..config::basic_debugging_options()
216+
},
207217
..config::basic_options().clone()
208218
};
209219

@@ -465,13 +475,14 @@ pub struct Collector {
465475
codemap: Option<Lrc<CodeMap>>,
466476
filename: Option<PathBuf>,
467477
linker: Option<PathBuf>,
478+
edition: Edition,
468479
}
469480

470481
impl Collector {
471482
pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
472483
use_headers: bool, opts: TestOptions, maybe_sysroot: Option<PathBuf>,
473484
codemap: Option<Lrc<CodeMap>>, filename: Option<PathBuf>,
474-
linker: Option<PathBuf>) -> Collector {
485+
linker: Option<PathBuf>, edition: Edition) -> Collector {
475486
Collector {
476487
tests: Vec::new(),
477488
names: Vec::new(),
@@ -486,6 +497,7 @@ impl Collector {
486497
codemap,
487498
filename,
488499
linker,
500+
edition,
489501
}
490502
}
491503

@@ -505,6 +517,7 @@ impl Collector {
505517
let opts = self.opts.clone();
506518
let maybe_sysroot = self.maybe_sysroot.clone();
507519
let linker = self.linker.clone();
520+
let edition = self.edition;
508521
debug!("Creating test {}: {}", name, test);
509522
self.tests.push(testing::TestDescAndFn {
510523
desc: testing::TestDesc {
@@ -535,7 +548,8 @@ impl Collector {
535548
error_codes,
536549
&opts,
537550
maybe_sysroot,
538-
linker)
551+
linker,
552+
edition)
539553
}))
540554
} {
541555
Ok(()) => (),

0 commit comments

Comments
 (0)