1
Fork 0

Rollup merge of #136577 - dianne:simple-pat-migration-simplification, r=Nadrieril

Pattern Migration 2024: try to suggest eliding redundant binding modifiers

This is based on #136475. Only the last commit is new.

This is a simpler, more restrictive alternative to #136496, meant to partially address #136047. If a pattern can be migrated to Rust 2024 solely by removing redundant binding modifiers, this will make that suggestion; otherwise, it uses the old suggestion of making the pattern fully explicit.

Relevant tracking issue: #131414

``@rustbot`` label A-diagnostics A-patterns A-edition-2024

r? ``@Nadrieril``
This commit is contained in:
Matthias Krüger 2025-02-07 18:26:27 +01:00 committed by GitHub
commit 20f9e973d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 1043 additions and 262 deletions

View file

@ -812,7 +812,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Determine the binding mode...
let bm = match user_bind_annot {
BindingMode(ByRef::No, Mutability::Mut) if matches!(def_br, ByRef::Yes(_)) => {
BindingMode(ByRef::No, Mutability::Mut) if let ByRef::Yes(def_br_mutbl) = def_br => {
// Only mention the experimental `mut_ref` feature if if we're in edition 2024 and
// using other experimental matching features compatible with it.
if pat.span.at_least_rust_2024()
@ -834,22 +834,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// `mut` resets the binding mode on edition <= 2021
self.add_rust_2024_migration_desugared_pat(
pat_info.top_info.hir_id,
pat.span,
pat,
ident.span,
"requires binding by-value, but the implicit default is by-reference",
def_br_mutbl,
);
BindingMode(ByRef::No, Mutability::Mut)
}
}
BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl),
BindingMode(ByRef::Yes(_), _) => {
if matches!(def_br, ByRef::Yes(_)) {
if let ByRef::Yes(def_br_mutbl) = def_br {
// `ref`/`ref mut` overrides the binding mode on edition <= 2021
self.add_rust_2024_migration_desugared_pat(
pat_info.top_info.hir_id,
pat.span,
pat,
ident.span,
"cannot override to bind by-reference when that is the implicit default",
def_br_mutbl,
);
}
user_bind_annot
@ -2386,9 +2386,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pat_info.binding_mode = ByRef::No;
self.add_rust_2024_migration_desugared_pat(
pat_info.top_info.hir_id,
pat.span,
pat,
inner.span,
"cannot implicitly match against multiple layers of reference",
inh_mut,
)
}
}
@ -2778,33 +2778,65 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn add_rust_2024_migration_desugared_pat(
&self,
pat_id: HirId,
subpat_span: Span,
subpat: &'tcx Pat<'tcx>,
cutoff_span: Span,
detailed_label: &str,
def_br_mutbl: Mutability,
) {
// Try to trim the span we're labeling to just the `&` or binding mode that's an issue.
// If the subpattern's span is is from an expansion, the emitted label will not be trimmed.
let source_map = self.tcx.sess.source_map();
let cutoff_span = source_map
.span_extend_prev_while(cutoff_span, char::is_whitespace)
.span_extend_prev_while(cutoff_span, |c| c.is_whitespace() || c == '(')
.unwrap_or(cutoff_span);
// Ensure we use the syntax context and thus edition of `subpat_span`; this will be a hard
// Ensure we use the syntax context and thus edition of `subpat.span`; this will be a hard
// error if the subpattern is of edition >= 2024.
let trimmed_span = subpat_span.until(cutoff_span).with_ctxt(subpat_span.ctxt());
let trimmed_span = subpat.span.until(cutoff_span).with_ctxt(subpat.span.ctxt());
let mut typeck_results = self.typeck_results.borrow_mut();
let mut table = typeck_results.rust_2024_migration_desugared_pats_mut();
// FIXME(ref_pat_eat_one_layer_2024): The migration diagnostic doesn't know how to track the
// default binding mode in the presence of Rule 3 or Rule 5. As a consequence, the labels it
// gives for default binding modes are wrong, as well as suggestions based on the default
// binding mode. This keeps it from making those suggestions, as doing so could panic.
let info = table.entry(pat_id).or_insert_with(|| ty::Rust2024IncompatiblePatInfo {
primary_labels: Vec::new(),
bad_modifiers: false,
bad_ref_pats: false,
suggest_eliding_modes: !self.tcx.features().ref_pat_eat_one_layer_2024()
&& !self.tcx.features().ref_pat_eat_one_layer_2024_structural(),
});
// Only provide a detailed label if the problematic subpattern isn't from an expansion.
// In the case that it's from a macro, we'll add a more detailed note in the emitter.
let desc = if subpat_span.from_expansion() {
"default binding mode is reset within expansion"
let from_expansion = subpat.span.from_expansion();
let primary_label = if from_expansion {
// NB: This wording assumes the only expansions that can produce problematic reference
// patterns and bindings are macros. If a desugaring or AST pass is added that can do
// so, we may want to inspect the span's source callee or macro backtrace.
"occurs within macro expansion".to_owned()
} else {
detailed_label
let pat_kind = if let PatKind::Binding(user_bind_annot, _, _, _) = subpat.kind {
info.bad_modifiers |= true;
// If the user-provided binding modifier doesn't match the default binding mode, we'll
// need to suggest reference patterns, which can affect other bindings.
// For simplicity, we opt to suggest making the pattern fully explicit.
info.suggest_eliding_modes &=
user_bind_annot == BindingMode(ByRef::Yes(def_br_mutbl), Mutability::Not);
"binding modifier"
} else {
info.bad_ref_pats |= true;
// For simplicity, we don't try to suggest eliding reference patterns. Thus, we'll
// suggest adding them instead, which can affect the types assigned to bindings.
// As such, we opt to suggest making the pattern fully explicit.
info.suggest_eliding_modes = false;
"reference pattern"
};
self.typeck_results
.borrow_mut()
.rust_2024_migration_desugared_pats_mut()
.entry(pat_id)
.or_default()
.push((trimmed_span, desc.to_owned()));
let dbm_str = match def_br_mutbl {
Mutability::Not => "ref",
Mutability::Mut => "ref mut",
};
format!("{pat_kind} not allowed under `{dbm_str}` default binding mode")
};
info.primary_labels.push((trimmed_span, primary_label));
}
}

View file

@ -94,7 +94,7 @@ pub use self::sty::{
pub use self::trait_def::TraitDef;
pub use self::typeck_results::{
CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, IsIdentity,
TypeckResults, UserType, UserTypeAnnotationIndex, UserTypeKind,
Rust2024IncompatiblePatInfo, TypeckResults, UserType, UserTypeAnnotationIndex, UserTypeKind,
};
pub use self::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason};

View file

