From 1277bfe0fb256059232dbbfd565bd4ffa9b5c6c6 Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 9 Sep 2019 13:02:25 +0200 Subject: [PATCH 1/2] Fix setting configuration params Fixes #627 Fixes a regression caused by #579, specifically commit cc8872b4eec3f39896ccb11d9c25a30a79c04dd7 . The code was intended to perform a comparison between the wanted output type and "Tagged" in order to be able to provide a special-cased path for Tagged. When I wrote the code, I used "name" as a variable name and only later realized that it shadowed the "name" param to the function, so I renamed it to type_name, but forgot to change the comparison. This broke the special-casing, as the name param only contains the name of the struct without generics (like "Tagged"), while `std::any::type_name` (in the current implementation) contains the full paths of the struct including all generic params (like "nu::object::meta::Tagged"). --- src/parser/deserializer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parser/deserializer.rs b/src/parser/deserializer.rs index 33a23189f1..d4d492966c 100644 --- a/src/parser/deserializer.rs +++ b/src/parser/deserializer.rs @@ -328,7 +328,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut ConfigDeserializer<'de> { let type_name = std::any::type_name::(); let tagged_val_name = std::any::type_name::>(); - if name == tagged_val_name { + if type_name == tagged_val_name { return visit::, _>(value.val, name, fields, visitor); } From 1d3483b59015d9cfe67de624cad0e8bbb600fe95 Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 9 Sep 2019 13:39:43 +0200 Subject: [PATCH 2/2] Add a test --- src/parser/deserializer.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/parser/deserializer.rs b/src/parser/deserializer.rs index d4d492966c..d5427766b5 100644 --- a/src/parser/deserializer.rs +++ b/src/parser/deserializer.rs @@ -467,3 +467,27 @@ impl<'a, 'de: 'a> de::SeqAccess<'de> for StructDeserializer<'a, 'de> { return Some(self.fields.len()); } } + +#[cfg(test)] +mod tests { + use super::*; + use std::any::type_name; + #[test] + fn check_type_name_properties() { + // This ensures that certain properties for the + // std::any::type_name function hold, that + // this code relies on. The type_name docs explicitly + // mention that the actual format of the output + // is unspecified and change is likely. + // This test makes sure that such change is detected + // by this test failing, and not things silently breaking. + // Specifically, we rely on this behaviour further above + // in the file to special case Tagged parsing. + let tuple = type_name::<()>(); + let tagged_tuple = type_name::>(); + let tagged_value = type_name::>(); + assert!(tuple != tagged_tuple); + assert!(tuple != tagged_value); + assert!(tagged_tuple != tagged_value); + } +}