Repository: clap-rs/clap (language: rust)

Issue:
Argument with `last` option set, still requires specifying its index
### Please complete the following tasks

- [X] I have searched the [discussions](https://github.com/clap-rs/clap/discussions)
- [X] I have searched the [open](https://github.com/clap-rs/clap/issues) and [rejected](https://github.com/clap-rs/clap/issues?q=is%3Aissue+label%3AS-wont-fix+is%3Aclosed) issues

### Rust Version

1.61.0-nightly

### Clap Version

3.1.6

### Minimal reproducible code

```rust
use clap::{Arg, Command};

fn main() {
    let cmd = Command::new("app")
        .arg(Arg::new("script").value_name("SCRIPT").index(1))
        .arg(
            Arg::new("args")
                .value_name("ARGS")
                .takes_value(true)
                .multiple_values(true)
                .last(true),
        );
    let matches = cmd.get_matches();
    println!("{:?}", matches);
}
```


### Steps to reproduce the bug with the above code

```terminal
cargo run app parser.sh -- strict raw
```

### Actual Behaviour

It should correctly accept multiple additional arguments after `--` delimiter.

### Expected Behaviour

```terminal
thread 'main' panicked at 'Command app: Argument 'script' has the same index as 'args' and they are both positional arguments

         Use Arg::multiple_values(true) to allow one positional argument to take multiple values', /Users/kamilogorek/.cargo/registry/src/github.com-1ecc6299db9ec823/clap-3.1.8/src/build/debug_asserts.rs:116:17
```

### Additional Context

This is currently fixable by adding `index(2)` to the argument that has `.last(true)` set. However, the docs state that it should be already done by adding the `last` option itself:

> This arg is the last, or final, positional argument (i.e. has the highest index) 

### Debug Output

```terminal
[        clap::build::command]  App::_do_parse
[        clap::build::command]  App::_build
[        clap::build::command]  App::_propagate:app
[        clap::build::command]  App::_check_help_and_version: app
[        clap::build::command]  App::_check_help_and_version: Removing generated version
[        clap::build::command]  App::_propagate_global_args:app
[        clap::build::command]  App::_derive_display_order:app
[  clap::build::debug_asserts]  Command::_debug_asserts
[  clap::build::debug_asserts]  Arg::_debug_asserts:help
[  clap::build::debug_asserts]  Arg::_debug_asserts:script
thread 'main' panicked at 'Command app: Argument 'script' has the same index as 'args' and they are both positional arguments

         Use Arg::multiple_values(true) to allow one positional argument to take multiple values', /Users/kamilogorek/.cargo/registry/src/github.com-1ecc6299db9ec823/clap-3.1.8/src/build/debug_asserts.rs:116:17
stack backtrace:
   0: rust_begin_unwind
             at /rustc/03918badd33d255de806b4a9a8aa75b031ed0738/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /rustc/03918badd33d255de806b4a9a8aa75b031ed0738/library/core/src/panicking.rs:143:14
   2: clap::build::debug_asserts::assert_app
             at /Users/kamilogorek/.cargo/registry/src/github.com-1ecc6299db9ec823/clap-3.1.8/src/build/debug_asserts.rs:116:17
   3: clap::build::command::App::_build
             at /Users/kamilogorek/.cargo/registry/src/github.com-1ecc6299db9ec823/clap-3.1.8/src/build/command.rs:4101:13
   4: clap::build::command::App::_do_parse
             at /Users/kamilogorek/.cargo/registry/src/github.com-1ecc6299db9ec823/clap-3.1.8/src/build/command.rs:3965:9
   5: clap::build::command::App::try_get_matches_from_mut
             at /Users/kamilogorek/.cargo/registry/src/github.com-1ecc6299db9ec823/clap-3.1.8/src/build/command.rs:681:9
   6: clap::build::command::App::get_matches_from
             at /Users/kamilogorek/.cargo/registry/src/github.com-1ecc6299db9ec823/clap-3.1.8/src/build/command.rs:551:9
   7: clap::build::command::App::get_matches
             at /Users/kamilogorek/.cargo/registry/src/github.com-1ecc6299db9ec823/clap-3.1.8/src/build/command.rs:463:9
   8: clap_bug::main
             at ./src/main.rs:13:19
   9: core::ops::function::FnOnce::call_once
             at /rustc/03918badd33d255de806b4a9a8aa75b031ed0738/library/core/src/ops/function.rs:227:5
```


Discussion / hints:
I'm assuming if you do not set `index(1)` it will work.

We will infer indexes.  Our counter starts at 1 and is only incremented on positional arguments without an index.  For us to do otherwise would require us to collect a list of all set indexes and skip over those, hoping that that is what the user intended.

Overall, I think we should remove `index` from all of our examples as it should be rare that someone needs to set it manually.
I can confirm that it works without explicit indexes. I'm fine with that solution, so feel free to close this issue if you think is the intended behavior. Thanks!

Fix patch:
diff --git a/src/build/arg.rs b/src/build/arg.rs
index 452880d2649..7be3cc9f598 100644
--- a/src/build/arg.rs
+++ b/src/build/arg.rs
@@ -648,8 +648,7 @@ impl<'help> Arg<'help> {
     ///         .takes_value(true)
     ///         .requires("input")
     ///         .long("config"))
-    ///     .arg(Arg::new("input")
-    ///         .index(1))
+    ///     .arg(Arg::new("input"))
     ///     .try_get_matches_from(vec![
     ///         "prog"
     ///     ]);
@@ -666,8 +665,7 @@ impl<'help> Arg<'help> {
     ///         .takes_value(true)
     ///         .requires("input")
     ///         .long("config"))
-    ///     .arg(Arg::new("input")
-    ///         .index(1))
+    ///     .arg(Arg::new("input"))
     ///     .try_get_matches_from(vec![
     ///         "prog", "--config", "file.conf"
     ///     ]);
@@ -707,8 +705,7 @@ impl<'help> Arg<'help> {
     ///         .long("exclusive"))
     ///     .arg(Arg::new("debug")
     ///         .long("debug"))
-    ///     .arg(Arg::new("input")
-    ///         .index(1))
+    ///     .arg(Arg::new("input"))
     ///     .try_get_matches_from(vec![
     ///         "prog", "--exclusive", "file.conf", "file.txt"
     ///     ]);
@@ -1097,8 +1094,7 @@ impl<'help> Arg<'help> {
     ///         .takes_value(true)
     ///         .multiple_values(true)
     ///         .short('F'))
-    ///     .arg(Arg::new("word")
-    ///         .index(1))
+    ///     .arg(Arg::new("word"))
     ///     .get_matches_from(vec![
     ///         "prog", "-F", "file1", "file2", "file3", "word"
     ///     ]);
@@ -1123,8 +1119,7 @@ impl<'help> Arg<'help> {
     ///         .takes_value(true)
     ///         .multiple_occurrences(true)
     ///         .short('F'))
-    ///     .arg(Arg::new("word")
-    ///         .index(1))
+    ///     .arg(Arg::new("word"))
     ///     .get_matches_from(vec![
     ///         "prog", "-F", "file1", "-F", "file2", "-F", "file3", "word"
     ///     ]);
@@ -1145,8 +1140,7 @@ impl<'help> Arg<'help> {
     ///         .takes_value(true)
     ///         .multiple_occurrences(true)
     ///         .short('F'))
-    ///     .arg(Arg::new("word")
-    ///         .index(1))
+    ///     .arg(Arg::new("word"))
     ///     .try_get_matches_from(vec![
     ///         "prog", "-F", "file1", "file2", "file3", "word"
     ///     ]);
@@ -1518,7 +1512,6 @@ impl<'help> Arg<'help> {
     /// }
     /// let res = Command::new("prog")
     ///     .arg(Arg::new("file")
-    ///         .index(1)
     ///         .validator(has_at))
     ///     .try_get_matches_from(vec![
     ///         "prog", "some@file"
@@ -1558,7 +1551,6 @@ impl<'help> Arg<'help> {
     /// }
     /// let res = Command::new("prog")
     ///     .arg(Arg::new("file")
-    ///         .index(1)
     ///         .validator_os(has_ampersand))
     ///     .try_get_matches_from(vec![
     ///         "prog", "Fish & chips"
@@ -1610,7 +1602,6 @@ impl<'help> Arg<'help> {
     ///
     /// let res = Command::new("prog")
     ///     .arg(Arg::new("digits")
-    ///         .index(1)
     ///         .validator_regex(&digits, "only digits are allowed"))
     ///     .try_get_matches_from(vec![
     ///         "prog", "12345"
@@ -1629,7 +1620,6 @@ impl<'help> Arg<'help> {
     ///
     /// let res = Command::new("prog")
     ///     .arg(Arg::new("priority")
-    ///         .index(1)
     ///         .validator_regex(priority, "only priorities A, B or C are allowed"))
     ///     .try_get_matches_from(vec![
     ///         "prog", "12345"
@@ -4203,10 +4193,8 @@ impl<'help> Arg<'help> {
     ///         .takes_value(true)
     ///         .requires("input")
     ///         .long("config"))
-    ///     .arg(Arg::new("input")
-    ///         .index(1))
-    ///     .arg(Arg::new("output")
-    ///         .index(2))
+    ///     .arg(Arg::new("input"))
+    ///     .arg(Arg::new("output"))
     ///     .try_get_matches_from(vec![
     ///         "prog"
     ///     ]);
@@ -4224,10 +4212,8 @@ impl<'help> Arg<'help> {
     ///         .takes_value(true)
     ///         .requires_all(&["input", "output"])
     ///         .long("config"))
-    ///     .arg(Arg::new("input")
-    ///         .index(1))
-    ///     .arg(Arg::new("output")
-    ///         .index(2))
+    ///     .arg(Arg::new("input"))
+    ///     .arg(Arg::new("output"))
     ///     .try_get_matches_from(vec![
     ///         "prog", "--config", "file.conf", "in.txt"
     ///     ]);
@@ -4328,8 +4314,7 @@ impl<'help> Arg<'help> {
     ///         .long("config"))
     ///     .arg(Arg::new("debug")
     ///         .long("debug"))
-    ///     .arg(Arg::new("input")
-    ///         .index(1))
+    ///     .arg(Arg::new("input"))
     ///     .try_get_matches_from(vec![
     ///         "prog", "--config", "file.conf", "file.txt"
     ///     ]);
diff --git a/src/build/command.rs b/src/build/command.rs
index 719d12ddd6a..03e4e00c910 100644
--- a/src/build/command.rs
+++ b/src/build/command.rs
@@ -58,7 +58,7 @@ use crate::build::debug_asserts::assert_app;
 ///     .version("1.0.2")
 ///     .about("Explains in brief what the program does")
 ///     .arg(
-///         Arg::new("in_file").index(1)
+///         Arg::new("in_file")
 ///     )
 ///     .after_help("Longer explanation to appear after the options when \
 ///                  displaying the help information from --help or -h")
@@ -202,7 +202,7 @@ impl<'help> App<'help> {
     /// Command::new("myprog")
     ///     .args(&[
     ///         arg!("[debug] -d 'turns on debugging info'"),
-    ///         Arg::new("input").index(1).help("the input file to use")
+    ///         Arg::new("input").help("the input file to use")
     ///     ])
     /// # ;
     /// ```
@@ -378,7 +378,7 @@ impl<'help> App<'help> {
     /// # Command::new("myprog")
     /// .subcommands( vec![
     ///        Command::new("config").about("Controls configuration functionality")
-    ///                                 .arg(Arg::new("config_file").index(1)),
+    ///                                 .arg(Arg::new("config_file")),
     ///        Command::new("debug").about("Controls debug functionality")])
     /// # ;
     /// ```
@@ -2347,7 +2347,6 @@ impl<'help> App<'help> {
     ///         .aliases(&["do-stuff", "do-tests", "tests"]))
     ///         .arg(Arg::new("input")
     ///             .help("the file to add")
-    ///             .index(1)
     ///             .required(false))
     ///     .get_matches_from(vec!["myprog", "do-tests"]);
     /// assert_eq!(m.subcommand_name(), Some("test"));
@@ -2374,7 +2373,6 @@ impl<'help> App<'help> {
     ///         .short_flag_aliases(&['a', 'b', 'c']))
     ///         .arg(Arg::new("input")
     ///             .help("the file to add")
-    ///             .index(1)
     ///             .required(false))
     ///     .get_matches_from(vec!["myprog", "-a"]);
     /// assert_eq!(m.subcommand_name(), Some("test"));
@@ -2403,7 +2401,6 @@ impl<'help> App<'help> {
     ///                 .long_flag_aliases(&["testing", "testall", "test_all"]))
     ///                 .arg(Arg::new("input")
     ///                             .help("the file to add")
-    ///                             .index(1)
     ///                             .required(false))
     ///             .get_matches_from(vec!["myprog", "--testing"]);
     /// assert_eq!(m.subcommand_name(), Some("test"));
diff --git a/src/error/kind.rs b/src/error/kind.rs
index 1d27f433d62..2c7c422a634 100644
--- a/src/error/kind.rs
+++ b/src/error/kind.rs
@@ -47,8 +47,7 @@ pub enum ErrorKind {
     ///     .subcommand(Command::new("config")
     ///         .about("Used for configuration")
     ///         .arg(Arg::new("config_file")
-    ///             .help("The configuration file to use")
-    ///             .index(1)))
+    ///             .help("The configuration file to use")))
     ///     .try_get_matches_from(vec!["prog", "confi"]);
     /// assert!(result.is_err());
     /// assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidSubcommand);
@@ -74,8 +73,7 @@ pub enum ErrorKind {
     ///     .subcommand(Command::new("config")
     ///         .about("Used for configuration")
     ///         .arg(Arg::new("config_file")
-    ///             .help("The configuration file to use")
-    ///             .index(1)))
+    ///             .help("The configuration file to use")))
     ///     .try_get_matches_from(vec!["prog", "help", "nothing"]);
     /// assert!(result.is_err());
     /// assert_eq!(result.unwrap_err().kind(), ErrorKind::UnrecognizedSubcommand);


Test patch: