Upgrade rust/crates/structopt-derive to 0.4.11 am: ad4a5aaeb5 am: 584fdffac1

Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/structopt-derive/+/1435858

Change-Id: I46f0e8750dfbf419856ba1c148f7b7ea47369b60
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 2df1587..bb978e8 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
 {
   "git": {
-    "sha1": "203c6bc19e561da1734873794bbd420e0bfc79b9"
+    "sha1": "ff542c67023cbddbb2198df4087abc6aa6c8d5b7"
   }
 }
diff --git a/Cargo.toml b/Cargo.toml
index 301f046..5afdc79 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
 [package]
 edition = "2018"
 name = "structopt-derive"
-version = "0.4.7"
+version = "0.4.11"
 authors = ["Guillaume Pinot <[email protected]>"]
 description = "Parse command line argument by defining a struct, derive crate."
 documentation = "https://docs.rs/structopt-derive"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 4e97528..ff14f47 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "structopt-derive"
-version = "0.4.7"
+version = "0.4.11"
 edition = "2018"
 authors = ["Guillaume Pinot <[email protected]>"]
 description = "Parse command line argument by defining a struct, derive crate."
diff --git a/METADATA b/METADATA
index bbf085b..b40e4df 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/structopt-derive/structopt-derive-0.4.7.crate"
+    value: "https://static.crates.io/crates/structopt-derive/structopt-derive-0.4.11.crate"
   }
-  version: "0.4.7"
+  version: "0.4.11"
   license_type: NOTICE
   last_upgrade_date {
     year: 2020
-    month: 5
+    month: 10
     day: 6
   }
 }
diff --git a/src/attrs.rs b/src/attrs.rs
index d75b50c..11655b8 100644
--- a/src/attrs.rs
+++ b/src/attrs.rs
@@ -65,6 +65,10 @@
     Snake,
     /// Use the original attribute name defined in the code.
     Verbatim,
+    /// Keep all letters lowercase and remove word boundaries.
+    Lower,
+    /// Keep all letters uppercase and remove word boundaries.
+    Upper,
 }
 
 #[derive(Clone)]
@@ -188,6 +192,8 @@
             "screamingsnake" | "screamingsnakecase" => cs(ScreamingSnake),
             "snake" | "snakecase" => cs(Snake),
             "verbatim" | "verbatimcase" => cs(Verbatim),
+            "lower" | "lowercase" => cs(Lower),
+            "upper" | "uppercase" => cs(Upper),
             s => abort!(name, "unsupported casing: `{}`", s),
         }
     }
@@ -208,6 +214,8 @@
                     ScreamingSnake => s.to_shouty_snake_case(),
                     Snake => s.to_snake_case(),
                     Verbatim => s,
+                    Lower => s.to_snake_case().replace("_", ""),
+                    Upper => s.to_shouty_snake_case().replace("_", ""),
                 };
                 quote_spanned!(ident.span()=> #s)
             }
@@ -437,12 +445,16 @@
                         "parse attribute is not allowed for flattened entry"
                     );
                 }
-                if res.has_explicit_methods() || res.has_doc_methods() {
+                if res.has_explicit_methods() {
                     abort!(
                         res.kind.span(),
-                        "methods and doc comments are not allowed for flattened entry"
+                        "methods are not allowed for flattened entry"
                     );
                 }
+
+                if res.has_doc_methods() {
+                    res.doc_comment = vec![];
+                }
             }
 
             Kind::ExternalSubcommand => {}
diff --git a/src/lib.rs b/src/lib.rs
index 5e49468..6cc415b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -11,6 +11,7 @@
 //! for the usage of `#[derive(StructOpt)]`.
 
 #![allow(clippy::large_enum_variant)]
+#![forbid(unsafe_code)]
 
 extern crate proc_macro;
 
@@ -28,7 +29,7 @@
 
 use proc_macro2::{Span, TokenStream};
 use proc_macro_error::{abort, abort_call_site, proc_macro_error, set_dummy};
-use quote::{quote, quote_spanned};
+use quote::{format_ident, quote, quote_spanned};
 use syn::{punctuated::Punctuated, spanned::Spanned, token::Comma, *};
 
 /// Default casing style for generated arguments.
