Skip to content

Commit 001013c

Browse files
committed
Simplify command-line-option declarations in the compiler
1 parent 584c820 commit 001013c

File tree

1 file changed

+147
-117
lines changed

1 file changed

+147
-117
lines changed

Diff for: compiler/rustc_session/src/config.rs

+147-117
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::hash::Hash;
1212
use std::path::{Path, PathBuf};
1313
use std::str::{self, FromStr};
1414
use std::sync::LazyLock;
15-
use std::{fmt, fs, iter};
15+
use std::{cmp, fmt, fs, iter};
1616

1717
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
1818
use rustc_data_structures::stable_hasher::{StableOrd, ToStableHashKey};
@@ -1367,11 +1367,36 @@ pub fn build_target_config(early_dcx: &EarlyDiagCtxt, opts: &Options, sysroot: &
13671367
}
13681368

13691369
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
1370-
enum OptionStability {
1370+
pub enum OptionStability {
13711371
Stable,
13721372
Unstable,
13731373
}
13741374

1375+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
1376+
pub enum OptionKind {
1377+
/// An option that takes a value, and cannot appear more than once (e.g. `--out-dir`).
1378+
///
1379+
/// Corresponds to [`getopts::Options::optopt`].
1380+
Opt,
1381+
1382+
/// An option that takes a value, and can appear multiple times (e.g. `--emit`).
1383+
///
1384+
/// Corresponds to [`getopts::Options::optmulti`].
1385+
Multi,
1386+
1387+
/// An option that does not take a value, and cannot appear more than once (e.g. `--help`).
1388+
///
1389+
/// Corresponds to [`getopts::Options::optflag`].
1390+
/// The `hint` string must be empty.
1391+
Flag,
1392+
1393+
/// An option that does not take a value, and can appear multiple times (e.g. `-O`).
1394+
///
1395+
/// Corresponds to [`getopts::Options::optflagmulti`].
1396+
/// The `hint` string must be empty.
1397+
FlagMulti,
1398+
}
1399+
13751400
pub struct RustcOptGroup {
13761401
apply: Box<dyn Fn(&mut getopts::Options) -> &mut getopts::Options>,
13771402
pub name: &'static str,
@@ -1402,58 +1427,37 @@ impl RustcOptGroup {
14021427
}
14031428
}
14041429

1405-
// The `opt` local module holds wrappers around the `getopts` API that
1406-
// adds extra rustc-specific metadata to each option; such metadata
1407-
// is exposed by . The public
1408-
// functions below ending with `_u` are the functions that return
1409-
// *unstable* options, i.e., options that are only enabled when the
1410-
// user also passes the `-Z unstable-options` debugging flag.
1411-
mod opt {
1412-
// The `fn flag*` etc below are written so that we can use them
1413-
// in the future; do not warn about them not being used right now.
1414-
#![allow(dead_code)]
1415-
1416-
use super::RustcOptGroup;
1417-
1418-
type R = RustcOptGroup;
1419-
type S = &'static str;
1420-
1421-
fn stable<F>(name: S, f: F) -> R
1422-
where
1423-
F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static,
1424-
{
1425-
RustcOptGroup::stable(name, f)
1426-
}
1427-
1428-
fn unstable<F>(name: S, f: F) -> R
1429-
where
1430-
F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static,
1431-
{
1432-
RustcOptGroup::unstable(name, f)
1433-
}
1434-
1435-
fn longer(a: S, b: S) -> S {
1436-
if a.len() > b.len() { a } else { b }
1437-
}
1438-
1439-
pub(crate) fn opt_s(a: S, b: S, c: S, d: S) -> R {
1440-
stable(longer(a, b), move |opts| opts.optopt(a, b, c, d))
1441-
}
1442-
pub(crate) fn multi_s(a: S, b: S, c: S, d: S) -> R {
1443-
stable(longer(a, b), move |opts| opts.optmulti(a, b, c, d))
1444-
}
1445-
pub(crate) fn flag_s(a: S, b: S, c: S) -> R {
1446-
stable(longer(a, b), move |opts| opts.optflag(a, b, c))
1447-
}
1448-
pub(crate) fn flagmulti_s(a: S, b: S, c: S) -> R {
1449-
stable(longer(a, b), move |opts| opts.optflagmulti(a, b, c))
1450-
}
1451-
1452-
fn opt(a: S, b: S, c: S, d: S) -> R {
1453-
unstable(longer(a, b), move |opts| opts.optopt(a, b, c, d))
1454-
}
1455-
pub(crate) fn multi(a: S, b: S, c: S, d: S) -> R {
1456-
unstable(longer(a, b), move |opts| opts.optmulti(a, b, c, d))
1430+
pub fn make_opt(
1431+
stability: OptionStability,
1432+
kind: OptionKind,
1433+
short_name: &'static str,
1434+
long_name: &'static str,
1435+
desc: &'static str,
1436+
hint: &'static str,
1437+
) -> RustcOptGroup {
1438+
RustcOptGroup {
1439+
name: cmp::max_by_key(short_name, long_name, |s| s.len()),
1440+
stability,
1441+
apply: match kind {
1442+
OptionKind::Opt => Box::new(move |opts: &mut getopts::Options| {
1443+
opts.optopt(short_name, long_name, desc, hint)
1444+
}),
1445+
OptionKind::Multi => Box::new(move |opts: &mut getopts::Options| {
1446+
opts.optmulti(short_name, long_name, desc, hint)
1447+
}),
1448+
OptionKind::Flag => {
1449+
assert_eq!(hint, "");
1450+
Box::new(move |opts: &mut getopts::Options| {
1451+
opts.optflag(short_name, long_name, desc)
1452+
})
1453+
}
1454+
OptionKind::FlagMulti => {
1455+
assert_eq!(hint, "");
1456+
Box::new(move |opts: &mut getopts::Options| {
1457+
opts.optflagmulti(short_name, long_name, desc)
1458+
})
1459+
}
1460+
},
14571461
}
14581462
}
14591463

@@ -1468,46 +1472,60 @@ The default is {DEFAULT_EDITION} and the latest stable edition is {LATEST_STABLE
14681472
/// including metadata for each option, such as whether the option is
14691473
/// part of the stable long-term interface for rustc.
14701474
pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
1475+
use OptionKind::{Flag, FlagMulti, Multi, Opt};
1476+
use OptionStability::Stable;
1477+
1478+
use self::make_opt as opt;
1479+
14711480
vec![
1472-
opt::flag_s("h", "help", "Display this message"),
1473-
opt::multi_s("", "cfg", "Configure the compilation environment.
1474-
SPEC supports the syntax `NAME[=\"VALUE\"]`.", "SPEC"),
1475-
opt::multi_s("", "check-cfg", "Provide list of expected cfgs for checking", "SPEC"),
1476-
opt::multi_s(
1481+
opt(Stable, Flag, "h", "help", "Display this message", ""),
1482+
opt(
1483+
Stable,
1484+
Multi,
1485+
"",
1486+
"cfg",
1487+
"Configure the compilation environment.\n\
1488+
SPEC supports the syntax `NAME[=\"VALUE\"]`.",
1489+
"SPEC",
1490+
),
1491+
opt(Stable, Multi, "", "check-cfg", "Provide list of expected cfgs for checking", "SPEC"),
1492+
opt(
1493+
Stable,
1494+
Multi,
14771495
"L",
14781496
"",
1479-
"Add a directory to the library search path. The
1480-
optional KIND can be one of dependency, crate, native,
1481-
framework, or all (the default).",
1497+
"Add a directory to the library search path. \
1498+
The optional KIND can be one of dependency, crate, native, framework, or all (the default).",
14821499
"[KIND=]PATH",
14831500
),
1484-
opt::multi_s(
1501+
opt(
1502+
Stable,
1503+
Multi,
14851504
"l",
14861505
"",
1487-
"Link the generated crate(s) to the specified native
1488-
library NAME. The optional KIND can be one of
1489-
static, framework, or dylib (the default).
1490-
Optional comma separated MODIFIERS (bundle|verbatim|whole-archive|as-needed)
1491-
may be specified each with a prefix of either '+' to
1492-
enable or '-' to disable.",
1506+
"Link the generated crate(s) to the specified native\n\
1507+
library NAME. The optional KIND can be one of\n\
1508+
static, framework, or dylib (the default).\n\
1509+
Optional comma separated MODIFIERS\n\
1510+
(bundle|verbatim|whole-archive|as-needed)\n\
1511+
may be specified each with a prefix of either '+' to\n\
1512+
enable or '-' to disable.",
14931513
"[KIND[:MODIFIERS]=]NAME[:RENAME]",
14941514
),
14951515
make_crate_type_option(),
1496-
opt::opt_s("", "crate-name", "Specify the name of the crate being built", "NAME"),
1497-
opt::opt_s(
1498-
"",
1499-
"edition",
1500-
&EDITION_STRING,
1501-
EDITION_NAME_LIST,
1502-
),
1503-
opt::multi_s(
1516+
opt(Stable, Opt, "", "crate-name", "Specify the name of the crate being built", "NAME"),
1517+
opt(Stable, Opt, "", "edition", &EDITION_STRING, EDITION_NAME_LIST),
1518+
opt(
1519+
Stable,
1520+
Multi,
15041521
"",
15051522
"emit",
1506-
"Comma separated list of types of output for \
1507-
the compiler to emit",
1523+
"Comma separated list of types of output for the compiler to emit",
15081524
"[asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]",
15091525
),
1510-
opt::multi_s(
1526+
opt(
1527+
Stable,
1528+
Multi,
15111529
"",
15121530
"print",
15131531
"Compiler information to print on stdout",
@@ -1516,67 +1534,73 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
15161534
tls-models|target-spec-json|all-target-specs-json|native-static-libs|\
15171535
stack-protector-strategies|link-args|deployment-target]",
15181536
),
1519-
opt::flagmulti_s("g", "", "Equivalent to -C debuginfo=2"),
1520-
opt::flagmulti_s("O", "", "Equivalent to -C opt-level=2"),
1521-
opt::opt_s("o", "", "Write output to <filename>", "FILENAME"),
1522-
opt::opt_s(
1523-
"",
1524-
"out-dir",
1525-
"Write output to compiler-chosen filename \
1526-
in <dir>",
1527-
"DIR",
1528-
),
1529-
opt::opt_s(
1537+
opt(Stable, FlagMulti, "g", "", "Equivalent to -C debuginfo=2", ""),
1538+
opt(Stable, FlagMulti, "O", "", "Equivalent to -C opt-level=2", ""),
1539+
opt(Stable, Opt, "o", "", "Write output to <filename>", "FILENAME"),
1540+
opt(Stable, Opt, "", "out-dir", "Write output to compiler-chosen filename in <dir>", "DIR"),
1541+
opt(
1542+
Stable,
1543+
Opt,
15301544
"",
15311545
"explain",
1532-
"Provide a detailed explanation of an error \
1533-
message",
1546+
"Provide a detailed explanation of an error message",
15341547
"OPT",
15351548
),
1536-
opt::flag_s("", "test", "Build a test harness"),
1537-
opt::opt_s("", "target", "Target triple for which the code is compiled", "TARGET"),
1538-
opt::multi_s("A", "allow", "Set lint allowed", "LINT"),
1539-
opt::multi_s("W", "warn", "Set lint warnings", "LINT"),
1540-
opt::multi_s("", "force-warn", "Set lint force-warn", "LINT"),
1541-
opt::multi_s("D", "deny", "Set lint denied", "LINT"),
1542-
opt::multi_s("F", "forbid", "Set lint forbidden", "LINT"),
1543-
opt::multi_s(
1549+
opt(Stable, Flag, "", "test", "Build a test harness", ""),
1550+
opt(Stable, Opt, "", "target", "Target triple for which the code is compiled", "TARGET"),
1551+
opt(Stable, Multi, "A", "allow", "Set lint allowed", "LINT"),
1552+
opt(Stable, Multi, "W", "warn", "Set lint warnings", "LINT"),
1553+
opt(Stable, Multi, "", "force-warn", "Set lint force-warn", "LINT"),
1554+
opt(Stable, Multi, "D", "deny", "Set lint denied", "LINT"),
1555+
opt(Stable, Multi, "F", "forbid", "Set lint forbidden", "LINT"),
1556+
opt(
1557+
Stable,
1558+
Multi,
15441559
"",
15451560
"cap-lints",
1546-
"Set the most restrictive lint level. \
1547-
More restrictive lints are capped at this \
1548-
level",
1561+
"Set the most restrictive lint level. More restrictive lints are capped at this level",
15491562
"LEVEL",
15501563
),
1551-
opt::multi_s("C", "codegen", "Set a codegen option", "OPT[=VALUE]"),
1552-
opt::flag_s("V", "version", "Print version info and exit"),
1553-
opt::flag_s("v", "verbose", "Use verbose output"),
1564+
opt(Stable, Multi, "C", "codegen", "Set a codegen option", "OPT[=VALUE]"),
1565+
opt(Stable, Flag, "V", "version", "Print version info and exit", ""),
1566+
opt(Stable, Flag, "v", "verbose", "Use verbose output", ""),
15541567
]
15551568
}
15561569

15571570
/// Returns all rustc command line options, including metadata for
15581571
/// each option, such as whether the option is part of the stable
15591572
/// long-term interface for rustc.
15601573
pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
1574+
use OptionKind::{Multi, Opt};
1575+
use OptionStability::{Stable, Unstable};
1576+
1577+
use self::make_opt as opt;
1578+
15611579
let mut opts = rustc_short_optgroups();
15621580
// FIXME: none of these descriptions are actually used
15631581
opts.extend(vec![
1564-
opt::multi_s(
1582+
opt(
1583+
Stable,
1584+
Multi,
15651585
"",
15661586
"extern",
15671587
"Specify where an external rust library is located",
15681588
"NAME[=PATH]",
15691589
),
1570-
opt::opt_s("", "sysroot", "Override the system root", "PATH"),
1571-
opt::multi("Z", "", "Set unstable / perma-unstable options", "FLAG"),
1572-
opt::opt_s(
1590+
opt(Stable, Opt, "", "sysroot", "Override the system root", "PATH"),
1591+
opt(Unstable, Multi, "Z", "", "Set unstable / perma-unstable options", "FLAG"),
1592+
opt(
1593+
Stable,
1594+
Opt,
15731595
"",
15741596
"error-format",
15751597
"How errors and other messages are produced",
15761598
"human|json|short",
15771599
),
1578-
opt::multi_s("", "json", "Configure the JSON output of the compiler", "CONFIG"),
1579-
opt::opt_s(
1600+
opt(Stable, Multi, "", "json", "Configure the JSON output of the compiler", "CONFIG"),
1601+
opt(
1602+
Stable,
1603+
Opt,
15801604
"",
15811605
"color",
15821606
"Configure coloring of output:
@@ -1585,19 +1609,23 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
15851609
never = never colorize output",
15861610
"auto|always|never",
15871611
),
1588-
opt::opt_s(
1612+
opt(
1613+
Stable,
1614+
Opt,
15891615
"",
15901616
"diagnostic-width",
15911617
"Inform rustc of the width of the output so that diagnostics can be truncated to fit",
15921618
"WIDTH",
15931619
),
1594-
opt::multi_s(
1620+
opt(
1621+
Stable,
1622+
Multi,
15951623
"",
15961624
"remap-path-prefix",
15971625
"Remap source names in all output (compiler messages and output files)",
15981626
"FROM=TO",
15991627
),
1600-
opt::multi("", "env-set", "Inject an environment variable", "VAR=VALUE"),
1628+
opt(Unstable, Multi, "", "env-set", "Inject an environment variable", "VAR=VALUE"),
16011629
]);
16021630
opts
16031631
}
@@ -2760,7 +2788,9 @@ fn parse_pretty(early_dcx: &EarlyDiagCtxt, unstable_opts: &UnstableOptions) -> O
27602788
}
27612789

27622790
pub fn make_crate_type_option() -> RustcOptGroup {
2763-
opt::multi_s(
2791+
make_opt(
2792+
OptionStability::Stable,
2793+
OptionKind::Multi,
27642794
"",
27652795
"crate-type",
27662796
"Comma separated list of types of crates

0 commit comments

Comments
 (0)