Repository: clap-rs/clap (rust)

Issue:
#![deny(missing_docs)] incompatible with #[clap(flatten)]
### Code

```rust
use clap::Clap;

/// Docs included
#[derive(Clap)]
#[clap(author, version)]
struct Opts {
    /// Document debug
    #[clap(short, long)]
    debug: bool,

    /// Flatten
    #[clap(flatten)]
    thing: ThingConfig,

}

/// Thing CLI Configuration
#[derive(Clap)]
#[clap(name = "thing")]
struct ThingConfig {
    /// Thing URI
    #[clap(long)]
    uri: String,
}
```

### Steps to reproduce the issue

1. Run `cargo build`
2. ???
3. PROFIT!!!

### Version

* **Rust**: rustc 1.47.0-nightly (de521cbb3 2020-08-21)

* **Clap**: "3.0.0-beta.1"

### Actual Behavior Summary

When compiling with a doc on the flattened `thing: ThingConfig`

```rust
error: methods and doc comments are not allowed for flattened entry
  --> src/clapped.rs
   |
45 |     #[clap(flatten)]
   |            ^^^^^^^

```

When compiling without it (since I can't)

```rust
error: missing documentation for the crate
```

### Expected Behavior Summary

Flattened options should not raise a missing docs warning.


Pull request description:
Allow flatten with doc comments
<!--
If your PR closes some issues, please write `Closes #XXXX`
where `XXXX` is the number of the issue you want to fix.
Each issue goes on its own line.
-->
Closes #2108

Patch:
diff --git a/clap_derive/examples/env.rs b/clap_derive/examples/env.rs
index 2f668601..38ba425e 100644
--- a/clap_derive/examples/env.rs
+++ b/clap_derive/examples/env.rs
@@ -1,7 +1,7 @@
 //! How to use environment variable fallback an how it
 //! interacts with `default_value`.
 
-use clap::{ArgSettings, Clap};
+use clap::Clap;
 
 /// Example for allowing to specify options via environment variables.
 #[derive(Clap, Debug)]
@@ -18,12 +18,6 @@ struct Opt {
     /// Number of retries
     #[clap(long, env = "RETRIES", default_value = "5")]
     retries: u32,
-
-    // If an environment variable contains a sensitive value, it can be hidden
-    // from the help screen with a special setting.
-    /// Secret token
-    #[clap(long, env = "SECRET_TOKEN", setting = ArgSettings::HideEnvValues)]
-    token: String,
 }
 
 fn main() {
diff --git a/clap_derive/src/attrs.rs b/clap_derive/src/attrs.rs
index 2561294f..b40da9a1 100644
--- a/clap_derive/src/attrs.rs
+++ b/clap_derive/src/attrs.rs
@@ -481,12 +481,15 @@ impl Attrs {
                         "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"
                     );
                 }
+
+                // ignore doc comments
+                res.doc_comment = vec![];
             }
 
             Kind::ExternalSubcommand => {
@@ -695,14 +698,6 @@ impl Attrs {
             .iter()
             .any(|m| m.name != "about" && m.name != "long_about")
     }
-
-    pub fn has_doc_methods(&self) -> bool {
-        !self.doc_comment.is_empty()
-            || self
-                .methods
-                .iter()
-                .any(|m| m.name == "about" || m.name == "long_about")
-    }
 }
 
 /// replace all `:` with `, ` when not inside the `<>`
diff --git a/clap_generate/src/generators/shells/zsh.rs b/clap_generate/src/generators/shells/zsh.rs
index 54ff712c..e32303d6 100644
--- a/clap_generate/src/generators/shells/zsh.rs
+++ b/clap_generate/src/generators/shells/zsh.rs
@@ -119,8 +119,7 @@ _{bin_name_underscore}_commands() {{
 }}",
             bin_name_underscore = bin_name.replace(" ", "__"),
             bin_name = bin_name,
-            subcommands_and_args =
-                subcommands_of(parser_of(p, bin_name).expect(INTERNAL_ERROR_MSG))
+            subcommands_and_args = subcommands_of(parser_of(p, bin_name))
         ));
     }
 
