Skip to content

Commit

Permalink
Fix the problem where the build fails due to the ambiguous type of `m…
Browse files Browse the repository at this point in the history
…ap` (#491)
  • Loading branch information
nullpo-head committed Aug 30, 2021
1 parent 4a31aae commit 7fef417
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 2 deletions.
1 change: 1 addition & 0 deletions 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)

Expand Down
11 changes: 9 additions & 2 deletions structopt-derive/src/lib.rs
Expand Up @@ -330,6 +330,13 @@ fn gen_constructor(fields: &Punctuated<Field, Comma>, 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)),

Expand All @@ -349,15 +356,15 @@ fn gen_constructor(fields: &Punctuated<Field, Comma>, 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
}
},

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()=>
Expand Down
29 changes: 29 additions & 0 deletions tests/issues.rs
Expand Up @@ -115,3 +115,32 @@ fn issue_359() {
Opt::from_iter(&["test", "only_one_arg"])
);
}

#[test]
fn issue_490() {
use std::iter::FromIterator;
use std::str::FromStr;
use structopt::StructOpt;

struct U16ish;
impl FromStr for U16ish {
type Err = ();
fn from_str(_: &str) -> Result<Self, Self::Err> {
unimplemented!()
}
}
impl<'a> FromIterator<&'a U16ish> for Vec<u16> {
fn from_iter<T: IntoIterator<Item = &'a U16ish>>(_: T) -> Self {
unimplemented!()
}
}

#[derive(StructOpt, Debug)]
struct Opt {
opt_vec: Vec<u16>,
#[structopt(long)]
opt_opt_vec: Option<Vec<u16>>,
}

// Assert that it compiles
}

0 comments on commit 7fef417

Please sign in to comment.