Skip to content

Commit c08a666

Browse files
committed
Fix config deserilization of check-cfg
1 parent dbff32b commit c08a666

File tree

1 file changed

+45
-29
lines changed

1 file changed

+45
-29
lines changed

src/cargo/core/features.rs

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,7 @@ unstable_cli_options!(
641641
build_std_features: Option<Vec<String>> = ("Configure features enabled for the standard library itself when building the standard library"),
642642
config_include: bool = ("Enable the `include` key in config files"),
643643
credential_process: bool = ("Add a config setting to fetch registry authentication tokens by calling an external process"),
644+
#[serde(deserialize_with = "deserialize_check_cfg")]
644645
check_cfg: Option<(/*features:*/ bool, /*well_known_names:*/ bool, /*well_known_values:*/ bool, /*output:*/ bool)> = ("Specify scope of compile-time checking of `cfg` names/values"),
645646
doctest_in_workspace: bool = ("Compile doctests with paths relative to the workspace root"),
646647
doctest_xcompile: bool = ("Compile and run doctests for non-host target using runner config"),
@@ -733,6 +734,47 @@ where
733734
))
734735
}
735736

737+
fn deserialize_check_cfg<'de, D>(
738+
deserializer: D,
739+
) -> Result<Option<(bool, bool, bool, bool)>, D::Error>
740+
where
741+
D: serde::Deserializer<'de>,
742+
{
743+
use serde::de::Error;
744+
let crates = match <Option<Vec<String>>>::deserialize(deserializer)? {
745+
Some(list) => list,
746+
None => return Ok(None),
747+
};
748+
749+
parse_check_cfg(crates.into_iter()).map_err(D::Error::custom)
750+
}
751+
752+
fn parse_check_cfg(
753+
it: impl Iterator<Item = impl AsRef<str>>,
754+
) -> CargoResult<Option<(bool, bool, bool, bool)>> {
755+
let mut features = false;
756+
let mut well_known_names = false;
757+
let mut well_known_values = false;
758+
let mut output = false;
759+
760+
for e in it {
761+
match e.as_ref() {
762+
"features" => features = true,
763+
"names" => well_known_names = true,
764+
"values" => well_known_values = true,
765+
"output" => output = true,
766+
_ => bail!("unstable check-cfg only takes `features`, `names`, `values` or `output` as valid inputs"),
767+
}
768+
}
769+
770+
Ok(Some((
771+
features,
772+
well_known_names,
773+
well_known_values,
774+
output,
775+
)))
776+
}
777+
736778
impl CliUnstable {
737779
pub fn parse(
738780
&mut self,
@@ -783,34 +825,6 @@ impl CliUnstable {
783825
}
784826
}
785827

786-
fn parse_check_cfg(value: Option<&str>) -> CargoResult<Option<(bool, bool, bool, bool)>> {
787-
if let Some(value) = value {
788-
let mut features = false;
789-
let mut well_known_names = false;
790-
let mut well_known_values = false;
791-
let mut output = false;
792-
793-
for e in value.split(',') {
794-
match e {
795-
"features" => features = true,
796-
"names" => well_known_names = true,
797-
"values" => well_known_values = true,
798-
"output" => output = true,
799-
_ => bail!("flag -Zcheck-cfg only takes `features`, `names`, `values` or `output` as valid inputs"),
800-
}
801-
}
802-
803-
Ok(Some((
804-
features,
805-
well_known_names,
806-
well_known_values,
807-
output,
808-
)))
809-
} else {
810-
Ok(None)
811-
}
812-
}
813-
814828
// Asserts that there is no argument to the flag.
815829
fn parse_empty(key: &str, value: Option<&str>) -> CargoResult<bool> {
816830
if let Some(v) = value {
@@ -868,7 +882,9 @@ impl CliUnstable {
868882
"minimal-versions" => self.minimal_versions = parse_empty(k, v)?,
869883
"advanced-env" => self.advanced_env = parse_empty(k, v)?,
870884
"config-include" => self.config_include = parse_empty(k, v)?,
871-
"check-cfg" => self.check_cfg = parse_check_cfg(v)?,
885+
"check-cfg" => {
886+
self.check_cfg = v.map_or(Ok(None), |v| parse_check_cfg(v.split(',')))?
887+
}
872888
"dual-proc-macros" => self.dual_proc_macros = parse_empty(k, v)?,
873889
// can also be set in .cargo/config or with and ENV
874890
"mtime-on-use" => self.mtime_on_use = parse_empty(k, v)?,

0 commit comments

Comments
 (0)