Description
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), writingmut
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 aref mut
DBM treated as aref
one under Rule 5), set the DBM toref
whenever we would otherwise set it toref mut
. - Rule 4: If an
&
or&mut
pattern is being matched against a non-reference type and if the DBM isref
orref 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 aref mut
DBM under Rule 4), act as if the type were a shared reference instead (or that theref mut
DBM is aref
DBM instead).
In discussion toward the end of and after the meeting, there emerged some potentially good reasons to adopt a slight variation of Rule 4. The motivation is that, under Rule 4, this is an error:
let [&mut x] = &mut [&T]; //~ ERROR
(T
here is a unit struct that implements Copy
.)
That's kind of awkward and unfortunate, because without the &mut
in the pattern, we get a type of &mut &T
, so we really want adding &mut
to get us a &T
, since, in all other cases, that's what happens.
We can make this work with a small tweak to Rule 4 (which we'll call the extended Rule 4):
- Rule 4 (extended): 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 isref
orref mut
, match the pattern against the DBM as though it were a type.
(Emphasis highlights the diff.)
We've analyzed this now, and think it's OK and a good tweak. We nominate to confirm this sounds good to the team.
If adopted, we'll revise Rule 4 to be the extended version.
Tracking:
@rustbot labels +T-lang +I-lang-nominated +C-discussion