@@ -218,20 +217,14 @@ fn get_subcommands_of(p: &App) -> String {
     let mut subcmds = vec![];
 
     for &(ref name, ref bin_name) in &sc_names {
-        debug!(
-            "get_subcommands_of:iter: p={}, name={}, bin_name={}",
-            p.get_name(),
-            name,
-            bin_name,
-        );
         let mut v = vec![format!("({})", name)];
-        let subcommand_args = get_args_of(parser_of(p, &*bin_name).expect(INTERNAL_ERROR_MSG));
+        let subcommand_args = get_args_of(parser_of(p, &*bin_name));
 
         if !subcommand_args.is_empty() {
             v.push(subcommand_args);
         }
 
-        let subcommands = get_subcommands_of(parser_of(p, &*bin_name).expect(INTERNAL_ERROR_MSG));
+        let subcommands = get_subcommands_of(parser_of(p, &*bin_name));
 
         if !subcommands.is_empty() {
             v.push(subcommands);
@@ -259,24 +252,15 @@ esac",
     )
 }
 
-// Get the App for a given subcommand tree.
-//
-// Given the bin_name "a b c" and the App for "a" this returns the "c" App.
-// Given the bin_name "a b c" and the App for "b" this returns the "c" App.
-fn parser_of<'help, 'app>(p: &'app App<'help>, bin_name: &str) -> Option<&'app App<'help>> {
-    debug!("parser_of: p={}, bin_name={}", p.get_name(), bin_name);
-
-    if bin_name == p.get_bin_name().unwrap_or(&String::new()) {
-        return Some(p);
-    }
+fn parser_of<'help, 'app>(p: &'app App<'help>, mut sc: &str) -> &'app App<'help> {
+    debug!("parser_of: sc={}", sc);
 
-    for sc in p.get_subcommands() {
-        if let Some(ret) = parser_of(sc, bin_name) {
-            return Some(ret);
-        }
+    if sc == p.get_bin_name().unwrap_or(&String::new()) {
+        return p;
     }
 
-    None
+    sc = sc.split(' ').last().unwrap();
+    p.find_subcommand(sc).expect(INTERNAL_ERROR_MSG)
 }
 
 // Writes out the args section, which ends up being the flags, opts and positionals, and a jump to
diff --git a/examples/03_args.rs b/examples/03_args.rs
index 86cfa997..dca9d2d6 100644
--- a/examples/03_args.rs
+++ b/examples/03_args.rs
@@ -41,6 +41,7 @@ fn main() {
                 .long("config"),
             Arg::new("input")
                 .about("the input file to use")
+                .index(1)
                 .required(true),
         ])
         // *Note* the following two examples are convenience methods, if you wish
diff --git a/examples/05_flag_args.rs b/examples/05_flag_args.rs
index 28e771d3..6183a0df 100644
--- a/examples/05_flag_args.rs
+++ b/examples/05_flag_args.rs
@@ -29,8 +29,9 @@ fn main() {
                                            // also has a conflicts_with_all(Vec<&str>)
                                            // and an exclusive(true)
         )
-        .arg("-c, --config=[FILE] 'sets a custom config file'")
-        .arg("<output> 'sets an output file'")
+        // NOTE: In order to compile this example, comment out requires() and
+        // conflicts_with() because we have not defined an "output" or "config"
+        // argument.
         .get_matches();
 
     // We can find out whether or not awesome was used
diff --git a/examples/06_positional_args.rs b/examples/06_positional_args.rs
index 31d2d66f..2a2d6a64 100644
--- a/examples/06_positional_args.rs
+++ b/examples/06_positional_args.rs
@@ -33,7 +33,8 @@ fn main() {
         // requires "config"
         // Note, we also do not need to specify requires("input")
         // because requires lists are automatically two-way
-        .arg(Arg::new("output").about("the output file to use").index(3))
+        // NOTE: In order to compile this example, comment out conflicts_with()
+        // because we have not defined an "output" argument.
         .get_matches();
 
     // We can find out whether or not "input" or "config" were used
diff --git a/examples/07_option_args.rs b/examples/07_option_args.rs
index 1c5eb438..2933b71b 100644
--- a/examples/07_option_args.rs
+++ b/examples/07_option_args.rs
@@ -33,8 +33,9 @@ fn main() {
                                            // also has a conflicts_with_all(Vec<&str>)
                                            // and an exclusive(true)
         )
-        .arg("-c, --config=[FILE] 'the config file to use'")
-        .arg("<output> 'the output file to use'")
+        // NOTE: In order to compile this example, comment out conflicts_with()
+        // and requires() because we have not defined an "output" or "config"
+        // argument.
         .get_matches();
 
     // We can find out whether or not "input" was used
diff --git a/examples/14_groups.rs b/examples/14_groups.rs
index 7341193d..4fbc727d 100644
--- a/examples/14_groups.rs
+++ b/examples/14_groups.rs
@@ -34,7 +34,7 @@ fn main() {
         .group(
             ArgGroup::new("vers")
                 .required(true)
-                .args(&["set-ver", "major", "minor", "patch"]),
+                .args(&["ver", "major", "minor", "patch"]),
         )
         // Arguments can also be added to a group individually, these two arguments
         // are part of the "input" group which is not required
diff --git a/src/build/app/mod.rs b/src/build/app/mod.rs
index dc8e47bd..0216a0e8 100644
--- a/src/build/app/mod.rs
+++ b/src/build/app/mod.rs
@@ -263,8 +263,6 @@ impl<'help> App<'help> {
     }
 
     /// Find subcommand such that its name or one of aliases equals `name`.
-    ///
-    /// This does not recurse through subcommands of subcommands.
     #[inline]
     pub fn find_subcommand<T>(&self, name: &T) -> Option<&App<'help>>
     where
@@ -2141,8 +2139,6 @@ impl<'help> App<'help> {
         // Make sure all the globally set flags apply to us as well
         self.settings = self.settings | self.g_settings;
 
-        self._propagate(Propagation::Full);
-
         self._derive_display_order();
         self._create_help_and_version();
 
@@ -2246,11 +2242,8 @@ impl<'help> App<'help> {
                     $sc.max_w = $_self.max_w;
                 }
                 {
-                    // FIXME: This doesn't belong here at all.
                     for a in $_self.args.args.iter().filter(|a| a.global) {
-                        if $sc.find(&a.id).is_none() {
-                            $sc.args.push(a.clone());
-                        }
+                        $sc.args.push(a.clone());
                     }
                 }
             }};
diff --git a/src/build/arg/mod.rs b/src/build/arg/mod.rs
index 59b2e2b6..50c0cc98 100644
--- a/src/build/arg/mod.rs
+++ b/src/build/arg/mod.rs
@@ -2210,9 +2210,9 @@ impl<'help> Arg<'help> {
     /// different. `Arg::default_value` *only* takes affect when the user has not provided this arg
     /// at runtime. `Arg::default_value_if` however only takes effect when the user has not provided
     /// a value at runtime **and** these other conditions are met as well. If you have set
-    /// `Arg::default_value` and `Arg::default_value_if`, and the user **did not** provide this arg
-    /// at runtime, nor were the conditions met for `Arg::default_value_if`, the `Arg::default_value`
-    /// will be applied.
+    /// `Arg::default_value` and `Arg::default_value_if`, and the user **did not** provide a this
+    /// arg at runtime, nor did were the conditions met for `Arg::default_value_if`, the
+    /// `Arg::default_value` will be applied.
     ///
     /// **NOTE:** This implicitly sets [`Arg::takes_value(true)`].
     ///
@@ -2403,8 +2403,9 @@ impl<'help> Arg<'help> {
     /// different. `Arg::default_value` *only* takes affect when the user has not provided this arg
     /// at runtime. This setting however only takes affect when the user has not provided a value at
     /// runtime **and** these other conditions are met as well. If you have set `Arg::default_value`
-    /// and `Arg::default_value_if`, and the user **did not** provide this arg at runtime, nor were
-    /// the conditions met for `Arg::default_value_if`, the `Arg::default_value` will be applied.
+    /// and `Arg::default_value_if`, and the user **did not** provide a this arg at runtime, nor did
+    /// were the conditions met for `Arg::default_value_if`, the `Arg::default_value` will be
+    /// applied.
     ///
     /// **NOTE:** This implicitly sets [`Arg::takes_value(true)`].
     ///
diff --git a/src/output/help.rs b/src/output/help.rs
index ed11da1a..ad114a26 100644
--- a/src/output/help.rs
+++ b/src/output/help.rs
@@ -504,7 +504,7 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> {
             } else {
                 String::new()
             };
-            let env_info = format!("[env: {}{}]", env.0.to_string_lossy(), env_val);
+            let env_info = format!(" [env: {}{}]", env.0.to_string_lossy(), env_val);
             spec_vals.push(env_info);
         }
         if !a.is_set(ArgSettings::HideDefaultValue) && !a.default_vals.is_empty() {
@@ -520,7 +520,7 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> {
                 .collect::<Vec<_>>()
                 .join(" ");
 
-            spec_vals.push(format!("[default: {}]", pvs));
+            spec_vals.push(format!(" [default: {}]", pvs));
         }
         if !a.aliases.is_empty() {
             debug!("Help::spec_vals: Found aliases...{:?}", a.aliases);
@@ -534,7 +534,7 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> {
                 .join(", ");
 
             if !als.is_empty() {
-                spec_vals.push(format!("[aliases: {}]", als));
+                spec_vals.push(format!(" [aliases: {}]", als));
             }
         }
 
@@ -566,14 +566,12 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> {
                 a.possible_vals
             );
 
-            spec_vals.push(format!("[possible values: {}]", a.possible_vals.join(", ")));
+            spec_vals.push(format!(
+                " [possible values: {}]",
+                a.possible_vals.join(", ")
+            ));
         }
-        let prefix = if !spec_vals.is_empty() && !a.get_about().unwrap_or("").is_empty() {
-            " "
-        } else {
-            ""
-        };
-        prefix.to_string() + &spec_vals.join(" ")
+        spec_vals.join(" ")
     }
 }
 


Test patch:
diff --git a/clap_derive/tests/flatten.rs b/clap_derive/tests/flatten.rs
index 77f99add..702f1ae9 100644
--- a/clap_derive/tests/flatten.rs
+++ b/clap_derive/tests/flatten.rs
@@ -132,3 +132,22 @@ fn merge_subcommands_with_flatten() {
         Opt::parse_from(&["test", "command2", "43"])
     );
 }
+
+#[test]
+fn flatten_with_doc_comment() {
+    #[derive(Clap, Debug)]
+    struct DaemonOpts {
+        #[clap(short)]
+        user: String,
+        #[clap(short)]
+        group: String,
+    }
+
+    #[derive(Clap, Debug)]
+    #[clap(name = "basic")]
+    struct Opt {
+        /// A very important doc comment I just can't leave out!
+        #[clap(flatten)]
+        opts: DaemonOpts,
+    }
+}
diff --git a/clap_derive/tests/ui/flatten_and_doc.rs b/clap_derive/tests/ui/flatten_and_doc.rs
deleted file mode 100644
index dea35c23..00000000
--- a/clap_derive/tests/ui/flatten_and_doc.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use clap::Clap;
-
-#[derive(Clap, Debug)]
-struct DaemonOpts {
-    #[clap(short)]
-    user: String,
-    #[clap(short)]
-    group: String,
-}
-
-#[derive(Clap, Debug)]
-#[clap(name = "basic")]
-struct Opt {
-    /// Opts.
-    #[clap(flatten)]
-    opts: DaemonOpts,
-}
-
-fn main() {
-    let opt = Opt::parse();
-    println!("{:?}", opt);
-}
diff --git a/clap_derive/tests/ui/flatten_and_doc.stderr b/clap_derive/tests/ui/flatten_and_doc.stderr
deleted file mode 100644
index fec9a79b..00000000
--- a/clap_derive/tests/ui/flatten_and_doc.stderr
+++ /dev/null
@@ -1,5 +0,0 @@
-error: methods and doc comments are not allowed for flattened entry
-  --> $DIR/flatten_and_doc.rs:23:12
-   |
-23 |     #[clap(flatten)]
-   |            ^^^^^^^
diff --git a/clap_derive/tests/ui/flatten_and_methods.stderr b/clap_derive/tests/ui/flatten_and_methods.stderr
index 0b86ceed..772f2df8 100644
--- a/clap_derive/tests/ui/flatten_and_methods.stderr
+++ b/clap_derive/tests/ui/flatten_and_methods.stderr
@@ -1,4 +1,4 @@
-error: methods and doc comments are not allowed for flattened entry
+error: methods are not allowed for flattened entry
   --> $DIR/flatten_and_methods.rs:22:19
    |
 22 |     #[clap(short, flatten)]
diff --git a/clap_generate/tests/completions.rs b/clap_generate/tests/completions.rs
index c26ecd1a..1aa76b31 100644
--- a/clap_generate/tests/completions.rs
+++ b/clap_generate/tests/completions.rs
@@ -712,108 +712,6 @@ _my_app_commands() {
 
 _my_app "$@""#;
 
-static ZSH_NESTED_SUBCOMMANDS: &str = r#"#compdef my_app
-
-autoload -U is-at-least
-
-_my_app() {
-    typeset -A opt_args
-    typeset -a _arguments_options
-    local ret=1
-
-    if is-at-least 5.2; then
-        _arguments_options=(-s -S -C)
-    else
-        _arguments_options=(-s -C)
-    fi
-
-    local context curcontext="$curcontext" state line
-    _arguments "${_arguments_options[@]}" \
-'-h[Prints help information]' \
-'--help[Prints help information]' \
-'-V[Prints version information]' \
-'--version[Prints version information]' \
-":: :_my_app_commands" \
-"*::: :->first" \
-&& ret=0
-    case $state in
-    (first)
-        words=($line[1] "${words[@]}")
-        (( CURRENT += 1 ))
-        curcontext="${curcontext%:*:*}:my_app-command-$line[1]:"
-        case $line[1] in
-            (second)
-_arguments "${_arguments_options[@]}" \
-'-h[Prints help information]' \
-'--help[Prints help information]' \
-'-V[Prints version information]' \
-'--version[Prints version information]' \
-":: :_my_app__second_commands" \
-"*::: :->second" \
-&& ret=0
-case $state in
-    (second)
-        words=($line[1] "${words[@]}")
-        (( CURRENT += 1 ))
-        curcontext="${curcontext%:*:*}:my_app-second-command-$line[1]:"
-        case $line[1] in
-            (third)
-_arguments "${_arguments_options[@]}" \
-'-h[Prints help information]' \
-'--help[Prints help information]' \
-'-V[Prints version information]' \
-'--version[Prints version information]' \
-&& ret=0
-;;
-        esac
-    ;;
-esac
-;;
-(help)
-_arguments "${_arguments_options[@]}" \
-'-h[Prints help information]' \
-'--help[Prints help information]' \
-'-V[Prints version information]' \
-'--version[Prints version information]' \
-&& ret=0
-;;
-        esac
-    ;;
-esac
-}
-
-(( $+functions[_my_app_commands] )) ||
-_my_app_commands() {
-    local commands; commands=(
-        "second:" \
-"help:Prints this message or the help of the given subcommand(s)" \
-    )
-    _describe -t commands 'my_app commands' commands "$@"
-}
-(( $+functions[_my_app__help_commands] )) ||
-_my_app__help_commands() {
-    local commands; commands=(
-        
-    )
-    _describe -t commands 'my_app help commands' commands "$@"
-}
-(( $+functions[_my_app__second_commands] )) ||
-_my_app__second_commands() {
-    local commands; commands=(
-        "third:" \
-    )
-    _describe -t commands 'my_app second commands' commands "$@"
-}
-(( $+functions[_my_app__second__third_commands] )) ||
-_my_app__second__third_commands() {
-    local commands; commands=(
-        
-    )
-    _describe -t commands 'my_app second third commands' commands "$@"
-}
-
-_my_app "$@""#;
-
 fn build_app() -> App<'static> {
     build_app_with_name("myapp")
 }
@@ -879,10 +777,6 @@ fn build_app_special_help() -> App<'static> {
         )
 }
 
