Auto merge of #132815 - matthiaskrgr:rollup-nti992u, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #132341 (Reject raw lifetime followed by `'`, like regular lifetimes do)
 - #132363 (Enforce that raw lifetimes must be valid raw identifiers)
 - #132744 (add regression test for #90781)
 - #132754 (Simplify the internal API for declaring command-line options)
 - #132772 (use `download-rustc="if-unchanged"` as a global default)
 - #132774 (Use lld with non-LLVM backends)
 - #132799 (Make `Ty::primitive_symbol` recognize `str`)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-11-09 19:52:46 +00:00
commit 4adafcf40a
27 changed files with 1059 additions and 651 deletions

View File

@ -3305,23 +3305,6 @@ fn add_lld_args(
let self_contained_cli = sess.opts.cg.link_self_contained.is_linker_enabled();
let self_contained_target = self_contained_components.is_linker_enabled();
// FIXME: in the future, codegen backends may need to have more control over this process: they
// don't always support all the features the linker expects here, and vice versa. For example,
// at the time of writing this, lld expects a newer style of aarch64 TLS relocations that
// cranelift doesn't implement yet. That in turn can impact whether linking would succeed on
// such a target when using the `cg_clif` backend and lld.
//
// Until interactions between backends and linker features are expressible, we limit target
// specs to opt-in to lld only when we're on the llvm backend, where it's expected to work and
// tested on CI. As usual, the CLI still has precedence over this, so that users and developers
// can still override this default when needed (e.g. for tests).
let uses_llvm_backend =
matches!(sess.opts.unstable_opts.codegen_backend.as_deref(), None | Some("llvm"));
if !uses_llvm_backend && !self_contained_cli && sess.opts.cg.linker_flavor.is_none() {
// We bail if we're not using llvm and lld was not explicitly requested on the CLI.
return;
}
let self_contained_linker = self_contained_cli || self_contained_target;
if self_contained_linker && !sess.opts.cg.link_self_contained.is_linker_disabled() {
let mut linker_path_exists = false;

View File

@ -937,7 +937,7 @@ fn usage(verbose: bool, include_unstable_options: bool, nightly_build: bool) {
let groups = if verbose { config::rustc_optgroups() } else { config::rustc_short_optgroups() };
let mut options = getopts::Options::new();
for option in groups.iter().filter(|x| include_unstable_options || x.is_stable()) {
(option.apply)(&mut options);
option.apply(&mut options);
}
let message = "Usage: rustc [OPTIONS] INPUT";
let nightly_help = if nightly_build {
@ -1219,7 +1219,7 @@ pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<geto
let mut options = getopts::Options::new();
let optgroups = config::rustc_optgroups();
for option in &optgroups {
(option.apply)(&mut options);
option.apply(&mut options);
}
let matches = options.parse(args).unwrap_or_else(|e| {
let msg: Option<String> = match e {
@ -1233,7 +1233,7 @@ pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<geto
optgroups.iter().find(|option| option.name == opt).map(|option| {
// Print the help just for the option in question.
let mut options = getopts::Options::new();
(option.apply)(&mut options);
option.apply(&mut options);
// getopt requires us to pass a function for joining an iterator of
// strings, even though in this case we expect exactly one string.
options.usage_with_format(|it| {

View File

@ -102,7 +102,7 @@ fn new_public_extern_entry<S, I>(locations: I) -> ExternEntry
fn optgroups() -> getopts::Options {
let mut opts = getopts::Options::new();
for group in rustc_optgroups() {
(group.apply)(&mut opts);
group.apply(&mut opts);
}
return opts;
}

View File

@ -715,7 +715,17 @@ fn lifetime_or_char(&mut self) -> TokenKind {
self.bump();
self.bump();
self.eat_while(is_id_continue);
return RawLifetime;
match self.first() {
'\'' => {
// Check if after skipping literal contents we've met a closing
// single quote (which means that user attempted to create a
// string with single quotes).
self.bump();
let kind = Char { terminated: true };
return Literal { kind, suffix_start: self.pos_within_token() };
}
_ => return RawLifetime,
}
}
// Either a lifetime or a character literal with

View File

@ -1933,6 +1933,7 @@ pub fn primitive_symbol(self) -> Option<Symbol> {
ty::UintTy::U64 => Some(sym::u64),
ty::UintTy::U128 => Some(sym::u128),
},
ty::Str => Some(sym::str),
_ => None,
}
}

View File

@ -77,6 +77,8 @@ parse_box_syntax_removed_suggestion = use `Box::new()` instead
parse_cannot_be_raw_ident = `{$ident}` cannot be a raw identifier
parse_cannot_be_raw_lifetime = `{$ident}` cannot be a raw lifetime
parse_catch_after_try = keyword `catch` cannot follow a `try` block
.help = try using `match` on the result of the `try` block instead

View File

@ -2018,6 +2018,14 @@ pub(crate) struct CannotBeRawIdent {
pub ident: Symbol,
}
#[derive(Diagnostic)]
#[diag(parse_cannot_be_raw_lifetime)]
pub(crate) struct CannotBeRawLifetime {
#[primary_span]
pub span: Span,
pub ident: Symbol,
}
#[derive(Diagnostic)]
#[diag(parse_keyword_lifetime)]
pub(crate) struct KeywordLifetime {

View File

@ -294,15 +294,21 @@ fn next_token(&mut self) -> (Token, bool) {
let prefix_span = self.mk_sp(start, ident_start);
if prefix_span.at_least_rust_2021() {
let lifetime_name_without_tick = self.str_from(ident_start);
let span = self.mk_sp(start, self.pos);
let lifetime_name_without_tick = Symbol::intern(&self.str_from(ident_start));
if !lifetime_name_without_tick.can_be_raw() {
self.dcx().emit_err(errors::CannotBeRawLifetime { span, ident: lifetime_name_without_tick });
}
// Put the `'` back onto the lifetime name.
let mut lifetime_name = String::with_capacity(lifetime_name_without_tick.len() + 1);
let mut lifetime_name = String::with_capacity(lifetime_name_without_tick.as_str().len() + 1);
lifetime_name.push('\'');
lifetime_name += lifetime_name_without_tick;
lifetime_name += lifetime_name_without_tick.as_str();
let sym = Symbol::intern(&lifetime_name);
// Make sure we mark this as a raw identifier.
self.psess.raw_identifier_spans.push(self.mk_sp(start, self.pos));
self.psess.raw_identifier_spans.push(span);
token::Lifetime(sym, IdentIsRaw::Yes)
} else {

View File

@ -12,7 +12,7 @@
use std::path::{Path, PathBuf};
use std::str::{self, FromStr};
use std::sync::LazyLock;
use std::{fmt, fs, iter};
use std::{cmp, fmt, fs, iter};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_data_structures::stable_hasher::{StableOrd, ToStableHashKey};
@ -1367,13 +1367,38 @@ pub fn build_target_config(early_dcx: &EarlyDiagCtxt, opts: &Options, sysroot: &
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
enum OptionStability {
pub enum OptionStability {
Stable,
Unstable,
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum OptionKind {
/// An option that takes a value, and cannot appear more than once (e.g. `--out-dir`).
///
/// Corresponds to [`getopts::Options::optopt`].
Opt,
/// An option that takes a value, and can appear multiple times (e.g. `--emit`).
///
/// Corresponds to [`getopts::Options::optmulti`].
Multi,
/// An option that does not take a value, and cannot appear more than once (e.g. `--help`).
///
/// Corresponds to [`getopts::Options::optflag`].
/// The `hint` string must be empty.
Flag,
/// An option that does not take a value, and can appear multiple times (e.g. `-O`).
///
/// Corresponds to [`getopts::Options::optflagmulti`].
/// The `hint` string must be empty.
FlagMulti,
}
pub struct RustcOptGroup {
pub apply: Box<dyn Fn(&mut getopts::Options) -> &mut getopts::Options>,
apply: Box<dyn Fn(&mut getopts::Options) -> &mut getopts::Options>,
pub name: &'static str,
stability: OptionStability,
}
@ -1383,73 +1408,42 @@ pub fn is_stable(&self) -> bool {
self.stability == OptionStability::Stable
}
pub fn stable<F>(name: &'static str, f: F) -> RustcOptGroup
where
F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static,
{
RustcOptGroup { name, apply: Box::new(f), stability: OptionStability::Stable }
}
pub fn unstable<F>(name: &'static str, f: F) -> RustcOptGroup
where
F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static,
{
RustcOptGroup { name, apply: Box::new(f), stability: OptionStability::Unstable }
pub fn apply(&self, options: &mut getopts::Options) {
(self.apply)(options);
}
}
// The `opt` local module holds wrappers around the `getopts` API that
// adds extra rustc-specific metadata to each option; such metadata
// is exposed by . The public
// functions below ending with `_u` are the functions that return
// *unstable* options, i.e., options that are only enabled when the
// user also passes the `-Z unstable-options` debugging flag.
mod opt {
// The `fn flag*` etc below are written so that we can use them
// in the future; do not warn about them not being used right now.
#![allow(dead_code)]
use super::RustcOptGroup;
type R = RustcOptGroup;
type S = &'static str;
fn stable<F>(name: S, f: F) -> R
where
F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static,
{
RustcOptGroup::stable(name, f)
}
fn unstable<F>(name: S, f: F) -> R
where
F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static,
{
RustcOptGroup::unstable(name, f)
}
fn longer(a: S, b: S) -> S {
if a.len() > b.len() { a } else { b }
}
pub(crate) fn opt_s(a: S, b: S, c: S, d: S) -> R {
stable(longer(a, b), move |opts| opts.optopt(a, b, c, d))
}
pub(crate) fn multi_s(a: S, b: S, c: S, d: S) -> R {
stable(longer(a, b), move |opts| opts.optmulti(a, b, c, d))
}
pub(crate) fn flag_s(a: S, b: S, c: S) -> R {
stable(longer(a, b), move |opts| opts.optflag(a, b, c))
}
pub(crate) fn flagmulti_s(a: S, b: S, c: S) -> R {
stable(longer(a, b), move |opts| opts.optflagmulti(a, b, c))
}
fn opt(a: S, b: S, c: S, d: S) -> R {
unstable(longer(a, b), move |opts| opts.optopt(a, b, c, d))
}
pub(crate) fn multi(a: S, b: S, c: S, d: S) -> R {
unstable(longer(a, b), move |opts| opts.optmulti(a, b, c, d))
pub fn make_opt(
stability: OptionStability,
kind: OptionKind,
short_name: &'static str,
long_name: &'static str,
desc: &'static str,
hint: &'static str,
) -> RustcOptGroup {
RustcOptGroup {
name: cmp::max_by_key(short_name, long_name, |s| s.len()),
stability,
apply: match kind {
OptionKind::Opt => Box::new(move |opts: &mut getopts::Options| {
opts.optopt(short_name, long_name, desc, hint)
}),
OptionKind::Multi => Box::new(move |opts: &mut getopts::Options| {
opts.optmulti(short_name, long_name, desc, hint)
}),
OptionKind::Flag => {
assert_eq!(hint, "");
Box::new(move |opts: &mut getopts::Options| {
opts.optflag(short_name, long_name, desc)
})
}
OptionKind::FlagMulti => {
assert_eq!(hint, "");
Box::new(move |opts: &mut getopts::Options| {
opts.optflagmulti(short_name, long_name, desc)
})
}
},
}
}
@ -1464,46 +1458,60 @@ pub(crate) fn multi(a: S, b: S, c: S, d: S) -> R {
/// including metadata for each option, such as whether the option is
/// part of the stable long-term interface for rustc.
pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
use OptionKind::{Flag, FlagMulti, Multi, Opt};
use OptionStability::Stable;
use self::make_opt as opt;
vec![
opt::flag_s("h", "help", "Display this message"),
opt::multi_s("", "cfg", "Configure the compilation environment.
SPEC supports the syntax `NAME[=\"VALUE\"]`.", "SPEC"),
opt::multi_s("", "check-cfg", "Provide list of expected cfgs for checking", "SPEC"),
opt::multi_s(
opt(Stable, Flag, "h", "help", "Display this message", ""),
opt(
Stable,
Multi,
"",
"cfg",
"Configure the compilation environment.\n\
SPEC supports the syntax `NAME[=\"VALUE\"]`.",
"SPEC",
),
opt(Stable, Multi, "", "check-cfg", "Provide list of expected cfgs for checking", "SPEC"),
opt(
Stable,
Multi,
"L",
"",
"Add a directory to the library search path. The
optional KIND can be one of dependency, crate, native,
framework, or all (the default).",
"Add a directory to the library search path. \
The optional KIND can be one of dependency, crate, native, framework, or all (the default).",
"[KIND=]PATH",
),
opt::multi_s(
opt(
Stable,
Multi,
"l",
"",
"Link the generated crate(s) to the specified native
library NAME. The optional KIND can be one of
static, framework, or dylib (the default).
Optional comma separated MODIFIERS (bundle|verbatim|whole-archive|as-needed)
may be specified each with a prefix of either '+' to
enable or '-' to disable.",
"Link the generated crate(s) to the specified native\n\
library NAME. The optional KIND can be one of\n\
static, framework, or dylib (the default).\n\
Optional comma separated MODIFIERS\n\
(bundle|verbatim|whole-archive|as-needed)\n\
may be specified each with a prefix of either '+' to\n\
enable or '-' to disable.",
"[KIND[:MODIFIERS]=]NAME[:RENAME]",
),
make_crate_type_option(),
opt::opt_s("", "crate-name", "Specify the name of the crate being built", "NAME"),
opt::opt_s(
"",
"edition",
&EDITION_STRING,
EDITION_NAME_LIST,
),
opt::multi_s(
opt(Stable, Opt, "", "crate-name", "Specify the name of the crate being built", "NAME"),
opt(Stable, Opt, "", "edition", &EDITION_STRING, EDITION_NAME_LIST),
opt(
Stable,
Multi,
"",
"emit",
"Comma separated list of types of output for \
the compiler to emit",
"Comma separated list of types of output for the compiler to emit",
"[asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]",
),
opt::multi_s(
opt(
Stable,
Multi,
"",
"print",
"Compiler information to print on stdout",
@ -1512,41 +1520,36 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
tls-models|target-spec-json|all-target-specs-json|native-static-libs|\
stack-protector-strategies|link-args|deployment-target]",
),
opt::flagmulti_s("g", "", "Equivalent to -C debuginfo=2"),
opt::flagmulti_s("O", "", "Equivalent to -C opt-level=2"),
opt::opt_s("o", "", "Write output to <filename>", "FILENAME"),
opt::opt_s(
"",
"out-dir",
"Write output to compiler-chosen filename \
in <dir>",
"DIR",
),
opt::opt_s(
opt(Stable, FlagMulti, "g", "", "Equivalent to -C debuginfo=2", ""),
opt(Stable, FlagMulti, "O", "", "Equivalent to -C opt-level=2", ""),
opt(Stable, Opt, "o", "", "Write output to <filename>", "FILENAME"),
opt(Stable, Opt, "", "out-dir", "Write output to compiler-chosen filename in <dir>", "DIR"),
opt(
Stable,
Opt,
"",
"explain",
"Provide a detailed explanation of an error \
message",
"Provide a detailed explanation of an error message",
"OPT",
),
opt::flag_s("", "test", "Build a test harness"),
opt::opt_s("", "target", "Target triple for which the code is compiled", "TARGET"),
opt::multi_s("A", "allow", "Set lint allowed", "LINT"),
opt::multi_s("W", "warn", "Set lint warnings", "LINT"),
opt::multi_s("", "force-warn", "Set lint force-warn", "LINT"),
opt::multi_s("D", "deny", "Set lint denied", "LINT"),
opt::multi_s("F", "forbid", "Set lint forbidden", "LINT"),
opt::multi_s(
opt(Stable, Flag, "", "test", "Build a test harness", ""),
opt(Stable, Opt, "", "target", "Target triple for which the code is compiled", "TARGET"),
opt(Stable, Multi, "A", "allow", "Set lint allowed", "LINT"),
opt(Stable, Multi, "W", "warn", "Set lint warnings", "LINT"),
opt(Stable, Multi, "", "force-warn", "Set lint force-warn", "LINT"),
opt(Stable, Multi, "D", "deny", "Set lint denied", "LINT"),
opt(Stable, Multi, "F", "forbid", "Set lint forbidden", "LINT"),
opt(
Stable,
Multi,
"",
"cap-lints",
"Set the most restrictive lint level. \
More restrictive lints are capped at this \
level",
"Set the most restrictive lint level. More restrictive lints are capped at this level",
"LEVEL",
),
opt::multi_s("C", "codegen", "Set a codegen option", "OPT[=VALUE]"),
opt::flag_s("V", "version", "Print version info and exit"),
opt::flag_s("v", "verbose", "Use verbose output"),
opt(Stable, Multi, "C", "codegen", "Set a codegen option", "OPT[=VALUE]"),
opt(Stable, Flag, "V", "version", "Print version info and exit", ""),
opt(Stable, Flag, "v", "verbose", "Use verbose output", ""),
]
}
@ -1554,25 +1557,36 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
/// each option, such as whether the option is part of the stable
/// long-term interface for rustc.
pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
use OptionKind::{Multi, Opt};
use OptionStability::{Stable, Unstable};
use self::make_opt as opt;
let mut opts = rustc_short_optgroups();
// FIXME: none of these descriptions are actually used
opts.extend(vec![
opt::multi_s(
opt(
Stable,
Multi,
"",
"extern",
"Specify where an external rust library is located",
"NAME[=PATH]",
),
opt::opt_s("", "sysroot", "Override the system root", "PATH"),
opt::multi("Z", "", "Set unstable / perma-unstable options", "FLAG"),
opt::opt_s(
opt(Stable, Opt, "", "sysroot", "Override the system root", "PATH"),
opt(Unstable, Multi, "Z", "", "Set unstable / perma-unstable options", "FLAG"),
opt(
Stable,
Opt,
"",
"error-format",
"How errors and other messages are produced",
"human|json|short",
),
opt::multi_s("", "json", "Configure the JSON output of the compiler", "CONFIG"),
opt::opt_s(
opt(Stable, Multi, "", "json", "Configure the JSON output of the compiler", "CONFIG"),
opt(
Stable,
Opt,
"",
"color",
"Configure coloring of output:
@ -1581,19 +1595,23 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
never = never colorize output",
"auto|always|never",
),
opt::opt_s(
opt(
Stable,
Opt,
"",
"diagnostic-width",
"Inform rustc of the width of the output so that diagnostics can be truncated to fit",
"WIDTH",
),
opt::multi_s(
opt(
Stable,
Multi,
"",
"remap-path-prefix",
"Remap source names in all output (compiler messages and output files)",
"FROM=TO",
),
opt::multi("", "env-set", "Inject an environment variable", "VAR=VALUE"),
opt(Unstable, Multi, "", "env-set", "Inject an environment variable", "VAR=VALUE"),
]);
opts
}
@ -2756,7 +2774,9 @@ fn parse_pretty(early_dcx: &EarlyDiagCtxt, unstable_opts: &UnstableOptions) -> O
}
pub fn make_crate_type_option() -> RustcOptGroup {
opt::multi_s(
make_opt(
OptionStability::Stable,
OptionKind::Multi,
"",
"crate-type",
"Comma separated list of types of crates

View File

@ -11,6 +11,7 @@ extended = true
# Most users installing from source want to build all parts of the project from source.
[llvm]
download-ci-llvm = false
[rust]
# We have several defaults in bootstrap that depend on whether the channel is `dev` (e.g. `omit-git-hash` and `download-ci-llvm`).
# Make sure they don't get set when installing from source.

View File

@ -8,9 +8,6 @@ bench-stage = 0
[rust]
# This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower.
incremental = true
# Download rustc from CI instead of building it from source.
# For stage > 1 builds, this cuts compile times significantly when there are no changes on "compiler" tree.
download-rustc = "if-unchanged"
# Make the compiler and standard library faster to build, at the expense of a ~20% runtime slowdown.
lto = "off"

View File

@ -3,11 +3,6 @@
[rust]
# This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower.
incremental = true
# Download rustc from CI instead of building it from source.
# For stage > 1 builds, this cuts compile times significantly when there are no changes on "compiler" tree.
# Using these defaults will download the stage2 compiler (see `download-rustc`
# setting) and the stage2 toolchain should therefore be used for these defaults.
download-rustc = "if-unchanged"
[build]
# Document with the in-tree rustdoc by default, since `download-rustc` makes it quick to compile.

View File

@ -1665,10 +1665,26 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
let mut debuginfo_level_tools = None;
let mut debuginfo_level_tests = None;
let mut optimize = None;
let mut omit_git_hash = None;
let mut lld_enabled = None;
let mut std_features = None;
let default = config.channel == "dev";
config.omit_git_hash = toml.rust.as_ref().and_then(|r| r.omit_git_hash).unwrap_or(default);
config.rust_info = GitInfo::new(config.omit_git_hash, &config.src);
config.cargo_info = GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/cargo"));
config.rust_analyzer_info =
GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/rust-analyzer"));
config.clippy_info =
GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/clippy"));
config.miri_info = GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/miri"));
config.rustfmt_info =
GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/rustfmt"));
config.enzyme_info =
GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/enzyme"));
config.in_tree_llvm_info = GitInfo::new(false, &config.src.join("src/llvm-project"));
config.in_tree_gcc_info = GitInfo::new(false, &config.src.join("src/gcc"));
let mut is_user_configured_rust_channel = false;
if let Some(rust) = toml.rust {
@ -1699,7 +1715,7 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
verbose_tests,
optimize_tests,
codegen_tests,
omit_git_hash: omit_git_hash_toml,
omit_git_hash: _, // already handled above
dist_src,
save_toolstates,
codegen_backends,
@ -1750,7 +1766,6 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
std_features = std_features_toml;
optimize = optimize_toml;
omit_git_hash = omit_git_hash_toml;
config.rust_new_symbol_mangling = new_symbol_mangling;
set(&mut config.rust_optimize_tests, optimize_tests);
set(&mut config.codegen_tests, codegen_tests);
@ -1826,24 +1841,6 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
config.reproducible_artifacts = flags.reproducible_artifact;
// rust_info must be set before is_ci_llvm_available() is called.
let default = config.channel == "dev";
config.omit_git_hash = omit_git_hash.unwrap_or(default);
config.rust_info = GitInfo::new(config.omit_git_hash, &config.src);
config.cargo_info = GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/cargo"));
config.rust_analyzer_info =
GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/rust-analyzer"));
config.clippy_info =
GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/clippy"));
config.miri_info = GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/miri"));
config.rustfmt_info =
GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/rustfmt"));
config.enzyme_info =
GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/enzyme"));
config.in_tree_llvm_info = GitInfo::new(false, &config.src.join("src/llvm-project"));
config.in_tree_gcc_info = GitInfo::new(false, &config.src.join("src/gcc"));
// We need to override `rust.channel` if it's manually specified when using the CI rustc.
// This is because if the compiler uses a different channel than the one specified in config.toml,
// tests may fail due to using a different channel than the one used by the compiler during tests.
@ -2760,9 +2757,19 @@ fn download_ci_rustc_commit(
// If `download-rustc` is not set, default to rebuilding.
let if_unchanged = match download_rustc {
None | Some(StringOrBool::Bool(false)) => return None,
None => self.rust_info.is_managed_git_subrepository(),
Some(StringOrBool::Bool(false)) => return None,
Some(StringOrBool::Bool(true)) => false,
Some(StringOrBool::String(s)) if s == "if-unchanged" => true,
Some(StringOrBool::String(s)) if s == "if-unchanged" => {
if !self.rust_info.is_managed_git_subrepository() {
println!(
"ERROR: `download-rustc=if-unchanged` is only compatible with Git managed sources."
);
crate::exit!(1);
}
true
}
Some(StringOrBool::String(other)) => {
panic!("unrecognized option for download-rustc: {other}")
}
@ -2789,7 +2796,7 @@ fn download_ci_rustc_commit(
}
println!("ERROR: could not find commit hash for downloading rustc");
println!("HELP: maybe your repository history is too shallow?");
println!("HELP: consider disabling `download-rustc`");
println!("HELP: consider setting `rust.download-rustc=false` in config.toml");
println!("HELP: or fetch enough history to include one upstream commit");
crate::exit!(1);
}

View File

@ -135,6 +135,7 @@ fn override_toml() {
[rust]
lto = "off"
deny-warnings = true
download-rustc=false
[build]
gdb = "foo"
@ -200,6 +201,8 @@ fn override_toml() {
.collect(),
"setting dictionary value"
);
assert!(!config.llvm_from_ci);
assert!(!config.download_rustc());
}
#[test]

View File

@ -215,477 +215,482 @@ fn init_logging(early_dcx: &EarlyDiagCtxt) {
}
fn opts() -> Vec<RustcOptGroup> {
let stable: fn(_, fn(&mut getopts::Options) -> &mut _) -> _ = RustcOptGroup::stable;
let unstable: fn(_, fn(&mut getopts::Options) -> &mut _) -> _ = RustcOptGroup::unstable;
use rustc_session::config::OptionKind::{Flag, FlagMulti, Multi, Opt};
use rustc_session::config::OptionStability::{Stable, Unstable};
use rustc_session::config::make_opt as opt;
vec![
stable("h", |o| o.optflagmulti("h", "help", "show this help message")),
stable("V", |o| o.optflagmulti("V", "version", "print rustdoc's version")),
stable("v", |o| o.optflagmulti("v", "verbose", "use verbose output")),
stable("w", |o| o.optopt("w", "output-format", "the output type to write", "[html]")),
stable("output", |o| {
o.optopt(
"",
"output",
"Which directory to place the output. \
This option is deprecated, use --out-dir instead.",
"PATH",
)
}),
stable("o", |o| o.optopt("o", "out-dir", "which directory to place the output", "PATH")),
stable("crate-name", |o| {
o.optopt("", "crate-name", "specify the name of this crate", "NAME")
}),
opt(Stable, FlagMulti, "h", "help", "show this help message", ""),
opt(Stable, FlagMulti, "V", "version", "print rustdoc's version", ""),
opt(Stable, FlagMulti, "v", "verbose", "use verbose output", ""),
opt(Stable, Opt, "w", "output-format", "the output type to write", "[html]"),
opt(
Stable,
Opt,
"",
"output",
"Which directory to place the output. This option is deprecated, use --out-dir instead.",
"PATH",
),
opt(Stable, Opt, "o", "out-dir", "which directory to place the output", "PATH"),
opt(Stable, Opt, "", "crate-name", "specify the name of this crate", "NAME"),
make_crate_type_option(),
stable("L", |o| {
o.optmulti("L", "library-path", "directory to add to crate search path", "DIR")
}),
stable("cfg", |o| o.optmulti("", "cfg", "pass a --cfg to rustc", "")),
stable("check-cfg", |o| o.optmulti("", "check-cfg", "pass a --check-cfg to rustc", "")),
stable("extern", |o| o.optmulti("", "extern", "pass an --extern to rustc", "NAME[=PATH]")),
unstable("extern-html-root-url", |o| {
o.optmulti(
"",
"extern-html-root-url",
"base URL to use for dependencies; for example, \
\"std=/doc\" links std::vec::Vec to /doc/std/vec/struct.Vec.html",
"NAME=URL",
)
}),
unstable("extern-html-root-takes-precedence", |o| {
o.optflagmulti(
"",
"extern-html-root-takes-precedence",
"give precedence to `--extern-html-root-url`, not `html_root_url`",
)
}),
stable("C", |o| {
o.optmulti("C", "codegen", "pass a codegen option to rustc", "OPT[=VALUE]")
}),
stable("document-private-items", |o| {
o.optflagmulti("", "document-private-items", "document private items")
}),
unstable("document-hidden-items", |o| {
o.optflagmulti("", "document-hidden-items", "document items that have doc(hidden)")
}),
stable("test", |o| o.optflagmulti("", "test", "run code examples as tests")),
stable("test-args", |o| {
o.optmulti("", "test-args", "arguments to pass to the test runner", "ARGS")
}),
stable("test-run-directory", |o| {
o.optopt(
"",
"test-run-directory",
"The working directory in which to run tests",
"PATH",
)
}),
stable("target", |o| o.optopt("", "target", "target triple to document", "TRIPLE")),
stable("markdown-css", |o| {
o.optmulti(
"",
"markdown-css",
"CSS files to include via <link> in a rendered Markdown file",
"FILES",
)
}),
stable("html-in-header", |o| {
o.optmulti(
"",
"html-in-header",
"files to include inline in the <head> section of a rendered Markdown file \
or generated documentation",
"FILES",
)
}),
stable("html-before-content", |o| {
o.optmulti(
"",
"html-before-content",
"files to include inline between <body> and the content of a rendered \
Markdown file or generated documentation",
"FILES",
)
}),
stable("html-after-content", |o| {
o.optmulti(
"",
"html-after-content",
"files to include inline between the content and </body> of a rendered \
Markdown file or generated documentation",
"FILES",
)
}),
unstable("markdown-before-content", |o| {
o.optmulti(
"",
"markdown-before-content",
"files to include inline between <body> and the content of a rendered \
Markdown file or generated documentation",
"FILES",
)
}),
unstable("markdown-after-content", |o| {
o.optmulti(
"",
"markdown-after-content",
"files to include inline between the content and </body> of a rendered \
Markdown file or generated documentation",
"FILES",
)
}),
stable("markdown-playground-url", |o| {
o.optopt("", "markdown-playground-url", "URL to send code snippets to", "URL")
}),
stable("markdown-no-toc", |o| {
o.optflagmulti("", "markdown-no-toc", "don't include table of contents")
}),
stable("e", |o| {
o.optopt(
"e",
"extend-css",
"To add some CSS rules with a given file to generate doc with your \
own theme. However, your theme might break if the rustdoc's generated HTML \
changes, so be careful!",
"PATH",
)
}),
unstable("Z", |o| {
o.optmulti("Z", "", "unstable / perma-unstable options (only on nightly build)", "FLAG")
}),
stable("sysroot", |o| o.optopt("", "sysroot", "Override the system root", "PATH")),
unstable("playground-url", |o| {
o.optopt(
"",
"playground-url",
"URL to send code snippets to, may be reset by --markdown-playground-url \
or `#![doc(html_playground_url=...)]`",
"URL",
)
}),
unstable("display-doctest-warnings", |o| {
o.optflagmulti(
"",
"display-doctest-warnings",
"show warnings that originate in doctests",
)
}),
stable("crate-version", |o| {
o.optopt("", "crate-version", "crate version to print into documentation", "VERSION")
}),
unstable("sort-modules-by-appearance", |o| {
o.optflagmulti(
"",
"sort-modules-by-appearance",
"sort modules by where they appear in the program, rather than alphabetically",
)
}),
stable("default-theme", |o| {
o.optopt(
"",
"default-theme",
"Set the default theme. THEME should be the theme name, generally lowercase. \
If an unknown default theme is specified, the builtin default is used. \
The set of themes, and the rustdoc built-in default, are not stable.",
"THEME",
)
}),
unstable("default-setting", |o| {
o.optmulti(
"",
"default-setting",
"Default value for a rustdoc setting (used when \"rustdoc-SETTING\" is absent \
from web browser Local Storage). If VALUE is not supplied, \"true\" is used. \
Supported SETTINGs and VALUEs are not documented and not stable.",
"SETTING[=VALUE]",
)
}),
stable("theme", |o| {
o.optmulti(
"",
"theme",
"additional themes which will be added to the generated docs",
"FILES",
)
}),
stable("check-theme", |o| {
o.optmulti("", "check-theme", "check if given theme is valid", "FILES")
}),
unstable("resource-suffix", |o| {
o.optopt(
"",
"resource-suffix",
"suffix to add to CSS and JavaScript files, e.g., \"search-index.js\" will \
become \"search-index-suffix.js\"",
"PATH",
)
}),
stable("edition", |o| {
o.optopt(
"",
"edition",
"edition to use when compiling rust code (default: 2015)",
"EDITION",
)
}),
stable("color", |o| {
o.optopt(
"",
"color",
"Configure coloring of output:
opt(Stable, Multi, "L", "library-path", "directory to add to crate search path", "DIR"),
opt(Stable, Multi, "", "cfg", "pass a --cfg to rustc", ""),
opt(Stable, Multi, "", "check-cfg", "pass a --check-cfg to rustc", ""),
opt(Stable, Multi, "", "extern", "pass an --extern to rustc", "NAME[=PATH]"),
opt(
Unstable,
Multi,
"",
"extern-html-root-url",
"base URL to use for dependencies; for example, \
\"std=/doc\" links std::vec::Vec to /doc/std/vec/struct.Vec.html",
"NAME=URL",
),
opt(
Unstable,
FlagMulti,
"",
"extern-html-root-takes-precedence",
"give precedence to `--extern-html-root-url`, not `html_root_url`",
"",
),
opt(Stable, Multi, "C", "codegen", "pass a codegen option to rustc", "OPT[=VALUE]"),
opt(Stable, FlagMulti, "", "document-private-items", "document private items", ""),
opt(
Unstable,
FlagMulti,
"",
"document-hidden-items",
"document items that have doc(hidden)",
"",
),
opt(Stable, FlagMulti, "", "test", "run code examples as tests", ""),
opt(Stable, Multi, "", "test-args", "arguments to pass to the test runner", "ARGS"),
opt(
Stable,
Opt,
"",
"test-run-directory",
"The working directory in which to run tests",
"PATH",
),
opt(Stable, Opt, "", "target", "target triple to document", "TRIPLE"),
opt(
Stable,
Multi,
"",
"markdown-css",
"CSS files to include via <link> in a rendered Markdown file",
"FILES",
),
opt(
Stable,
Multi,
"",
"html-in-header",
"files to include inline in the <head> section of a rendered Markdown file \
or generated documentation",
"FILES",
),
opt(
Stable,
Multi,
"",
"html-before-content",
"files to include inline between <body> and the content of a rendered \
Markdown file or generated documentation",
"FILES",
),
opt(
Stable,
Multi,
"",
"html-after-content",
"files to include inline between the content and </body> of a rendered \
Markdown file or generated documentation",
"FILES",
),
opt(
Unstable,
Multi,
"",
"markdown-before-content",
"files to include inline between <body> and the content of a rendered \
Markdown file or generated documentation",
"FILES",
),
opt(
Unstable,
Multi,
"",
"markdown-after-content",
"files to include inline between the content and </body> of a rendered \
Markdown file or generated documentation",
"FILES",
),
opt(Stable, Opt, "", "markdown-playground-url", "URL to send code snippets to", "URL"),
opt(Stable, FlagMulti, "", "markdown-no-toc", "don't include table of contents", ""),
opt(
Stable,
Opt,
"e",
"extend-css",
"To add some CSS rules with a given file to generate doc with your own theme. \
However, your theme might break if the rustdoc's generated HTML changes, so be careful!",
"PATH",
),
opt(
Unstable,
Multi,
"Z",
"",
"unstable / perma-unstable options (only on nightly build)",
"FLAG",
),
opt(Stable, Opt, "", "sysroot", "Override the system root", "PATH"),
opt(
Unstable,
Opt,
"",
"playground-url",
"URL to send code snippets to, may be reset by --markdown-playground-url \
or `#![doc(html_playground_url=...)]`",
"URL",
),
opt(
Unstable,
FlagMulti,
"",
"display-doctest-warnings",
"show warnings that originate in doctests",
"",
),
opt(
Stable,
Opt,
"",
"crate-version",
"crate version to print into documentation",
"VERSION",
),
opt(
Unstable,
FlagMulti,
"",
"sort-modules-by-appearance",
"sort modules by where they appear in the program, rather than alphabetically",
"",
),
opt(
Stable,
Opt,
"",
"default-theme",
"Set the default theme. THEME should be the theme name, generally lowercase. \
If an unknown default theme is specified, the builtin default is used. \
The set of themes, and the rustdoc built-in default, are not stable.",
"THEME",
),
opt(
Unstable,
Multi,
"",
"default-setting",
"Default value for a rustdoc setting (used when \"rustdoc-SETTING\" is absent \
from web browser Local Storage). If VALUE is not supplied, \"true\" is used. \
Supported SETTINGs and VALUEs are not documented and not stable.",
"SETTING[=VALUE]",
),
opt(
Stable,
Multi,
"",
"theme",
"additional themes which will be added to the generated docs",
"FILES",
),
opt(Stable, Multi, "", "check-theme", "check if given theme is valid", "FILES"),
opt(
Unstable,
Opt,
"",
"resource-suffix",
"suffix to add to CSS and JavaScript files, \
e.g., \"search-index.js\" will become \"search-index-suffix.js\"",
"PATH",
),
opt(
Stable,
Opt,
"",
"edition",
"edition to use when compiling rust code (default: 2015)",
"EDITION",
),
opt(
Stable,
Opt,
"",
"color",
"Configure coloring of output:
auto = colorize, if output goes to a tty (default);
always = always colorize output;
never = never colorize output",
"auto|always|never",
)
}),
stable("error-format", |o| {
o.optopt(
"",
"error-format",
"How errors and other messages are produced",
"human|json|short",
)
}),
stable("diagnostic-width", |o| {
o.optopt(
"",
"diagnostic-width",
"Provide width of the output for truncated error messages",
"WIDTH",
)
}),
stable("json", |o| {
o.optopt("", "json", "Configure the structure of JSON diagnostics", "CONFIG")
}),
stable("allow", |o| o.optmulti("A", "allow", "Set lint allowed", "LINT")),
stable("warn", |o| o.optmulti("W", "warn", "Set lint warnings", "LINT")),
stable("force-warn", |o| o.optmulti("", "force-warn", "Set lint force-warn", "LINT")),
stable("deny", |o| o.optmulti("D", "deny", "Set lint denied", "LINT")),
stable("forbid", |o| o.optmulti("F", "forbid", "Set lint forbidden", "LINT")),
stable("cap-lints", |o| {
o.optmulti(
"",
"cap-lints",
"Set the most restrictive lint level. \
More restrictive lints are capped at this \
level. By default, it is at `forbid` level.",
"LEVEL",
)
}),
unstable("index-page", |o| {
o.optopt("", "index-page", "Markdown file to be used as index page", "PATH")
}),
unstable("enable-index-page", |o| {
o.optflagmulti("", "enable-index-page", "To enable generation of the index page")
}),
unstable("static-root-path", |o| {
o.optopt(
"",
"static-root-path",
"Path string to force loading static files from in output pages. \
If not set, uses combinations of '../' to reach the documentation root.",
"PATH",
)
}),
unstable("persist-doctests", |o| {
o.optopt(
"",
"persist-doctests",
"Directory to persist doctest executables into",
"PATH",
)
}),
unstable("show-coverage", |o| {
o.optflagmulti(
"",
"show-coverage",
"calculate percentage of public items with documentation",
)
}),
unstable("enable-per-target-ignores", |o| {
o.optflagmulti(
"",
"enable-per-target-ignores",
"parse ignore-foo for ignoring doctests on a per-target basis",
)
}),
unstable("runtool", |o| {
o.optopt(
"",
"runtool",
"",
"The tool to run tests with when building for a different target than host",
)
}),
unstable("runtool-arg", |o| {
o.optmulti(
"",
"runtool-arg",
"",
"One (of possibly many) arguments to pass to the runtool",
)
}),
unstable("test-builder", |o| {
o.optopt("", "test-builder", "The rustc-like binary to use as the test builder", "PATH")
}),
unstable("test-builder-wrapper", |o| {
o.optmulti(
"",
"test-builder-wrapper",
"Wrapper program to pass test-builder and arguments",
"PATH",
)
}),
unstable("check", |o| o.optflagmulti("", "check", "Run rustdoc checks")),
unstable("generate-redirect-map", |o| {
o.optflagmulti(
"",
"generate-redirect-map",
"Generate JSON file at the top level instead of generating HTML redirection files",
)
}),
unstable("emit", |o| {
o.optmulti(
"",
"emit",
"Comma separated list of types of output for rustdoc to emit",
"[unversioned-shared-resources,toolchain-shared-resources,invocation-specific]",
)
}),
unstable("no-run", |o| {
o.optflagmulti("", "no-run", "Compile doctests without running them")
}),
unstable("remap-path-prefix", |o| {
o.optmulti(
"",
"remap-path-prefix",
"Remap source names in compiler messages",
"FROM=TO",
)
}),
unstable("show-type-layout", |o| {
o.optflagmulti("", "show-type-layout", "Include the memory layout of types in the docs")
}),
unstable("nocapture", |o| {
o.optflag("", "nocapture", "Don't capture stdout and stderr of tests")
}),
unstable("generate-link-to-definition", |o| {
o.optflag(
"",
"generate-link-to-definition",
"Make the identifiers in the HTML source code pages navigable",
)
}),
unstable("scrape-examples-output-path", |o| {
o.optopt(
"",
"scrape-examples-output-path",
"",
"collect function call information and output at the given path",
)
}),
unstable("scrape-examples-target-crate", |o| {
o.optmulti(
"",
"scrape-examples-target-crate",
"",
"collect function call information for functions from the target crate",
)
}),
unstable("scrape-tests", |o| {
o.optflag("", "scrape-tests", "Include test code when scraping examples")
}),
unstable("with-examples", |o| {
o.optmulti(
"",
"with-examples",
"",
"path to function call information (for displaying examples in the documentation)",
)
}),
unstable("merge", |o| {
o.optopt(
"",
"merge",
"Controls how rustdoc handles files from previously documented crates in the doc root
none = Do not write cross-crate information to the --out-dir
shared = Append current crate's info to files found in the --out-dir
finalize = Write current crate's info and --include-parts-dir info to the --out-dir, overwriting conflicting files",
"none|shared|finalize",
)
}),
unstable("parts-out-dir", |o| {
o.optopt(
"",
"parts-out-dir",
"Writes trait implementations and other info for the current crate to provided path. Only use with --merge=none",
"path/to/doc.parts/<crate-name>",
)
}),
unstable("include-parts-dir", |o| {
o.optmulti(
"",
"include-parts-dir",
"Includes trait implementations and other crate info from provided path. Only use with --merge=finalize",
"path/to/doc.parts/<crate-name>",
)
}),
"auto|always|never",
),
opt(
Stable,
Opt,
"",
"error-format",
"How errors and other messages are produced",
"human|json|short",
),
opt(
Stable,
Opt,
"",
"diagnostic-width",
"Provide width of the output for truncated error messages",
"WIDTH",
),
opt(Stable, Opt, "", "json", "Configure the structure of JSON diagnostics", "CONFIG"),
opt(Stable, Multi, "A", "allow", "Set lint allowed", "LINT"),
opt(Stable, Multi, "W", "warn", "Set lint warnings", "LINT"),
opt(Stable, Multi, "", "force-warn", "Set lint force-warn", "LINT"),
opt(Stable, Multi, "D", "deny", "Set lint denied", "LINT"),
opt(Stable, Multi, "F", "forbid", "Set lint forbidden", "LINT"),
opt(
Stable,
Multi,
"",
"cap-lints",
"Set the most restrictive lint level. \
More restrictive lints are capped at this level. \
By default, it is at `forbid` level.",
"LEVEL",
),
opt(Unstable, Opt, "", "index-page", "Markdown file to be used as index page", "PATH"),
opt(
Unstable,
FlagMulti,
"",
"enable-index-page",
"To enable generation of the index page",
"",
),
opt(
Unstable,
Opt,
"",
"static-root-path",
"Path string to force loading static files from in output pages. \
If not set, uses combinations of '../' to reach the documentation root.",
"PATH",
),
opt(
Unstable,
Opt,
"",
"persist-doctests",
"Directory to persist doctest executables into",
"PATH",
),
opt(
Unstable,
FlagMulti,
"",
"show-coverage",
"calculate percentage of public items with documentation",
"",
),
opt(
Unstable,
FlagMulti,
"",
"enable-per-target-ignores",
"parse ignore-foo for ignoring doctests on a per-target basis",
"",
),
opt(
Unstable,
Opt,
"",
"runtool",
"",
"The tool to run tests with when building for a different target than host",
),
opt(
Unstable,
Multi,
"",
"runtool-arg",
"",
"One (of possibly many) arguments to pass to the runtool",
),
opt(
Unstable,
Opt,
"",
"test-builder",
"The rustc-like binary to use as the test builder",
"PATH",
),
opt(
Unstable,
Multi,
"",
"test-builder-wrapper",
"Wrapper program to pass test-builder and arguments",
"PATH",
),
opt(Unstable, FlagMulti, "", "check", "Run rustdoc checks", ""),
opt(
Unstable,
FlagMulti,
"",
"generate-redirect-map",
"Generate JSON file at the top level instead of generating HTML redirection files",
"",
),
opt(
Unstable,
Multi,
"",
"emit",
"Comma separated list of types of output for rustdoc to emit",
"[unversioned-shared-resources,toolchain-shared-resources,invocation-specific]",
),
opt(Unstable, FlagMulti, "", "no-run", "Compile doctests without running them", ""),
opt(
Unstable,
Multi,
"",
"remap-path-prefix",
"Remap source names in compiler messages",
"FROM=TO",
),
opt(
Unstable,
FlagMulti,
"",
"show-type-layout",
"Include the memory layout of types in the docs",
"",
),
opt(Unstable, Flag, "", "nocapture", "Don't capture stdout and stderr of tests", ""),
opt(
Unstable,
Flag,
"",
"generate-link-to-definition",
"Make the identifiers in the HTML source code pages navigable",
"",
),
opt(
Unstable,
Opt,
"",
"scrape-examples-output-path",
"",
"collect function call information and output at the given path",
),
opt(
Unstable,
Multi,
"",
"scrape-examples-target-crate",
"",
"collect function call information for functions from the target crate",
),
opt(Unstable, Flag, "", "scrape-tests", "Include test code when scraping examples", ""),
opt(
Unstable,
Multi,
"",
"with-examples",
"",
"path to function call information (for displaying examples in the documentation)",
),
opt(
Unstable,
Opt,
"",
"merge",
"Controls how rustdoc handles files from previously documented crates in the doc root\n\
none = Do not write cross-crate information to the --out-dir\n\
shared = Append current crate's info to files found in the --out-dir\n\
finalize = Write current crate's info and --include-parts-dir info to the --out-dir, overwriting conflicting files",
"none|shared|finalize",
),
opt(
Unstable,
Opt,
"",
"parts-out-dir",
"Writes trait implementations and other info for the current crate to provided path. Only use with --merge=none",
"path/to/doc.parts/<crate-name>",
),
opt(
Unstable,
Multi,
"",
"include-parts-dir",
"Includes trait implementations and other crate info from provided path. Only use with --merge=finalize",
"path/to/doc.parts/<crate-name>",
),
// deprecated / removed options
unstable("disable-minification", |o| o.optflagmulti("", "disable-minification", "removed")),
stable("plugin-path", |o| {
o.optmulti(
"",
"plugin-path",
"removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> \
for more information",
"DIR",
)
}),
stable("passes", |o| {
o.optmulti(
"",
"passes",
"removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> \
for more information",
"PASSES",
)
}),
stable("plugins", |o| {
o.optmulti(
"",
"plugins",
"removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> \
for more information",
"PLUGINS",
)
}),
stable("no-default", |o| {
o.optflagmulti(
"",
"no-defaults",
"removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> \
for more information",
)
}),
stable("r", |o| {
o.optopt(
"r",
"input-format",
"removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> \
for more information",
"[rust]",
)
}),
unstable("html-no-source", |o| {
o.optflag("", "html-no-source", "Disable HTML source code pages generation")
}),
opt(Unstable, FlagMulti, "", "disable-minification", "removed", ""),
opt(
Stable,
Multi,
"",
"plugin-path",
"removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information",
"DIR",
),
opt(
Stable,
Multi,
"",
"passes",
"removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information",
"PASSES",
),
opt(
Stable,
Multi,
"",
"plugins",
"removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information",
"PLUGINS",
),
opt(
Stable,
FlagMulti,
"",
"no-defaults",
"removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information",
"",
),
opt(
Stable,
Opt,
"r",
"input-format",
"removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information",
"[rust]",
),
opt(Unstable, Flag, "", "html-no-source", "Disable HTML source code pages generation", ""),
]
}
fn usage(argv0: &str) {
let mut options = getopts::Options::new();
for option in opts() {
(option.apply)(&mut options);
option.apply(&mut options);
}
println!("{}", options.usage(&format!("{argv0} [options] <input>")));
println!(" @path Read newline separated options from `path`\n");
@ -769,7 +774,7 @@ fn main_args(
let mut options = getopts::Options::new();
for option in opts() {
(option.apply)(&mut options);
option.apply(&mut options);
}
let matches = match options.parse(&args) {
Ok(m) => m,

View File

@ -41,6 +41,7 @@ pub mod rfs {
pub use object;
pub use regex;
pub use serde_json;
pub use similar;
pub use wasmparser;
// tidy-alphabetical-end

View File

@ -0,0 +1,29 @@
@@ -51,10 +51,27 @@
Set a codegen option
-V, --version Print version info and exit
-v, --verbose Use verbose output
+ --extern NAME[=PATH]
+ Specify where an external rust library is located
+ --sysroot PATH Override the system root
+ --error-format human|json|short
+ How errors and other messages are produced
+ --json CONFIG Configure the JSON output of the compiler
+ --color auto|always|never
+ Configure coloring of output:
+ auto = colorize, if output goes to a tty (default);
+ always = always colorize output;
+ never = never colorize output
+ --diagnostic-width WIDTH
+ Inform rustc of the width of the output so that
+ diagnostics can be truncated to fit
+ --remap-path-prefix FROM=TO
+ Remap source names in all output (compiler messages
+ and output files)
+ @path Read newline separated options from `path`
Additional help:
-C help Print codegen options
-W help Print 'lint' options and default settings
-Z help Print unstable compiler options
- --help -v Print the full set of options rustc accepts

View File

@ -0,0 +1,77 @@
Usage: rustc [OPTIONS] INPUT
Options:
-h, --help Display this message
--cfg SPEC Configure the compilation environment.
SPEC supports the syntax `NAME[="VALUE"]`.
--check-cfg SPEC
Provide list of expected cfgs for checking
-L [KIND=]PATH Add a directory to the library search path. The
optional KIND can be one of dependency, crate, native,
framework, or all (the default).
-l [KIND[:MODIFIERS]=]NAME[:RENAME]
Link the generated crate(s) to the specified native
library NAME. The optional KIND can be one of
static, framework, or dylib (the default).
Optional comma separated MODIFIERS
(bundle|verbatim|whole-archive|as-needed)
may be specified each with a prefix of either '+' to
enable or '-' to disable.
--crate-type [bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]
Comma separated list of types of crates
for the compiler to emit
--crate-name NAME
Specify the name of the crate being built
--edition 2015|2018|2021|2024
Specify which edition of the compiler to use when
compiling code. The default is 2015 and the latest
stable edition is 2021.
--emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]
Comma separated list of types of output for the
compiler to emit
--print [crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|target-list|target-cpus|target-features|relocation-models|code-models|tls-models|target-spec-json|all-target-specs-json|native-static-libs|stack-protector-strategies|link-args|deployment-target]
Compiler information to print on stdout
-g Equivalent to -C debuginfo=2
-O Equivalent to -C opt-level=2
-o FILENAME Write output to <filename>
--out-dir DIR Write output to compiler-chosen filename in <dir>
--explain OPT Provide a detailed explanation of an error message
--test Build a test harness
--target TARGET Target triple for which the code is compiled
-A, --allow LINT Set lint allowed
-W, --warn LINT Set lint warnings
--force-warn LINT
Set lint force-warn
-D, --deny LINT Set lint denied
-F, --forbid LINT Set lint forbidden
--cap-lints LEVEL
Set the most restrictive lint level. More restrictive
lints are capped at this level
-C, --codegen OPT[=VALUE]
Set a codegen option
-V, --version Print version info and exit
-v, --verbose Use verbose output
--extern NAME[=PATH]
Specify where an external rust library is located
--sysroot PATH Override the system root
--error-format human|json|short
How errors and other messages are produced
--json CONFIG Configure the JSON output of the compiler
--color auto|always|never
Configure coloring of output:
auto = colorize, if output goes to a tty (default);
always = always colorize output;
never = never colorize output
--diagnostic-width WIDTH
Inform rustc of the width of the output so that
diagnostics can be truncated to fit
--remap-path-prefix FROM=TO
Remap source names in all output (compiler messages
and output files)
@path Read newline separated options from `path`
Additional help:
-C help Print codegen options
-W help Print 'lint' options and default settings
-Z help Print unstable compiler options

View File

@ -0,0 +1,60 @@
Usage: rustc [OPTIONS] INPUT
Options:
-h, --help Display this message
--cfg SPEC Configure the compilation environment.
SPEC supports the syntax `NAME[="VALUE"]`.
--check-cfg SPEC
Provide list of expected cfgs for checking
-L [KIND=]PATH Add a directory to the library search path. The
optional KIND can be one of dependency, crate, native,
framework, or all (the default).
-l [KIND[:MODIFIERS]=]NAME[:RENAME]
Link the generated crate(s) to the specified native
library NAME. The optional KIND can be one of
static, framework, or dylib (the default).
Optional comma separated MODIFIERS
(bundle|verbatim|whole-archive|as-needed)
may be specified each with a prefix of either '+' to
enable or '-' to disable.
--crate-type [bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]
Comma separated list of types of crates
for the compiler to emit
--crate-name NAME
Specify the name of the crate being built
--edition 2015|2018|2021|2024
Specify which edition of the compiler to use when
compiling code. The default is 2015 and the latest
stable edition is 2021.
--emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]
Comma separated list of types of output for the
compiler to emit
--print [crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|target-list|target-cpus|target-features|relocation-models|code-models|tls-models|target-spec-json|all-target-specs-json|native-static-libs|stack-protector-strategies|link-args|deployment-target]
Compiler information to print on stdout
-g Equivalent to -C debuginfo=2
-O Equivalent to -C opt-level=2
-o FILENAME Write output to <filename>
--out-dir DIR Write output to compiler-chosen filename in <dir>
--explain OPT Provide a detailed explanation of an error message
--test Build a test harness
--target TARGET Target triple for which the code is compiled
-A, --allow LINT Set lint allowed
-W, --warn LINT Set lint warnings
--force-warn LINT
Set lint force-warn
-D, --deny LINT Set lint denied
-F, --forbid LINT Set lint forbidden
--cap-lints LEVEL
Set the most restrictive lint level. More restrictive
lints are capped at this level
-C, --codegen OPT[=VALUE]
Set a codegen option
-V, --version Print version info and exit
-v, --verbose Use verbose output
Additional help:
-C help Print codegen options
-W help Print 'lint' options and default settings
-Z help Print unstable compiler options
--help -v Print the full set of options rustc accepts

View File

@ -0,0 +1,21 @@
// Tests `rustc --help` and similar invocations against snapshots and each other.
use run_make_support::{bare_rustc, diff, similar};
fn main() {
// `rustc --help`
let help = bare_rustc().arg("--help").run().stdout_utf8();
diff().expected_file("help.stdout").actual_text("(rustc --help)", &help).run();
// `rustc` should be the same as `rustc --help`
let bare = bare_rustc().run().stdout_utf8();
diff().expected_text("(rustc --help)", &help).actual_text("(rustc)", &bare).run();
// `rustc --help -v` should give a similar but longer help message
let help_v = bare_rustc().arg("--help").arg("-v").run().stdout_utf8();
diff().expected_file("help-v.stdout").actual_text("(rustc --help -v)", &help_v).run();
// Check the diff between `rustc --help` and `rustc --help -v`.
let help_v_diff = similar::TextDiff::from_lines(&help, &help_v).unified_diff().to_string();
diff().expected_file("help-v.diff").actual_text("actual", &help_v_diff).run();
}

View File

@ -0,0 +1,78 @@
//@ compile-flags: -Z unstable-options --document-hidden-items --document-private-items
// regression test for https://github.com/rust-lang/rust/issues/90781
#![crate_name = "foo"]
//@ has foo/trait.TPubVis.html
//@ has - '//*[@id="implementors-list"]' 'HidPriv'
//@ has - '//*[@id="implementors-list"]' 'HidPub'
//@ has - '//*[@id="implementors-list"]' 'VisPriv'
//@ has - '//*[@id="implementors-list"]' 'VisPub'
pub trait TPubVis {}
//@ has foo/trait.TPubHidden.html
//@ has - '//*[@id="implementors-list"]' 'HidPriv'
//@ has - '//*[@id="implementors-list"]' 'HidPub'
//@ has - '//*[@id="implementors-list"]' 'VisPriv'
//@ has - '//*[@id="implementors-list"]' 'VisPub'
#[doc(hidden)]
pub trait TPubHidden {}
//@ has foo/trait.TPrivVis.html
//@ has - '//*[@id="implementors-list"]' 'HidPriv'
//@ has - '//*[@id="implementors-list"]' 'HidPub'
//@ has - '//*[@id="implementors-list"]' 'VisPriv'
//@ has - '//*[@id="implementors-list"]' 'VisPub'
trait TPrivVis {}
#[doc(hidden)]
//@ has foo/trait.TPrivHidden.html
//@ has - '//*[@id="impl-TPrivHidden-for-HidPriv"]' 'HidPriv'
//@ has - '//*[@id="impl-TPrivHidden-for-HidPub"]' 'HidPub'
//@ has - '//*[@id="impl-TPrivHidden-for-VisPriv"]' 'VisPriv'
//@ has - '//*[@id="impl-TPrivHidden-for-VisPub"]' 'VisPub'
trait TPrivHidden {}
//@ has foo/struct.VisPub.html
//@ has - '//*[@id="trait-implementations-list"]' 'TPrivHidden'
//@ has - '//*[@id="trait-implementations-list"]' 'TPrivVis'
//@ has - '//*[@id="trait-implementations-list"]' 'TPubHidden'
//@ has - '//*[@id="trait-implementations-list"]' 'TPubVis'
pub struct VisPub;
//@ has foo/struct.VisPriv.html
//@ has - '//*[@id="trait-implementations-list"]' 'TPrivHidden'
//@ has - '//*[@id="trait-implementations-list"]' 'TPrivVis'
//@ has - '//*[@id="trait-implementations-list"]' 'TPubHidden'
//@ has - '//*[@id="trait-implementations-list"]' 'TPubVis'
struct VisPriv;
//@ has foo/struct.HidPub.html
//@ has - '//*[@id="trait-implementations-list"]' 'TPrivHidden'
//@ has - '//*[@id="trait-implementations-list"]' 'TPrivVis'
//@ has - '//*[@id="trait-implementations-list"]' 'TPubHidden'
//@ has - '//*[@id="trait-implementations-list"]' 'TPubVis'
#[doc(hidden)]
pub struct HidPub;
//@ has foo/struct.HidPriv.html
//@ has - '//*[@id="trait-implementations-list"]' 'TPrivHidden'
//@ has - '//*[@id="trait-implementations-list"]' 'TPrivVis'
//@ has - '//*[@id="trait-implementations-list"]' 'TPubHidden'
//@ has - '//*[@id="trait-implementations-list"]' 'TPubVis'
#[doc(hidden)]
struct HidPriv;
macro_rules! implement {
($trait:ident - $($struct:ident)+) => {
$(
impl $trait for $struct {}
)+
}
}
implement!(TPubVis - VisPub VisPriv HidPub HidPriv);
implement!(TPubHidden - VisPub VisPriv HidPub HidPriv);
implement!(TPrivVis - VisPub VisPriv HidPub HidPriv);
implement!(TPrivHidden - VisPub VisPriv HidPub HidPriv);

View File

@ -0,0 +1,14 @@
//@ edition: 2021
// Make sure we reject the case where a raw lifetime is immediately followed by another
// lifetime. This reserves a modest amount of space for changing lexing to, for example,
// delay rejection of overlong char literals like `'r#long'id`.
macro_rules! w {
($($tt:tt)*) => {}
}
w!('r#long'id);
//~^ ERROR character literal may only contain one codepoint
fn main() {}

View File

@ -0,0 +1,13 @@
error: character literal may only contain one codepoint
--> $DIR/immediately-followed-by-lt.rs:11:4
|
LL | w!('r#long'id);
| ^^^^^^^^
|
help: if you meant to write a string literal, use double quotes
|
LL | w!("r#long"id);
| ~ ~
error: aborting due to 1 previous error

View File

@ -0,0 +1,20 @@
//@ edition: 2021
// Reject raw lifetimes with identifier parts that wouldn't be valid raw identifiers.
macro_rules! w {
($tt:tt) => {};
}
w!('r#_);
//~^ ERROR `_` cannot be a raw lifetime
w!('r#self);
//~^ ERROR `self` cannot be a raw lifetime
w!('r#super);
//~^ ERROR `super` cannot be a raw lifetime
w!('r#Self);
//~^ ERROR `Self` cannot be a raw lifetime
w!('r#crate);
//~^ ERROR `crate` cannot be a raw lifetime
fn main() {}

View File

@ -0,0 +1,32 @@
error: `_` cannot be a raw lifetime
--> $DIR/raw-lt-invalid-raw-id.rs:9:4
|
LL | w!('r#_);
| ^^^^
error: `self` cannot be a raw lifetime
--> $DIR/raw-lt-invalid-raw-id.rs:11:4
|
LL | w!('r#self);
| ^^^^^^^
error: `super` cannot be a raw lifetime
--> $DIR/raw-lt-invalid-raw-id.rs:13:4
|
LL | w!('r#super);
| ^^^^^^^^
error: `Self` cannot be a raw lifetime
--> $DIR/raw-lt-invalid-raw-id.rs:15:4
|
LL | w!('r#Self);
| ^^^^^^^
error: `crate` cannot be a raw lifetime
--> $DIR/raw-lt-invalid-raw-id.rs:17:4
|
LL | w!('r#crate);
| ^^^^^^^^
error: aborting due to 5 previous errors

View File

@ -1,10 +1,14 @@
#![allow(non_camel_case_types)]
struct bool;
struct str;
fn foo(_: bool) {}
fn bar(_: &str) {}
fn main() {
foo(true);
//~^ ERROR mismatched types [E0308]
bar("hello");
//~^ ERROR mismatched types [E0308]
}

View File

@ -1,5 +1,5 @@
error[E0308]: mismatched types
--> $DIR/similar_paths_primitive.rs:8:9
--> $DIR/similar_paths_primitive.rs:10:9
|
LL | foo(true);
| --- ^^^^ expected `bool`, found a different `bool`
@ -14,11 +14,32 @@ note: `bool` is defined in the current crate
LL | struct bool;
| ^^^^^^^^^^^
note: function defined here
--> $DIR/similar_paths_primitive.rs:5:4
--> $DIR/similar_paths_primitive.rs:6:4
|
LL | fn foo(_: bool) {}
| ^^^ -------
error: aborting due to 1 previous error
error[E0308]: mismatched types
--> $DIR/similar_paths_primitive.rs:12:9
|
LL | bar("hello");
| --- ^^^^^^^ expected `str`, found a different `str`
| |
| arguments to this function are incorrect
|
= note: str and `str` have similar names, but are actually distinct types
= note: str is a primitive defined by the language
note: `str` is defined in the current crate
--> $DIR/similar_paths_primitive.rs:4:1
|
LL | struct str;
| ^^^^^^^^^^
note: function defined here
--> $DIR/similar_paths_primitive.rs:7:4
|
LL | fn bar(_: &str) {}
| ^^^ -------
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.