Skip to content

suggest use of the match_default_bindings feature gate #45383

Closed
@nikomatsakis

Description

@nikomatsakis

Right now, if the match_default_bindings is not enabled, then type check does not even attempt to auto-deref on pattern match. This makes it rather undiscoverable. If I try to run this program, for example:

fn foo(x: &Option<i32>) {
  if let Some(y) = x {
    println!("{}", y);
  }
}

fn main() {
  foo(&Some(22));
}

I get:

Standard Error

   Compiling playground v0.0.1 (file:///playground)
error[E0308]: mismatched types
 --> src/main.rs:2:10
  |
2 |   if let Some(y) = x {
  |          ^^^^^^^ expected reference, found enum `std::option::Option`
  |
  = note: expected type `&std::option::Option<i32>`
             found type `std::option::Option<_>`

Of course, if I add the feature gate, it works.

What I would like is for some kind of hint that the feature gate is available, at least on nightly builds. As an example, if I use slice patterns (also unstable) on nightly, I get:

error: slice pattern syntax is experimental (see issue #23121)
 --> src/main.rs:2:7
  |
2 |   let [x, y] = [1, 2];
  |       ^^^^^^
  = help: add #![feature(slice_patterns)] to the crate attributes to enable

(On stable, the help is not present.) This error results from this code here which invokes the gate_features_post! macro. I'm not 100% sure what error message we should use here, but I think we should do something similar.

Roughly speaking, the idea would be this:

  • Remove the feature check for tcx.sess.features.borrow().match_default_bindings from this line and instead enter the if the same either way.
  • Instead, we can do the feature check only once we actually decide to insert match default bindings -- this code only runs for patterns that would result in an error without the feature-gate enabled anyhow.
  • In that branch, if the feature-gate is disabled, we can invoke the feature_err function to create an error to emit.
    • Perhaps we should a help or suggestion like, "to make this code work without the feature gate, consider using an &-pattern here".

The final error would thus look something like:

error: matching a value of reference type with a non-reference pattern is unstable
 --> src/main.rs:2:10
  |
2 |   if let Some(y) = x {
  |          ^^^^^^^ `&`-pattern required: `&Some(y)`
  |
  = help: add `#![feature(match_default_bindings)]` to the crate attributes to enable

This error is...a bit funky. We might want to play with the wording. Maybe it wants to be something like:

error[Ε0123]: non-reference pattern used to match a reference
 --> src/main.rs:2:10
  |
2 |   if let Some(y) = x {
  |          ^^^^^^^ `&`-pattern required: `&Some(y)`
  |
  = help: you can add `#![feature(match_default_bindings)]` to the crate attributes to enable

We could then make an extended error message for E0123 that explains the RFC a bit too.

cc @tschottdorf @estebank

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-enhancementCategory: An issue proposing an enhancement or a PR with one.E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.WG-diagnosticsWorking group: Diagnostics

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions