Skip to content

Commit 3e70dfd

Browse files
committed
Auto merge of #49956 - QuietMisdreavus:rustdoc-codegen, r=GuillaumeGomez
rustdoc: port the -C option from rustc Blocked on #49864. The included test won't work without those changes, so this PR includes those commits as well. When documenting items that require certain target features, it helps to be able to force those target features into existence. Rather than include a flag just to parse those features, i instead decided to port the `-C` flag from rustc in its entirety. It takes the same parameters, because it runs through the same parsing function. This has the added benefit of being able to control the codegen of doctests as well. One concern i have with the flag is that i set it to stable here. My rationale is that it is a direct port of functionality on rustc that is currently stable, used only in mechanisms that it is originally used for. If needed, i can set it back to be unstable.
2 parents 748c549 + a5456bd commit 3e70dfd

File tree

6 files changed

+84
-20
lines changed

6 files changed

+84
-20
lines changed

src/doc/rustdoc/src/command-line-arguments.md

+25
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,31 @@ Similar to `--library-path`, `--extern` is about specifying the location
141141
of a dependency. `--library-path` provides directories to search in, `--extern`
142142
instead lets you specify exactly which dependency is located where.
143143

144+
## `-C`/`--codegen`: pass codegen options to rustc
145+
146+
Using this flag looks like this:
147+
148+
```bash
149+
$ rustdoc src/lib.rs -C target_feature=+avx
150+
$ rustdoc src/lib.rs --codegen target_feature=+avx
151+
152+
$ rustdoc --test src/lib.rs -C target_feature=+avx
153+
$ rustdoc --test src/lib.rs --codegen target_feature=+avx
154+
155+
$ rustdoc --test README.md -C target_feature=+avx
156+
$ rustdoc --test README.md --codegen target_feature=+avx
157+
```
158+
159+
When rustdoc generates documentation, looks for documentation tests, or executes documentation
160+
tests, it needs to compile some rust code, at least part-way. This flag allows you to tell rustdoc
161+
to provide some extra codegen options to rustc when it runs these compilations. Most of the time,
162+
these options won't affect a regular documentation run, but if something depends on target features
163+
to be enabled, or documentation tests need to use some additional options, this flag allows you to
164+
affect that.
165+
166+
The arguments to this flag are the same as those for the `-C` flag on rustc. Run `rustc -C help` to
167+
get the full list.
168+
144169
## `--passes`: add more rustdoc passes
145170

146171
Using this flag looks like this:

src/librustdoc/core.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use clean;
4242
use clean::Clean;
4343
use html::render::RenderInfo;
4444

45-
pub use rustc::session::config::Input;
45+
pub use rustc::session::config::{Input, CodegenOptions};
4646
pub use rustc::session::search_paths::SearchPaths;
4747

