Skip to content

Commit 544d124

Browse files
committed
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.)
2 parents 1b30245 + 273e0a2 commit 544d124

File tree

4 files changed

+85
-73
lines changed

4 files changed

+85
-73
lines changed

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -685,10 +685,10 @@ impl Default for Options {
685685
target_triple: TargetTriple::from_triple(host_triple()),
686686
test: false,
687687
incremental: None,
688-
debugging_opts: basic_debugging_options(),
688+
debugging_opts: Default::default(),
689689
prints: Vec::new(),
690690
borrowck_mode: BorrowckMode::Migrate,
691-
cg: basic_codegen_options(),
691+
cg: Default::default(),
692692
error_format: ErrorOutputType::default(),
693693
externs: Externs(BTreeMap::new()),
694694
extern_dep_specs: ExternDepSpecs(BTreeMap::new()),
@@ -1925,7 +1925,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
19251925

19261926
let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
19271927

1928-
let mut debugging_opts = build_debugging_options(matches, error_format);
1928+
let mut debugging_opts = DebuggingOptions::build(matches, error_format);
19291929
check_debug_option_stability(&debugging_opts, error_format, json_rendered);
19301930

19311931
if !debugging_opts.unstable_options && json_unused_externs {
@@ -1938,7 +1938,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
19381938

19391939
let output_types = parse_output_types(&debugging_opts, matches, error_format);
19401940

1941-
let mut cg = build_codegen_options(matches, error_format);
1941+
let mut cg = CodegenOptions::build(matches, error_format);
19421942
let (disable_thinlto, mut codegen_units) = should_override_cgus_and_disable_thinlto(
19431943
&output_types,
19441944
matches,

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

+78-62
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,7 @@ top_level_options!(
210210
/// generated code to parse an option into its respective field in the struct. There are a few
211211
/// hand-written parsers for parsing specific types of values in this module.
212212
macro_rules! options {
213-
($struct_name:ident, $setter_name:ident, $defaultfn:ident,
214-
$buildfn:ident, $prefix:expr, $outputname:expr,
215-
$stat:ident,
213+
($struct_name:ident, $stat:ident, $prefix:expr, $outputname:expr,
216214
$($( #[$attr:meta] )* $opt:ident : $t:ty = (
217215
$init:expr,
218216
$parse:ident,
@@ -223,50 +221,20 @@ macro_rules! options {
223221
#[derive(Clone)]
224222
pub struct $struct_name { $(pub $opt: $t),* }
225223

226-
pub fn $defaultfn() -> $struct_name {
227-
$struct_name { $( $( #[$attr] )* $opt: $init),* }
228-
}
229-
230-
pub fn $buildfn(matches: &getopts::Matches, error_format: ErrorOutputType) -> $struct_name
231-
{
232-
let mut op = $defaultfn();
233-
for option in matches.opt_strs($prefix) {
234-
let (key, value) = match option.split_once('=') {
235-
None => (option, None),
236-
Some((k, v)) => (k.to_string(), Some(v)),
237-
};
238-
let option_to_lookup = key.replace("-", "_");
239-
let mut found = false;
240-
for &(candidate, setter, type_desc, _) in $stat {
241-
if option_to_lookup != candidate { continue }
242-
if !setter(&mut op, value) {
243-
match value {
244-
None => {
245-
early_error(error_format, &format!("{0} option `{1}` requires \
246-
{2} ({3} {1}=<value>)",
247-
$outputname, key,
248-
type_desc, $prefix))
249-
}
250-
Some(value) => {
251-
early_error(error_format, &format!("incorrect value `{}` for {} \
252-
option `{}` - {} was expected",
253-
value, $outputname,
254-
key, type_desc))
255-
}
256-
}
257-
}
258-
found = true;
259-
break;
260-
}
261-
if !found {
262-
early_error(error_format, &format!("unknown {} option: `{}`",
263-
$outputname, key));
264-
}
224+
impl Default for $struct_name {
225+
fn default() -> $struct_name {
226+
$struct_name { $( $( #[$attr] )* $opt: $init),* }
265227
}
266-
return op;
267228
}
268229

269230
impl $struct_name {
231+
pub fn build(
232+
matches: &getopts::Matches,
233+
error_format: ErrorOutputType,
234+
) -> $struct_name {
235+
build_options(matches, $stat, $prefix, $outputname, error_format)
236+
}
237+
270238
fn dep_tracking_hash(&self, _for_crate_hash: bool, error_format: ErrorOutputType) -> u64 {
271239
let mut sub_hashes = BTreeMap::new();
272240
$({
@@ -284,26 +252,76 @@ macro_rules! options {
284252
}
285253
}
286254

287-
pub type $setter_name = fn(&mut $struct_name, v: Option<&str>) -> bool;
288-
pub const $stat: &[(&str, $setter_name, &str, &str)] =
289-
&[ $( (stringify!($opt), $crate::options::parse::$opt, $crate::options::desc::$parse, $desc) ),* ];
290-
291-
// Sometimes different options need to build a common structure.
292-
// That structure can kept in one of the options' fields, the others become dummy.
293-
macro_rules! redirect_field {
294-
($cg:ident.link_arg) => { $cg.link_args };
295-
($cg:ident.pre_link_arg) => { $cg.pre_link_args };
296-
($cg:ident.$field:ident) => { $cg.$field };
297-
}
255+
pub const $stat: OptionDescrs<$struct_name> =
256+
&[ $( (stringify!($opt), $opt, desc::$parse, $desc) ),* ];
298257

299258
$(
300-
pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool {
301-
$crate::options::parse::$parse(&mut redirect_field!(cg.$opt), v)
259+
fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool {
260+
parse::$parse(&mut redirect_field!(cg.$opt), v)
302261
}
303262
)*
304263

305264
) }
306265

266+
// Sometimes different options need to build a common structure.
267+
// That structure can be kept in one of the options' fields, the others become dummy.
268+
macro_rules! redirect_field {
269+
($cg:ident.link_arg) => {
270+
$cg.link_args
271+
};
272+
($cg:ident.pre_link_arg) => {
273+
$cg.pre_link_args
274+
};
275+
($cg:ident.$field:ident) => {
276+
$cg.$field
277+
};
278+
}
279+
280+
type OptionSetter<O> = fn(&mut O, v: Option<&str>) -> bool;
281+
type OptionDescrs<O> = &'static [(&'static str, OptionSetter<O>, &'static str, &'static str)];
282+
283+
fn build_options<O: Default>(
284+
matches: &getopts::Matches,
285+
descrs: OptionDescrs<O>,
286+
prefix: &str,
287+
outputname: &str,
288+
error_format: ErrorOutputType,
289+
) -> O {
290+
let mut op = O::default();
291+
for option in matches.opt_strs(prefix) {
292+
let (key, value) = match option.split_once('=') {
293+
None => (option, None),
294+
Some((k, v)) => (k.to_string(), Some(v)),
295+
};
296+
297+
let option_to_lookup = key.replace("-", "_");
298+
match descrs.iter().find(|(name, ..)| *name == option_to_lookup) {
299+
Some((_, setter, type_desc, _)) => {
300+
if !setter(&mut op, value) {
301+
match value {
302+
None => early_error(
303+
error_format,
304+
&format!(
305+
"{0} option `{1}` requires {2} ({3} {1}=<value>)",
306+
outputname, key, type_desc, prefix
307+
),
308+
),
309+
Some(value) => early_error(
310+
error_format,
311+
&format!(
312+
"incorrect value `{}` for {} option `{}` - {} was expected",
313+
value, outputname, key, type_desc
314+
),
315+
),
316+
}
317+
}
318+
}
319+
None => early_error(error_format, &format!("unknown {} option: `{}`", outputname, key)),
320+
}
321+
}
322+
return op;
323+
}
324+
307325
#[allow(non_upper_case_globals)]
308326
mod desc {
309327
pub const parse_no_flag: &str = "no value";
@@ -847,9 +865,8 @@ mod parse {
847865
}
848866
}
849867

850-
options! {CodegenOptions, CodegenSetter, basic_codegen_options,
851-
build_codegen_options, "C", "codegen",
852-
CG_OPTIONS,
868+
options! {
869+
CodegenOptions, CG_OPTIONS, "C", "codegen",
853870

854871
// This list is in alphabetical order.
855872
//
@@ -957,9 +974,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
957974
// - src/doc/rustc/src/codegen-options/index.md
958975
}
959976

960-
options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
961-
build_debugging_options, "Z", "debugging",
962-
DB_OPTIONS,
977+
options! {
978+
DebuggingOptions, DB_OPTIONS, "Z", "debugging",
963979

964980
// This list is in alphabetical order.
965981
//

Diff for: src/librustdoc/config.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@ use std::str::FromStr;
77

88
use rustc_data_structures::fx::FxHashMap;
99
use rustc_session::config::{self, parse_crate_types_from_list, parse_externs, CrateType};
10-
use rustc_session::config::{
11-
build_codegen_options, build_debugging_options, get_cmd_lint_options, host_triple,
12-
nightly_options,
13-
};
10+
use rustc_session::config::{get_cmd_lint_options, host_triple, nightly_options};
1411
use rustc_session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs};
1512
use rustc_session::getopts;
1613
use rustc_session::lint::Level;
@@ -360,8 +357,8 @@ impl Options {
360357
config::parse_json(&matches);
361358
let error_format = config::parse_error_format(&matches, color, json_rendered);
362359

363-
let codegen_options = build_codegen_options(matches, error_format);
364-
let debugging_opts = build_debugging_options(matches, error_format);
360+
let codegen_options = CodegenOptions::build(matches, error_format);
361+
let debugging_opts = DebuggingOptions::build(matches, error_format);
365362

366363
let diag = new_handler(error_format, None, &debugging_opts);
367364

Diff for: src/librustdoc/doctest.rs

-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
7676
externs: options.externs.clone(),
7777
unstable_features: options.render_options.unstable_features,
7878
actually_rustdoc: true,
79-
debugging_opts: config::DebuggingOptions { ..config::basic_debugging_options() },
8079
edition: options.edition,
8180
target_triple: options.target.clone(),
8281
crate_name: options.crate_name.clone(),

0 commit comments

Comments
 (0)