@ -73,9 +73,9 @@ pub struct TypeckResults<'tcx> {
/// Stores the actual binding mode for all instances of [`BindingMode`].
pat_binding_modes: ItemLocalMap<BindingMode>,
/// Top-level patterns whose match ergonomics need to be desugared by the Rust 2021 -> 2024
/// migration lint. Problematic subpatterns are stored in the `Vec` for the lint to highlight.
rust_2024_migration_desugared_pats: ItemLocalMap<Vec<(Span, String)>>,
/// Top-level patterns incompatible with Rust 2024's match ergonomics. These will be translated
/// to a form valid in all Editions, either as a lint diagnostic or hard error.
rust_2024_migration_desugared_pats: ItemLocalMap<Rust2024IncompatiblePatInfo>,
/// Stores the types which were implicitly dereferenced in pattern binding modes
/// for later usage in THIR lowering. For example,
@ -420,7 +420,7 @@ impl<'tcx> TypeckResults<'tcx> {
pub fn rust_2024_migration_desugared_pats(
&self,
) -> LocalTableInContext<'_, Vec<(Span, String)>> {
) -> LocalTableInContext<'_, Rust2024IncompatiblePatInfo> {
LocalTableInContext {
hir_owner: self.hir_owner,
data: &self.rust_2024_migration_desugared_pats,
@ -429,7 +429,7 @@ impl<'tcx> TypeckResults<'tcx> {
pub fn rust_2024_migration_desugared_pats_mut(
&mut self,
) -> LocalTableInContextMut<'_, Vec<(Span, String)>> {
) -> LocalTableInContextMut<'_, Rust2024IncompatiblePatInfo> {
LocalTableInContextMut {
hir_owner: self.hir_owner,
data: &mut self.rust_2024_migration_desugared_pats,
@ -811,3 +811,17 @@ impl<'tcx> std::fmt::Display for UserTypeKind<'tcx> {
}
}
}
/// Information on a pattern incompatible with Rust 2024, for use by the error/migration diagnostic
/// emitted during THIR construction.
#[derive(TyEncodable, TyDecodable, Debug, HashStable)]
pub struct Rust2024IncompatiblePatInfo {
/// Labeled spans for `&`s, `&mut`s, and binding modifiers incompatible with Rust 2024.
pub primary_labels: Vec<(Span, String)>,
/// Whether any binding modifiers occur under a non-`move` default binding mode.
pub bad_modifiers: bool,
/// Whether any `&` or `&mut` patterns occur under a non-`move` default binding mode.
pub bad_ref_pats: bool,
/// If `true`, we can give a simpler suggestion solely by eliding explicit binding modifiers.
pub suggest_eliding_modes: bool,
}

View file

@ -285,7 +285,16 @@ 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_rust_2024_incompatible_pat = this pattern relies on behavior which may change in edition 2024
mir_build_rust_2024_incompatible_pat = {$bad_modifiers ->
*[true] binding modifiers{$bad_ref_pats ->
*[true] {" "}and reference patterns
[false] {""}
}
[false] reference patterns
} may only be written when the default binding mode is `move`{$is_hard_error ->
*[true] {""}
[false] {" "}in Rust 2024
}
mir_build_static_in_pattern = statics cannot be referenced in patterns
.label = can't be used in patterns

View file

