From 53e3be154f05cab29d53c0d280e16f0263c9e6e7 Mon Sep 17 00:00:00 2001 From: Takaya Saeki Date: Sat, 21 Aug 2021 19:51:25 +0900 Subject: [PATCH 1/3] Fix a compile error which occurs when the type of map is ambiguous --- structopt-derive/src/lib.rs | 11 +++++++++-- tests/issues.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/structopt-derive/src/lib.rs b/structopt-derive/src/lib.rs index b8e86de4..b80ae176 100644 --- a/structopt-derive/src/lib.rs +++ b/structopt-derive/src/lib.rs @@ -330,6 +330,13 @@ fn gen_constructor(fields: &Punctuated, parent_attribute: &Attrs) let flag = *attrs.parser().kind == ParserKind::FromFlag; let occurrences = *attrs.parser().kind == ParserKind::FromOccurrences; let name = attrs.cased_name(); + let convert_type = match **ty { + Ty::Vec | Ty::Option => sub_type(&field.ty).unwrap_or(&field.ty), + Ty::OptionOption | Ty::OptionVec => { + sub_type(&field.ty).and_then(sub_type).unwrap_or(&field.ty) + } + _ => &field.ty, + }; let field_value = match **ty { Ty::Bool => quote_spanned!(ty.span()=> #matches.is_present(#name)), @@ -349,7 +356,7 @@ fn gen_constructor(fields: &Punctuated, parent_attribute: &Attrs) Ty::OptionVec => quote_spanned! { ty.span()=> if #matches.is_present(#name) { Some(#matches.#values_of(#name) - .map_or_else(Vec::new, |v| v.map(#parse).collect())) + .map_or_else(Vec::new, |v| v.map::<#convert_type, _>(#parse).collect())) } else { None } @@ -357,7 +364,7 @@ fn gen_constructor(fields: &Punctuated, parent_attribute: &Attrs) Ty::Vec => quote_spanned! { ty.span()=> #matches.#values_of(#name) - .map_or_else(Vec::new, |v| v.map(#parse).collect()) + .map_or_else(Vec::new, |v| v.map::<#convert_type, _>(#parse).collect()) }, Ty::Other if occurrences => quote_spanned! { ty.span()=> diff --git a/tests/issues.rs b/tests/issues.rs index 8b4ac4b5..4dece208 100644 --- a/tests/issues.rs +++ b/tests/issues.rs @@ -115,3 +115,32 @@ fn issue_359() { Opt::from_iter(&["test", "only_one_arg"]) ); } + +#[test] +fn issue_indicatif() { + use std::iter::FromIterator; + use std::str::FromStr; + use structopt::StructOpt; + + struct U16ish; + impl FromStr for U16ish { + type Err = (); + fn from_str(_: &str) -> Result { + unimplemented!() + } + } + impl<'a> FromIterator<&'a U16ish> for Vec { + fn from_iter>(_: T) -> Self { + unimplemented!() + } + } + + #[derive(StructOpt, Debug)] + struct Opt { + opt_vec: Vec, + #[structopt(long)] + opt_opt_vec: Option>, + } + + // Assert that it compiles +} From 2bcb17dc6f85280b63a1044348766c3e7985aaf5 Mon Sep 17 00:00:00 2001 From: Takaya Saeki Date: Sun, 22 Aug 2021 00:52:35 +0900 Subject: [PATCH 2/3] Update the name of the test for the map type inference issue to the actual issue number --- tests/issues.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/issues.rs b/tests/issues.rs index 4dece208..5860c493 100644 --- a/tests/issues.rs +++ b/tests/issues.rs @@ -117,7 +117,7 @@ fn issue_359() { } #[test] -fn issue_indicatif() { +fn issue_490() { use std::iter::FromIterator; use std::str::FromStr; use structopt::StructOpt; From c36930d2244ac1eee4e5cf12b11abf4268f2bddb Mon Sep 17 00:00:00 2001 From: Takaya Saeki Date: Sat, 28 Aug 2021 18:20:34 +0900 Subject: [PATCH 3/3] Update the changelog. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c35dd24..0a0f9c63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # v0.3.23 (unreleased) * Update minimal rust version to 1.46 because of bitflags 1.3 +* Fixed [a bug that occurs when the type of `map` becomes ambiguous](https://github.com/TeXitoi/structopt/issues/490). # v0.3.22 (2021-07-04)