Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve missing @ in slice binding pattern diagnostics #72534

Merged
merged 1 commit into from
May 29, 2020

Conversation

chrissimpkins
Copy link
Member

@chrissimpkins chrissimpkins commented May 24, 2020

Closes #72373

Includes a new suggestion with Applicability::MaybeIncorrect confidence level.

Before:

 --> src/main.rs:5:19
  |
5 |         [h, ref ts..] => foo(c, n - h) + foo(ts, n),
  |                   -^
  |                   |
  |                   expected one of `,`, `@`, `]`, or `|`
  |                   help: missing `,`

error[E0308]: mismatched types
 --> src/main.rs:5:46
  |
5 |         [h, ref ts..] => foo(c, n - h) + foo(ts, n),
  |                                              ^^ expected slice `[u32]`, found `u32`
  |
  = note: expected reference `&[u32]`
             found reference `&u32`

error: aborting due to 2 previous errors

After:

error: expected one of `,`, `@`, `]`, or `|`, found `..`
 --> src/main.rs:5:20
  |
5 |         [h, ref ts..] => foo(c, n - h) + foo(ts, n),
  |                    ^^ expected one of `,`, `@`, `]`, or `|`
  |
help: if you meant to bind the contents of the rest of the array pattern into `ts`, use `@`
  |
5 |         [h, ref ts @ ..] => foo(c, n - h) + foo(ts, n),
  |                    ^

error: aborting due to previous error

