diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 44007974a158b..f517c483758d2 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -685,10 +685,10 @@ impl Default for Options { target_triple: TargetTriple::from_triple(host_triple()), test: false, incremental: None, - debugging_opts: basic_debugging_options(), + debugging_opts: Default::default(), prints: Vec::new(), borrowck_mode: BorrowckMode::Migrate, - cg: basic_codegen_options(), + cg: Default::default(), error_format: ErrorOutputType::default(), externs: Externs(BTreeMap::new()), extern_dep_specs: ExternDepSpecs(BTreeMap::new()), @@ -1925,7 +1925,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); - let mut debugging_opts = build_debugging_options(matches, error_format); + let mut debugging_opts = DebuggingOptions::build(matches, error_format); check_debug_option_stability(&debugging_opts, error_format, json_rendered); if !debugging_opts.unstable_options && json_unused_externs { @@ -1938,7 +1938,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let output_types = parse_output_types(&debugging_opts, matches, error_format); - let mut cg = build_codegen_options(matches, error_format); + let mut cg = CodegenOptions::build(matches, error_format); let (disable_thinlto, mut codegen_units) = should_override_cgus_and_disable_thinlto( &output_types, matches, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index da6e2af276053..10e195f4f2548 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -210,9 +210,7 @@ top_level_options!( /// generated code to parse an option into its respective field in the struct. There are a few /// hand-written parsers for parsing specific types of values in this module. macro_rules! options { - ($struct_name:ident, $setter_name:ident, $defaultfn:ident, - $buildfn:ident, $prefix:expr, $outputname:expr, - $stat:ident, + ($struct_name:ident, $stat:ident, $prefix:expr, $outputname:expr, $($( #[$attr:meta] )* $opt:ident : $t:ty = ( $init:expr, $parse:ident, @@ -223,50 +221,20 @@ macro_rules! options { #[derive(Clone)] pub struct $struct_name { $(pub $opt: $t),* } - pub fn $defaultfn() -> $struct_name { - $struct_name { $( $( #[$attr] )* $opt: $init),* } - } - - pub fn $buildfn(matches: &getopts::Matches, error_format: ErrorOutputType) -> $struct_name - { - let mut op = $defaultfn(); - for option in matches.opt_strs($prefix) { - let (key, value) = match option.split_once('=') { - None => (option, None), - Some((k, v)) => (k.to_string(), Some(v)), - }; - let option_to_lookup = key.replace("-", "_"); - let mut found = false; - for &(candidate, setter, type_desc, _) in $stat { - if option_to_lookup != candidate { continue } - if !setter(&mut op, value) { - match value { - None => { - early_error(error_format, &format!("{0} option `{1}` requires \ - {2} ({3} {1}=)", - $outputname, key, - type_desc, $prefix)) - } - Some(value) => { - early_error(error_format, &format!("incorrect value `{}` for {} \ - option `{}` - {} was expected", - value, $outputname, - key, type_desc)) - } - } - } - found = true; - break; - } - if !found { - early_error(error_format, &format!("unknown {} option: `{}`", - $outputname, key)); - } + impl Default for $struct_name { + fn default() -> $struct_name { + $struct_name { $( $( #[$attr] )* $opt: $init),* } } - return op; } impl $struct_name { + pub fn build( + matches: &getopts::Matches, + error_format: ErrorOutputType, + ) -> $struct_name { + build_options(matches, $stat, $prefix, $outputname, error_format) + } + fn dep_tracking_hash(&self, _for_crate_hash: bool, error_format: ErrorOutputType) -> u64 { let mut sub_hashes = BTreeMap::new(); $({ @@ -284,26 +252,76 @@ macro_rules! options { } } - pub type $setter_name = fn(&mut $struct_name, v: Option<&str>) -> bool; - pub const $stat: &[(&str, $setter_name, &str, &str)] = - &[ $( (stringify!($opt), $crate::options::parse::$opt, $crate::options::desc::$parse, $desc) ),* ]; - - // Sometimes different options need to build a common structure. - // That structure can kept in one of the options' fields, the others become dummy. - macro_rules! redirect_field { - ($cg:ident.link_arg) => { $cg.link_args }; - ($cg:ident.pre_link_arg) => { $cg.pre_link_args }; - ($cg:ident.$field:ident) => { $cg.$field }; - } + pub const $stat: OptionDescrs<$struct_name> = + &[ $( (stringify!($opt), $opt, desc::$parse, $desc) ),* ]; $( - pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool { - $crate::options::parse::$parse(&mut redirect_field!(cg.$opt), v) + fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool { + parse::$parse(&mut redirect_field!(cg.$opt), v) } )* ) } +// Sometimes different options need to build a common structure. +// That structure can be kept in one of the options' fields, the others become dummy. +macro_rules! redirect_field { + ($cg:ident.link_arg) => { + $cg.link_args + }; + ($cg:ident.pre_link_arg) => { + $cg.pre_link_args + }; + ($cg:ident.$field:ident) => { + $cg.$field + }; +} + +type OptionSetter = fn(&mut O, v: Option<&str>) -> bool; +type OptionDescrs = &'static [(&'static str, OptionSetter, &'static str, &'static str)]; + +fn build_options( + matches: &getopts::Matches, + descrs: OptionDescrs, + prefix: &str, + outputname: &str, + error_format: ErrorOutputType, +) -> O { + let mut op = O::default(); + for option in matches.opt_strs(prefix) { + let (key, value) = match option.split_once('=') { + None => (option, None), + Some((k, v)) => (k.to_string(), Some(v)), + }; + + let option_to_lookup = key.replace("-", "_"); + match descrs.iter().find(|(name, ..)| *name == option_to_lookup) { + Some((_, setter, type_desc, _)) => { + if !setter(&mut op, value) { + match value { + None => early_error( + error_format, + &format!( + "{0} option `{1}` requires {2} ({3} {1}=)", + outputname, key, type_desc, prefix + ), + ), + Some(value) => early_error( + error_format, + &format!( + "incorrect value `{}` for {} option `{}` - {} was expected", + value, outputname, key, type_desc + ), + ), + } + } + } + None => early_error(error_format, &format!("unknown {} option: `{}`", outputname, key)), + } + } + return op; +} + #[allow(non_upper_case_globals)] mod desc { pub const parse_no_flag: &str = "no value"; @@ -847,9 +865,8 @@ mod parse { } } -options! {CodegenOptions, CodegenSetter, basic_codegen_options, - build_codegen_options, "C", "codegen", - CG_OPTIONS, +options! { + CodegenOptions, CG_OPTIONS, "C", "codegen", // This list is in alphabetical order. // @@ -957,9 +974,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, // - src/doc/rustc/src/codegen-options/index.md } -options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, - build_debugging_options, "Z", "debugging", - DB_OPTIONS, +options! { + DebuggingOptions, DB_OPTIONS, "Z", "debugging", // This list is in alphabetical order. // diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 48eb14ed29147..045b42d0dcaf7 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -7,10 +7,7 @@ use std::str::FromStr; use rustc_data_structures::fx::FxHashMap; use rustc_session::config::{self, parse_crate_types_from_list, parse_externs, CrateType}; -use rustc_session::config::{ - build_codegen_options, build_debugging_options, get_cmd_lint_options, host_triple, - nightly_options, -}; +use rustc_session::config::{get_cmd_lint_options, host_triple, nightly_options}; use rustc_session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs}; use rustc_session::getopts; use rustc_session::lint::Level; @@ -360,8 +357,8 @@ impl Options { config::parse_json(&matches); let error_format = config::parse_error_format(&matches, color, json_rendered); - let codegen_options = build_codegen_options(matches, error_format); - let debugging_opts = build_debugging_options(matches, error_format); + let codegen_options = CodegenOptions::build(matches, error_format); + let debugging_opts = DebuggingOptions::build(matches, error_format); let diag = new_handler(error_format, None, &debugging_opts); diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index e563889f776e5..03e3fe52f71ee 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -76,7 +76,6 @@ crate fn run(options: Options) -> Result<(), ErrorReported> { externs: options.externs.clone(), unstable_features: options.render_options.unstable_features, actually_rustdoc: true, - debugging_opts: config::DebuggingOptions { ..config::basic_debugging_options() }, edition: options.edition, target_triple: options.target.clone(), crate_name: options.crate_name.clone(),