@@ -239,6 +240,16 @@
 }
 
 fn gen_constructor(fields: &Punctuated<Field, Comma>, parent_attribute: &Attrs) -> TokenStream {
+    // This ident is used in several match branches below,
+    // and the `quote[_spanned]` invocations have different spans.
+    //
+    // Given that this ident is used in several places and
+    // that the branches are located inside of a loop, it is possible that
+    // this ident will be given _different_ spans in different places, and
+    // thus will not be the _same_ ident anymore. To make sure the `matches`
+    // is always the same, we factor it out.
+    let matches = format_ident!("matches");
+
     let fields = fields.iter().map(|field| {
         let attrs = Attrs::from_field(
             field,
@@ -265,13 +276,13 @@
                 };
                 quote_spanned! { kind.span()=>
                     #field_name: <#subcmd_type as ::structopt::StructOptInternal>::from_subcommand(
-                        matches.subcommand())
+                        #matches.subcommand())
                         #unwrapper
                 }
             }
 
             Kind::Flatten => quote_spanned! { kind.span()=>
-                #field_name: ::structopt::StructOpt::from_clap(matches)
+                #field_name: ::structopt::StructOpt::from_clap(#matches)
             },
 
             Kind::Skip(val) => match val {
@@ -318,24 +329,24 @@
                 let occurrences = *attrs.parser().kind == ParserKind::FromOccurrences;
                 let name = attrs.cased_name();
                 let field_value = match **ty {
-                    Ty::Bool => quote_spanned!(ty.span()=> matches.is_present(#name)),
+                    Ty::Bool => quote_spanned!(ty.span()=> #matches.is_present(#name)),
 
                     Ty::Option => quote_spanned! { ty.span()=>
-                        matches.#value_of(#name)
+                        #matches.#value_of(#name)
                             .map(#parse)
                     },
 
                     Ty::OptionOption => quote_spanned! { ty.span()=>
-                        if matches.is_present(#name) {
-                            Some(matches.#value_of(#name).map(#parse))
+                        if #matches.is_present(#name) {
+                            Some(#matches.#value_of(#name).map(#parse))
                         } else {
                             None
                         }
                     },
 
                     Ty::OptionVec => quote_spanned! { ty.span()=>
-                        if matches.is_present(#name) {
-                            Some(matches.#values_of(#name)
+                        if #matches.is_present(#name) {
+                            Some(#matches.#values_of(#name)
                                  .map_or_else(Vec::new, |v| v.map(#parse).collect()))
                         } else {
                             None
@@ -343,20 +354,20 @@
                     },
 
                     Ty::Vec => quote_spanned! { ty.span()=>
-                        matches.#values_of(#name)
+                        #matches.#values_of(#name)
                             .map_or_else(Vec::new, |v| v.map(#parse).collect())
                     },
 
                     Ty::Other if occurrences => quote_spanned! { ty.span()=>
-                        #parse(matches.#value_of(#name))
+                        #parse(#matches.#value_of(#name))
                     },
 
                     Ty::Other if flag => quote_spanned! { ty.span()=>
-                        #parse(matches.is_present(#name))
+                        #parse(#matches.is_present(#name))
                     },
 
                     Ty::Other => quote_spanned! { ty.span()=>
-                        matches.#value_of(#name)
+                        #matches.#value_of(#name)
                             .map(#parse)
                             .unwrap()
                     },
@@ -471,8 +482,9 @@
         let kind = attrs.kind();
         match &*kind {
             Kind::ExternalSubcommand => {
+                let app_var = Ident::new("app", Span::call_site());
                 quote_spanned! { attrs.kind().span()=>
-                    let app = app.setting(
+                    let #app_var = #app_var.setting(
                         ::structopt::clap::AppSettings::AllowExternalSubcommands
                     );
                 }
@@ -549,7 +561,8 @@
     quote! {
         fn from_clap(matches: &::structopt::clap::ArgMatches) -> Self {
             <#name as ::structopt::StructOptInternal>::from_subcommand(matches.subcommand())
-                .unwrap()
+                .expect("structopt misuse: You likely tried to #[flatten] a struct \
+                         that contains #[subcommand]. This is forbidden.")
         }
     }
 }
@@ -648,10 +661,10 @@
                 }
 
                 (external, None) => {
-                    ::std::option::Option::Some(#name::#var_name({
+                    ::std::option::Option::Some(#name::#var_name(
                         ::std::iter::once(#str_ty::from(external))
                             .collect::<::std::vec::Vec<_>>()
-                    }))
+                    ))
                 }
             }
         },
@@ -720,7 +733,7 @@
 #[cfg(feature = "paw")]
 fn gen_paw_impl(name: &Ident) -> TokenStream {
     quote! {
-        impl paw::ParseArgs for #name {
+        impl ::structopt::paw::ParseArgs for #name {
             type Error = std::io::Error;
 
             fn parse_args() -> std::result::Result<Self, Self::Error> {
diff --git a/src/spanned.rs b/src/spanned.rs
index 19dbe47..1c02a82 100644
--- a/src/spanned.rs
+++ b/src/spanned.rs
@@ -88,7 +88,7 @@
         // this is the simplest way out of correct ones to change span on
         // arbitrary token tree I can come up with
         let tt = self.val.to_token_stream().into_iter().map(|mut tt| {
-            tt.set_span(self.span.clone());
+            tt.set_span(self.span);
             tt
         });