mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 14:01:51 +00:00
Rollup merge of #125168 - Jules-Bertholet:match-ergonomics-2024-align-with-rfc, r=Nadrieril
Match ergonomics 2024: align implementation with RFC - Remove eat-two-layers (`ref_pat_everywhere`) - Consolidate `mut_preserve_binding_mode_2024` into `ref_pat_eat_one_layer_2024` - `&mut` no longer peels off `&` - Apply "no `ref mut` behind `&`" rule on all editions with `ref_pat_eat_one_layer_2024` - Require `mut_ref` feature gate for all mutable by-reference bindings r? ``@Nadrieril`` cc https://github.com/rust-lang/rust/issues/123076 ``@rustbot`` label A-edition-2024 A-patterns
This commit is contained in:
commit
2611b292c4
@ -128,6 +128,8 @@ declare_features! (
|
||||
/// Allows the use of type alias impl trait in function return positions
|
||||
(removed, min_type_alias_impl_trait, "1.56.0", Some(63063),
|
||||
Some("removed in favor of full type_alias_impl_trait")),
|
||||
/// Make `mut` not reset the binding mode on edition >= 2024.
|
||||
(removed, mut_preserve_binding_mode_2024, "1.79.0", Some(123076), Some("superseded by `ref_pat_eat_one_layer_2024`")),
|
||||
(removed, needs_allocator, "1.4.0", Some(27389),
|
||||
Some("subsumed by `#![feature(allocator_internals)]`")),
|
||||
/// Allows use of unary negate on unsigned integers, e.g., -e for e: u8
|
||||
@ -181,6 +183,7 @@ declare_features! (
|
||||
(removed, pushpop_unsafe, "1.2.0", None, None),
|
||||
(removed, quad_precision_float, "1.0.0", None, None),
|
||||
(removed, quote, "1.33.0", Some(29601), None),
|
||||
(removed, ref_pat_everywhere, "1.79.0", Some(123076), Some("superseded by `ref_pat_eat_one_layer_2024")),
|
||||
(removed, reflect, "1.0.0", Some(27749), None),
|
||||
/// Allows using the `#[register_attr]` attribute.
|
||||
(removed, register_attr, "1.65.0", Some(66080),
|
||||
|
@ -529,8 +529,6 @@ declare_features! (
|
||||
(unstable, more_qualified_paths, "1.54.0", Some(86935)),
|
||||
/// Allows the `#[must_not_suspend]` attribute.
|
||||
(unstable, must_not_suspend, "1.57.0", Some(83310)),
|
||||
/// Make `mut` not reset the binding mode on edition >= 2024.
|
||||
(incomplete, mut_preserve_binding_mode_2024, "1.79.0", Some(123076)),
|
||||
/// Allows `mut ref` and `mut ref mut` identifier patterns.
|
||||
(incomplete, mut_ref, "1.79.0", Some(123076)),
|
||||
/// Allows using `#[naked]` on functions.
|
||||
@ -573,8 +571,6 @@ declare_features! (
|
||||
(unstable, raw_ref_op, "1.41.0", Some(64490)),
|
||||
/// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024.
|
||||
(incomplete, ref_pat_eat_one_layer_2024, "1.79.0", Some(123076)),
|
||||
/// Allows `&` and `&mut` patterns to consume match-ergonomics-inserted references.
|
||||
(incomplete, ref_pat_everywhere, "1.79.0", Some(123076)),
|
||||
/// Allows using the `#[register_tool]` attribute.
|
||||
(unstable, register_tool, "1.41.0", Some(66079)),
|
||||
/// Allows the `#[repr(i128)]` attribute for enums.
|
||||
|
@ -12,7 +12,7 @@ use rustc_infer::infer;
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
|
||||
use rustc_session::{lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS, parse::feature_err};
|
||||
use rustc_span::edit_distance::find_best_match_for_name;
|
||||
use rustc_span::hygiene::DesugaringKind;
|
||||
use rustc_span::source_map::Spanned;
|
||||
@ -335,9 +335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
match adjust_mode {
|
||||
AdjustMode::Pass => (expected, def_br, max_ref_mutbl),
|
||||
AdjustMode::Reset => (expected, ByRef::No, MutblCap::Mut),
|
||||
AdjustMode::Peel => {
|
||||
self.peel_off_references(pat, expected, def_br, Mutability::Mut, max_ref_mutbl)
|
||||
}
|
||||
AdjustMode::Peel => self.peel_off_references(pat, expected, def_br, max_ref_mutbl),
|
||||
}
|
||||
}
|
||||
|
||||
@ -408,8 +406,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
pat: &'tcx Pat<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
mut def_br: ByRef,
|
||||
max_peelable_mutability: Mutability,
|
||||
mut max_ref_mutability: MutblCap,
|
||||
mut max_ref_mutbl: MutblCap,
|
||||
) -> (Ty<'tcx>, ByRef, MutblCap) {
|
||||
let mut expected = self.try_structurally_resolve_type(pat.span, expected);
|
||||
// Peel off as many `&` or `&mut` from the scrutinee type as possible. For example,
|
||||
@ -421,9 +418,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
//
|
||||
// See the examples in `ui/match-defbm*.rs`.
|
||||
let mut pat_adjustments = vec![];
|
||||
while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind()
|
||||
&& inner_mutability <= max_peelable_mutability
|
||||
{
|
||||
while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() {
|
||||
debug!("inspecting {:?}", expected);
|
||||
|
||||
debug!("current discriminant is Ref, inserting implicit deref");
|
||||
@ -443,10 +438,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
});
|
||||
}
|
||||
|
||||
if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
|
||||
def_br = def_br.cap_ref_mutability(max_ref_mutability.as_mutbl());
|
||||
if self.tcx.features().ref_pat_eat_one_layer_2024 {
|
||||
def_br = def_br.cap_ref_mutability(max_ref_mutbl.as_mutbl());
|
||||
if def_br == ByRef::Yes(Mutability::Not) {
|
||||
max_ref_mutability = MutblCap::Not;
|
||||
max_ref_mutbl = MutblCap::Not;
|
||||
}
|
||||
}
|
||||
|
||||
@ -458,7 +453,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
.insert(pat.hir_id, pat_adjustments);
|
||||
}
|
||||
|
||||
(expected, def_br, max_ref_mutability)
|
||||
(expected, def_br, max_ref_mutbl)
|
||||
}
|
||||
|
||||
fn check_pat_lit(
|
||||
@ -674,17 +669,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
// Determine the binding mode...
|
||||
let bm = match user_bind_annot {
|
||||
// `mut` resets binding mode on edition <= 2021
|
||||
BindingMode(ByRef::No, Mutability::Mut)
|
||||
if !(pat.span.at_least_rust_2024()
|
||||
&& self.tcx.features().mut_preserve_binding_mode_2024)
|
||||
&& matches!(def_br, ByRef::Yes(_)) =>
|
||||
{
|
||||
self.typeck_results
|
||||
.borrow_mut()
|
||||
.rust_2024_migration_desugared_pats_mut()
|
||||
.insert(pat_info.top_info.hir_id);
|
||||
BindingMode(ByRef::No, Mutability::Mut)
|
||||
BindingMode(ByRef::No, Mutability::Mut) if matches!(def_br, ByRef::Yes(_)) => {
|
||||
if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
|
||||
if !self.tcx.features().mut_ref {
|
||||
feature_err(
|
||||
&self.tcx.sess,
|
||||
sym::mut_ref,
|
||||
pat.span.until(ident.span),
|
||||
"binding cannot be both mutable and by-reference",
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
|
||||
BindingMode(def_br, Mutability::Mut)
|
||||
} else {
|
||||
// `mut` resets binding mode on edition <= 2021
|
||||
self.typeck_results
|
||||
.borrow_mut()
|
||||
.rust_2024_migration_desugared_pats_mut()
|
||||
.insert(pat_info.top_info.hir_id);
|
||||
BindingMode(ByRef::No, Mutability::Mut)
|
||||
}
|
||||
}
|
||||
BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl),
|
||||
BindingMode(ByRef::Yes(_), _) => user_bind_annot,
|
||||
@ -2126,57 +2131,47 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
mut expected: Ty<'tcx>,
|
||||
mut pat_info: PatInfo<'tcx, '_>,
|
||||
) -> Ty<'tcx> {
|
||||
// FIXME: repace with `bool` once final decision on 1 vs 2 layers is made
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
enum MatchErgonomicsMode {
|
||||
EatOneLayer,
|
||||
EatTwoLayers,
|
||||
Legacy,
|
||||
}
|
||||
let no_ref_mut_behind_and = self.tcx.features().ref_pat_eat_one_layer_2024;
|
||||
let new_match_ergonomics = pat.span.at_least_rust_2024() && no_ref_mut_behind_and;
|
||||
|
||||
let match_ergonomics_mode =
|
||||
if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
|
||||
MatchErgonomicsMode::EatOneLayer
|
||||
} else if self.tcx.features().ref_pat_everywhere {
|
||||
MatchErgonomicsMode::EatTwoLayers
|
||||
} else {
|
||||
MatchErgonomicsMode::Legacy
|
||||
};
|
||||
let pat_prefix_span =
|
||||
inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end));
|
||||
|
||||
let mut inherited_ref_mutbl_match = false;
|
||||
if match_ergonomics_mode != MatchErgonomicsMode::Legacy {
|
||||
if no_ref_mut_behind_and {
|
||||
if pat_mutbl == Mutability::Not {
|
||||
// Prevent the inner pattern from binding with `ref mut`.
|
||||
pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not(
|
||||
inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end)),
|
||||
);
|
||||
pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not(pat_prefix_span);
|
||||
}
|
||||
} else {
|
||||
pat_info.max_ref_mutbl = MutblCap::Mut;
|
||||
}
|
||||
|
||||
if new_match_ergonomics {
|
||||
if let ByRef::Yes(inh_mut) = pat_info.binding_mode {
|
||||
inherited_ref_mutbl_match = pat_mutbl <= inh_mut;
|
||||
}
|
||||
// ref pattern consumes inherited reference
|
||||
|
||||
if inherited_ref_mutbl_match {
|
||||
pat_info.binding_mode = ByRef::No;
|
||||
if match_ergonomics_mode == MatchErgonomicsMode::EatOneLayer {
|
||||
self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
|
||||
self.check_pat(inner, expected, pat_info);
|
||||
return expected;
|
||||
if pat_mutbl > inh_mut {
|
||||
// Tried to match inherited `ref` with `&mut`, which is an error
|
||||
let err_msg = "cannot match inherited `&` with `&mut` pattern";
|
||||
let err = if let Some(span) = pat_prefix_span {
|
||||
let mut err = self.dcx().struct_span_err(span, err_msg);
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
"replace this `&mut` pattern with `&`",
|
||||
"&",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err
|
||||
} else {
|
||||
self.dcx().struct_span_err(pat.span, err_msg)
|
||||
};
|
||||
err.emit();
|
||||
}
|
||||
} else if match_ergonomics_mode == MatchErgonomicsMode::EatOneLayer
|
||||
&& pat_mutbl == Mutability::Mut
|
||||
{
|
||||
// `&mut` patterns pell off `&` references
|
||||
let (new_expected, new_bm, max_ref_mutbl) = self.peel_off_references(
|
||||
pat,
|
||||
expected,
|
||||
pat_info.binding_mode,
|
||||
Mutability::Not,
|
||||
pat_info.max_ref_mutbl,
|
||||
);
|
||||
expected = new_expected;
|
||||
pat_info.binding_mode = new_bm;
|
||||
pat_info.max_ref_mutbl = max_ref_mutbl;
|
||||
|
||||
pat_info.binding_mode = ByRef::No;
|
||||
self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
|
||||
self.check_pat(inner, expected, pat_info);
|
||||
return expected;
|
||||
}
|
||||
} else {
|
||||
// Reset binding mode on old editions
|
||||
@ -2189,8 +2184,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
.rust_2024_migration_desugared_pats_mut()
|
||||
.insert(pat_info.top_info.hir_id);
|
||||
}
|
||||
|
||||
pat_info.max_ref_mutbl = MutblCap::Mut;
|
||||
}
|
||||
|
||||
let tcx = self.tcx;
|
||||
@ -2205,34 +2198,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// the bad interactions of the given hack detailed in (note_1).
|
||||
debug!("check_pat_ref: expected={:?}", expected);
|
||||
match *expected.kind() {
|
||||
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == pat_mutbl => {
|
||||
if r_mutbl == Mutability::Not
|
||||
&& match_ergonomics_mode != MatchErgonomicsMode::Legacy
|
||||
{
|
||||
ty::Ref(_, r_ty, r_mutbl)
|
||||
if (new_match_ergonomics && r_mutbl >= pat_mutbl)
|
||||
|| r_mutbl == pat_mutbl =>
|
||||
{
|
||||
if no_ref_mut_behind_and && r_mutbl == Mutability::Not {
|
||||
pat_info.max_ref_mutbl = MutblCap::Not;
|
||||
}
|
||||
|
||||
(expected, r_ty)
|
||||
}
|
||||
|
||||
// `&` pattern eats `&mut` reference
|
||||
ty::Ref(_, r_ty, Mutability::Mut)
|
||||
if pat_mutbl == Mutability::Not
|
||||
&& match_ergonomics_mode != MatchErgonomicsMode::Legacy =>
|
||||
{
|
||||
(expected, r_ty)
|
||||
}
|
||||
|
||||
_ if inherited_ref_mutbl_match
|
||||
&& match_ergonomics_mode == MatchErgonomicsMode::EatTwoLayers =>
|
||||
{
|
||||
// We already matched against a match-ergonmics inserted reference,
|
||||
// so we don't need to match against a reference from the original type.
|
||||
// Save this info for use in lowering later
|
||||
self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
|
||||
(expected, expected)
|
||||
}
|
||||
|
||||
_ => {
|
||||
let inner_ty = self.next_ty_var(inner.span);
|
||||
let ref_ty = self.new_ref_ty(pat.span, pat_mutbl, inner_ty);
|
||||
|
@ -1,14 +0,0 @@
|
||||
pub fn main() {
|
||||
if let Some(Some(&x)) = &Some(&Some(0)) {
|
||||
//~^ ERROR: mismatched types [E0308]
|
||||
let _: u32 = x;
|
||||
}
|
||||
if let Some(&Some(x)) = &Some(Some(0)) {
|
||||
//~^ ERROR: mismatched types [E0308]
|
||||
let _: u32 = x;
|
||||
}
|
||||
if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
||||
//~^ ERROR: mismatched types [E0308]
|
||||
let _: u32 = x;
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/feature-gate-ref_pat_everywhere.rs:2:22
|
||||
|
|
||||
LL | if let Some(Some(&x)) = &Some(&Some(0)) {
|
||||
| ^^ --------------- this expression has type `&Option<&Option<{integer}>>`
|
||||
| |
|
||||
| expected integer, found `&_`
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
found reference `&_`
|
||||
help: consider removing `&` from the pattern
|
||||
|
|
||||
LL | if let Some(Some(x)) = &Some(&Some(0)) {
|
||||
| ~
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/feature-gate-ref_pat_everywhere.rs:6:17
|
||||
|
|
||||
LL | if let Some(&Some(x)) = &Some(Some(0)) {
|
||||
| ^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>`
|
||||
| |
|
||||
| expected `Option<{integer}>`, found `&_`
|
||||
|
|
||||
= note: expected enum `Option<{integer}>`
|
||||
found reference `&_`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/feature-gate-ref_pat_everywhere.rs:10:22
|
||||
|
|
||||
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
||||
| ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>`
|
||||
| |
|
||||
| expected integer, found `&mut _`
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
found mutable reference `&mut _`
|
||||
note: to declare a mutable binding use: `mut x`
|
||||
--> $DIR/feature-gate-ref_pat_everywhere.rs:10:22
|
||||
|
|
||||
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
||||
| ^^^^^^
|
||||
help: consider removing `&mut` from the pattern
|
||||
|
|
||||
LL | if let Some(Some(x)) = &mut Some(&mut Some(0)) {
|
||||
| ~
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -23,9 +23,6 @@ pub fn main() {
|
||||
if let Some(Some(&x)) = &Some(&Some(0)) {
|
||||
let _: u32 = x;
|
||||
}
|
||||
if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
|
||||
let _: u32 = x;
|
||||
}
|
||||
if let Some(&Some(&x)) = &mut Some(&Some(0)) {
|
||||
let _: u32 = x;
|
||||
}
|
||||
@ -35,9 +32,6 @@ pub fn main() {
|
||||
if let Some(&Some(&mut ref x)) = Some(&Some(&mut 0)) {
|
||||
let _: &u32 = x;
|
||||
}
|
||||
if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
|
||||
let _: &u32 = x;
|
||||
}
|
||||
if let &Some(Some(x)) = &Some(&mut Some(0)) {
|
||||
let _: &u32 = x;
|
||||
}
|
||||
@ -59,13 +53,4 @@ pub fn main() {
|
||||
if let Some(&Some(x)) = &mut Some(Some(0)) {
|
||||
let _: u32 = x;
|
||||
}
|
||||
|
||||
let &mut x = &&mut 0;
|
||||
let _: &u32 = x;
|
||||
|
||||
let &mut x = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
|
||||
let _: &u32 = x;
|
||||
|
||||
let &mut &mut &mut &mut x = &mut &&&&mut &&&mut &mut 0;
|
||||
let _: &u32 = x;
|
||||
}
|
||||
|
@ -5,26 +5,26 @@
|
||||
|
||||
pub fn main() {
|
||||
if let Some(&mut Some(&_)) = &Some(&Some(0)) {
|
||||
//~^ ERROR: mismatched types
|
||||
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
|
||||
}
|
||||
if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
|
||||
//~^ ERROR: mismatched types
|
||||
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
|
||||
}
|
||||
if let Some(&Some(x)) = &mut Some(&Some(0)) {
|
||||
let _: &mut u32 = x;
|
||||
//~^ ERROR: mismatched types
|
||||
}
|
||||
if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
|
||||
//~^ ERROR: mismatched types
|
||||
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
|
||||
}
|
||||
if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
|
||||
//~^ ERROR: mismatched types
|
||||
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
|
||||
}
|
||||
if let Some(&mut Some(x)) = &Some(Some(0)) {
|
||||
//~^ ERROR: mismatched types
|
||||
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
|
||||
}
|
||||
if let Some(&mut Some(x)) = &Some(Some(0)) {
|
||||
//~^ ERROR: mismatched types
|
||||
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
|
||||
}
|
||||
|
||||
let &mut _ = &&0;
|
||||
@ -32,4 +32,31 @@ pub fn main() {
|
||||
|
||||
let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
|
||||
//~^ ERROR: mismatched types
|
||||
|
||||
if let Some(&mut Some(&_)) = &Some(&mut Some(0)) {
|
||||
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
|
||||
}
|
||||
|
||||
if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
|
||||
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
|
||||
}
|
||||
|
||||
let &mut _ = &&mut 0;
|
||||
//~^ ERROR: mismatched types
|
||||
|
||||
let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
|
||||
//~^ ERROR: mismatched types
|
||||
|
||||
let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
|
||||
//~^ ERROR: mismatched types
|
||||
|
||||
struct Foo(u8);
|
||||
|
||||
let Foo(mut a) = &Foo(0);
|
||||
//~^ ERROR: binding cannot be both mutable and by-reference
|
||||
a = &42;
|
||||
|
||||
let Foo(mut a) = &mut Foo(0);
|
||||
//~^ ERROR: binding cannot be both mutable and by-reference
|
||||
a = &mut 42;
|
||||
}
|
||||
|
@ -1,24 +1,24 @@
|
||||
error[E0308]: mismatched types
|
||||
error: cannot match inherited `&` with `&mut` pattern
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:7:17
|
||||
|
|
||||
LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) {
|
||||
| ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>`
|
||||
| |
|
||||
| expected `Option<{integer}>`, found `&mut _`
|
||||
| ^^^^^
|
||||
|
|
||||
= note: expected enum `Option<{integer}>`
|
||||
found mutable reference `&mut _`
|
||||
help: replace this `&mut` pattern with `&`
|
||||
|
|
||||
LL | if let Some(&Some(&_)) = &Some(&Some(0)) {
|
||||
| ~
|
||||
|
||||
error[E0308]: mismatched types
|
||||
error: cannot match inherited `&` with `&mut` pattern
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:10:23
|
||||
|
|
||||
LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
|
||||
| ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>`
|
||||
| |
|
||||
| expected integer, found `&mut _`
|
||||
| ^^^^^
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
found mutable reference `&mut _`
|
||||
help: replace this `&mut` pattern with `&`
|
||||
|
|
||||
LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) {
|
||||
| ~
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:14:27
|
||||
@ -31,49 +31,49 @@ LL | let _: &mut u32 = x;
|
||||
= note: expected mutable reference `&mut u32`
|
||||
found reference `&{integer}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
error: cannot match inherited `&` with `&mut` pattern
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:17:23
|
||||
|
|
||||
LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
|
||||
| ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>`
|
||||
| |
|
||||
| expected integer, found `&mut _`
|
||||
| ^^^^^
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
found mutable reference `&mut _`
|
||||
help: replace this `&mut` pattern with `&`
|
||||
|
|
||||
LL | if let Some(&Some(&_)) = &mut Some(&Some(0)) {
|
||||
| ~
|
||||
|
||||
error[E0308]: mismatched types
|
||||
error: cannot match inherited `&` with `&mut` pattern
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:20:29
|
||||
|
|
||||
LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
|
||||
| ^^^^^^ ------------------------- this expression has type `&Option<Option<&mut Option<{integer}>>>`
|
||||
| |
|
||||
| expected integer, found `&mut _`
|
||||
| ^^^^^
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
found mutable reference `&mut _`
|
||||
help: replace this `&mut` pattern with `&`
|
||||
|
|
||||
LL | if let Some(&Some(Some((&_)))) = &Some(Some(&mut Some(0))) {
|
||||
| ~
|
||||
|
||||
error[E0308]: mismatched types
|
||||
error: cannot match inherited `&` with `&mut` pattern
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:23:17
|
||||
|
|
||||
LL | if let Some(&mut Some(x)) = &Some(Some(0)) {
|
||||
| ^^^^^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>`
|
||||
| |
|
||||
| expected `Option<{integer}>`, found `&mut _`
|
||||
| ^^^^^
|
||||
|
|
||||
= note: expected enum `Option<{integer}>`
|
||||
found mutable reference `&mut _`
|
||||
help: replace this `&mut` pattern with `&`
|
||||
|
|
||||
LL | if let Some(&Some(x)) = &Some(Some(0)) {
|
||||
| ~
|
||||
|
||||
error[E0308]: mismatched types
|
||||
error: cannot match inherited `&` with `&mut` pattern
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:17
|
||||
|
|
||||
LL | if let Some(&mut Some(x)) = &Some(Some(0)) {
|
||||
| ^^^^^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>`
|
||||
| |
|
||||
| expected `Option<{integer}>`, found `&mut _`
|
||||
| ^^^^^
|
||||
|
|
||||
= note: expected enum `Option<{integer}>`
|
||||
found mutable reference `&mut _`
|
||||
help: replace this `&mut` pattern with `&`
|
||||
|
|
||||
LL | if let Some(&Some(x)) = &Some(Some(0)) {
|
||||
| ~
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:30:9
|
||||
@ -81,9 +81,9 @@ error[E0308]: mismatched types
|
||||
LL | let &mut _ = &&0;
|
||||
| ^^^^^^ --- this expression has type `&&{integer}`
|
||||
| |
|
||||
| expected integer, found `&mut _`
|
||||
| types differ in mutability
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
= note: expected reference `&&{integer}`
|
||||
found mutable reference `&mut _`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
@ -92,11 +92,87 @@ error[E0308]: mismatched types
|
||||
LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
|
||||
| ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
|
||||
| |
|
||||
| expected integer, found `&mut _`
|
||||
| types differ in mutability
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
= note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
|
||||
found mutable reference `&mut _`
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
error: cannot match inherited `&` with `&mut` pattern
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:36:17
|
||||
|
|
||||
LL | if let Some(&mut Some(&_)) = &Some(&mut Some(0)) {
|
||||
| ^^^^^
|
||||
|
|
||||
help: replace this `&mut` pattern with `&`
|
||||
|
|
||||
LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) {
|
||||
| ~
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
error: cannot match inherited `&` with `&mut` pattern
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:40:22
|
||||
|
|
||||
LL | if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
|
||||
| ^^^^^
|
||||
|
|
||||
help: replace this `&mut` pattern with `&`
|
||||
|
|
||||
LL | if let Some(Some(&x)) = &Some(Some(&mut 0)) {
|
||||
| ~
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:44:9
|
||||
|
|
||||
LL | let &mut _ = &&mut 0;
|
||||
| ^^^^^^ ------- this expression has type `&&mut {integer}`
|
||||
| |
|
||||
| types differ in mutability
|
||||
|
|
||||
= note: expected reference `&&mut {integer}`
|
||||
found mutable reference `&mut _`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:47:9
|
||||
|
|
||||
LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
|
||||
| ^^^^^^ --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
|
||||
| |
|
||||
| types differ in mutability
|
||||
|
|
||||
= note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
|
||||
found mutable reference `&mut _`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:50:14
|
||||
|
|
||||
LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
|
||||
| ^^^^^^^^^^^^^^^^ -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}`
|
||||
| |
|
||||
| types differ in mutability
|
||||
|
|
||||
= note: expected reference `&&&&mut &&&mut &mut {integer}`
|
||||
found mutable reference `&mut _`
|
||||
|
||||
error[E0658]: binding cannot be both mutable and by-reference
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:55:13
|
||||
|
|
||||
LL | let Foo(mut a) = &Foo(0);
|
||||
| ^^^^
|
||||
|
|
||||
= note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
|
||||
= help: add `#![feature(mut_ref)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: binding cannot be both mutable and by-reference
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:59:13
|
||||
|
|
||||
LL | let Foo(mut a) = &mut Foo(0);
|
||||
| ^^^^
|
||||
|
|
||||
= note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
|
||||
= help: add `#![feature(mut_ref)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error: aborting due to 16 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0658.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
|
@ -1,12 +0,0 @@
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(ref_pat_everywhere)]
|
||||
pub fn main() {
|
||||
if let Some(&x) = Some(0) {
|
||||
//~^ ERROR: mismatched types [E0308]
|
||||
let _: u32 = x;
|
||||
}
|
||||
if let Some(&mut x) = Some(&0) {
|
||||
//~^ ERROR: mismatched types [E0308]
|
||||
let _: u32 = x;
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ref_pat_everywhere-fail.rs:4:17
|
||||
|
|
||||
LL | if let Some(&x) = Some(0) {
|
||||
| ^^ ------- this expression has type `Option<{integer}>`
|
||||
| |
|
||||
| expected integer, found `&_`
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
found reference `&_`
|
||||
help: consider removing `&` from the pattern
|
||||
|
|
||||
LL | if let Some(x) = Some(0) {
|
||||
| ~
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ref_pat_everywhere-fail.rs:8:17
|
||||
|
|
||||
LL | if let Some(&mut x) = Some(&0) {
|
||||
| ^^^^^^ -------- this expression has type `Option<&{integer}>`
|
||||
| |
|
||||
| types differ in mutability
|
||||
|
|
||||
= note: expected reference `&{integer}`
|
||||
found mutable reference `&mut _`
|
||||
note: to declare a mutable binding use: `mut x`
|
||||
--> $DIR/ref_pat_everywhere-fail.rs:8:17
|
||||
|
|
||||
LL | if let Some(&mut x) = Some(&0) {
|
||||
| ^^^^^^
|
||||
help: consider removing `&mut` from the pattern
|
||||
|
|
||||
LL | if let Some(x) = Some(&0) {
|
||||
| ~
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -1,24 +0,0 @@
|
||||
//@ run-pass
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(ref_pat_everywhere)]
|
||||
|
||||
pub fn main() {
|
||||
if let Some(Some(&x)) = &Some(&Some(0)) {
|
||||
let _: u32 = x;
|
||||
}
|
||||
if let Some(&Some(x)) = &Some(Some(0)) {
|
||||
let _: u32 = x;
|
||||
}
|
||||
if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
||||
let _: u32 = x;
|
||||
}
|
||||
if let Some(Some(&x)) = &Some(&mut Some(0)) {
|
||||
let _: u32 = x;
|
||||
}
|
||||
if let &Some(x) = &mut Some(0) {
|
||||
let _: u32 = x;
|
||||
}
|
||||
if let Some(&x) = &mut Some(0) {
|
||||
let _: u32 = x;
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
//@ edition: 2024
|
||||
//@ compile-flags: -Zunstable-options
|
||||
|
||||
struct Foo(u8);
|
||||
|
||||
fn main() {
|
||||
let Foo(mut a) = &Foo(0);
|
||||
a = &42;
|
||||
//~^ ERROR: mismatched types
|
||||
|
||||
let Foo(mut a) = &mut Foo(0);
|
||||
a = &mut 42;
|
||||
//~^ ERROR: mismatched types
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/feature-gate-mut_preserve_binding_mode_2024.rs:8:9
|
||||
|
|
||||
LL | let Foo(mut a) = &Foo(0);
|
||||
| ----- expected due to the type of this binding
|
||||
LL | a = &42;
|
||||
| ^^^ expected `u8`, found `&{integer}`
|
||||
|
|
||||
help: consider removing the borrow
|
||||
|
|
||||
LL - a = &42;
|
||||
LL + a = 42;
|
||||
|
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/feature-gate-mut_preserve_binding_mode_2024.rs:12:9
|
||||
|
|
||||
LL | let Foo(mut a) = &mut Foo(0);
|
||||
| ----- expected due to the type of this binding
|
||||
LL | a = &mut 42;
|
||||
| ^^^^^^^ expected `u8`, found `&mut {integer}`
|
||||
|
|
||||
help: consider removing the borrow
|
||||
|
|
||||
LL - a = &mut 42;
|
||||
LL + a = 42;
|
||||
|
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -2,7 +2,7 @@
|
||||
//@ run-rustfix
|
||||
//@ rustfix-only-machine-applicable
|
||||
//@ aux-build:match_ergonomics_2024_macros.rs
|
||||
#![feature(mut_preserve_binding_mode_2024, ref_pat_eat_one_layer_2024)]
|
||||
#![feature(mut_ref, ref_pat_eat_one_layer_2024)]
|
||||
#![allow(incomplete_features, unused)]
|
||||
#![deny(rust_2024_incompatible_pat)]
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
//@ run-rustfix
|
||||
//@ rustfix-only-machine-applicable
|
||||
//@ aux-build:match_ergonomics_2024_macros.rs
|
||||
#![feature(mut_preserve_binding_mode_2024, ref_pat_eat_one_layer_2024)]
|
||||
#![feature(mut_ref, ref_pat_eat_one_layer_2024)]
|
||||
#![allow(incomplete_features, unused)]
|
||||
#![deny(rust_2024_incompatible_pat)]
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
//@ edition: 2021
|
||||
//@ compile-flags: -Zunstable-options
|
||||
#![feature(mut_preserve_binding_mode_2024)]
|
||||
#![feature(ref_pat_eat_one_layer_2024)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
struct Foo(u8);
|
||||
|
@ -1,7 +1,7 @@
|
||||
//@ run-pass
|
||||
//@ edition: 2024
|
||||
//@ compile-flags: -Zunstable-options
|
||||
#![feature(mut_preserve_binding_mode_2024)]
|
||||
#![feature(mut_ref, ref_pat_eat_one_layer_2024)]
|
||||
#![allow(incomplete_features, unused)]
|
||||
|
||||
struct Foo(u8);
|
||||
|
9
tests/ui/pattern/no_ref_mut_behind_and.rs
Normal file
9
tests/ui/pattern/no_ref_mut_behind_and.rs
Normal file
@ -0,0 +1,9 @@
|
||||
//@ edition: 2021
|
||||
//@ run-pass
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(ref_pat_eat_one_layer_2024)]
|
||||
|
||||
fn main() {
|
||||
let &[[x]] = &[&mut [42]];
|
||||
let _: &i32 = x;
|
||||
}
|
Loading…
Reference in New Issue
Block a user