-fn build_app_nested_subcommands() -> App<'static> {
-    App::new("first").subcommand(App::new("second").subcommand(App::new("third")))
-}
-
 pub fn common<G: Generator>(app: &mut App, name: &str, fixture: &str) {
     let mut buf = vec![];
     generate::<G, _>(app, name, &mut buf);
@@ -962,9 +856,3 @@ fn zsh_with_special_help() {
     let mut app = build_app_special_help();
     common::<Zsh>(&mut app, "my_app", ZSH_SPECIAL_HELP);
 }
-
-#[test]
-fn zsh_with_nested_subcommands() {
-    let mut app = build_app_nested_subcommands();
-    common::<Zsh>(&mut app, "my_app", ZSH_NESTED_SUBCOMMANDS);
-}
diff --git a/src/build/app/tests.rs b/src/build/app/tests.rs
index 2f9aaa25..bdf21114 100644
--- a/src/build/app/tests.rs
+++ b/src/build/app/tests.rs
@@ -51,13 +51,3 @@ fn app_send_sync() {
     fn foo<T: Send + Sync>(_: T) {}
     foo(App::new("test"))
 }
-
-#[test]
-fn issue_2090() {
-    let mut app = App::new("app")
-        .global_setting(AppSettings::DisableVersion)
-        .subcommand(App::new("sub"));
-    app._build();
-
-    assert!(app.subcommands[0].is_set(AppSettings::DisableVersion));
-}
diff --git a/tests/arg_aliases.rs b/tests/arg_aliases.rs
index 41643e14..46e179ba 100644
--- a/tests/arg_aliases.rs
+++ b/tests/arg_aliases.rs
@@ -9,12 +9,12 @@ USAGE:
     ct test [FLAGS] [OPTIONS]
 
 FLAGS:
-    -f, --flag       [aliases: v_flg, flag2, flg3]
+    -f, --flag        [aliases: v_flg, flag2, flg3]
     -h, --help       Prints help information
     -V, --version    Prints version information
 
 OPTIONS:
-    -o, --opt <opt>    [aliases: visible]";
+    -o, --opt <opt>     [aliases: visible]";
 
 static SC_INVISIBLE_ALIAS_HELP: &str = "ct-test 1.2
 Some help
diff --git a/tests/arg_aliases_short.rs b/tests/arg_aliases_short.rs
index 102b0f87..865dc8bc 100644
--- a/tests/arg_aliases_short.rs
+++ b/tests/arg_aliases_short.rs
@@ -9,7 +9,7 @@ USAGE:
     ct test [FLAGS] [OPTIONS]
 
 FLAGS:
-    -f, --flag       [aliases: flag1] [short aliases: a, b, 🦆]
+    -f, --flag        [aliases: flag1] [short aliases: a, b, 🦆]
     -h, --help       Prints help information
     -V, --version    Prints version information
 
diff --git a/tests/examples.rs b/tests/examples.rs
deleted file mode 100644
index 2c080256..00000000
--- a/tests/examples.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-#![cfg(not(tarpaulin))]
-
-use std::ffi::OsStr;
-use std::fs;
-use std::process::{Command, Output};
-
-fn run_example<S: AsRef<str>>(name: S, args: &[&str]) -> Output {
-    let mut all_args = vec![
-        "run",
-        "--example",
-        name.as_ref(),
-        "--features",
-        "yaml unstable",
-        "--",
-    ];
-    all_args.extend_from_slice(args);
-
-    Command::new(env!("CARGO"))
-        .args(all_args)
-        .output()
-        .expect("failed to run example")
-}
-
-#[test]
-fn examples_are_functional() {
-    let example_paths = fs::read_dir("examples")
-        .expect("couldn't read examples directory")
-        .map(|result| result.expect("couldn't get directory entry").path())
-        .filter(|path| path.is_file() && path.extension().and_then(OsStr::to_str) == Some("rs"));
-
-    let mut example_count = 0;
-    for path in example_paths {
-        example_count += 1;
-
-        let example_name = path
-            .file_stem()
-            .and_then(OsStr::to_str)
-            .expect("unable to determine example name");
-
-        let help_output = run_example(example_name, &["--help"]);
-        assert!(
-            help_output.status.success(),
-            "{} --help exited with nonzero",
-            example_name,
-        );
-        assert!(
-            !help_output.stdout.is_empty(),
-            "{} --help had no output",
-            example_name,
-        );
-    }
-    assert!(example_count > 0);
-}