Rollup merge of #131381 - Nadrieril:min-match-ergonomics, r=pnkfelix
Implement edition 2024 match ergonomics restrictions This implements the minimalest version of [match ergonomics for edition 2024](https://rust-lang.github.io/rfcs/3627-match-ergonomics-2024.html). This minimal version makes it an error to ever reset the default binding mode. The implemented proposal is described precisely [here](https://hackmd.io/zUqs2ISNQ0Wrnxsa9nhD0Q#RFC-3627-nano), where it is called "RFC 3627-nano". Rules: - Rule 1C: When the DBM (default binding mode) is not `move` (whether or not behind a reference), writing `mut`, `ref`, or `ref mut` on a binding is an error. - Rule 2C: Reference patterns can only match against references in the scrutinee when the DBM is `move`. This minimal version is forward-compatible with the main proposals for match ergonomics 2024: [RFC3627](https://rust-lang.github.io/rfcs/3627-match-ergonomics-2024.html) itself, the alternative [rule 4-early variant](https://rust-lang.github.io/rfcs/3627-match-ergonomics-2024.html), and [others](https://hackmd.io/zUqs2ISNQ0Wrnxsa9nhD0Q). The idea is to give us more time to iron out a final proposal. This includes a migration lint that desugars any offending pattern into one that doesn't make use of match ergonomics. Such patterns have identical meaning across editions. This PR insta-stabilizes the proposed behavior onto edition 2024. r? `@ghost` Tracking: - https://github.com/rust-lang/rust/issues/123076
This commit is contained in:
@@ -690,16 +690,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
BindingMode(def_br, Mutability::Mut)
|
BindingMode(def_br, Mutability::Mut)
|
||||||
} else {
|
} else {
|
||||||
// `mut` resets binding mode on edition <= 2021
|
// `mut` resets the binding mode on edition <= 2021
|
||||||
self.typeck_results
|
*self
|
||||||
|
.typeck_results
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.rust_2024_migration_desugared_pats_mut()
|
.rust_2024_migration_desugared_pats_mut()
|
||||||
.insert(pat_info.top_info.hir_id);
|
.entry(pat_info.top_info.hir_id)
|
||||||
|
.or_default() |= pat.span.at_least_rust_2024();
|
||||||
BindingMode(ByRef::No, Mutability::Mut)
|
BindingMode(ByRef::No, Mutability::Mut)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl),
|
BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl),
|
||||||
BindingMode(ByRef::Yes(_), _) => user_bind_annot,
|
BindingMode(ByRef::Yes(_), _) => {
|
||||||
|
if matches!(def_br, ByRef::Yes(_)) {
|
||||||
|
// `ref`/`ref mut` overrides the binding mode on edition <= 2021
|
||||||
|
*self
|
||||||
|
.typeck_results
|
||||||
|
.borrow_mut()
|
||||||
|
.rust_2024_migration_desugared_pats_mut()
|
||||||
|
.entry(pat_info.top_info.hir_id)
|
||||||
|
.or_default() |= pat.span.at_least_rust_2024();
|
||||||
|
}
|
||||||
|
user_bind_annot
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if bm.0 == ByRef::Yes(Mutability::Mut)
|
if bm.0 == ByRef::Yes(Mutability::Mut)
|
||||||
@@ -2204,14 +2217,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Reset binding mode on old editions
|
// Reset binding mode on old editions
|
||||||
|
|
||||||
if pat_info.binding_mode != ByRef::No {
|
if pat_info.binding_mode != ByRef::No {
|
||||||
pat_info.binding_mode = ByRef::No;
|
pat_info.binding_mode = ByRef::No;
|
||||||
|
*self
|
||||||
self.typeck_results
|
.typeck_results
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.rust_2024_migration_desugared_pats_mut()
|
.rust_2024_migration_desugared_pats_mut()
|
||||||
.insert(pat_info.top_info.hir_id);
|
.entry(pat_info.top_info.hir_id)
|
||||||
|
.or_default() |= pat.span.at_least_rust_2024();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2262,6 +2275,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
(err, err)
|
(err, err)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.check_pat(inner, inner_ty, pat_info);
|
self.check_pat(inner, inner_ty, pat_info);
|
||||||
ref_ty
|
ref_ty
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -635,7 +635,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||||||
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "debug")]
|
||||||
fn visit_rust_2024_migration_desugared_pats(&mut self, hir_id: hir::HirId) {
|
fn visit_rust_2024_migration_desugared_pats(&mut self, hir_id: hir::HirId) {
|
||||||
if self
|
if let Some(is_hard_error) = self
|
||||||
.fcx
|
.fcx
|
||||||
.typeck_results
|
.typeck_results
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
@@ -645,7 +645,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||||||
debug!(
|
debug!(
|
||||||
"node is a pat whose match ergonomics are desugared by the Rust 2024 migration lint"
|
"node is a pat whose match ergonomics are desugared by the Rust 2024 migration lint"
|
||||||
);
|
);
|
||||||
self.typeck_results.rust_2024_migration_desugared_pats_mut().insert(hir_id);
|
self.typeck_results
|
||||||
|
.rust_2024_migration_desugared_pats_mut()
|
||||||
|
.insert(hir_id, is_hard_error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1651,7 +1651,6 @@ declare_lint! {
|
|||||||
/// ### Example
|
/// ### Example
|
||||||
///
|
///
|
||||||
/// ```rust,edition2021
|
/// ```rust,edition2021
|
||||||
/// #![feature(ref_pat_eat_one_layer_2024)]
|
|
||||||
/// #![warn(rust_2024_incompatible_pat)]
|
/// #![warn(rust_2024_incompatible_pat)]
|
||||||
///
|
///
|
||||||
/// if let Some(&a) = &Some(&0u8) {
|
/// if let Some(&a) = &Some(&0u8) {
|
||||||
@@ -1672,12 +1671,10 @@ declare_lint! {
|
|||||||
pub RUST_2024_INCOMPATIBLE_PAT,
|
pub RUST_2024_INCOMPATIBLE_PAT,
|
||||||
Allow,
|
Allow,
|
||||||
"detects patterns whose meaning will change in Rust 2024",
|
"detects patterns whose meaning will change in Rust 2024",
|
||||||
@feature_gate = ref_pat_eat_one_layer_2024;
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
// FIXME uncomment below upon stabilization
|
|
||||||
/*@future_incompatible = FutureIncompatibleInfo {
|
|
||||||
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
|
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
|
||||||
reference: "123076",
|
reference: "123076",
|
||||||
};*/
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
|
|||||||
@@ -73,9 +73,10 @@ pub struct TypeckResults<'tcx> {
|
|||||||
/// Stores the actual binding mode for all instances of [`BindingMode`].
|
/// Stores the actual binding mode for all instances of [`BindingMode`].
|
||||||
pat_binding_modes: ItemLocalMap<BindingMode>,
|
pat_binding_modes: ItemLocalMap<BindingMode>,
|
||||||
|
|
||||||
/// Top-level patterns whose match ergonomics need to be desugared
|
/// Top-level patterns whose match ergonomics need to be desugared by the Rust 2021 -> 2024
|
||||||
/// by the Rust 2021 -> 2024 migration lint.
|
/// migration lint. The boolean indicates whether the emitted diagnostic should be a hard error
|
||||||
rust_2024_migration_desugared_pats: ItemLocalSet,
|
/// (if any of the incompatible pattern elements are in edition 2024).
|
||||||
|
rust_2024_migration_desugared_pats: ItemLocalMap<bool>,
|
||||||
|
|
||||||
/// Stores the types which were implicitly dereferenced in pattern binding modes
|
/// Stores the types which were implicitly dereferenced in pattern binding modes
|
||||||
/// for later usage in THIR lowering. For example,
|
/// for later usage in THIR lowering. For example,
|
||||||
@@ -418,15 +419,15 @@ impl<'tcx> TypeckResults<'tcx> {
|
|||||||
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
|
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rust_2024_migration_desugared_pats(&self) -> LocalSetInContext<'_> {
|
pub fn rust_2024_migration_desugared_pats(&self) -> LocalTableInContext<'_, bool> {
|
||||||
LocalSetInContext {
|
LocalTableInContext {
|
||||||
hir_owner: self.hir_owner,
|
hir_owner: self.hir_owner,
|
||||||
data: &self.rust_2024_migration_desugared_pats,
|
data: &self.rust_2024_migration_desugared_pats,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rust_2024_migration_desugared_pats_mut(&mut self) -> LocalSetInContextMut<'_> {
|
pub fn rust_2024_migration_desugared_pats_mut(&mut self) -> LocalTableInContextMut<'_, bool> {
|
||||||
LocalSetInContextMut {
|
LocalTableInContextMut {
|
||||||
hir_owner: self.hir_owner,
|
hir_owner: self.hir_owner,
|
||||||
data: &mut self.rust_2024_migration_desugared_pats,
|
data: &mut self.rust_2024_migration_desugared_pats,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ mir_build_pointer_pattern = function pointers and raw pointers not derived from
|
|||||||
|
|
||||||
mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
|
mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
|
||||||
|
|
||||||
mir_build_rust_2024_incompatible_pat = the semantics of this pattern will change in edition 2024
|
mir_build_rust_2024_incompatible_pat = patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
|
||||||
mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly
|
mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly
|
||||||
.attributes = no other attributes may be applied
|
.attributes = no other attributes may be applied
|
||||||
|
|||||||
@@ -983,6 +983,8 @@ pub(crate) struct Rust2024IncompatiblePat {
|
|||||||
|
|
||||||
pub(crate) struct Rust2024IncompatiblePatSugg {
|
pub(crate) struct Rust2024IncompatiblePatSugg {
|
||||||
pub(crate) suggestion: Vec<(Span, String)>,
|
pub(crate) suggestion: Vec<(Span, String)>,
|
||||||
|
/// Whether the incompatibility is a hard error because a relevant span is in edition 2024.
|
||||||
|
pub(crate) is_hard_error: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for Rust2024IncompatiblePatSugg {
|
impl Subdiagnostic for Rust2024IncompatiblePatSugg {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ use tracing::{debug, instrument};
|
|||||||
|
|
||||||
pub(crate) use self::check_match::check_match;
|
pub(crate) use self::check_match::check_match;
|
||||||
use crate::errors::*;
|
use crate::errors::*;
|
||||||
|
use crate::fluent_generated as fluent;
|
||||||
use crate::thir::util::UserAnnotatedTyHelpers;
|
use crate::thir::util::UserAnnotatedTyHelpers;
|
||||||
|
|
||||||
struct PatCtxt<'a, 'tcx> {
|
struct PatCtxt<'a, 'tcx> {
|
||||||
@@ -48,18 +49,28 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
|
|||||||
typeck_results,
|
typeck_results,
|
||||||
rust_2024_migration_suggestion: typeck_results
|
rust_2024_migration_suggestion: typeck_results
|
||||||
.rust_2024_migration_desugared_pats()
|
.rust_2024_migration_desugared_pats()
|
||||||
.contains(pat.hir_id)
|
.get(pat.hir_id)
|
||||||
.then_some(Rust2024IncompatiblePatSugg { suggestion: Vec::new() }),
|
.map(|&is_hard_error| Rust2024IncompatiblePatSugg {
|
||||||
|
suggestion: Vec::new(),
|
||||||
|
is_hard_error,
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
let result = pcx.lower_pattern(pat);
|
let result = pcx.lower_pattern(pat);
|
||||||
debug!("pat_from_hir({:?}) = {:?}", pat, result);
|
debug!("pat_from_hir({:?}) = {:?}", pat, result);
|
||||||
if let Some(sugg) = pcx.rust_2024_migration_suggestion {
|
if let Some(sugg) = pcx.rust_2024_migration_suggestion {
|
||||||
tcx.emit_node_span_lint(
|
if sugg.is_hard_error {
|
||||||
lint::builtin::RUST_2024_INCOMPATIBLE_PAT,
|
let mut err =
|
||||||
pat.hir_id,
|
tcx.dcx().struct_span_err(pat.span, fluent::mir_build_rust_2024_incompatible_pat);
|
||||||
pat.span,
|
err.subdiagnostic(sugg);
|
||||||
Rust2024IncompatiblePat { sugg },
|
err.emit();
|
||||||
);
|
} else {
|
||||||
|
tcx.emit_node_span_lint(
|
||||||
|
lint::builtin::RUST_2024_INCOMPATIBLE_PAT,
|
||||||
|
pat.hir_id,
|
||||||
|
pat.span,
|
||||||
|
Rust2024IncompatiblePat { sugg },
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
//@ edition: 2021
|
|
||||||
//@ run-rustfix
|
|
||||||
//@ rustfix-only-machine-applicable
|
|
||||||
//@ aux-build:match_ergonomics_2024_macros.rs
|
|
||||||
#![feature(mut_ref, ref_pat_eat_one_layer_2024)]
|
|
||||||
#![allow(incomplete_features, unused)]
|
|
||||||
#![deny(rust_2024_incompatible_pat)]
|
|
||||||
|
|
||||||
extern crate match_ergonomics_2024_macros;
|
|
||||||
|
|
||||||
struct Foo(u8);
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let &Foo(mut a) = &Foo(0);
|
|
||||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
|
||||||
a = 42;
|
|
||||||
|
|
||||||
let &mut Foo(mut a) = &mut Foo(0);
|
|
||||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
|
||||||
a = 42;
|
|
||||||
|
|
||||||
if let &&&&&Some(&_) = &&&&&Some(&0u8) {}
|
|
||||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
|
||||||
|
|
||||||
if let &&&&&Some(&mut _) = &&&&&Some(&mut 0u8) {}
|
|
||||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
|
||||||
|
|
||||||
if let &&&&&mut Some(&_) = &&&&&mut Some(&0u8) {}
|
|
||||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
|
||||||
|
|
||||||
if let &mut Some(&mut Some(&mut Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {}
|
|
||||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
|
||||||
|
|
||||||
if let &mut Some(&mut Some(&mut Some(ref mut _a))) = &mut Some(&mut Some(&mut Some(0u8))) {}
|
|
||||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
|
||||||
|
|
||||||
struct Struct {
|
|
||||||
a: u32,
|
|
||||||
b: u32,
|
|
||||||
c: u32,
|
|
||||||
}
|
|
||||||
let s = Struct { a: 0, b: 0, c: 0 };
|
|
||||||
let &Struct { ref a, mut b, ref c } = &s;
|
|
||||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
|
||||||
|
|
||||||
#[warn(rust_2024_incompatible_pat)]
|
|
||||||
match &(Some(0), Some(0)) {
|
|
||||||
// The two patterns are the same syntactically, but because they're defined in different
|
|
||||||
// editions they don't mean the same thing.
|
|
||||||
(Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => {
|
|
||||||
//~^ WARN: the semantics of this pattern will change in edition 2024
|
|
||||||
_x = 4;
|
|
||||||
_y = &7;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
//@ edition: 2021
|
|
||||||
//@ run-rustfix
|
|
||||||
//@ rustfix-only-machine-applicable
|
|
||||||
//@ aux-build:match_ergonomics_2024_macros.rs
|
|
||||||
#![feature(mut_ref, ref_pat_eat_one_layer_2024)]
|
|
||||||
#![allow(incomplete_features, unused)]
|
|
||||||
#![deny(rust_2024_incompatible_pat)]
|
|
||||||
|
|
||||||
extern crate match_ergonomics_2024_macros;
|
|
||||||
|
|
||||||
struct Foo(u8);
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let Foo(mut a) = &Foo(0);
|
|
||||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
|
||||||
a = 42;
|
|
||||||
|
|
||||||
let Foo(mut a) = &mut Foo(0);
|
|
||||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
|
||||||
a = 42;
|
|
||||||
|
|
||||||
if let Some(&_) = &&&&&Some(&0u8) {}
|
|
||||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
|
||||||
|
|
||||||
if let Some(&mut _) = &&&&&Some(&mut 0u8) {}
|
|
||||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
|
||||||
|
|
||||||
if let Some(&_) = &&&&&mut Some(&0u8) {}
|
|
||||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
|
||||||
|
|
||||||
if let Some(&mut Some(Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {}
|
|
||||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
|
||||||
|
|
||||||
if let Some(&mut Some(Some(_a))) = &mut Some(&mut Some(&mut Some(0u8))) {}
|
|
||||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
|
||||||
|
|
||||||
struct Struct {
|
|
||||||
a: u32,
|
|
||||||
b: u32,
|
|
||||||
c: u32,
|
|
||||||
}
|
|
||||||
let s = Struct { a: 0, b: 0, c: 0 };
|
|
||||||
let Struct { a, mut b, c } = &s;
|
|
||||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
|
||||||
|
|
||||||
#[warn(rust_2024_incompatible_pat)]
|
|
||||||
match &(Some(0), Some(0)) {
|
|
||||||
// The two patterns are the same syntactically, but because they're defined in different
|
|
||||||
// editions they don't mean the same thing.
|
|
||||||
(Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => {
|
|
||||||
//~^ WARN: the semantics of this pattern will change in edition 2024
|
|
||||||
_x = 4;
|
|
||||||
_y = &7;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
error: the semantics of this pattern will change in edition 2024
|
|
||||||
--> $DIR/match_ergonomics_2024.rs:14:9
|
|
||||||
|
|
|
||||||
LL | let Foo(mut a) = &Foo(0);
|
|
||||||
| -^^^^^^^^^
|
|
||||||
| |
|
|
||||||
| help: desugar the match ergonomics: `&`
|
|
||||||
|
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/match_ergonomics_2024.rs:7:9
|
|
||||||
|
|
|
||||||
LL | #![deny(rust_2024_incompatible_pat)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: the semantics of this pattern will change in edition 2024
|
|
||||||
--> $DIR/match_ergonomics_2024.rs:18:9
|
|
||||||
|
|
|
||||||
LL | let Foo(mut a) = &mut Foo(0);
|
|
||||||
| -^^^^^^^^^
|
|
||||||
| |
|
|
||||||
| help: desugar the match ergonomics: `&mut`
|
|
||||||
|
|
||||||
error: the semantics of this pattern will change in edition 2024
|
|
||||||
--> $DIR/match_ergonomics_2024.rs:22:12
|
|
||||||
|
|
|
||||||
LL | if let Some(&_) = &&&&&Some(&0u8) {}
|
|
||||||
| -^^^^^^^
|
|
||||||
| |
|
|
||||||
| help: desugar the match ergonomics: `&&&&&`
|
|
||||||
|
|
||||||
error: the semantics of this pattern will change in edition 2024
|
|
||||||
--> $DIR/match_ergonomics_2024.rs:25:12
|
|
||||||
|
|
|
||||||
LL | if let Some(&mut _) = &&&&&Some(&mut 0u8) {}
|
|
||||||
| -^^^^^^^^^^^
|
|
||||||
| |
|
|
||||||
| help: desugar the match ergonomics: `&&&&&`
|
|
||||||
|
|
||||||
error: the semantics of this pattern will change in edition 2024
|
|
||||||
--> $DIR/match_ergonomics_2024.rs:28:12
|
|
||||||
|
|
|
||||||
LL | if let Some(&_) = &&&&&mut Some(&0u8) {}
|
|
||||||
| -^^^^^^^
|
|
||||||
| |
|
|
||||||
| help: desugar the match ergonomics: `&&&&&mut`
|
|
||||||
|
|
||||||
error: the semantics of this pattern will change in edition 2024
|
|
||||||
--> $DIR/match_ergonomics_2024.rs:31:12
|
|
||||||
|
|
|
||||||
LL | if let Some(&mut Some(Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
help: desugar the match ergonomics
|
|
||||||
|
|
|
||||||
LL | if let &mut Some(&mut Some(&mut Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {}
|
|
||||||
| ++++ ++++
|
|
||||||
|
|
||||||
error: the semantics of this pattern will change in edition 2024
|
|
||||||
--> $DIR/match_ergonomics_2024.rs:34:12
|
|
||||||
|
|
|
||||||
LL | if let Some(&mut Some(Some(_a))) = &mut Some(&mut Some(&mut Some(0u8))) {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
help: desugar the match ergonomics
|
|
||||||
|
|
|
||||||
LL | if let &mut Some(&mut Some(&mut Some(ref mut _a))) = &mut Some(&mut Some(&mut Some(0u8))) {}
|
|
||||||
| ++++ ++++ +++++++
|
|
||||||
|
|
||||||
error: the semantics of this pattern will change in edition 2024
|
|
||||||
--> $DIR/match_ergonomics_2024.rs:43:9
|
|
||||||
|
|
|
||||||
LL | let Struct { a, mut b, c } = &s;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
help: desugar the match ergonomics
|
|
||||||
|
|
|
||||||
LL | let &Struct { ref a, mut b, ref c } = &s;
|
|
||||||
| + +++ +++
|
|
||||||
|
|
||||||
warning: the semantics of this pattern will change in edition 2024
|
|
||||||
--> $DIR/match_ergonomics_2024.rs:50:9
|
|
||||||
|
|
|
||||||
LL | (Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/match_ergonomics_2024.rs:46:12
|
|
||||||
|
|
|
||||||
LL | #[warn(rust_2024_incompatible_pat)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
help: desugar the match ergonomics
|
|
||||||
|
|
|
||||||
LL | &(Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(ref _y)) => {
|
|
||||||
| + +++
|
|
||||||
|
|
||||||
error: aborting due to 8 previous errors; 1 warning emitted
|
|
||||||
|
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
//@ edition: 2021
|
||||||
|
//@ run-rustfix
|
||||||
|
//@ rustfix-only-machine-applicable
|
||||||
|
//@ aux-build:migration_lint_macros.rs
|
||||||
|
#![feature(mut_ref)]
|
||||||
|
#![allow(incomplete_features, unused)]
|
||||||
|
#![deny(rust_2024_incompatible_pat)]
|
||||||
|
|
||||||
|
extern crate migration_lint_macros;
|
||||||
|
|
||||||
|
struct Foo<T>(T);
|
||||||
|
|
||||||
|
// Tests type equality in a way that avoids coercing `&&T` to `&T`.
|
||||||
|
trait Eq<T> {}
|
||||||
|
impl<T> Eq<T> for T {}
|
||||||
|
fn assert_type_eq<T, U: Eq<T>>(_: T, _: U) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let Foo(x) = &Foo(0);
|
||||||
|
assert_type_eq(x, &0u8);
|
||||||
|
|
||||||
|
let Foo(x) = &mut Foo(0);
|
||||||
|
assert_type_eq(x, &mut 0u8);
|
||||||
|
|
||||||
|
let &Foo(mut x) = &Foo(0);
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
|
||||||
|
let &mut Foo(mut x) = &mut Foo(0);
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
|
||||||
|
let &Foo(ref x) = &Foo(0);
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, &0u8);
|
||||||
|
|
||||||
|
let &mut Foo(ref x) = &mut Foo(0);
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, &0u8);
|
||||||
|
|
||||||
|
let &Foo(x) = &Foo(0);
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
|
||||||
|
let &mut Foo(x) = &mut Foo(0);
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
|
||||||
|
let &Foo(x) = &Foo(&0);
|
||||||
|
assert_type_eq(x, &0u8);
|
||||||
|
|
||||||
|
let &mut Foo(x) = &mut Foo(&0);
|
||||||
|
assert_type_eq(x, &0u8);
|
||||||
|
|
||||||
|
let &Foo(&x) = &Foo(&0);
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
|
||||||
|
let &Foo(&mut x) = &Foo(&mut 0);
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
|
||||||
|
let &mut Foo(&x) = &mut Foo(&0);
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
|
||||||
|
let &mut Foo(&mut x) = &mut Foo(&mut 0);
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
|
||||||
|
if let Some(x) = &&&&&Some(&0u8) {
|
||||||
|
assert_type_eq(x, &&0u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let &&&&&Some(&x) = &&&&&Some(&0u8) {
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) {
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) {
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) {
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, &mut 0u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Struct<A, B, C> {
|
||||||
|
a: A,
|
||||||
|
b: B,
|
||||||
|
c: C,
|
||||||
|
}
|
||||||
|
|
||||||
|
let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 };
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(a, &0u32);
|
||||||
|
assert_type_eq(b, 0u32);
|
||||||
|
|
||||||
|
let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 };
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(a, 0u32);
|
||||||
|
assert_type_eq(b, &&0u32);
|
||||||
|
assert_type_eq(c, &&0u32);
|
||||||
|
|
||||||
|
if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } =
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
&(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) })
|
||||||
|
{
|
||||||
|
assert_type_eq(a, &0u32);
|
||||||
|
assert_type_eq(b, 0u32);
|
||||||
|
assert_type_eq(c, &&0u32);
|
||||||
|
}
|
||||||
|
|
||||||
|
match &(Some(0), Some(0)) {
|
||||||
|
// The two patterns are the same syntactically, but because they're defined in different
|
||||||
|
// editions they don't mean the same thing.
|
||||||
|
&(Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
assert_type_eq(x, 0u32);
|
||||||
|
assert_type_eq(y, 0u32);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
//@ edition: 2021
|
||||||
|
//@ run-rustfix
|
||||||
|
//@ rustfix-only-machine-applicable
|
||||||
|
//@ aux-build:migration_lint_macros.rs
|
||||||
|
#![feature(mut_ref)]
|
||||||
|
#![allow(incomplete_features, unused)]
|
||||||
|
#![deny(rust_2024_incompatible_pat)]
|
||||||
|
|
||||||
|
extern crate migration_lint_macros;
|
||||||
|
|
||||||
|
struct Foo<T>(T);
|
||||||
|
|
||||||
|
// Tests type equality in a way that avoids coercing `&&T` to `&T`.
|
||||||
|
trait Eq<T> {}
|
||||||
|
impl<T> Eq<T> for T {}
|
||||||
|
fn assert_type_eq<T, U: Eq<T>>(_: T, _: U) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let Foo(x) = &Foo(0);
|
||||||
|
assert_type_eq(x, &0u8);
|
||||||
|
|
||||||
|
let Foo(x) = &mut Foo(0);
|
||||||
|
assert_type_eq(x, &mut 0u8);
|
||||||
|
|
||||||
|
let Foo(mut x) = &Foo(0);
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
|
||||||
|
let Foo(mut x) = &mut Foo(0);
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
|
||||||
|
let Foo(ref x) = &Foo(0);
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, &0u8);
|
||||||
|
|
||||||
|
let Foo(ref x) = &mut Foo(0);
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, &0u8);
|
||||||
|
|
||||||
|
let &Foo(x) = &Foo(0);
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
|
||||||
|
let &mut Foo(x) = &mut Foo(0);
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
|
||||||
|
let &Foo(x) = &Foo(&0);
|
||||||
|
assert_type_eq(x, &0u8);
|
||||||
|
|
||||||
|
let &mut Foo(x) = &mut Foo(&0);
|
||||||
|
assert_type_eq(x, &0u8);
|
||||||
|
|
||||||
|
let Foo(&x) = &Foo(&0);
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
|
||||||
|
let Foo(&mut x) = &Foo(&mut 0);
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
|
||||||
|
let Foo(&x) = &mut Foo(&0);
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
|
||||||
|
let Foo(&mut x) = &mut Foo(&mut 0);
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
|
||||||
|
if let Some(x) = &&&&&Some(&0u8) {
|
||||||
|
assert_type_eq(x, &&0u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(&x) = &&&&&Some(&0u8) {
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(&mut x) = &&&&&Some(&mut 0u8) {
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(&x) = &&&&&mut Some(&0u8) {
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, 0u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(x, &mut 0u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Struct<A, B, C> {
|
||||||
|
a: A,
|
||||||
|
b: B,
|
||||||
|
c: C,
|
||||||
|
}
|
||||||
|
|
||||||
|
let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(a, &0u32);
|
||||||
|
assert_type_eq(b, 0u32);
|
||||||
|
|
||||||
|
let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
assert_type_eq(a, 0u32);
|
||||||
|
assert_type_eq(b, &&0u32);
|
||||||
|
assert_type_eq(c, &&0u32);
|
||||||
|
|
||||||
|
if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
&(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) })
|
||||||
|
{
|
||||||
|
assert_type_eq(a, &0u32);
|
||||||
|
assert_type_eq(b, 0u32);
|
||||||
|
assert_type_eq(c, &&0u32);
|
||||||
|
}
|
||||||
|
|
||||||
|
match &(Some(0), Some(0)) {
|
||||||
|
// The two patterns are the same syntactically, but because they're defined in different
|
||||||
|
// editions they don't mean the same thing.
|
||||||
|
(Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
|
||||||
|
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||||
|
assert_type_eq(x, 0u32);
|
||||||
|
assert_type_eq(y, 0u32);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,188 @@
|
|||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/migration_lint.rs:25:9
|
||||||
|
|
|
||||||
|
LL | let Foo(mut x) = &Foo(0);
|
||||||
|
| -^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| help: desugar the match ergonomics: `&`
|
||||||
|
|
|
||||||
|
= warning: this changes meaning in Rust 2024
|
||||||
|
= note: for more information, see 123076
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/migration_lint.rs:7:9
|
||||||
|
|
|
||||||
|
LL | #![deny(rust_2024_incompatible_pat)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/migration_lint.rs:30:9
|
||||||
|
|
|
||||||
|
LL | let Foo(mut x) = &mut Foo(0);
|
||||||
|
| -^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| help: desugar the match ergonomics: `&mut`
|
||||||
|
|
|
||||||
|
= warning: this changes meaning in Rust 2024
|
||||||
|
= note: for more information, see 123076
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/migration_lint.rs:35:9
|
||||||
|
|
|
||||||
|
LL | let Foo(ref x) = &Foo(0);
|
||||||
|
| -^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| help: desugar the match ergonomics: `&`
|
||||||
|
|
|
||||||
|
= warning: this changes meaning in Rust 2024
|
||||||
|
= note: for more information, see 123076
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/migration_lint.rs:40:9
|
||||||
|
|
|
||||||
|
LL | let Foo(ref x) = &mut Foo(0);
|
||||||
|
| -^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| help: desugar the match ergonomics: `&mut`
|
||||||
|
|
|
||||||
|
= warning: this changes meaning in Rust 2024
|
||||||
|
= note: for more information, see 123076
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/migration_lint.rs:57:9
|
||||||
|
|
|
||||||
|
LL | let Foo(&x) = &Foo(&0);
|
||||||
|
| -^^^^^^
|
||||||
|
| |
|
||||||
|
| help: desugar the match ergonomics: `&`
|
||||||
|
|
|
||||||
|
= warning: this changes meaning in Rust 2024
|
||||||
|
= note: for more information, see 123076
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/migration_lint.rs:62:9
|
||||||
|
|
|
||||||
|
LL | let Foo(&mut x) = &Foo(&mut 0);
|
||||||
|
| -^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| help: desugar the match ergonomics: `&`
|
||||||
|
|
|
||||||
|
= warning: this changes meaning in Rust 2024
|
||||||
|
= note: for more information, see 123076
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/migration_lint.rs:67:9
|
||||||
|
|
|
||||||
|
LL | let Foo(&x) = &mut Foo(&0);
|
||||||
|
| -^^^^^^
|
||||||
|
| |
|
||||||
|
| help: desugar the match ergonomics: `&mut`
|
||||||
|
|
|
||||||
|
= warning: this changes meaning in Rust 2024
|
||||||
|
= note: for more information, see 123076
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/migration_lint.rs:72:9
|
||||||
|
|
|
||||||
|
LL | let Foo(&mut x) = &mut Foo(&mut 0);
|
||||||
|
| -^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| help: desugar the match ergonomics: `&mut`
|
||||||
|
|
|
||||||
|
= warning: this changes meaning in Rust 2024
|
||||||
|
= note: for more information, see 123076
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/migration_lint.rs:81:12
|
||||||
|
|
|
||||||
|
LL | if let Some(&x) = &&&&&Some(&0u8) {
|
||||||
|
| -^^^^^^^
|
||||||
|
| |
|
||||||
|
| help: desugar the match ergonomics: `&&&&&`
|
||||||
|
|
|
||||||
|
= warning: this changes meaning in Rust 2024
|
||||||
|
= note: for more information, see 123076
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/migration_lint.rs:87:12
|
||||||
|
|
|
||||||
|
LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) {
|
||||||
|
| -^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| help: desugar the match ergonomics: `&&&&&`
|
||||||
|
|
|
||||||
|
= warning: this changes meaning in Rust 2024
|
||||||
|
= note: for more information, see 123076
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/migration_lint.rs:93:12
|
||||||
|
|
|
||||||
|
LL | if let Some(&x) = &&&&&mut Some(&0u8) {
|
||||||
|
| -^^^^^^^
|
||||||
|
| |
|
||||||
|
| help: desugar the match ergonomics: `&&&&&mut`
|
||||||
|
|
|
||||||
|
= warning: this changes meaning in Rust 2024
|
||||||
|
= note: for more information, see 123076
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/migration_lint.rs:99:12
|
||||||
|
|
|
||||||
|
LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this changes meaning in Rust 2024
|
||||||
|
= note: for more information, see 123076
|
||||||
|
help: desugar the match ergonomics
|
||||||
|
|
|
||||||
|
LL | if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) {
|
||||||
|
| ++++ ++++ +++++++
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/migration_lint.rs:111:9
|
||||||
|
|
|
||||||
|
LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this changes meaning in Rust 2024
|
||||||
|
= note: for more information, see 123076
|
||||||
|
help: desugar the match ergonomics
|
||||||
|
|
|
||||||
|
LL | let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 };
|
||||||
|
| + +++ +++
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/migration_lint.rs:117:9
|
||||||
|
|
|
||||||
|
LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this changes meaning in Rust 2024
|
||||||
|
= note: for more information, see 123076
|
||||||
|
help: desugar the match ergonomics
|
||||||
|
|
|
||||||
|
LL | let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 };
|
||||||
|
| + +++
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/migration_lint.rs:124:12
|
||||||
|
|
|
||||||
|
LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this changes meaning in Rust 2024
|
||||||
|
= note: for more information, see 123076
|
||||||
|
help: desugar the match ergonomics
|
||||||
|
|
|
||||||
|
LL | if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } =
|
||||||
|
| + + + +++
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/migration_lint.rs:137:9
|
||||||
|
|
|
||||||
|
LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
|
||||||
|
| -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| help: desugar the match ergonomics: `&`
|
||||||
|
|
||||||
|
error: aborting due to 16 previous errors
|
||||||
|
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
//@ check-fail
|
||||||
|
//@ edition: 2024
|
||||||
|
//@ compile-flags: -Zunstable-options
|
||||||
|
#![deny(rust_2024_incompatible_pat)]
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
struct T;
|
||||||
|
|
||||||
|
struct Foo {
|
||||||
|
f: &'static (u8,),
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! test_pat_on_type {
|
||||||
|
($($tt:tt)*) => {
|
||||||
|
const _: () = {
|
||||||
|
// Define a new function to ensure all cases are tested independently.
|
||||||
|
fn foo($($tt)*) {}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
test_pat_on_type![(&x,): &(T,)]; //~ ERROR mismatched types
|
||||||
|
test_pat_on_type![(&x,): &(&T,)]; //~ ERROR patterns are not allowed to reset the default binding mode
|
||||||
|
test_pat_on_type![(&x,): &(&mut T,)]; //~ ERROR mismatched types
|
||||||
|
test_pat_on_type![(&mut x,): &(&T,)]; //~ ERROR mismatched types
|
||||||
|
test_pat_on_type![(&mut x,): &(&mut T,)]; //~ ERROR patterns are not allowed to reset the default binding mode
|
||||||
|
test_pat_on_type![(&x,): &&mut &(T,)]; //~ ERROR mismatched types
|
||||||
|
test_pat_on_type![Foo { f: (&x,) }: Foo]; //~ ERROR mismatched types
|
||||||
|
test_pat_on_type![Foo { f: (&x,) }: &mut Foo]; //~ ERROR mismatched types
|
||||||
|
test_pat_on_type![Foo { f: &(x,) }: &Foo]; //~ ERROR patterns are not allowed to reset the default binding mode
|
||||||
|
test_pat_on_type![(mut x,): &(T,)]; //~ ERROR patterns are not allowed to reset the default binding mode
|
||||||
|
test_pat_on_type![(ref x,): &(T,)]; //~ ERROR patterns are not allowed to reset the default binding mode
|
||||||
|
test_pat_on_type![(ref mut x,): &mut (T,)]; //~ ERROR patterns are not allowed to reset the default binding mode
|
||||||
|
|
||||||
|
fn get<X>() -> X {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure this works even when the underlying type is inferred. This test passes on rust stable.
|
||||||
|
fn infer<X: Copy>() -> X {
|
||||||
|
match &get() {
|
||||||
|
(&x,) => x, //~ ERROR patterns are not allowed to reset the default binding mode
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/min_match_ergonomics_fail.rs:24:20
|
||||||
|
|
|
||||||
|
LL | test_pat_on_type![(&x,): &(T,)];
|
||||||
|
| ^^ ----- expected due to this
|
||||||
|
| |
|
||||||
|
| expected `T`, found `&_`
|
||||||
|
|
|
||||||
|
= note: expected struct `T`
|
||||||
|
found reference `&_`
|
||||||
|
help: consider removing `&` from the pattern
|
||||||
|
|
|
||||||
|
LL - test_pat_on_type![(&x,): &(T,)];
|
||||||
|
LL + test_pat_on_type![(x,): &(T,)];
|
||||||
|
|
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/min_match_ergonomics_fail.rs:26:20
|
||||||
|
|
|
||||||
|
LL | test_pat_on_type![(&x,): &(&mut T,)];
|
||||||
|
| ^^ ---------- expected due to this
|
||||||
|
| |
|
||||||
|
| types differ in mutability
|
||||||
|
|
|
||||||
|
= note: expected mutable reference `&mut T`
|
||||||
|
found reference `&_`
|
||||||
|
help: consider removing `&` from the pattern
|
||||||
|
|
|
||||||
|
LL - test_pat_on_type![(&x,): &(&mut T,)];
|
||||||
|
LL + test_pat_on_type![(x,): &(&mut T,)];
|
||||||
|
|
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/min_match_ergonomics_fail.rs:27:20
|
||||||
|
|
|
||||||
|
LL | test_pat_on_type![(&mut x,): &(&T,)];
|
||||||
|
| ^^^^^^ ------ expected due to this
|
||||||
|
| |
|
||||||
|
| types differ in mutability
|
||||||
|
|
|
||||||
|
= note: expected reference `&T`
|
||||||
|
found mutable reference `&mut _`
|
||||||
|
note: to declare a mutable binding use: `mut x`
|
||||||
|
--> $DIR/min_match_ergonomics_fail.rs:27:20
|
||||||
|
|
|
||||||
|
LL | test_pat_on_type![(&mut x,): &(&T,)];
|
||||||
|
| ^^^^^^
|
||||||
|
help: consider removing `&mut` from the pattern
|
||||||
|
|
|
||||||
|
LL - test_pat_on_type![(&mut x,): &(&T,)];
|
||||||
|
LL + test_pat_on_type![(x,): &(&T,)];
|
||||||
|
|
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/min_match_ergonomics_fail.rs:29:20
|
||||||
|
|
|
||||||
|
LL | test_pat_on_type![(&x,): &&mut &(T,)];
|
||||||
|
| ^^ ----------- expected due to this
|
||||||
|
| |
|
||||||
|
| expected `T`, found `&_`
|
||||||
|
|
|
||||||
|
= note: expected struct `T`
|
||||||
|
found reference `&_`
|
||||||
|
help: consider removing `&` from the pattern
|
||||||
|
|
|
||||||
|
LL - test_pat_on_type![(&x,): &&mut &(T,)];
|
||||||
|
LL + test_pat_on_type![(x,): &&mut &(T,)];
|
||||||
|
|
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/min_match_ergonomics_fail.rs:30:29
|
||||||
|
|
|
||||||
|
LL | test_pat_on_type![Foo { f: (&x,) }: Foo];
|
||||||
|
| ^^ --- expected due to this
|
||||||
|
| |
|
||||||
|
| expected `u8`, found `&_`
|
||||||
|
|
|
||||||
|
= note: expected type `u8`
|
||||||
|
found reference `&_`
|
||||||
|
help: consider removing `&` from the pattern
|
||||||
|
|
|
||||||
|
LL - test_pat_on_type![Foo { f: (&x,) }: Foo];
|
||||||
|
LL + test_pat_on_type![Foo { f: (x,) }: Foo];
|
||||||
|
|
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/min_match_ergonomics_fail.rs:31:29
|
||||||
|
|
|
||||||
|
LL | test_pat_on_type![Foo { f: (&x,) }: &mut Foo];
|
||||||
|
| ^^ -------- expected due to this
|
||||||
|
| |
|
||||||
|
| expected `u8`, found `&_`
|
||||||
|
|
|
||||||
|
= note: expected type `u8`
|
||||||
|
found reference `&_`
|
||||||
|
help: consider removing `&` from the pattern
|
||||||
|
|
|
||||||
|
LL - test_pat_on_type![Foo { f: (&x,) }: &mut Foo];
|
||||||
|
LL + test_pat_on_type![Foo { f: (x,) }: &mut Foo];
|
||||||
|
|
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/min_match_ergonomics_fail.rs:25:19
|
||||||
|
|
|
||||||
|
LL | test_pat_on_type![(&x,): &(&T,)];
|
||||||
|
| -^^^^
|
||||||
|
| |
|
||||||
|
| help: desugar the match ergonomics: `&`
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/min_match_ergonomics_fail.rs:28:19
|
||||||
|
|
|
||||||
|
LL | test_pat_on_type![(&mut x,): &(&mut T,)];
|
||||||
|
| -^^^^^^^^
|
||||||
|
| |
|
||||||
|
| help: desugar the match ergonomics: `&`
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/min_match_ergonomics_fail.rs:32:19
|
||||||
|
|
|
||||||
|
LL | test_pat_on_type![Foo { f: &(x,) }: &Foo];
|
||||||
|
| -^^^^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| help: desugar the match ergonomics: `&`
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/min_match_ergonomics_fail.rs:33:19
|
||||||
|
|
|
||||||
|
LL | test_pat_on_type![(mut x,): &(T,)];
|
||||||
|
| -^^^^^^^
|
||||||
|
| |
|
||||||
|
| help: desugar the match ergonomics: `&`
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/min_match_ergonomics_fail.rs:34:19
|
||||||
|
|
|
||||||
|
LL | test_pat_on_type![(ref x,): &(T,)];
|
||||||
|
| -^^^^^^^
|
||||||
|
| |
|
||||||
|
| help: desugar the match ergonomics: `&`
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/min_match_ergonomics_fail.rs:35:19
|
||||||
|
|
|
||||||
|
LL | test_pat_on_type![(ref mut x,): &mut (T,)];
|
||||||
|
| -^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| help: desugar the match ergonomics: `&mut`
|
||||||
|
|
||||||
|
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||||
|
--> $DIR/min_match_ergonomics_fail.rs:44:9
|
||||||
|
|
|
||||||
|
LL | (&x,) => x,
|
||||||
|
| -^^^^
|
||||||
|
| |
|
||||||
|
| help: desugar the match ergonomics: `&`
|
||||||
|
|
||||||
|
error: aborting due to 13 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
//@ check-pass
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
||||||
|
// Tests type equality in a way that avoids coercing `&&T` to `&T`.
|
||||||
|
trait Eq<T> {}
|
||||||
|
impl<T> Eq<T> for T {}
|
||||||
|
fn assert_type_eq<T, U: Eq<T>>(_: T, _: U) {}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
struct T;
|
||||||
|
|
||||||
|
fn test() {
|
||||||
|
let (x,) = &(&T,);
|
||||||
|
assert_type_eq(x, &&T);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user