@@ -12,7 +12,7 @@ use std::hash::Hash;
1212use std:: path:: { Path , PathBuf } ;
1313use std:: str:: { self , FromStr } ;
1414use std:: sync:: LazyLock ;
15- use std:: { fmt, fs, iter} ;
15+ use std:: { cmp , fmt, fs, iter} ;
1616
1717use rustc_data_structures:: fx:: { FxHashSet , FxIndexMap } ;
1818use 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+
13751400pub 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.
14701474pub 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.
15601573pub 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
27622790pub 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