@ -1,3 +1,4 @@
use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::codes::*;
use rustc_errors::{
Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level,
@ -1097,41 +1098,70 @@ pub(crate) enum MiscPatternSuggestion {
#[derive(LintDiagnostic)]
#[diag(mir_build_rust_2024_incompatible_pat)]
pub(crate) struct Rust2024IncompatiblePat<'a> {
pub(crate) struct Rust2024IncompatiblePat {
#[subdiagnostic]
pub(crate) sugg: Rust2024IncompatiblePatSugg<'a>,
pub(crate) sugg: Rust2024IncompatiblePatSugg,
pub(crate) bad_modifiers: bool,
pub(crate) bad_ref_pats: bool,
pub(crate) is_hard_error: bool,
}
pub(crate) struct Rust2024IncompatiblePatSugg<'a> {
pub(crate) struct Rust2024IncompatiblePatSugg {
/// If true, our suggestion is to elide explicit binding modifiers.
/// If false, our suggestion is to make the pattern fully explicit.
pub(crate) suggest_eliding_modes: bool,
pub(crate) suggestion: Vec<(Span, String)>,
pub(crate) ref_pattern_count: usize,
pub(crate) binding_mode_count: usize,
/// Labeled spans for subpatterns invalid in Rust 2024.
pub(crate) labels: &'a [(Span, String)],
/// Internal state: the ref-mutability of the default binding mode at the subpattern being
/// lowered, with the span where it was introduced. `None` for a by-value default mode.
pub(crate) default_mode_span: Option<(Span, ty::Mutability)>,
/// Labels for where incompatibility-causing by-ref default binding modes were introduced.
pub(crate) default_mode_labels: FxIndexMap<Span, ty::Mutability>,
}
impl<'a> Subdiagnostic for Rust2024IncompatiblePatSugg<'a> {
impl Subdiagnostic for Rust2024IncompatiblePatSugg {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
_f: &F,
) {
// Format and emit explanatory notes about default binding modes. Reversing the spans' order
// means if we have nested spans, the innermost ones will be visited first.
for (span, def_br_mutbl) in self.default_mode_labels.into_iter().rev() {
// Don't point to a macro call site.
if !span.from_expansion() {
let note_msg = "matching on a reference type with a non-reference pattern changes the default binding mode";
let label_msg =
format!("this matches on type `{}_`", def_br_mutbl.ref_prefix_str());
let mut label = MultiSpan::from(span);
label.push_span_label(span, label_msg);
diag.span_note(label, note_msg);
}
}
// Format and emit the suggestion.
let applicability =
if self.suggestion.iter().all(|(span, _)| span.can_be_used_for_suggestions()) {
Applicability::MachineApplicable
} else {
Applicability::MaybeIncorrect
};
let msg = if self.suggest_eliding_modes {
let plural_modes = pluralize!(self.binding_mode_count);
format!("remove the unnecessary binding modifier{plural_modes}")
} else {
let plural_derefs = pluralize!(self.ref_pattern_count);
let and_modes = if self.binding_mode_count > 0 {
format!(" and variable binding mode{}", pluralize!(self.binding_mode_count))
} else {
String::new()
};
diag.multipart_suggestion_verbose(
format!("make the implied reference pattern{plural_derefs}{and_modes} explicit"),
self.suggestion,
applicability,
);
format!("make the implied reference pattern{plural_derefs}{and_modes} explicit")
};
// FIXME(dianne): for peace of mind, don't risk emitting a 0-part suggestion (that panics!)
if !self.suggestion.is_empty() {
diag.multipart_suggestion_verbose(msg, self.suggestion, applicability);
}
}
}

View file

@ -35,7 +35,7 @@ struct PatCtxt<'a, 'tcx> {
typeck_results: &'a ty::TypeckResults<'tcx>,
/// Used by the Rust 2024 migration lint.
rust_2024_migration_suggestion: Option<Rust2024IncompatiblePatSugg<'a>>,
rust_2024_migration_suggestion: Option<Rust2024IncompatiblePatSugg>,
}
pub(super) fn pat_from_hir<'a, 'tcx>(
@ -44,25 +44,30 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
typeck_results: &'a ty::TypeckResults<'tcx>,
pat: &'tcx hir::Pat<'tcx>,
) -> Box<Pat<'tcx>> {
let migration_info = typeck_results.rust_2024_migration_desugared_pats().get(pat.hir_id);
let mut pcx = PatCtxt {
tcx,
typing_env,
typeck_results,
rust_2024_migration_suggestion: typeck_results
.rust_2024_migration_desugared_pats()
.get(pat.hir_id)
.map(|labels| Rust2024IncompatiblePatSugg {
rust_2024_migration_suggestion: migration_info.and_then(|info| {
Some(Rust2024IncompatiblePatSugg {
suggest_eliding_modes: info.suggest_eliding_modes,
suggestion: Vec::new(),
ref_pattern_count: 0,
binding_mode_count: 0,
labels: labels.as_slice(),
default_mode_span: None,
default_mode_labels: Default::default(),
})
}),
};
let result = pcx.lower_pattern(pat);
debug!("pat_from_hir({:?}) = {:?}", pat, result);
if let Some(sugg) = pcx.rust_2024_migration_suggestion {
let mut spans = MultiSpan::from_spans(sugg.labels.iter().map(|(span, _)| *span).collect());
for (span, label) in sugg.labels {
if let Some(info) = migration_info
&& let Some(sugg) = pcx.rust_2024_migration_suggestion
{
let mut spans =
MultiSpan::from_spans(info.primary_labels.iter().map(|(span, _)| *span).collect());
for (span, label) in &info.primary_labels {
spans.push_span_label(*span, label.clone());
}
// If a relevant span is from at least edition 2024, this is a hard error.
@ -70,10 +75,13 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
if is_hard_error {
let mut err =
tcx.dcx().struct_span_err(spans, fluent::mir_build_rust_2024_incompatible_pat);
if let Some(info) = lint::builtin::RUST_2024_INCOMPATIBLE_PAT.future_incompatible {
if let Some(lint_info) = lint::builtin::RUST_2024_INCOMPATIBLE_PAT.future_incompatible {
// provide the same reference link as the lint
err.note(format!("for more information, see {}", info.reference));
err.note(format!("for more information, see {}", lint_info.reference));
}
err.arg("bad_modifiers", info.bad_modifiers);
err.arg("bad_ref_pats", info.bad_ref_pats);
err.arg("is_hard_error", true);
err.subdiagnostic(sugg);
err.emit();
} else {
@ -81,7 +89,12 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
lint::builtin::RUST_2024_INCOMPATIBLE_PAT,
pat.hir_id,
spans,
Rust2024IncompatiblePat { sugg },
Rust2024IncompatiblePat {
sugg,
bad_modifiers: info.bad_modifiers,
bad_ref_pats: info.bad_ref_pats,
is_hard_error,
},
);
}
}
@ -90,6 +103,35 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
let adjustments: &[Ty<'tcx>] =
self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(&[], |v| &**v);
let mut opt_old_mode_span = None;
if let Some(s) = &mut self.rust_2024_migration_suggestion
&& !adjustments.is_empty()
{
let implicit_deref_mutbls = adjustments.iter().map(|ref_ty| {
let &ty::Ref(_, _, mutbl) = ref_ty.kind() else {
span_bug!(pat.span, "pattern implicitly dereferences a non-ref type");
};
mutbl
});
if !s.suggest_eliding_modes {
let suggestion_str: String =
implicit_deref_mutbls.clone().map(|mutbl| mutbl.ref_prefix_str()).collect();
s.suggestion.push((pat.span.shrink_to_lo(), suggestion_str));
s.ref_pattern_count += adjustments.len();
}
// Remember if this changed the default binding mode, in case we want to label it.
let min_mutbl = implicit_deref_mutbls.min().unwrap();
if s.default_mode_span.is_none_or(|(_, old_mutbl)| min_mutbl < old_mutbl) {
opt_old_mode_span = Some(s.default_mode_span);
s.default_mode_span = Some((pat.span, min_mutbl));
}
};
// When implicit dereferences have been inserted in this pattern, the unadjusted lowered
// pattern has the type that results *after* dereferencing. For example, in this code:
//
@ -118,8 +160,6 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
_ => self.lower_pattern_unadjusted(pat),
};
let adjustments: &[Ty<'tcx>] =
self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(&[], |v| &**v);
let adjusted_pat = adjustments.iter().rev().fold(unadjusted_pat, |thir_pat, ref_ty| {
debug!("{:?}: wrapping pattern with type {:?}", thir_pat, ref_ty);
Box::new(Pat {
@ -130,24 +170,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
});
if let Some(s) = &mut self.rust_2024_migration_suggestion
&& !adjustments.is_empty()
&& let Some(old_mode_span) = opt_old_mode_span
{
let suggestion_str: String = adjustments
.iter()
.map(|ref_ty| {
let &ty::Ref(_, _, mutbl) = ref_ty.kind() else {
span_bug!(pat.span, "pattern implicitly dereferences a non-ref type");
};
match mutbl {
ty::Mutability::Not => "&",
ty::Mutability::Mut => "&mut ",
s.default_mode_span = old_mode_span;
}
})
.collect();
s.suggestion.push((pat.span.shrink_to_lo(), suggestion_str));
s.ref_pattern_count += adjustments.len();
};
adjusted_pat
}
@ -340,7 +366,22 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
let mutability = if mutable { hir::Mutability::Mut } else { hir::Mutability::Not };
PatKind::DerefPattern { subpattern: self.lower_pattern(subpattern), mutability }
}
hir::PatKind::Ref(subpattern, _) | hir::PatKind::Box(subpattern) => {
hir::PatKind::Ref(subpattern, _) => {
// Track the default binding mode for the Rust 2024 migration suggestion.
let old_mode_span = self.rust_2024_migration_suggestion.as_mut().and_then(|s| {
if let Some((default_mode_span, default_ref_mutbl)) = s.default_mode_span {
// If this eats a by-ref default binding mode, label the binding mode.
s.default_mode_labels.insert(default_mode_span, default_ref_mutbl);
}
s.default_mode_span.take()
});
let subpattern = self.lower_pattern(subpattern);
if let Some(s) = &mut self.rust_2024_migration_suggestion {
s.default_mode_span = old_mode_span;
}
PatKind::Deref { subpattern }
}
hir::PatKind::Box(subpattern) => {
PatKind::Deref { subpattern: self.lower_pattern(subpattern) }
}
@ -367,7 +408,19 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
.get(pat.hir_id)
.expect("missing binding mode");
if let Some(s) = &mut self.rust_2024_migration_suggestion
if let Some(s) = &mut self.rust_2024_migration_suggestion {
if explicit_ba != hir::BindingMode::NONE
&& let Some((default_mode_span, default_ref_mutbl)) = s.default_mode_span
{
// If this overrides a by-ref default binding mode, label the binding mode.
s.default_mode_labels.insert(default_mode_span, default_ref_mutbl);
// If our suggestion is to elide redundnt modes, this will be one of them.
if s.suggest_eliding_modes {
s.suggestion.push((pat.span.with_hi(ident.span.lo()), String::new()));
s.binding_mode_count += 1;
}
}
if !s.suggest_eliding_modes
&& explicit_ba.0 == ByRef::No
&& let ByRef::Yes(mutbl) = mode.0
{
@ -381,6 +434,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
));
s.binding_mode_count += 1;
}
}
// A ref x pattern is the same node used for x, and as such it has
// x's type, which is &T, where we want T (the type being matched).

View file

@ -1,5 +1,5 @@
error[E0308]: mismatched types
--> $DIR/ref-binding-on-inh-ref-errors.rs:60:10
--> $DIR/ref-binding-on-inh-ref-errors.rs:54:10
|
LL | let [&mut ref x] = &[&mut 0];
| ^^^^^
@ -10,55 +10,75 @@ help: replace this `&mut` pattern with `&`
LL | let [&ref x] = &[&mut 0];
| ~
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:74:10
error: binding modifiers may only be written when the default binding mode is `move`
--> $DIR/ref-binding-on-inh-ref-errors.rs:67:10
|
LL | let [ref mut x] = &[0];
| ^^^^^^^ cannot override to bind by-reference when that is the implicit default
| ^^^^^^^ binding modifier not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/ref-binding-on-inh-ref-errors.rs:67:9
|
LL | let [ref mut x] = &[0];
| ^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference pattern explicit
|
LL | let &[ref mut x] = &[0];
| +
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/ref-binding-on-inh-ref-errors.rs:74:10
--> $DIR/ref-binding-on-inh-ref-errors.rs:67:10
|
LL | let [ref mut x] = &[0];
| ^^^^^^^^^ cannot borrow as mutable
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:83:10
error: binding modifiers may only be written when the default binding mode is `move`
--> $DIR/ref-binding-on-inh-ref-errors.rs:75:10
|
LL | let [ref x] = &[0];
| ^^^ cannot override to bind by-reference when that is the implicit default
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/ref-binding-on-inh-ref-errors.rs:75:9
|
LL | let [ref x] = &[0];
| ^^^^^^^ this matches on type `&_`
help: make the implied reference pattern explicit
|
LL | let &[ref x] = &[0];
| +
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:88:10
error: binding modifiers may only be written when the default binding mode is `move`
--> $DIR/ref-binding-on-inh-ref-errors.rs:79:10
|
LL | let [ref x] = &mut [0];
| ^^^ cannot override to bind by-reference when that is the implicit default
| ^^^ binding modifier not allowed under `ref mut` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/ref-binding-on-inh-ref-errors.rs:79:9
|
LL | let [ref x] = &mut [0];
| ^^^^^^^ this matches on type `&mut _`
help: make the implied reference pattern explicit
|
LL | let &mut [ref x] = &mut [0];
| ++++
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:93:10
error: binding modifiers may only be written when the default binding mode is `move`
--> $DIR/ref-binding-on-inh-ref-errors.rs:83:10
|
LL | let [ref mut x] = &mut [0];
| ^^^^^^^ cannot override to bind by-reference when that is the implicit default
| ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/ref-binding-on-inh-ref-errors.rs:83:9
|
LL | let [ref mut x] = &mut [0];
| ^^^^^^^^^^^ this matches on type `&mut _`
help: make the implied reference pattern explicit
|
LL | let &mut [ref mut x] = &mut [0];

View file

@ -13,26 +13,22 @@
/// The eat-outer variant eats the inherited reference, so binding with `ref` isn't a problem.
fn errors_from_eating_the_real_reference() {
let [&ref x] = &[&0];
//[structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024
//[structural2024]~| cannot override to bind by-reference when that is the implicit default
//[structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move`
#[cfg(stable2021)] let _: &u32 = x;
#[cfg(classic2024)] let _: &&u32 = x;
let [&ref x] = &mut [&0];
//[structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024
//[structural2024]~| cannot override to bind by-reference when that is the implicit default
//[structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move`
#[cfg(stable2021)] let _: &u32 = x;
#[cfg(classic2024)] let _: &&u32 = x;
let [&mut ref x] = &mut [&mut 0];
//[structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024
//[structural2024]~| cannot override to bind by-reference when that is the implicit default
//[structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move`
#[cfg(stable2021)] let _: &u32 = x;
#[cfg(classic2024)] let _: &&mut u32 = x;
let [&mut ref mut x] = &mut [&mut 0];
//[structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024
//[structural2024]~| cannot override to bind by-reference when that is the implicit default
//[structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move`
#[cfg(stable2021)] let _: &mut u32 = x;
#[cfg(classic2024)] let _: &mut &mut u32 = x;
}
@ -43,15 +39,13 @@ fn errors_from_eating_the_real_reference_caught_in_hir_typeck_on_stable() {
let [&ref x] = &[&mut 0];
//[stable2021]~^ ERROR: mismatched types
//[stable2021]~| types differ in mutability
//[structural2024]~^^^ ERROR: this pattern relies on behavior which may change in edition 2024
//[structural2024]~| cannot override to bind by-reference when that is the implicit default
//[structural2024]~^^^ ERROR: binding modifiers may only be written when the default binding mode is `move`
#[cfg(classic2024)] let _: &&mut u32 = x;
let [&ref x] = &mut [&mut 0];
//[stable2021]~^ ERROR: mismatched types
//[stable2021]~| types differ in mutability
//[structural2024]~^^^ ERROR: this pattern relies on behavior which may change in edition 2024
//[structural2024]~| cannot override to bind by-reference when that is the implicit default
//[structural2024]~^^^ ERROR: binding modifiers may only be written when the default binding mode is `move`
#[cfg(classic2024)] let _: &&mut u32 = x;
}
@ -60,8 +54,7 @@ fn errors_dependent_on_eating_order_caught_in_hir_typeck_when_eating_outer() {
let [&mut ref x] = &[&mut 0];
//[classic2024]~^ ERROR: mismatched types
//[classic2024]~| cannot match inherited `&` with `&mut` pattern
//[structural2024]~^^^ ERROR: this pattern relies on behavior which may change in edition 2024
//[structural2024]~| cannot override to bind by-reference when that is the implicit default
//[structural2024]~^^^ ERROR: binding modifiers may only be written when the default binding mode is `move`
#[cfg(stable2021)] let _: &u32 = x;
}
@ -73,25 +66,21 @@ fn errors_dependent_on_eating_order_caught_in_hir_typeck_when_eating_outer() {
fn borrowck_errors_in_old_editions() {
let [ref mut x] = &[0];
//~^ ERROR: cannot borrow data in a `&` reference as mutable
//[classic2024,structural2024]~| ERROR: this pattern relies on behavior which may change in edition 2024
//[classic2024,structural2024]~| cannot override to bind by-reference when that is the implicit default
//[classic2024,structural2024]~| ERROR: binding modifiers may only be written when the default binding mode is `move`
}
/// The remaining tests are purely for testing `ref` bindings in the presence of an inherited
/// reference. These should always fail on edition 2024 and succeed on edition 2021.
pub fn main() {
let [ref x] = &[0];
//[classic2024,structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024
//[classic2024,structural2024]~| cannot override to bind by-reference when that is the implicit default
//[classic2024,structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move`
#[cfg(stable2021)] let _: &u32 = x;
let [ref x] = &mut [0];
//[classic2024,structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024
//[classic2024,structural2024]~| cannot override to bind by-reference when that is the implicit default
//[classic2024,structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move`
#[cfg(stable2021)] let _: &u32 = x;
let [ref mut x] = &mut [0];
//[classic2024,structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024
//[classic2024,structural2024]~| cannot override to bind by-reference when that is the implicit default
//[classic2024,structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move`
#[cfg(stable2021)] let _: &mut u32 = x;
}

View file

@ -1,5 +1,5 @@
error[E0308]: mismatched types
--> $DIR/ref-binding-on-inh-ref-errors.rs:43:10
--> $DIR/ref-binding-on-inh-ref-errors.rs:39:10
|
LL | let [&ref x] = &[&mut 0];
| ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]`
@ -15,7 +15,7 @@ LL + let [ref x] = &[&mut 0];
|
error[E0308]: mismatched types
--> $DIR/ref-binding-on-inh-ref-errors.rs:50:10
--> $DIR/ref-binding-on-inh-ref-errors.rs:45:10
|
LL | let [&ref x] = &mut [&mut 0];
| ^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]`
@ -31,7 +31,7 @@ LL + let [ref x] = &mut [&mut 0];
|
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/ref-binding-on-inh-ref-errors.rs:74:10
--> $DIR/ref-binding-on-inh-ref-errors.rs:67:10
|
LL | let [ref mut x] = &[0];
| ^^^^^^^^^ cannot borrow as mutable

View file

@ -1,136 +1,191 @@
error: this pattern relies on behavior which may change in edition 2024
error: binding modifiers may only be written when the default binding mode is `move`
--> $DIR/ref-binding-on-inh-ref-errors.rs:15:11
|
LL | let [&ref x] = &[&0];
| ^^^ cannot override to bind by-reference when that is the implicit default
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/ref-binding-on-inh-ref-errors.rs:15:9
|
LL | let [&ref x] = &[&0];
| ^^^^^^^^ this matches on type `&_`
help: make the implied reference pattern explicit
|
LL | let &[&ref x] = &[&0];
| +
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:21:11
error: binding modifiers may only be written when the default binding mode is `move`
--> $DIR/ref-binding-on-inh-ref-errors.rs:20:11
|
LL | let [&ref x] = &mut [&0];
| ^^^ cannot override to bind by-reference when that is the implicit default
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/ref-binding-on-inh-ref-errors.rs:20:9
|
LL | let [&ref x] = &mut [&0];
| ^^^^^^^^ this matches on type `&mut _`
help: make the implied reference pattern explicit
|
LL | let &mut [&ref x] = &mut [&0];
| ++++
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:27:15
error: binding modifiers may only be written when the default binding mode is `move`
--> $DIR/ref-binding-on-inh-ref-errors.rs:25:15
|
LL | let [&mut ref x] = &mut [&mut 0];
| ^^^ cannot override to bind by-reference when that is the implicit default
| ^^^ binding modifier not allowed under `ref mut` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/ref-binding-on-inh-ref-errors.rs:25:9
|
LL | let [&mut ref x] = &mut [&mut 0];
| ^^^^^^^^^^^^ this matches on type `&mut _`
help: make the implied reference pattern explicit
|
LL | let &mut [&mut ref x] = &mut [&mut 0];
| ++++
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:33:15
error: binding modifiers may only be written when the default binding mode is `move`
--> $DIR/ref-binding-on-inh-ref-errors.rs:30:15
|
LL | let [&mut ref mut x] = &mut [&mut 0];
| ^^^^^^^ cannot override to bind by-reference when that is the implicit default
| ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/ref-binding-on-inh-ref-errors.rs:30:9
|
LL | let [&mut ref mut x] = &mut [&mut 0];
| ^^^^^^^^^^^^^^^^ this matches on type `&mut _`
help: make the implied reference pattern explicit
|
LL | let &mut [&mut ref mut x] = &mut [&mut 0];
| ++++
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:43:11
error: binding modifiers may only be written when the default binding mode is `move`
--> $DIR/ref-binding-on-inh-ref-errors.rs:39:11
|
LL | let [&ref x] = &[&mut 0];
| ^^^ cannot override to bind by-reference when that is the implicit default
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/ref-binding-on-inh-ref-errors.rs:39:9
|
LL | let [&ref x] = &[&mut 0];
| ^^^^^^^^ this matches on type `&_`
help: make the implied reference pattern explicit
|
LL | let &[&ref x] = &[&mut 0];
| +
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:50:11
error: binding modifiers may only be written when the default binding mode is `move`
--> $DIR/ref-binding-on-inh-ref-errors.rs:45:11
|
LL | let [&ref x] = &mut [&mut 0];
| ^^^ cannot override to bind by-reference when that is the implicit default
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/ref-binding-on-inh-ref-errors.rs:45:9
|
LL | let [&ref x] = &mut [&mut 0];
| ^^^^^^^^ this matches on type `&mut _`
help: make the implied reference pattern explicit
|
LL | let &mut [&ref x] = &mut [&mut 0];
| ++++
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:60:15
error: binding modifiers may only be written when the default binding mode is `move`
--> $DIR/ref-binding-on-inh-ref-errors.rs:54:15
|
LL | let [&mut ref x] = &[&mut 0];
| ^^^ cannot override to bind by-reference when that is the implicit default
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/ref-binding-on-inh-ref-errors.rs:54:9
|
LL | let [&mut ref x] = &[&mut 0];
| ^^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference pattern explicit
|
LL | let &[&mut ref x] = &[&mut 0];
| +
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:74:10
error: binding modifiers may only be written when the default binding mode is `move`
--> $DIR/ref-binding-on-inh-ref-errors.rs:67:10
|
LL | let [ref mut x] = &[0];
| ^^^^^^^ cannot override to bind by-reference when that is the implicit default
| ^^^^^^^ binding modifier not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/ref-binding-on-inh-ref-errors.rs:67:9
|
LL | let [ref mut x] = &[0];
| ^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference pattern explicit
|
LL | let &[ref mut x] = &[0];
| +
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/ref-binding-on-inh-ref-errors.rs:74:10
--> $DIR/ref-binding-on-inh-ref-errors.rs:67:10
|
LL | let [ref mut x] = &[0];
| ^^^^^^^^^ cannot borrow as mutable
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:83:10
error: binding modifiers may only be written when the default binding mode is `move`
--> $DIR/ref-binding-on-inh-ref-errors.rs:75:10
|
LL | let [ref x] = &[0];
| ^^^ cannot override to bind by-reference when that is the implicit default
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/ref-binding-on-inh-ref-errors.rs:75:9
|
LL | let [ref x] = &[0];
| ^^^^^^^ this matches on type `&_`
help: make the implied reference pattern explicit
|
LL | let &[ref x] = &[0];
| +
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:88:10
error: binding modifiers may only be written when the default binding mode is `move`
--> $DIR/ref-binding-on-inh-ref-errors.rs:79:10
|
LL | let [ref x] = &mut [0];
| ^^^ cannot override to bind by-reference when that is the implicit default
| ^^^ binding modifier not allowed under `ref mut` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/ref-binding-on-inh-ref-errors.rs:79:9
|
LL | let [ref x] = &mut [0];
| ^^^^^^^ this matches on type `&mut _`
help: make the implied reference pattern explicit
|
LL | let &mut [ref x] = &mut [0];
| ++++
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:93:10
error: binding modifiers may only be written when the default binding mode is `move`
--> $DIR/ref-binding-on-inh-ref-errors.rs:83:10
|
LL | let [ref mut x] = &mut [0];
| ^^^^^^^ cannot override to bind by-reference when that is the implicit default
| ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/ref-binding-on-inh-ref-errors.rs:83:9
|
LL | let [ref mut x] = &mut [0];
| ^^^^^^^^^^^ this matches on type `&mut _`
help: make the implied reference pattern explicit
|
LL | let &mut [ref mut x] = &mut [0];

View file

@ -23,22 +23,22 @@ fn main() {
assert_type_eq(x, &mut 0u8);
let &Foo(mut x) = &Foo(0);
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, 0u8);
let &mut Foo(mut x) = &mut Foo(0);
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, 0u8);
let &Foo(ref x) = &Foo(0);
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
let Foo(x) = &Foo(0);
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, &0u8);
let &mut Foo(ref x) = &mut Foo(0);
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, &0u8);
@ -55,22 +55,22 @@ fn main() {
assert_type_eq(x, &0u8);
let &Foo(&x) = &Foo(&0);
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, 0u8);
let &Foo(&mut x) = &Foo(&mut 0);
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, 0u8);
let &mut Foo(&x) = &mut Foo(&0);
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, 0u8);
let &mut Foo(&mut x) = &mut Foo(&mut 0);
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, 0u8);
@ -79,25 +79,25 @@ fn main() {
}
if let &&&&&Some(&x) = &&&&&Some(&0u8) {
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, 0u8);
}
if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) {
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, 0u8);
}
if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) {
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| 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: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, &mut 0u8);
}
@ -109,20 +109,20 @@ fn main() {
}
let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 };
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| 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: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| 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: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
&(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) })
{
@ -135,10 +135,108 @@ fn main() {
// 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: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move`
assert_type_eq(x, 0u32);
assert_type_eq(y, 0u32);
}
_ => {}
}
let &mut [&mut &[ref a]] = &mut [&mut &[0]];
//~^ ERROR: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
let &[&(_)] = &[&0];
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
// NB: Most of the following tests are for possible future improvements to migration suggestions
// Test removing multiple binding modifiers.
let Struct { a, b, c } = &Struct { a: 0, b: 0, c: 0 };
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(c, &0u32);
// Test that we don't change bindings' modes when removing binding modifiers.
let &mut Struct { ref a, ref mut b, ref mut c } = &mut Struct { a: 0, b: 0, c: 0 };
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, &mut 0u32);
assert_type_eq(c, &mut 0u32);
// Test removing multiple reference patterns of various mutabilities, plus a binding modifier.
let &mut &Struct { a: &[ref a], b: &mut [&[ref b]], ref c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, &0u32);
// Test that we don't change bindings' types when removing reference patterns.
let &Foo(&ref a) = &Foo(&0);
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
// Test that we don't change bindings' modes when adding reference paterns (caught early).
let &(&a, ref b, &[ref c], &mut [&mut (ref d, &[ref e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, 0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, &0u32);
assert_type_eq(d, &0u32);
assert_type_eq(e, &0u32);
// Test that we don't change bindings' modes when adding reference patterns (caught late).
let &(ref a, &mut [ref b], &[mut c]) = &(0, &mut [0], &[0]);
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, 0u32);
// Test featuring both additions and removals.
let &(&a, &mut (ref b, &[ref c])) = &(&0, &mut (0, &[0]));
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, 0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, &0u32);
// Test that bindings' subpatterns' modes are updated properly.
let &[mut a @ ref b] = &[0];
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, 0u32);
assert_type_eq(b, &0u32);
// Test that bindings' subpatterns' modes are checked properly.
let &[ref a @ mut b] = &[0];
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, 0u32);
// Test that we respect bindings' subpatterns' types when rewriting `&ref x` to `x`.
let [&Foo(&ref a @ ref b), &Foo(&ref c @ d)] = [&Foo(&0); 2];
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, &0u32);
assert_type_eq(d, 0u32);
// Test that we respect bindings' subpatterns' modes when rewriting `&ref x` to `x`.
let [&Foo(&ref a @ [ref b]), &Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &[0u32]);
assert_type_eq(b, &0u32);
assert_type_eq(c, &[0u32]);
assert_type_eq(d, 0u32);
}

