about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-05-10 12:26:46 +0000
committerbors <bors@rust-lang.org>2021-05-10 12:26:46 +0000
commit544d124b81fb54e1904b6cd53de9bf92b6b3d0b9 (patch)
tree0585f66ff0048606106ac857dfef46185c6eedc0
parent1b30245ea1286df96d673015c4519c861e06977a (diff)
parent273e0a2a051526b98b989a52405d9b6a626e0cad (diff)
downloadrust-544d124b81fb54e1904b6cd53de9bf92b6b3d0b9.tar.gz
rust-544d124b81fb54e1904b6cd53de9bf92b6b3d0b9.zip
Auto merge of #85079 - petrochenkov:sessclean, r=davidtwco
rustc_session: Move more option building code from the `options!` macro

The moved code doesn't need to be generated by a macro, it can use a regular (generic) function and type aliases instead.

(The refactoring is salvaged from a branch with different now abandoned work.)
-rw-r--r--compiler/rustc_session/src/config.rs8
-rw-r--r--compiler/rustc_session/src/options.rs140
-rw-r--r--src/librustdoc/config.rs9
-rw-r--r--src/librustdoc/doctest.rs1
4 files changed, 85 insertions, 73 deletions
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 44007974a15..f517c483758 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 da6e2af2760..10e195f4f25 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}=<value>)",
-                                                               $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<O> = fn(&mut O, v: Option<&str>) -> bool;
+type OptionDescrs<O> = &'static [(&'static str, OptionSetter<O>, &'static str, &'static str)];
+
+fn build_options<O: Default>(
+    matches: &getopts::Matches,
+    descrs: OptionDescrs<O>,
+    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}=<value>)",
+                                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 48eb14ed291..045b42d0dca 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 e563889f776..03e3fe52f71 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(),