Skip to content

Commit 75973f4

Browse files
authored
Optimize RustcCodegenFlags (#1305)
* Optimize RustcCodegenFlags Use `&str` instead of `String`. * Fix lifetime annotations * Fix compilation * Fix lifetime in flags.rs And remove unnecessary `.into()` * Fix compilation in flags.rs: Avoid allocation in prefix handling * FIx cargo-fmt in flags.rs
1 parent 5daf14e commit 75973f4

File tree

1 file changed

+60
-58
lines changed

1 file changed

+60
-58
lines changed

src/flags.rs

+60-58
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,26 @@ use std::ffi::OsString;
55
use std::path::Path;
66

77
#[derive(Debug, PartialEq, Default)]
8-
pub(crate) struct RustcCodegenFlags {
9-
branch_protection: Option<String>,
10-
code_model: Option<String>,
8+
pub(crate) struct RustcCodegenFlags<'a> {
9+
branch_protection: Option<&'a str>,
10+
code_model: Option<&'a str>,
1111
no_vectorize_loops: bool,
1212
no_vectorize_slp: bool,
13-
profile_generate: Option<String>,
14-
profile_use: Option<String>,
15-
control_flow_guard: Option<String>,
16-
lto: Option<String>,
17-
relocation_model: Option<String>,
13+
profile_generate: Option<&'a str>,
14+
profile_use: Option<&'a str>,
15+
control_flow_guard: Option<&'a str>,
16+
lto: Option<&'a str>,
17+
relocation_model: Option<&'a str>,
1818
embed_bitcode: Option<bool>,
1919
force_frame_pointers: Option<bool>,
2020
link_dead_code: Option<bool>,
2121
no_redzone: Option<bool>,
2222
soft_float: Option<bool>,
2323
}
2424

25-
impl RustcCodegenFlags {
25+
impl<'this> RustcCodegenFlags<'this> {
2626
// Parse flags obtained from CARGO_ENCODED_RUSTFLAGS
27-
pub(crate) fn parse(rustflags_env: &str) -> Result<RustcCodegenFlags, Error> {
27+
pub(crate) fn parse(rustflags_env: &'this str) -> Result<Self, Error> {
2828
fn is_flag_prefix(flag: &str) -> bool {
2929
[
3030
"-Z",
@@ -45,19 +45,19 @@ impl RustcCodegenFlags {
4545
.contains(&flag)
4646
}
4747

48-
fn handle_flag_prefix<'a>(prev: &'a str, curr: &'a str) -> Cow<'a, str> {
48+
fn handle_flag_prefix<'a>(prev: &'a str, curr: &'a str) -> (&'a str, &'a str) {
4949
match prev {
50-
"--codegen" | "-C" => Cow::from(format!("-C{}", curr)),
50+
"--codegen" | "-C" => ("-C", curr),
5151
// Handle flags passed like --codegen=code-model=small
52-
_ if curr.starts_with("--codegen=") => Cow::from(format!("-C{}", &curr[10..])),
53-
"-Z" => Cow::from(format!("-Z{}", curr)),
54-
"-L" | "-l" | "-o" => Cow::from(format!("{}{}", prev, curr)),
52+
_ if curr.starts_with("--codegen=") => ("-C", &curr[10..]),
53+
"-Z" => ("-Z", curr),
54+
"-L" | "-l" | "-o" => (prev, curr),
5555
// Handle lint flags
56-
"-W" | "--warn" => Cow::from(format!("-W{}", curr)),
57-
"-A" | "--allow" => Cow::from(format!("-A{}", curr)),
58-
"-D" | "--deny" => Cow::from(format!("-D{}", curr)),
59-
"-F" | "--forbid" => Cow::from(format!("-F{}", curr)),
60-
_ => Cow::from(curr),
56+
"-W" | "--warn" => ("-W", curr),
57+
"-A" | "--allow" => ("-A", curr),
58+
"-D" | "--deny" => ("-D", curr),
59+
"-F" | "--forbid" => ("-F", curr),
60+
_ => ("", curr),
6161
}
6262
}
6363

@@ -71,14 +71,14 @@ impl RustcCodegenFlags {
7171
continue;
7272
}
7373

74-
let rustc_flag = handle_flag_prefix(prev, curr);
75-
codegen_flags.set_rustc_flag(&rustc_flag)?;
74+
let (prefix, rustc_flag) = handle_flag_prefix(prev, curr);
75+
codegen_flags.set_rustc_flag(prefix, rustc_flag)?;
7676
}
7777

7878
Ok(codegen_flags)
7979
}
8080

81-
fn set_rustc_flag(&mut self, flag: &str) -> Result<(), Error> {
81+
fn set_rustc_flag(&mut self, prefix: &str, flag: &'this str) -> Result<(), Error> {
8282
// Convert a textual representation of a bool-like rustc flag argument into an actual bool
8383
fn arg_to_bool(arg: impl AsRef<str>) -> Option<bool> {
8484
match arg.as_ref() {
@@ -89,16 +89,24 @@ impl RustcCodegenFlags {
8989
}
9090

9191
let (flag, value) = if let Some((flag, value)) = flag.split_once('=') {
92-
(flag, Some(value.to_owned()))
92+
(flag, Some(value))
9393
} else {
9494
(flag, None)
9595
};
96+
let flag = if prefix.is_empty() {
97+
Cow::Borrowed(flag)
98+
} else {
99+
Cow::Owned(format!("{prefix}{flag}"))
100+
};
96101

97-
fn flag_ok_or(flag: Option<String>, msg: &'static str) -> Result<String, Error> {
102+
fn flag_ok_or<'flag>(
103+
flag: Option<&'flag str>,
104+
msg: &'static str,
105+
) -> Result<&'flag str, Error> {
98106
flag.ok_or(Error::new(ErrorKind::InvalidFlag, msg))
99107
}
100108

101-
match flag {
109+
match flag.as_ref() {
102110
// https://doc.rust-lang.org/rustc/codegen-options/index.html#code-model
103111
"-Ccode-model" => {
104112
self.code_model = Some(flag_ok_or(value, "-Ccode-model must have a value")?);
@@ -117,9 +125,9 @@ impl RustcCodegenFlags {
117125
self.profile_use = Some(flag_ok_or(value, "-Cprofile-use must have a value")?);
118126
}
119127
// https://doc.rust-lang.org/rustc/codegen-options/index.html#control-flow-guard
120-
"-Ccontrol-flow-guard" => self.control_flow_guard = value.or(Some("true".into())),
128+
"-Ccontrol-flow-guard" => self.control_flow_guard = value.or(Some("true")),
121129
// https://doc.rust-lang.org/rustc/codegen-options/index.html#lto
122-
"-Clto" => self.lto = value.or(Some("true".into())),
130+
"-Clto" => self.lto = value.or(Some("true")),
123131
// https://doc.rust-lang.org/rustc/codegen-options/index.html#relocation-model
124132
"-Crelocation-model" => {
125133
self.relocation_model =
@@ -176,13 +184,13 @@ impl RustcCodegenFlags {
176184
match family {
177185
ToolFamily::Clang { .. } | ToolFamily::Gnu => {
178186
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mbranch-protection
179-
if let Some(value) = &self.branch_protection {
187+
if let Some(value) = self.branch_protection {
180188
push_if_supported(
181189
format!("-mbranch-protection={}", value.replace(",", "+")).into(),
182190
);
183191
}
184192
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mcmodel
185-
if let Some(value) = &self.code_model {
193+
if let Some(value) = self.code_model {
186194
push_if_supported(format!("-mcmodel={value}").into());
187195
}
188196
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fno-vectorize
@@ -194,16 +202,16 @@ impl RustcCodegenFlags {
194202
push_if_supported("-fno-slp-vectorize".into());
195203
}
196204
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fprofile-generate
197-
if let Some(value) = &self.profile_generate {
205+
if let Some(value) = self.profile_generate {
198206
push_if_supported(format!("-fprofile-generate={value}").into());
199207
}
200208
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fprofile-use
201-
if let Some(value) = &self.profile_use {
209+
if let Some(value) = self.profile_use {
202210
push_if_supported(format!("-fprofile-use={value}").into());
203211
}
204212
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mguard
205-
if let Some(value) = &self.control_flow_guard {
206-
let cc_val = match value.as_str() {
213+
if let Some(value) = self.control_flow_guard {
214+
let cc_val = match value {
207215
"y" | "yes" | "on" | "true" | "checks" => Some("cf"),
208216
"nochecks" => Some("cf-nochecks"),
209217
"n" | "no" | "off" | "false" => Some("none"),
@@ -214,8 +222,8 @@ impl RustcCodegenFlags {
214222
}
215223
}
216224
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-flto
217-
if let Some(value) = &self.lto {
218-
let cc_val = match value.as_str() {
225+
if let Some(value) = self.lto {
226+
let cc_val = match value {
219227
"y" | "yes" | "on" | "true" | "fat" => Some("full"),
220228
"thin" => Some("thin"),
221229
_ => None,
@@ -227,8 +235,8 @@ impl RustcCodegenFlags {
227235
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fPIC
228236
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fPIE
229237
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mdynamic-no-pic
230-
if let Some(value) = &self.relocation_model {
231-
let cc_flag = match value.as_str() {
238+
if let Some(value) = self.relocation_model {
239+
let cc_flag = match value {
232240
"pic" => Some("-fPIC"),
233241
"pie" => Some("-fPIE"),
234242
"dynamic-no-pic" => Some("-mdynamic-no-pic"),
@@ -239,40 +247,34 @@ impl RustcCodegenFlags {
239247
}
240248
}
241249
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fembed-bitcode
242-
if let Some(value) = &self.embed_bitcode {
243-
let cc_val = if *value { "all" } else { "off" };
250+
if let Some(value) = self.embed_bitcode {
251+
let cc_val = if value { "all" } else { "off" };
244252
push_if_supported(format!("-fembed-bitcode={cc_val}").into());
245253
}
246254
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fno-omit-frame-pointer
247255
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fomit-frame-pointer
248-
if let Some(value) = &self.force_frame_pointers {
249-
let cc_flag = if *value {
256+
if let Some(value) = self.force_frame_pointers {
257+
let cc_flag = if value {
250258
"-fno-omit-frame-pointer"
251259
} else {
252260
"-fomit-frame-pointer"
253261
};
254262
push_if_supported(cc_flag.into());
255263
}
256264
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-dead_strip
257-
if let Some(value) = &self.link_dead_code {
258-
if !value {
259-
push_if_supported("-dead_strip".into());
260-
}
265+
if let Some(false) = self.link_dead_code {
266+
push_if_supported("-dead_strip".into());
261267
}
262268
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mno-red-zone
263269
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mred-zone
264-
if let Some(value) = &self.no_redzone {
265-
let cc_flag = if *value {
266-
"-mno-red-zone"
267-
} else {
268-
"-mred-zone"
269-
};
270+
if let Some(value) = self.no_redzone {
271+
let cc_flag = if value { "-mno-red-zone" } else { "-mred-zone" };
270272
push_if_supported(cc_flag.into());
271273
}
272274
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-msoft-float
273275
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mno-soft-float
274-
if let Some(value) = &self.soft_float {
275-
let cc_flag = if *value {
276+
if let Some(value) = self.soft_float {
277+
let cc_flag = if value {
276278
"-msoft-float"
277279
} else {
278280
"-mno-soft-float"
@@ -282,8 +284,8 @@ impl RustcCodegenFlags {
282284
}
283285
ToolFamily::Msvc { .. } => {
284286
// https://learn.microsoft.com/en-us/cpp/build/reference/guard-enable-control-flow-guard
285-
if let Some(value) = &self.control_flow_guard {
286-
let cc_val = match value.as_str() {
287+
if let Some(value) = self.control_flow_guard {
288+
let cc_val = match value {
287289
"y" | "yes" | "on" | "true" | "checks" => Some("cf"),
288290
"n" | "no" | "off" | "false" => Some("cf-"),
289291
_ => None,
@@ -293,8 +295,8 @@ impl RustcCodegenFlags {
293295
}
294296
}
295297
// https://learn.microsoft.com/en-us/cpp/build/reference/oy-frame-pointer-omission
296-
if let Some(value) = &self.force_frame_pointers {
297-
let cc_flag = if *value { "/Oy-" } else { "/Oy" };
298+
if let Some(value) = self.force_frame_pointers {
299+
let cc_flag = if value { "/Oy-" } else { "/Oy" };
298300
push_if_supported(cc_flag.into());
299301
}
300302
}

0 commit comments

Comments
 (0)