r? @estebank

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 24, 2020
expect_err
.span_suggestion_short(
self.token.span,
&format!("maybe missing `@` in binding pattern?"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
&format!("maybe missing `@` in binding pattern?"),
"maybe missing `@` in binding pattern?",

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we would want to change the message to be something like "if you meant to bind the contents of the rest of the array pattern into ts, use @. It would also be beneficial to verify that we are in an array pattern (but if it makes the code much more convoluted, we can skip that check).

Copy link
Member Author

@chrissimpkins chrissimpkins May 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0fdd31317a9c8d2fbc284546c711bc5d5139d83b

I was able to pull the name from the previous Ident token with pprust::token_to_string.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would also be beneficial to verify that we are in an array pattern (but if it makes the code much more convoluted, we can skip that check).

Is this valid in tuples too?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like that message could be cleaned up too:

error: `..` patterns are not allowed here
 --> src/main.rs:4:15
  |
4 |         (a, x@..) => {}
  |               ^^
  |
  = note: only allowed in tuple, tuple struct, and slice patterns

That note appears to be incorrect and the error should indicate @ .. are not allowed in the tuple, not ..?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked this for tuple structs and the same message appears. I will open a new issue for this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/librustc_parse/parser/mod.rs Outdated Show resolved Hide resolved
src/librustc_parse/parser/mod.rs Outdated Show resolved Hide resolved
@chrissimpkins
Copy link
Member Author

Thanks Esteban! Responses inline

@rust-highfive
Copy link
Collaborator

The job mingw-check of your PR failed (pretty log, raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
##[section]Starting: Linux mingw-check
##[section]Starting: Initialize job
Agent name: 'Azure Pipelines 24'
Agent machine name: 'fv-az578'
Current agent version: '2.169.0'
##[group]Operating System
16.04.6
LTS
LTS
##[endgroup]
##[group]Virtual Environment
Environment: ubuntu-16.04
Version: 20200517.1
Included Software: https://github.com/actions/virtual-environments/blob/ubuntu16/20200517.1/images/linux/Ubuntu1604-README.md
##[endgroup]
Agent running as: 'vsts'
Prepare build directory.
Set build variables.
Download all required tasks.
Download all required tasks.
Downloading task: Bash (3.163.2)
Checking job knob settings.
   Knob: AgentToolsDirectory = /opt/hostedtoolcache Source: ${AGENT_TOOLSDIRECTORY} 
   Knob: AgentPerflog = /home/vsts/perflog Source: ${VSTS_AGENT_PERFLOG} 
Start tracking orphan processes.
##[section]Finishing: Initialize job
##[section]Starting: Configure Job Name
==============================================================================
---
========================== Starting Command Output ===========================
[command]/bin/bash --noprofile --norc /home/vsts/work/_temp/0afdd8a5-ac7e-4afb-8651-454d63e6b472.sh

##[section]Finishing: Disable git automatic line ending conversion
##[section]Starting: Checkout rust-lang/rust@refs/pull/72534/merge to s
Task         : Get sources
Description  : Get sources from a repository. Supports Git, TfsVC, and SVN repositories.
Version      : 1.0.0
Author       : Microsoft
---
##[command]git remote add origin https://github.com/rust-lang/rust
##[command]git config gc.auto 0
##[command]git config --get-all http.https://github.com/rust-lang/rust.extraheader
##[command]git config --get-all http.proxy
##[command]git -c http.extraheader="AUTHORIZATION: basic ***" fetch --force --tags --prune --progress --no-recurse-submodules --depth=2 origin +refs/heads/*:refs/remotes/origin/* +refs/pull/72534/merge:refs/remotes/pull/72534/merge
---
 ---> 3adb0605cc65
Step 6/7 : ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1
 ---> Using cache
 ---> 28dbc326cb7f
Step 7/7 : ENV SCRIPT python3 ../x.py test src/tools/expand-yaml-anchors &&            python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu &&            python3 ../x.py build --stage 0 src/tools/build-manifest &&            python3 ../x.py test --stage 0 src/tools/compiletest &&            python3 ../x.py test src/tools/tidy &&            python3 ../x.py doc --stage 0 src/libstd &&            /scripts/validate-toolstate.sh
 ---> 537a01811900
Successfully built 537a01811900
Successfully tagged rust-ci:latest
Built container sha256:537a018119009dc218456238dec90b5530050db1e2a1e166550c218003f6159d
---
    Checking rustc_feature v0.0.0 (/checkout/src/librustc_feature)
    Checking fmt_macros v0.0.0 (/checkout/src/libfmt_macros)
    Checking rustc_ast_pretty v0.0.0 (/checkout/src/librustc_ast_pretty)
    Checking rustc_hir v0.0.0 (/checkout/src/librustc_hir)
    Checking rustc_query_system v0.0.0 (/checkout/src/librustc_query_system)
    Checking chalk-rust-ir v0.10.0
    Checking chalk-solve v0.10.0
    Checking rustc_hir_pretty v0.0.0 (/checkout/src/librustc_hir_pretty)
    Checking rustc_parse v0.0.0 (/checkout/src/librustc_parse)
    Checking rustc_ast_lowering v0.0.0 (/checkout/src/librustc_ast_lowering)
---
configure: rust.channel         := nightly
configure: build.locked-deps    := True
configure: dist.missing-tools   := True
configure: build.cargo-native-static := True
configure: build.configure-args := ['--enable-sccache', '--disable-manage-submodu ...
configure: writing `config.toml` in current directory
configure: 
configure: run `python /checkout/x.py --help`
configure: 
---
Hugepagesize:       2048 kB
DirectMap4k:      159680 kB
DirectMap2M:     4034560 kB
DirectMap1G:     5242880 kB
+ python3 ../x.py test src/tools/expand-yaml-anchors
Ensuring the YAML anchors in the GitHub Actions config were expanded
Ensuring the YAML anchors in the GitHub Actions config were expanded
Building stage0 tool expand-yaml-anchors (x86_64-unknown-linux-gnu)
   Compiling unicode-xid v0.2.0
   Compiling syn v1.0.11
   Compiling linked-hash-map v0.5.2
   Compiling lazy_static v1.4.0
   Compiling lazy_static v1.4.0
   Compiling yaml-rust v0.4.3
   Compiling quote v1.0.2
   Compiling thiserror-impl v1.0.5
   Compiling thiserror v1.0.5
   Compiling yaml-merge-keys v0.4.0
   Compiling expand-yaml-anchors v0.1.0 (/checkout/src/tools/expand-yaml-anchors)
Build completed successfully in 0:00:31
+ python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu
    Finished dev [unoptimized] target(s) in 0.24s
Checking rustdoc artifacts (x86_64-unknown-linux-gnu -> i686-pc-windows-gnu)
---
    Checking rustc_feature v0.0.0 (/checkout/src/librustc_feature)
    Checking fmt_macros v0.0.0 (/checkout/src/libfmt_macros)
    Checking rustc_ast_pretty v0.0.0 (/checkout/src/librustc_ast_pretty)
    Checking rustc_hir v0.0.0 (/checkout/src/librustc_hir)
    Checking chalk-rust-ir v0.10.0
    Checking rustc_query_system v0.0.0 (/checkout/src/librustc_query_system)
    Checking chalk-solve v0.10.0
    Checking rustc_hir_pretty v0.0.0 (/checkout/src/librustc_hir_pretty)
    Checking rustc_parse v0.0.0 (/checkout/src/librustc_parse)
    Checking rustc_ast_lowering v0.0.0 (/checkout/src/librustc_ast_lowering)
---
skip untracked path cpu-usage.csv during rustfmt invocations
skip untracked path src/doc/book/ during rustfmt invocations
skip untracked path src/doc/rust-by-example/ during rustfmt invocations
skip untracked path src/llvm-project/ during rustfmt invocations
Diff in /checkout/src/librustc_parse/parser/mod.rs at line 676:
                             // bail with a suggestion
                             // ***/issues/72373
                             if self.prev_token.is_ident() && &self.token.kind == &token::DotDot {
-                                let msg = &format!("if you meant to bind the contents of \
+                                let msg = &format!(
+                                    "if you meant to bind the contents of \
                                     the rest of the array pattern into `{}`, use `@`",
-                                    pprust::token_to_string(&self.prev_token));
+                                    pprust::token_to_string(&self.prev_token)
                                 expect_err
                                     .span_suggestion_verbose(
                                         self.token.span,
                                         self.token.span,
Running `"/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/rustfmt" "--config-path" "/checkout" "--edition" "2018" "--unstable-features" "--skip-children" "--check" "/checkout/src/librustc_parse/parser/mod.rs"` failed.
If you're running `tidy`, try again with `--bless`. Or, if you just want to format code, run `./x.py fmt` instead.
Build completed unsuccessfully in 0:00:43
== clock drift check ==
  local time: Sun May 24 23:07:03 UTC 2020
  network time: Sun, 24 May 2020 23:07:03 GMT
  network time: Sun, 24 May 2020 23:07:03 GMT
== end clock drift check ==

##[error]Bash exited with code '1'.
##[section]Finishing: Run build
##[section]Starting: Checkout rust-lang/rust@refs/pull/72534/merge to s
Task         : Get sources
Description  : Get sources from a repository. Supports Git, TfsVC, and SVN repositories.
Version      : 1.0.0
Author       : Microsoft
Author       : Microsoft
Help         : [More Information](https://go.microsoft.com/fwlink/?LinkId=798199)
==============================================================================
Cleaning any cached credential from repository: rust-lang/rust (GitHub)
##[section]Finishing: Checkout rust-lang/rust@refs/pull/72534/merge to s
Cleaning up task key
Start cleaning up orphan processes.
Terminate orphan process: pid (3706) (python)
##[section]Finishing: Finalize Job

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @rust-lang/infra. (Feature Requests)

src/librustc_parse/parser/mod.rs Outdated Show resolved Hide resolved
expect_err
.span_suggestion_short(
self.token.span,
&format!("maybe missing `@` in binding pattern?"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@estebank estebank left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to run ./x.py fmt. Other than that, and a couple of nitpicks, r=me!

@chrissimpkins
Copy link
Member Author

chrissimpkins commented May 25, 2020

I believe that everything is addressed as of 04cc168 except the check that we are in a slice from your comment in #72534 (comment).

I'll take a look into this tomorrow. Please let me know if you have any suggestions about where to start.

@chrissimpkins
Copy link
Member Author

chrissimpkins commented May 25, 2020

[ No longer an issue. Addressed in https://github.com//pull/72534#issuecomment-634759671 ]

These changes lead to an ICE when I try to compile the following:

fn main() {
    let x = (1, 2, 3);
    match x {
        (_a, 1, 1) => {}
        (_a, ..) => {}
    }
}

thread 'rustc' panicked at 'assertion failed: should_monomorphize_locally(tcx, &instance)', src/librustc_mir/monomorphize/collector.rs:366:13

Backtrace

export RUST_BACKTRACE=1; cargo +stage1 build
   Compiling binding2 v0.1.0 (/Users/chris/Desktop/tests/rustlang-tests/binding2)
thread 'rustc' panicked at 'assertion failed: should_monomorphize_locally(tcx, &instance)', src/librustc_mir/monomorphize/collector.rs:366:13
stack backtrace:
   0: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
   1: core::fmt::write
   2: std::io::Write::write_fmt
   3: std::sys_common::backtrace::print
   4: std::panicking::default_hook::{{closure}}
   5: std::panicking::default_hook
   6: rustc_driver::report_ice
   7: std::panicking::rust_panic_with_hook
   8: std::panicking::begin_panic
   9: rustc_mir::monomorphize::collector::collect_items_rec
  10: rustc_session::utils::<impl rustc_session::session::Session>::time
  11: rustc_mir::monomorphize::collector::collect_crate_mono_items
  12: rustc_mir::monomorphize::partitioning::collect_and_partition_mono_items
  13: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::collect_and_partition_mono_items>::compute
  14: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  15: rustc_data_structures::stack::ensure_sufficient_stack
  16: rustc_query_system::query::plumbing::get_query_impl
  17: rustc_codegen_ssa::base::codegen_crate
  18: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::backend::CodegenBackend>::codegen_crate
  19: rustc_session::utils::<impl rustc_session::session::Session>::time
  20: rustc_middle::ty::context::tls::enter_global
  21: rustc_interface::queries::Query<T>::compute
  22: rustc_interface::queries::Queries::ongoing_codegen
  23: rustc_interface::interface::run_compiler_in_existing_thread_pool
  24: rustc_ast::attr::with_globals
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.45.0-dev running on x86_64-apple-darwin

note: compiler flags: -C embed-bitcode=no -C debuginfo=2 -C incremental --crate-type bin

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
#0 [collect_and_partition_mono_items] collect_and_partition_mono_items
end of query stack

I don't see this on rustc 1.45.0-nightly (46e85b4 2020-05-24), rustc 1.44.0-beta.4 (02c25b3 2020-05-23), or rustc 1.43.1 (8d69840 2020-05-04).

When I compile the following (with the @ .. idiom):

fn main() {
    let x = (1, 2, 3);
    match x {
        (_a, 1, 1) => {}
        (_a, _x @ ..) => {}
    }
}

I get the expected error message that needs to be fixed (#72574) - notably, our changes here do not modify the diagnostics for tuples (or tuple structs, see next post):

cargo +stage1 build
   Compiling binding2 v0.1.0 (/Users/chris/Desktop/tests/rustlang-tests/binding2)
error: `..` patterns are not allowed here
 --> src/main.rs:5:19
  |
5 |         (_a, _x @ ..) => {}
  |                   ^^
  |
  = note: only allowed in tuple, tuple struct, and slice patterns

error[E0308]: mismatched types
 --> src/main.rs:5:9
  |
3 |     match x {
  |           - this expression has type `({integer}, {integer}, {integer})`
4 |         (_a, 1, 1) => {}
5 |         (_a, _x @ ..) => {}
  |         ^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 2 elements
  |
  = note: expected tuple `({integer}, {integer}, {integer})`
             found tuple `(_, _)`

error: aborting due to 2 previous errors

Thoughts? It is not clear to me what I am modifying that leads to this problem. The conditions for the new block of code are not met and it is not executed in the source that leads to an ICE.

@chrissimpkins
Copy link
Member Author

chrissimpkins commented May 25, 2020

[ No longer an issue. Addressed in https://github.com//pull/72534#issuecomment-634759671 ]

Tuple structs ICE too. I see the same ICE with the changes in this PR and the following source:

struct Binder(i32, i32, i32);

fn main() {
    let x = Binder(1, 2, 3);
    match x {
        Binder(_a, 1, 1) => {}
        Binder(_a, ..) => {}
    }
}

I see the #72574 error message when this is changed to use Binder(_a, _x @ ..) => {}

@chrissimpkins
Copy link
Member Author

Rebased on acfc558 and rebuilt stage 1 rustc from scratch without incremental compilation. This addressed the ICE issues for tuples and tuple structs above. If the CI passes here, I will squash commits and push.

I think that we are gtg.

… rest pattern

add issue 72373 tests


fmt test


fix suggestion format

Replacement, not insertion of suggested string

implement review changes

refactor to span_suggestion_verbose, improve suggestion message,  change id @ pattern space formatting

fmt


fix diagnostics spacing between ident and @


refactor reference
@chrissimpkins
Copy link
Member Author

chrissimpkins commented May 27, 2020

CI passed. Squashed and pushed.

#72534 (comment) was addressed by opening a new IR (#72574). I'll have a look at that in a new PR (#72677). I can confirm that these changes do not impact diagnostics for tuples or tuple structs with the @ .. idiom.

gtg from my standpoint.

@estebank
Copy link
Contributor

@bors r+ rollup

@bors
Copy link
Contributor

bors commented May 28, 2020

📌 Commit 593d1ee has been approved by estebank

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 28, 2020
bors added a commit to rust-lang-ci/rust that referenced this pull request May 29, 2020
Rollup of 11 pull requests

Successful merges:

 - rust-lang#71633 (Impl Error for Infallible)
 - rust-lang#71843 (Tweak and stabilize AtomicN::fetch_update)
 - rust-lang#72288 (Stabilization of weak-into-raw)
 - rust-lang#72324 (Stabilize AtomicN::fetch_min and AtomicN::fetch_max)
 - rust-lang#72452 (Clarified the documentation for Formatter::precision)
 - rust-lang#72495 (Improve E0601 explanation)
 - rust-lang#72534 (Improve missing `@` in slice binding pattern diagnostics)
 - rust-lang#72547 (Added a codegen test for a recent optimization for overflow-checks=on)
 - rust-lang#72711 (remove redundant `mk_const`)
 - rust-lang#72713 (Whitelist #[allow_internal_unstable])
 - rust-lang#72720 (Clarify the documentation of `take`)

Failed merges:

r? @ghost
@bors bors merged commit d19b51e into rust-lang:master May 29, 2020
JohnTitor added a commit to JohnTitor/rust that referenced this pull request May 30, 2020
Fix diagnostics for `@ ..` binding pattern in tuples and tuple structs

Fixes rust-lang#72574
Associated rust-lang#72534 rust-lang#72373

Includes a new suggestion with `Applicability::MaybeIncorrect` confidence level.

### Before

#### tuple

```
error: `..` patterns are not allowed here
 --> src/main.rs:4:19
  |
4 |         (_a, _x @ ..) => {}
  |                   ^^
  |
  = note: only allowed in tuple, tuple struct, and slice patterns

error[E0308]: mismatched types
 --> src/main.rs:4:9
  |
3 |     match x {
  |           - this expression has type `({integer}, {integer}, {integer})`
4 |         (_a, _x @ ..) => {}
  |         ^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 2 elements
  |
  = note: expected tuple `({integer}, {integer}, {integer})`
             found tuple `(_, _)`

error: aborting due to 2 previous errors
```

#### tuple struct

```
error: `..` patterns are not allowed here
 --> src/main.rs:6:25
  |
6 |         Binder(_a, _x @ ..) => {}
  |                         ^^
  |
  = note: only allowed in tuple, tuple struct, and slice patterns

error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 3 fields
 --> src/main.rs:6:9
  |
1 | struct Binder(i32, i32, i32);
  | ----------------------------- tuple struct defined here
...
6 |         Binder(_a, _x @ ..) => {}
  |         ^^^^^^^^^^^^^^^^^^^ expected 3 fields, found 2

error: aborting due to 2 previous errors
```

### After

*Note: final output edited during source review discussion, see thread for details*

#### tuple

```
error: `_x @` is not allowed in a tuple
 --> src/main.rs:4:14
  |
4 |         (_a, _x @ ..) => {}
  |              ^^^^^^^ is only allowed in a slice
  |
help: replace with `..` or use a different valid pattern
  |
4 |         (_a, ..) => {}
  |              ^^

error[E0308]: mismatched types
 --> src/main.rs:4:9
  |
3 |     match x {
  |           - this expression has type `({integer}, {integer}, {integer})`
4 |         (_a, _x @ ..) => {}
  |         ^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 1 element
  |
  = note: expected tuple `({integer}, {integer}, {integer})`
             found tuple `(_,)`

error: aborting due to 2 previous errors
```

#### tuple struct

```
error: `_x @` is not allowed in a tuple struct
 --> src/main.rs:6:20
  |
6 |         Binder(_a, _x @ ..) => {}
  |                    ^^^^^^^ is only allowed in a slice
  |
help: replace with `..` or use a different valid pattern
  |
6 |         Binder(_a, ..) => {}
  |                    ^^

error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 3 fields
 --> src/main.rs:6:9
  |
1 | struct Binder(i32, i32, i32);
  | ----------------------------- tuple struct defined here
...
6 |         Binder(_a, _x @ ..) => {}
  |         ^^^^^^^^^^^^^^^^^^^ expected 3 fields, found 1

error: aborting due to 2 previous errors
```

r? @estebank
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Sub-optional error message with slice rest syntax in patterns
4 participants