Pass --target to lint docs

Otherwise, we may not have a standard library built for the native "host" target
of the rustc being run.
This commit is contained in:
Mark Rousskov 2020-09-16 10:29:31 -04:00
parent ff806b8716
commit 7e24136996
4 changed files with 37 additions and 15 deletions

View file

@ -752,6 +752,7 @@ impl Step for RustcBook {
let out_listing = out_base.join("src/lints");
builder.cp_r(&builder.src.join("src/doc/rustc"), &out_base);
builder.info(&format!("Generating lint docs ({})", self.target));
let rustc = builder.rustc(self.compiler);
// The tool runs `rustc` for extracting output examples, so it needs a
// functional sysroot.
@ -762,7 +763,8 @@ impl Step for RustcBook {
cmd.arg("--out");
cmd.arg(&out_listing);
cmd.arg("--rustc");
cmd.arg(rustc);
cmd.arg(&rustc);
cmd.arg("--rustc-target").arg(&self.target.rustc_target_arg());
if builder.config.verbose() {
cmd.arg("--verbose");
}

View file

@ -18,10 +18,10 @@ static GROUP_DESCRIPTIONS: &[(&str, &str)] = &[
/// Updates the documentation of lint groups.
pub(crate) fn generate_group_docs(
lints: &[Lint],
rustc_path: &Path,
rustc: crate::Rustc<'_>,
out_path: &Path,
) -> Result<(), Box<dyn Error>> {
let groups = collect_groups(rustc_path)?;
let groups = collect_groups(rustc)?;
let groups_path = out_path.join("groups.md");
let contents = fs::read_to_string(&groups_path)
.map_err(|e| format!("could not read {}: {}", groups_path.display(), e))?;
@ -36,9 +36,9 @@ pub(crate) fn generate_group_docs(
type LintGroups = BTreeMap<String, BTreeSet<String>>;
/// Collects the group names from rustc.
fn collect_groups(rustc: &Path) -> Result<LintGroups, Box<dyn Error>> {
fn collect_groups(rustc: crate::Rustc<'_>) -> Result<LintGroups, Box<dyn Error>> {
let mut result = BTreeMap::new();
let mut cmd = Command::new(rustc);
let mut cmd = Command::new(rustc.path);
cmd.arg("-Whelp");
let output = cmd.output().map_err(|e| format!("failed to run command {:?}\n{}", cmd, e))?;
if !output.status.success() {

View file

@ -45,16 +45,22 @@ impl Level {
}
}
#[derive(Copy, Clone)]
pub struct Rustc<'a> {
pub path: &'a Path,
pub target: &'a str,
}
/// Collects all lints, and writes the markdown documentation at the given directory.
pub fn extract_lint_docs(
src_path: &Path,
out_path: &Path,
rustc_path: &Path,
rustc: Rustc<'_>,
verbose: bool,
) -> Result<(), Box<dyn Error>> {
let mut lints = gather_lints(src_path)?;
for lint in &mut lints {
generate_output_example(lint, rustc_path, verbose).map_err(|e| {
generate_output_example(lint, rustc, verbose).map_err(|e| {
format!(
"failed to test example in lint docs for `{}` in {}:{}: {}",
lint.name,
@ -65,7 +71,7 @@ pub fn extract_lint_docs(
})?;
}
save_lints_markdown(&lints, &out_path.join("listing"))?;
groups::generate_group_docs(&lints, rustc_path, out_path)?;
groups::generate_group_docs(&lints, rustc, out_path)?;
Ok(())
}
@ -208,7 +214,7 @@ fn lint_name(line: &str) -> Result<String, &'static str> {
/// actual output from the compiler.
fn generate_output_example(
lint: &mut Lint,
rustc_path: &Path,
rustc: Rustc<'_>,
verbose: bool,
) -> Result<(), Box<dyn Error>> {
// Explicit list of lints that are allowed to not have an example. Please
@ -230,7 +236,7 @@ fn generate_output_example(
// separate test suite, and use an include mechanism such as mdbook's
// `{{#rustdoc_include}}`.
if !lint.is_ignored() {
replace_produces(lint, rustc_path, verbose)?;
replace_produces(lint, rustc, verbose)?;
}
Ok(())
}
@ -261,7 +267,7 @@ fn check_style(lint: &Lint) -> Result<(), Box<dyn Error>> {
/// output from the compiler.
fn replace_produces(
lint: &mut Lint,
rustc_path: &Path,
rustc: Rustc<'_>,
verbose: bool,
) -> Result<(), Box<dyn Error>> {
let mut lines = lint.doc.iter_mut();
@ -302,7 +308,7 @@ fn replace_produces(
Some(line) if line.is_empty() => {}
Some(line) if line == "{{produces}}" => {
let output =
generate_lint_output(&lint.name, &example, &options, rustc_path, verbose)?;
generate_lint_output(&lint.name, &example, &options, rustc, verbose)?;
line.replace_range(
..,
&format!(
@ -329,7 +335,7 @@ fn generate_lint_output(
name: &str,
example: &[&mut String],
options: &[&str],
rustc_path: &Path,
rustc: Rustc<'_>,
verbose: bool,
) -> Result<String, Box<dyn Error>> {
if verbose {
@ -364,13 +370,14 @@ fn generate_lint_output(
}
fs::write(&tempfile, source)
.map_err(|e| format!("failed to write {}: {}", tempfile.display(), e))?;
let mut cmd = Command::new(rustc_path);
let mut cmd = Command::new(rustc.path);
if options.contains(&"edition2015") {
cmd.arg("--edition=2015");
} else {
cmd.arg("--edition=2018");
}
cmd.arg("--error-format=json");
cmd.arg("--target").arg(rustc.target);
if options.contains(&"test") {
cmd.arg("--test");
}

View file

@ -13,6 +13,7 @@ fn doit() -> Result<(), Box<dyn Error>> {
let mut src_path = None;
let mut out_path = None;
let mut rustc_path = None;
let mut rustc_target = None;
let mut verbose = false;
while let Some(arg) = args.next() {
match arg.as_str() {
@ -34,6 +35,12 @@ fn doit() -> Result<(), Box<dyn Error>> {
None => return Err("--rustc requires a value".into()),
};
}
"--rustc-target" => {
rustc_target = match args.next() {
Some(s) => Some(s),
None => return Err("--rustc-target requires a value".into()),
};
}
"-v" | "--verbose" => verbose = true,
s => return Err(format!("unexpected argument `{}`", s).into()),
}
@ -47,10 +54,16 @@ fn doit() -> Result<(), Box<dyn Error>> {
if rustc_path.is_none() {
return Err("--rustc must be specified to the path of rustc".into());
}
if rustc_target.is_none() {
return Err("--rustc-target must be specified to the rustc target".into());
}
lint_docs::extract_lint_docs(
&src_path.unwrap(),
&out_path.unwrap(),
&rustc_path.unwrap(),
lint_docs::Rustc {
path: rustc_path.as_deref().unwrap(),
target: rustc_target.as_deref().unwrap(),
},
verbose,
)
}