4848
pub type ExternalPaths = FxHashMap<DefId, (Vec<String>, clean::TypeKind)>;
@@ -125,7 +125,8 @@ pub fn run_core(search_paths: SearchPaths,
125125
allow_warnings: bool,
126126
crate_name: Option<String>,
127127
force_unstable_if_unmarked: bool,
128-
edition: Edition) -> (clean::Crate, RenderInfo)
128+
edition: Edition,
129+
cg: CodegenOptions) -> (clean::Crate, RenderInfo)
129130
{
130131
// Parse, resolve, and typecheck the given crate.
131132

@@ -143,6 +144,7 @@ pub fn run_core(search_paths: SearchPaths,
143144
crate_types: vec![config::CrateTypeRlib],
144145
lint_opts: if !allow_warnings { vec![(warning_lint, lint::Allow)] } else { vec![] },
145146
lint_cap: Some(lint::Allow),
147+
cg,
146148
externs,
147149
target_triple: triple.unwrap_or(host_triple),
148150
// Ensure that rustdoc works even if rustc is feature-staged

src/librustdoc/lib.rs

+15-7
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ use std::sync::mpsc::channel;
6161
use syntax::edition::Edition;
6262
use externalfiles::ExternalHtml;
6363
use rustc::session::search_paths::SearchPaths;
64-
use rustc::session::config::{ErrorOutputType, RustcOptGroup, nightly_options, Externs};
64+
use rustc::session::config::{ErrorOutputType, RustcOptGroup, Externs, CodegenOptions};
65+
use rustc::session::config::{nightly_options, build_codegen_options};
6566
use rustc_back::target::TargetTriple;
6667

6768
#[macro_use]
@@ -155,6 +156,9 @@ pub fn opts() -> Vec<RustcOptGroup> {
155156
stable("plugin-path", |o| {
156157
o.optmulti("", "plugin-path", "directory to load plugins from", "DIR")
157158
}),
159+
stable("C", |o| {
160+
o.optmulti("C", "codegen", "pass a codegen option to rustc", "OPT[=VALUE]")
161+
}),
158162
stable("passes", |o| {
159163
o.optmulti("", "passes",
160164
"list of passes to also run, you might want \
@@ -441,14 +445,16 @@ pub fn main_args(args: &[String]) -> isize {
441445
}
442446
};
443447

448+
let cg = build_codegen_options(&matches, ErrorOutputType::default());
449+
444450
match (should_test, markdown_input) {
445451
(true, true) => {
446452
return markdown::test(input, cfgs, libs, externs, test_args, maybe_sysroot,
447-
display_warnings, linker, edition)
453+
display_warnings, linker, edition, cg)
448454
}
449455
(true, false) => {
450456
return test::run(Path::new(input), cfgs, libs, externs, test_args, crate_name,
451-
maybe_sysroot, display_warnings, linker, edition)
457+
maybe_sysroot, display_warnings, linker, edition, cg)
452458
}
453459
(false, true) => return markdown::render(Path::new(input),
454460
output.unwrap_or(PathBuf::from("doc")),
@@ -458,7 +464,7 @@ pub fn main_args(args: &[String]) -> isize {
458464
}
459465

460466
let output_format = matches.opt_str("w");
461-
let res = acquire_input(PathBuf::from(input), externs, edition, &matches, move |out| {
467+
let res = acquire_input(PathBuf::from(input), externs, edition, cg, &matches, move |out| {
462468
let Output { krate, passes, renderinfo } = out;
463469
info!("going to format");
464470
match output_format.as_ref().map(|s| &**s) {
@@ -500,14 +506,15 @@ fn print_error<T>(error_message: T) where T: Display {
500506
fn acquire_input<R, F>(input: PathBuf,
501507
externs: Externs,
502508
edition: Edition,
509+
cg: CodegenOptions,
503510
matches: &getopts::Matches,
504511
f: F)
505512
-> Result<R, String>
506513
where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R {
507514
match matches.opt_str("r").as_ref().map(|s| &**s) {
508-
Some("rust") => Ok(rust_input(input, externs, edition, matches, f)),
515+
Some("rust") => Ok(rust_input(input, externs, edition, cg, matches, f)),
509516
Some(s) => Err(format!("unknown input format: {}", s)),
510-
None => Ok(rust_input(input, externs, edition, matches, f))
517+
None => Ok(rust_input(input, externs, edition, cg, matches, f))
511518
}
512519
}
513520

@@ -536,6 +543,7 @@ fn parse_externs(matches: &getopts::Matches) -> Result<Externs, String> {
536543
fn rust_input<R, F>(cratefile: PathBuf,
537544
externs: Externs,
538545
edition: Edition,
546+
cg: CodegenOptions,
539547
matches: &getopts::Matches,
540548
f: F) -> R
541549
where R: 'static + Send,
@@ -589,7 +597,7 @@ where R: 'static + Send,
589597
let (mut krate, renderinfo) =
590598
core::run_core(paths, cfgs, externs, Input::File(cratefile), triple, maybe_sysroot,
591599
display_warnings, crate_name.clone(),
592-
force_unstable_if_unmarked, edition);
600+
force_unstable_if_unmarked, edition, cg);
593601

594602
info!("finished with rustc");
595603

src/librustdoc/markdown.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use std::path::{PathBuf, Path};
1616
use getopts;
1717
use testing;
1818
use rustc::session::search_paths::SearchPaths;
19-
use rustc::session::config::Externs;
19+
use rustc::session::config::{Externs, CodegenOptions};
2020
use syntax::codemap::DUMMY_SP;
2121
use syntax::edition::Edition;
2222

@@ -140,7 +140,8 @@ pub fn render(input: &Path, mut output: PathBuf, matches: &getopts::Matches,
140140
/// Run any tests/code examples in the markdown file `input`.
141141
pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
142142
mut test_args: Vec<String>, maybe_sysroot: Option<PathBuf>,
143-
display_warnings: bool, linker: Option<PathBuf>, edition: Edition) -> isize {
143+
display_warnings: bool, linker: Option<PathBuf>, edition: Edition,
144+
cg: CodegenOptions) -> isize {
144145
let input_str = match load_string(input) {
145146
Ok(s) => s,
146147
Err(LoadStringError::ReadFail) => return 1,
@@ -150,7 +151,7 @@ pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
150151
let mut opts = TestOptions::default();
151152
opts.no_crate_inject = true;
152153
opts.display_warnings = display_warnings;
153-
let mut collector = Collector::new(input.to_owned(), cfgs, libs, externs,
154+
let mut collector = Collector::new(input.to_owned(), cfgs, libs, cg, externs,
154155
true, opts, maybe_sysroot, None,
155156
Some(PathBuf::from(input)),
156157
linker, edition);

src/librustdoc/test.rs

+15-8
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use rustc_lint;
2424
use rustc::hir;
2525
use rustc::hir::intravisit;
2626
use rustc::session::{self, CompileIncomplete, config};
27-
use rustc::session::config::{OutputType, OutputTypes, Externs};
27+
use rustc::session::config::{OutputType, OutputTypes, Externs, CodegenOptions};
2828
use rustc::session::search_paths::{SearchPaths, PathKind};
2929
use rustc_metadata::dynamic_lib::DynamicLibrary;
3030
use tempdir::TempDir;
@@ -64,7 +64,8 @@ pub fn run(input_path: &Path,
6464
maybe_sysroot: Option<PathBuf>,
6565
display_warnings: bool,
6666
linker: Option<PathBuf>,
67-
edition: Edition)
67+
edition: Edition,
68+
cg: CodegenOptions)
6869
-> isize {
6970
let input = config::Input::File(input_path.to_owned());
7071

@@ -73,6 +74,7 @@ pub fn run(input_path: &Path,
7374
|| Some(env::current_exe().unwrap().parent().unwrap().parent().unwrap().to_path_buf())),
7475
search_paths: libs.clone(),
7576
crate_types: vec![config::CrateTypeDylib],
77+
cg: cg.clone(),
7678
externs: externs.clone(),
7779
unstable_features: UnstableFeatures::from_environment(),
7880
lint_cap: Some(::rustc::lint::Level::Allow),
@@ -125,6 +127,7 @@ pub fn run(input_path: &Path,
125127
let mut collector = Collector::new(crate_name,
126128
cfgs,
127129
libs,
130+
cg,
128131
externs,
129132
false,
130133
opts,
@@ -190,7 +193,7 @@ fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions {
190193

191194
fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
192195
cfgs: Vec<String>, libs: SearchPaths,
193-
externs: Externs,
196+
cg: CodegenOptions, externs: Externs,
194197
should_panic: bool, no_run: bool, as_test_harness: bool,
195198
compile_fail: bool, mut error_codes: Vec<String>, opts: &TestOptions,
196199
maybe_sysroot: Option<PathBuf>, linker: Option<PathBuf>, edition: Edition) {
@@ -215,7 +218,7 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
215218
cg: config::CodegenOptions {
216219
prefer_dynamic: true,
217220
linker,
218-
.. config::basic_codegen_options()
221+
..cg
219222
},
220223
test: as_test_harness,
221224
unstable_features: UnstableFeatures::from_environment(),
@@ -478,6 +481,7 @@ pub struct Collector {
478481

479482
cfgs: Vec<String>,
480483
libs: SearchPaths,
484+
cg: CodegenOptions,
481485
externs: Externs,
482486
use_headers: bool,
483487
cratename: String,
@@ -491,15 +495,16 @@ pub struct Collector {
491495
}
492496

493497
impl Collector {
494-
pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
495-
use_headers: bool, opts: TestOptions, maybe_sysroot: Option<PathBuf>,
496-
codemap: Option<Lrc<CodeMap>>, filename: Option<PathBuf>,
497-
linker: Option<PathBuf>, edition: Edition) -> Collector {
498+
pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, cg: CodegenOptions,
499+
externs: Externs, use_headers: bool, opts: TestOptions,
500+
maybe_sysroot: Option<PathBuf>, codemap: Option<Lrc<CodeMap>>,
501+
filename: Option<PathBuf>, linker: Option<PathBuf>, edition: Edition) -> Collector {
498502
Collector {
499503
tests: Vec::new(),
500504
names: Vec::new(),
501505
cfgs,
502506
libs,
507+
cg,
503508
externs,
504509
use_headers,
505510
cratename,
@@ -524,6 +529,7 @@ impl Collector {
524529
let name = self.generate_name(line, &filename);
525530
let cfgs = self.cfgs.clone();
526531
let libs = self.libs.clone();
532+
let cg = self.cg.clone();
527533
let externs = self.externs.clone();
528534
let cratename = self.cratename.to_string();
529535
let opts = self.opts.clone();
@@ -552,6 +558,7 @@ impl Collector {
552558
line,
553559
cfgs,
554560
libs,
561+
cg,
555562
externs,
556563
should_panic,
557564
no_run,
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// only-x86_64
12+
// compile-flags:--test -C target-feature=+avx
13+
// should-fail
14+
15+
/// (written on a spider's web) Some Struct
16+
///
17+
/// ```
18+
/// panic!("oh no");
19+
/// ```
20+
#[doc(cfg(target_feature = "avx"))]
21+
pub struct SomeStruct;

0 commit comments

Comments
 (0)