Skip to content

Fix discrepancy between match ergonomics Rule 4 and implementation #127559

New issue

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

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

Already on GitHub? # to your account

Open
traviscross opened this issue Jul 10, 2024 · 2 comments
Open

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
# for free to join this conversation on GitHub. Already have an account? # 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