View file

@ -23,22 +23,22 @@ fn main() {
assert_type_eq(x, &mut 0u8);
let Foo(mut x) = &Foo(0);
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, 0u8);
let Foo(mut x) = &mut Foo(0);
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, 0u8);
let Foo(ref x) = &Foo(0);
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, &0u8);
let Foo(ref x) = &mut Foo(0);
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, &0u8);
@ -55,22 +55,22 @@ fn main() {
assert_type_eq(x, &0u8);
let Foo(&x) = &Foo(&0);
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, 0u8);
let Foo(&mut x) = &Foo(&mut 0);
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, 0u8);
let Foo(&x) = &mut Foo(&0);
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, 0u8);
let Foo(&mut x) = &mut Foo(&mut 0);
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, 0u8);
@ -79,25 +79,25 @@ fn main() {
}
if let Some(&x) = &&&&&Some(&0u8) {
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, 0u8);
}
if let Some(&mut x) = &&&&&Some(&mut 0u8) {
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, 0u8);
}
if let Some(&x) = &&&&&mut Some(&0u8) {
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| 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: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(x, &mut 0u8);
}
@ -109,20 +109,20 @@ fn main() {
}
let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| 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: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| 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: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
&(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) })
{
@ -135,10 +135,108 @@ fn main() {
// 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: this pattern relies on behavior which may change in edition 2024
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move`
assert_type_eq(x, 0u32);
assert_type_eq(y, 0u32);
}
_ => {}
}
let [&mut [ref a]] = &mut [&mut &[0]];
//~^ ERROR: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
let [&(_)] = &[&0];
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
// NB: Most of the following tests are for possible future improvements to migration suggestions
// Test removing multiple binding modifiers.
let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 };
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(c, &0u32);
// Test that we don't change bindings' modes when removing binding modifiers.
let Struct { ref a, ref mut b, c } = &mut Struct { a: 0, b: 0, c: 0 };
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, &mut 0u32);
assert_type_eq(c, &mut 0u32);
// Test removing multiple reference patterns of various mutabilities, plus a binding modifier.
let Struct { a: &[ref a], b: &mut [[b]], c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, &0u32);
// Test that we don't change bindings' types when removing reference patterns.
let Foo(&ref a) = &Foo(&0);
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
// Test that we don't change bindings' modes when adding reference paterns (caught early).
let (&a, b, [c], [(d, [e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, 0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, &0u32);
assert_type_eq(d, &0u32);
assert_type_eq(e, &0u32);
// Test that we don't change bindings' modes when adding reference patterns (caught late).
let (a, [b], [mut c]) = &(0, &mut [0], &[0]);
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, 0u32);
// Test featuring both additions and removals.
let (&a, (b, &[ref c])) = &(&0, &mut (0, &[0]));
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, 0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, &0u32);
// Test that bindings' subpatterns' modes are updated properly.
let [mut a @ b] = &[0];
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, 0u32);
assert_type_eq(b, &0u32);
// Test that bindings' subpatterns' modes are checked properly.
let [a @ mut b] = &[0];
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, 0u32);
// Test that we respect bindings' subpatterns' types when rewriting `&ref x` to `x`.
let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2];
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, &0u32);
assert_type_eq(d, 0u32);
// Test that we respect bindings' subpatterns' modes when rewriting `&ref x` to `x`.
let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &[0u32]);
assert_type_eq(b, &0u32);
assert_type_eq(c, &[0u32]);
assert_type_eq(d, 0u32);
}

View file

@ -1,11 +1,16 @@
error: this pattern relies on behavior which may change in edition 2024
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:25:13
|
LL | let Foo(mut x) = &Foo(0);
| ^^^ requires binding by-value, but the implicit default is by-reference
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:25:9
|
LL | let Foo(mut x) = &Foo(0);
| ^^^^^^^^^^ this matches on type `&_`
note: the lint level is defined here
--> $DIR/migration_lint.rs:7:9
|
@ -16,206 +21,546 @@ help: make the implied reference pattern explicit
LL | let &Foo(mut x) = &Foo(0);
| +
error: this pattern relies on behavior which may change in edition 2024
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:30:13
|
LL | let Foo(mut x) = &mut Foo(0);
| ^^^ requires binding by-value, but the implicit default is by-reference
| ^^^ binding modifier not allowed under `ref mut` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:30:9
|
LL | let Foo(mut x) = &mut Foo(0);
| ^^^^^^^^^^ this matches on type `&mut _`
help: make the implied reference pattern explicit
|
LL | let &mut Foo(mut x) = &mut Foo(0);
| ++++
error: this pattern relies on behavior which may change in edition 2024
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:35:13
|
LL | let Foo(ref x) = &Foo(0);
| ^^^ cannot override to bind by-reference when that is the implicit default
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:35:9
|
LL | let Foo(ref x) = &Foo(0);
| ^^^^^^^^^^ this matches on type `&_`
help: remove the unnecessary binding modifier
|
LL - let Foo(ref x) = &Foo(0);
LL + let Foo(x) = &Foo(0);
|
LL | let &Foo(ref x) = &Foo(0);
| +
error: this pattern relies on behavior which may change in edition 2024
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:40:13
|
LL | let Foo(ref x) = &mut Foo(0);
| ^^^ cannot override to bind by-reference when that is the implicit default
| ^^^ binding modifier not allowed under `ref mut` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:40:9
|
LL | let Foo(ref x) = &mut Foo(0);
| ^^^^^^^^^^ this matches on type `&mut _`
help: make the implied reference pattern explicit
|
LL | let &mut Foo(ref x) = &mut Foo(0);
| ++++
error: this pattern relies on behavior which may change in edition 2024
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:57:13
|
LL | let Foo(&x) = &Foo(&0);
| ^ cannot implicitly match against multiple layers of reference
| ^ reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:57:9
|
LL | let Foo(&x) = &Foo(&0);
| ^^^^^^^ this matches on type `&_`
help: make the implied reference pattern explicit
|
LL | let &Foo(&x) = &Foo(&0);
| +
error: this pattern relies on behavior which may change in edition 2024
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:62:13
|
LL | let Foo(&mut x) = &Foo(&mut 0);
| ^^^^ cannot implicitly match against multiple layers of reference
| ^^^^ reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:62:9
|
LL | let Foo(&mut x) = &Foo(&mut 0);
| ^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference pattern explicit
|
LL | let &Foo(&mut x) = &Foo(&mut 0);
| +
error: this pattern relies on behavior which may change in edition 2024
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:67:13
|
LL | let Foo(&x) = &mut Foo(&0);
| ^ cannot implicitly match against multiple layers of reference
| ^ reference pattern not allowed under `ref mut` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:67:9
|
LL | let Foo(&x) = &mut Foo(&0);
| ^^^^^^^ this matches on type `&mut _`
help: make the implied reference pattern explicit
|
LL | let &mut Foo(&x) = &mut Foo(&0);
| ++++
error: this pattern relies on behavior which may change in edition 2024
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:72:13
|
LL | let Foo(&mut x) = &mut Foo(&mut 0);
| ^^^^ cannot implicitly match against multiple layers of reference
| ^^^^ reference pattern not allowed under `ref mut` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:72:9
|
LL | let Foo(&mut x) = &mut Foo(&mut 0);
| ^^^^^^^^^^^ this matches on type `&mut _`
help: make the implied reference pattern explicit
|
LL | let &mut Foo(&mut x) = &mut Foo(&mut 0);
| ++++
error: this pattern relies on behavior which may change in edition 2024
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:81:17
|
LL | if let Some(&x) = &&&&&Some(&0u8) {
| ^ cannot implicitly match against multiple layers of reference
| ^ reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:81:12
|
LL | if let Some(&x) = &&&&&Some(&0u8) {
| ^^^^^^^^ this matches on type `&_`
help: make the implied reference patterns explicit
|
LL | if let &&&&&Some(&x) = &&&&&Some(&0u8) {
| +++++
error: this pattern relies on behavior which may change in edition 2024
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:87:17
|
LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) {
| ^^^^ cannot implicitly match against multiple layers of reference
| ^^^^ reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:87:12
|
LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) {
| ^^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference patterns explicit
|
LL | if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) {
| +++++
error: this pattern relies on behavior which may change in edition 2024
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:93:17
|
LL | if let Some(&x) = &&&&&mut Some(&0u8) {
| ^ cannot implicitly match against multiple layers of reference
| ^ reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:93:12
|
LL | if let Some(&x) = &&&&&mut Some(&0u8) {
| ^^^^^^^^ this matches on type `&_`
help: make the implied reference patterns explicit
|
LL | if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) {
| ++++++++
error: this pattern relies on behavior which may change in edition 2024
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:99:17
|
LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
| ^^^^ cannot implicitly match against multiple layers of reference
| ^^^^ reference pattern not allowed under `ref mut` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:99:12
|
LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
| ^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&mut _`
help: make the implied reference patterns and variable binding mode explicit
|
LL | if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) {
| ++++ ++++ +++++++
error: this pattern relies on behavior which may change in edition 2024
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:111:21
|
LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
| ^^^ requires binding by-value, but the implicit default is by-reference
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:111:9
|
LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
| ^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference pattern and variable binding modes explicit
|
LL | let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 };
| + +++ +++
error: this pattern relies on behavior which may change in edition 2024
error: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:117:21
|
LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
| ^ ^^^ cannot override to bind by-reference when that is the implicit default
| ^ ^^^ binding modifier not allowed under `ref` default binding mode
| |
| cannot implicitly match against multiple layers of reference
| reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:117:9
|
LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference pattern and variable binding mode explicit
|
LL | let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 };
| + +++
error: this pattern relies on behavior which may change in edition 2024
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:124:24
|
LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
| ^ ^ cannot implicitly match against multiple layers of reference
| ^ ^ reference pattern not allowed under `ref` default binding mode
| |
| cannot implicitly match against multiple layers of reference
| reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:124:12
|
LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference patterns and variable binding mode explicit
|
LL | if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } =
| + + + +++
error: this pattern relies on behavior which may change in edition 2024
error: binding modifiers may only be written when the default binding mode is `move`
--> $DIR/migration_lint.rs:137:15
|
LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
| ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ default binding mode is reset within expansion
| ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ occurs within macro expansion
| |
| requires binding by-value, but the implicit default is by-reference
| binding modifier not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:137:9
|
LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
= note: this error originates in the macro `migration_lint_macros::mixed_edition_pat` (in Nightly builds, run with -Z macro-backtrace for more info)
help: make the implied reference pattern explicit
|
LL | &(Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
| +
error: aborting due to 16 previous errors
error: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:145:10
|
LL | let [&mut [ref a]] = &mut [&mut &[0]];
| ^^^^ ^^^ binding modifier not allowed under `ref` default binding mode
| |
| reference pattern not allowed under `ref mut` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:145:15
|
LL | let [&mut [ref a]] = &mut [&mut &[0]];
| ^^^^^^^ this matches on type `&_`
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:145:9
|
LL | let [&mut [ref a]] = &mut [&mut &[0]];
| ^^^^^^^^^^^^^^ this matches on type `&mut _`
help: make the implied reference patterns explicit
|
LL | let &mut [&mut &[ref a]] = &mut [&mut &[0]];
| ++++ +
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:150:10
|
LL | let [&(_)] = &[&0];
| ^ reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:150:9
|
LL | let [&(_)] = &[&0];
| ^^^^^^ this matches on type `&_`
help: make the implied reference pattern explicit
|
LL | let &[&(_)] = &[&0];
| +
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:157:18
|
LL | let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 };
| ^^^ ^^^ binding modifier not allowed under `ref` default binding mode
| |
| binding modifier not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:157:9
|
LL | let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: remove the unnecessary binding modifiers
|
LL - let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 };
LL + let Struct { a, b, c } = &Struct { a: 0, b: 0, c: 0 };
|
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:164:18
|
LL | let Struct { ref a, ref mut b, c } = &mut Struct { a: 0, b: 0, c: 0 };
| ^^^ ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode
| |
| binding modifier not allowed under `ref mut` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:164:9
|
LL | let Struct { ref a, ref mut b, c } = &mut Struct { a: 0, b: 0, c: 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&mut _`
help: make the implied reference pattern and variable binding mode explicit
|
LL | let &mut Struct { ref a, ref mut b, ref mut c } = &mut Struct { a: 0, b: 0, c: 0 };
| ++++ +++++++
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:172:21
|
LL | let Struct { a: &[ref a], b: &mut [[b]], c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
| ^ ^^^^ reference pattern not allowed under `ref` default binding mode
| |
| reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:172:9
|
LL | let Struct { a: &[ref a], b: &mut [[b]], c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference patterns and variable binding modes explicit
|
LL | let &mut &Struct { a: &[ref a], b: &mut [&[ref b]], ref c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
| ++++++ + +++ +++
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:180:13
|
LL | let Foo(&ref a) = &Foo(&0);
| ^ reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:180:9
|
LL | let Foo(&ref a) = &Foo(&0);
| ^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference pattern explicit
|
LL | let &Foo(&ref a) = &Foo(&0);
| +
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:186:10
|
LL | let (&a, b, [c], [(d, [e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
| ^ reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:186:9
|
LL | let (&a, b, [c], [(d, [e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
| ^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference patterns and variable binding modes explicit
|
LL | let &(&a, ref b, &[ref c], &mut [&mut (ref d, &[ref e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
| + +++ + +++ ++++ ++++ +++ + +++
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:196:19
|
LL | let (a, [b], [mut c]) = &(0, &mut [0], &[0]);
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:196:9
|
LL | let (a, [b], [mut c]) = &(0, &mut [0], &[0]);
| ^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference patterns and variable binding modes explicit
|
LL | let &(ref a, &mut [ref b], &[mut c]) = &(0, &mut [0], &[0]);
| + +++ ++++ +++ +
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:204:10
|
LL | let (&a, (b, &[ref c])) = &(&0, &mut (0, &[0]));
| ^ ^ reference pattern not allowed under `ref` default binding mode
| |
| reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:204:9
|
LL | let (&a, (b, &[ref c])) = &(&0, &mut (0, &[0]));
| ^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference patterns and variable binding mode explicit
|
LL | let &(&a, &mut (ref b, &[ref c])) = &(&0, &mut (0, &[0]));
| + ++++ +++
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:212:10
|
LL | let [mut a @ b] = &[0];
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:212:9
|
LL | let [mut a @ b] = &[0];
| ^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference pattern and variable binding mode explicit
|
LL | let &[mut a @ ref b] = &[0];
| + +++
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:219:14
|
LL | let [a @ mut b] = &[0];
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:219:9
|
LL | let [a @ mut b] = &[0];
| ^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference pattern and variable binding mode explicit
|
LL | let &[ref a @ mut b] = &[0];
| + +++
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:226:14
|
LL | let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2];
| ^ ^ reference pattern not allowed under `ref` default binding mode
| |
| reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:226:31
|
LL | let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2];
| ^^^^^^^^^^^^^^^ this matches on type `&_`
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:226:10
|
LL | let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2];
| ^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference patterns explicit
|
LL | let [&Foo(&ref a @ ref b), &Foo(&ref c @ d)] = [&Foo(&0); 2];
| + +
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:235:14
|
LL | let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
| ^ ^ reference pattern not allowed under `ref` default binding mode
| |
| reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:235:33
|
LL | let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
| ^^^^^^^^^^^^^^^^^ this matches on type `&_`
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:235:10
|
LL | let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
| ^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference patterns explicit
|
LL | let [&Foo(&ref a @ [ref b]), &Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
| + +
error: aborting due to 29 previous errors

View file

@ -21,17 +21,17 @@ macro_rules! test_pat_on_type {
}
test_pat_on_type![(&x,): &(T,)]; //~ ERROR mismatched types
test_pat_on_type![(&x,): &(&T,)]; //~ ERROR this pattern relies on behavior which may change in edition 2024
test_pat_on_type![(&x,): &(&T,)]; //~ ERROR reference patterns may only be written when the default binding mode is `move`
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 this pattern relies on behavior which may change in edition 2024
test_pat_on_type![(&mut x,): &(&mut T,)]; //~ ERROR reference patterns may only be written when the default binding mode is `move`
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 this pattern relies on behavior which may change in edition 2024
test_pat_on_type![(mut x,): &(T,)]; //~ ERROR this pattern relies on behavior which may change in edition 2024
test_pat_on_type![(ref x,): &(T,)]; //~ ERROR this pattern relies on behavior which may change in edition 2024
test_pat_on_type![(ref mut x,): &mut (T,)]; //~ ERROR this pattern relies on behavior which may change in edition 2024
test_pat_on_type![Foo { f: &(x,) }: &Foo]; //~ ERROR reference patterns may only be written when the default binding mode is `move`
test_pat_on_type![(mut x,): &(T,)]; //~ ERROR binding modifiers may only be written when the default binding mode is `move`
test_pat_on_type![(ref x,): &(T,)]; //~ ERROR binding modifiers may only be written when the default binding mode is `move`
test_pat_on_type![(ref mut x,): &mut (T,)]; //~ ERROR binding modifiers may only be written when the default binding mode is `move`
fn get<X>() -> X {
unimplemented!()
@ -40,6 +40,6 @@ fn get<X>() -> X {
// 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 this pattern relies on behavior which may change in edition 2024
(&x,) => x, //~ ERROR reference patterns may only be written when the default binding mode is `move`
}
}

View file

@ -99,85 +99,122 @@ LL - test_pat_on_type![Foo { f: (&x,) }: &mut Foo];
LL + test_pat_on_type![Foo { f: (x,) }: &mut Foo];
|
error: this pattern relies on behavior which may change in edition 2024
error: reference patterns may only be written when the default binding mode is `move`
--> $DIR/min_match_ergonomics_fail.rs:24:20
|
LL | test_pat_on_type![(&x,): &(&T,)];
| ^ cannot implicitly match against multiple layers of reference
| ^ reference pattern not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/min_match_ergonomics_fail.rs:24:19
|
LL | test_pat_on_type![(&x,): &(&T,)];
| ^^^^^ this matches on type `&_`
help: make the implied reference pattern explicit
|
LL | test_pat_on_type![&(&x,): &(&T,)];
| +
error: this pattern relies on behavior which may change in edition 2024
error: reference patterns may only be written when the default binding mode is `move`
--> $DIR/min_match_ergonomics_fail.rs:27:20
|
LL | test_pat_on_type![(&mut x,): &(&mut T,)];
| ^^^^ cannot implicitly match against multiple layers of reference
| ^^^^ reference pattern not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/min_match_ergonomics_fail.rs:27:19
|
LL | test_pat_on_type![(&mut x,): &(&mut T,)];
| ^^^^^^^^^ this matches on type `&_`
help: make the implied reference pattern explicit
|
LL | test_pat_on_type![&(&mut x,): &(&mut T,)];
| +
error: this pattern relies on behavior which may change in edition 2024
error: reference patterns may only be written when the default binding mode is `move`
--> $DIR/min_match_ergonomics_fail.rs:31:28
|
LL | test_pat_on_type![Foo { f: &(x,) }: &Foo];
| ^ cannot implicitly match against multiple layers of reference
| ^ reference pattern not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/min_match_ergonomics_fail.rs:31:19
|
LL | test_pat_on_type![Foo { f: &(x,) }: &Foo];
| ^^^^^^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference pattern explicit
|
LL | test_pat_on_type![&Foo { f: &(x,) }: &Foo];
| +
error: this pattern relies on behavior which may change in edition 2024
error: binding modifiers may only be written when the default binding mode is `move`
--> $DIR/min_match_ergonomics_fail.rs:32:20
|
LL | test_pat_on_type![(mut x,): &(T,)];
| ^^^ requires binding by-value, but the implicit default is by-reference
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/min_match_ergonomics_fail.rs:32:19
|
LL | test_pat_on_type![(mut x,): &(T,)];
| ^^^^^^^^ this matches on type `&_`
help: make the implied reference pattern explicit
|
LL | test_pat_on_type![&(mut x,): &(T,)];
| +
error: this pattern relies on behavior which may change in edition 2024
error: binding modifiers may only be written when the default binding mode is `move`
--> $DIR/min_match_ergonomics_fail.rs:33:20
|
LL | test_pat_on_type![(ref x,): &(T,)];
| ^^^ cannot override to bind by-reference when that is the implicit default
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/min_match_ergonomics_fail.rs:33:19
|
LL | test_pat_on_type![(ref x,): &(T,)];
| ^^^^^^^^ this matches on type `&_`
help: remove the unnecessary binding modifier
|
LL - test_pat_on_type![(ref x,): &(T,)];
LL + test_pat_on_type![(x,): &(T,)];
|
LL | test_pat_on_type![&(ref x,): &(T,)];
| +
error: this pattern relies on behavior which may change in edition 2024
error: binding modifiers may only be written when the default binding mode is `move`
--> $DIR/min_match_ergonomics_fail.rs:34:20
|
LL | test_pat_on_type![(ref mut x,): &mut (T,)];
| ^^^^^^^ cannot override to bind by-reference when that is the implicit default
| ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/min_match_ergonomics_fail.rs:34:19
|
LL | test_pat_on_type![(ref mut x,): &mut (T,)];
| ^^^^^^^^^^^^ this matches on type `&mut _`
help: remove the unnecessary binding modifier
|
LL - test_pat_on_type![(ref mut x,): &mut (T,)];
LL + test_pat_on_type![(x,): &mut (T,)];
|
LL | test_pat_on_type![&mut (ref mut x,): &mut (T,)];
| ++++
error: this pattern relies on behavior which may change in edition 2024
error: reference patterns may only be written when the default binding mode is `move`
--> $DIR/min_match_ergonomics_fail.rs:43:10
|
LL | (&x,) => x,
| ^ cannot implicitly match against multiple layers of reference
| ^ reference pattern not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/min_match_ergonomics_fail.rs:43:9
|
LL | (&x,) => x,
| ^^^^^ this matches on type `&_`
help: make the implied reference pattern explicit
|
LL | &(&x,) => x,