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

Fix discrepancy between match ergonomics Rule 4 and implementation #127559

Open
Tracked by #123076
traviscross opened this issue Jul 10, 2024 · 2 comments
Open
Tracked by #123076

Fix discrepancy between match ergonomics Rule 4 and implementation #127559

traviscross opened this issue Jul 10, 2024 · 2 comments
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@traviscross
Copy link
Contributor

traviscross commented Jul 10, 2024

In our 2024-06-26 design meeting on match ergonomics (part 3):

...we decided on a slate on rules:

  • Rule 1: When the DBM (default binding mode) is not move (whether or not behind a reference), writing mut on a binding is an error.
  • Rule 2: When a reference pattern matches against a reference, do not update the DBM.
  • Rule 3: If we've previously matched against a shared reference in the scrutinee (or against a ref DBM under Rule 4, or against a mutable reference treated as a shared one or a ref mut DBM treated as a ref one under Rule 5), set the DBM to ref whenever we would otherwise set it to ref mut.
  • Rule 4: If an & or &mut pattern is being matched against a non-reference type and if the DBM is ref or ref mut, match the pattern against the DBM as though it were a type.
  • Rule 5: If an & pattern is being matched against a mutable reference type (or against a ref mut DBM under Rule 4), act as if the type were a shared reference instead (or that the ref mut DBM is a ref DBM instead).

We then, in:

...amended Rule 4 to read as follows:

  • Rule 4: If an & pattern is being matched against a non-reference type or an &mut pattern is being matched against a shared reference type or a non-reference type, and if the DBM is ref or ref mut, match the pattern against the DBM as though it were a type.

(Emphasis highlights the diff.)

We did that so that it would accept cases like this:

let [&mut x] = &mut [&T]; //~ x: &T

It had been proposed the amended Rule 4 was equivalent to an earlier proposal to accept the union of the code accepted under either the original Rule 4 (the "structural" variant) or under Rule 4 (early) (the "early" variant). (Rule 4 (early) breaks the primacy of structural matching by matching first against the DBM.)

However, in discussion, @WaffleLapkin found a case that shows that the amended Rule 4 isn't equivalent to accepting the union:

let [&&mut x] = &[&mut T];

This case is accepted by the early variant but not by the amended Rule 4.

However, this is accepted by the implementation by @Jules-Bertholet, as merged in:

We could adjust the implementation to match the accepted RFC.

Or, conceivably, we could amend the statement of Rule 4 to align with the implementation. If we did that, the re-revised statement of Rule 4 then would be:

  • Rule 4 (extended 2): If an & pattern is being matched against a mutable reference type or a non-reference type, or if an &mut pattern is being matched against a shared reference type or a non-reference type, and if the DBM is ref or ref mut, match the pattern against the DBM as though it were a type.

(Emphasis highlights the diff.)

Note that this would have the effect of taking precedence over Rule 5.

However, this too doesn't accept strictly more code. Because under the originally-amended Rule 4, we accept this:

let [&x] = &[&mut T]; //~ x: &T

...but under the extended 2 rule, that would be rejected:

let [&x] = &[&mut T]; //~ x: &mut T
//~^ ERROR cannot move out of non-copy array

We'll analyze this further, then nominate if we decide that the rule should be changed rather than the implementation. We're not really worried about it; we see a number of acceptable options here (including implementing the Rule 4 as written).

(If it were to come to it, we don't need to stabilize Rule 4 immediately. We only need to stabilize Rule 1 and Rule 2 in Rust 2024.)

Tracking:

@rustbot labels +T-lang

cc @Jules-Bertholet @Nadrieril

@rustbot rustbot added needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. I-lang-nominated Nominated for discussion during a lang team meeting. T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Jul 10, 2024
@traviscross traviscross changed the title Fix bug in statement of match ergonomics *Rule 4* Fix bug in statement of match ergonomics Rule 4 Jul 10, 2024
@traviscross traviscross removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. I-lang-nominated Nominated for discussion during a lang team meeting. labels Jul 10, 2024
@traviscross traviscross changed the title Fix bug in statement of match ergonomics Rule 4 Fix bug(?) in statement of match ergonomics Rule 4 Jul 10, 2024
@rustbot rustbot added the I-lang-nominated Nominated for discussion during a lang team meeting. label Jul 10, 2024
@Jules-Bertholet
Copy link
Contributor

Ah, good catch! A related question is, what should be the type of y in the following examples:

let &[ref y] = &[&mut T];
let [&ref y] = &[&mut T];

In the current impl, y is &&mut in both cases.

@traviscross traviscross removed the I-lang-nominated Nominated for discussion during a lang team meeting. label Jul 10, 2024
@traviscross traviscross changed the title Fix bug(?) in statement of match ergonomics Rule 4 Fix discrepancy between match ergonomics Rule 4 and implementation Jul 14, 2024
@traviscross traviscross added the C-discussion Category: Discussion or questions that doesn't represent real issues. label Jul 14, 2024
@WaffleLapkin WaffleLapkin added the A-edition-2024 Area: The 2024 edition label Jul 14, 2024
@traviscross
Copy link
Contributor Author

@rustbot labels -A-edition-2024

We reviewed this in the edition call. The Rule 4 behavior isn't edition dependent, in either configuration, so there's nothing here on this issue specifically for the edition, so we're going to remove that label.

@rustbot rustbot removed the A-edition-2024 Area: The 2024 edition label Jul 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants