From a676872e0ff6d00d72f322807e6214daec9f5112 Mon Sep 17 00:00:00 2001 From: dianne Date: Mon, 16 Dec 2024 09:51:15 -0800 Subject: [PATCH 1/4] Clarify the match ergonomics 2024 migration lint's output --- compiler/rustc_hir_typeck/src/pat.rs | 69 +++++-- .../rustc_middle/src/ty/typeck_results.rs | 13 +- compiler/rustc_mir_build/messages.ftl | 2 +- compiler/rustc_mir_build/src/errors.rs | 28 ++- .../rustc_mir_build/src/thir/pattern/mod.rs | 25 ++- .../migration_lint.fixed | 32 +-- .../migration_lint.rs | 32 +-- .../migration_lint.stderr | 184 ++++++++++-------- .../min_match_ergonomics_fail.rs | 14 +- .../min_match_ergonomics_fail.stderr | 91 +++++---- 10 files changed, 301 insertions(+), 189 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index e7726845652f3..f20db5c65019e 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -718,12 +718,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { BindingMode(def_br, Mutability::Mut) } else { // `mut` resets the binding mode on edition <= 2021 - *self - .typeck_results - .borrow_mut() - .rust_2024_migration_desugared_pats_mut() - .entry(pat_info.top_info.hir_id) - .or_default() |= pat.span.at_least_rust_2024(); + self.add_rust_2024_migration_desugared_pat( + pat_info.top_info.hir_id, + pat.span, + ident.span, + "requires binding by-value, but the implicit default is by-reference", + ); BindingMode(ByRef::No, Mutability::Mut) } } @@ -731,12 +731,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { BindingMode(ByRef::Yes(_), _) => { if matches!(def_br, ByRef::Yes(_)) { // `ref`/`ref mut` overrides the binding mode on edition <= 2021 - *self - .typeck_results - .borrow_mut() - .rust_2024_migration_desugared_pats_mut() - .entry(pat_info.top_info.hir_id) - .or_default() |= pat.span.at_least_rust_2024(); + self.add_rust_2024_migration_desugared_pat( + pat_info.top_info.hir_id, + pat.span, + ident.span, + "cannot override to bind by-reference when that is the implicit default", + ); } user_bind_annot } @@ -2266,12 +2266,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Reset binding mode on old editions if pat_info.binding_mode != ByRef::No { pat_info.binding_mode = ByRef::No; - *self - .typeck_results - .borrow_mut() - .rust_2024_migration_desugared_pats_mut() - .entry(pat_info.top_info.hir_id) - .or_default() |= pat.span.at_least_rust_2024(); + self.add_rust_2024_migration_desugared_pat( + pat_info.top_info.hir_id, + pat.span, + inner.span, + "cannot implicitly match against multiple layers of reference", + ) } } @@ -2630,4 +2630,37 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => (false, ty), } } + + /// Record a pattern that's invalid under Rust 2024 match ergonomics, along with a problematic + /// span, so that the pattern migration lint can desugar it during THIR construction. + fn add_rust_2024_migration_desugared_pat( + &self, + pat_id: HirId, + subpat_span: Span, + cutoff_span: Span, + detailed_label: &str, + ) { + // Try to trim the span we're labeling to just the `&` or binding mode that's an issue. + // If the subpattern span is a macro call site, no trimming will be done. + let source_map = self.tcx.sess.source_map(); + let cutoff_span = source_map + .span_extend_prev_while(cutoff_span, char::is_whitespace) + .unwrap_or(cutoff_span); + let trimmed_span = subpat_span.until(cutoff_span); + + // 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" + } else { + detailed_label + }; + + self.typeck_results + .borrow_mut() + .rust_2024_migration_desugared_pats_mut() + .entry(pat_id) + .or_default() + .push((trimmed_span, desc.to_owned())); + } } diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 551c113aa5922..f94f52e4f6180 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -74,9 +74,8 @@ pub struct TypeckResults<'tcx> { pat_binding_modes: ItemLocalMap, /// Top-level patterns whose match ergonomics need to be desugared by the Rust 2021 -> 2024 - /// migration lint. The boolean indicates whether the emitted diagnostic should be a hard error - /// (if any of the incompatible pattern elements are in edition 2024). - rust_2024_migration_desugared_pats: ItemLocalMap, + /// migration lint. Problematic subpatterns are stored in the `Vec` for the lint to highlight. + rust_2024_migration_desugared_pats: ItemLocalMap>, /// Stores the types which were implicitly dereferenced in pattern binding modes /// for later usage in THIR lowering. For example, @@ -419,14 +418,18 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments } } - pub fn rust_2024_migration_desugared_pats(&self) -> LocalTableInContext<'_, bool> { + pub fn rust_2024_migration_desugared_pats( + &self, + ) -> LocalTableInContext<'_, Vec<(Span, String)>> { LocalTableInContext { hir_owner: self.hir_owner, data: &self.rust_2024_migration_desugared_pats, } } - pub fn rust_2024_migration_desugared_pats_mut(&mut self) -> LocalTableInContextMut<'_, bool> { + pub fn rust_2024_migration_desugared_pats_mut( + &mut self, + ) -> LocalTableInContextMut<'_, Vec<(Span, String)>> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.rust_2024_migration_desugared_pats, diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index f647486f62ade..f7f55821d4b6e 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -285,7 +285,7 @@ mir_build_pointer_pattern = function pointers and raw pointers not derived from mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future -mir_build_rust_2024_incompatible_pat = patterns are not allowed to reset the default binding mode in edition 2024 +mir_build_rust_2024_incompatible_pat = pattern uses features incompatible with edition 2024 mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly .attributes = no other attributes may be applied diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 3632da943e18b..fac0db7d2f7fb 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -1,7 +1,7 @@ use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, - MultiSpan, SubdiagMessageOp, Subdiagnostic, + MultiSpan, SubdiagMessageOp, Subdiagnostic, pluralize, }; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::{self, Ty}; @@ -1089,18 +1089,20 @@ pub(crate) enum RustcBoxAttrReason { #[derive(LintDiagnostic)] #[diag(mir_build_rust_2024_incompatible_pat)] -pub(crate) struct Rust2024IncompatiblePat { +pub(crate) struct Rust2024IncompatiblePat<'a> { #[subdiagnostic] - pub(crate) sugg: Rust2024IncompatiblePatSugg, + pub(crate) sugg: Rust2024IncompatiblePatSugg<'a>, } -pub(crate) struct Rust2024IncompatiblePatSugg { +pub(crate) struct Rust2024IncompatiblePatSugg<'a> { pub(crate) suggestion: Vec<(Span, String)>, - /// Whether the incompatibility is a hard error because a relevant span is in edition 2024. - pub(crate) is_hard_error: bool, + 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)], } -impl Subdiagnostic for Rust2024IncompatiblePatSugg { +impl<'a> Subdiagnostic for Rust2024IncompatiblePatSugg<'a> { fn add_to_diag_with>( self, diag: &mut Diag<'_, G>, @@ -1112,6 +1114,16 @@ impl Subdiagnostic for Rust2024IncompatiblePatSugg { } else { Applicability::MaybeIncorrect }; - diag.multipart_suggestion("desugar the match ergonomics", self.suggestion, applicability); + 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, + ); } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 2dbc8b7b57385..62bbb31440f83 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -6,6 +6,7 @@ mod const_to_pat; use std::cmp::Ordering; use rustc_abi::{FieldIdx, Integer}; +use rustc_errors::MultiSpan; use rustc_errors::codes::*; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; @@ -34,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, + rust_2024_migration_suggestion: Option>, } pub(super) fn pat_from_hir<'a, 'tcx>( @@ -50,24 +51,32 @@ pub(super) fn pat_from_hir<'a, 'tcx>( rust_2024_migration_suggestion: typeck_results .rust_2024_migration_desugared_pats() .get(pat.hir_id) - .map(|&is_hard_error| Rust2024IncompatiblePatSugg { + .map(|labels| Rust2024IncompatiblePatSugg { suggestion: Vec::new(), - is_hard_error, + ref_pattern_count: 0, + binding_mode_count: 0, + labels: labels.as_slice(), }), }; let result = pcx.lower_pattern(pat); debug!("pat_from_hir({:?}) = {:?}", pat, result); if let Some(sugg) = pcx.rust_2024_migration_suggestion { - if sugg.is_hard_error { + let mut spans = MultiSpan::from_spans(sugg.labels.iter().map(|(span, _)| *span).collect()); + for (span, label) in sugg.labels { + spans.push_span_label(*span, label.clone()); + } + // If a relevant span is from at least edition 2024, this is a hard error. + let is_hard_error = spans.primary_spans().iter().any(|span| span.at_least_rust_2024()); + if is_hard_error { let mut err = - tcx.dcx().struct_span_err(pat.span, fluent::mir_build_rust_2024_incompatible_pat); + tcx.dcx().struct_span_err(spans, fluent::mir_build_rust_2024_incompatible_pat); err.subdiagnostic(sugg); err.emit(); } else { tcx.emit_node_span_lint( lint::builtin::RUST_2024_INCOMPATIBLE_PAT, pat.hir_id, - pat.span, + spans, Rust2024IncompatiblePat { sugg }, ); } @@ -133,6 +142,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { }) .collect(); s.suggestion.push((pat.span.shrink_to_lo(), suggestion_str)); + s.ref_pattern_count += adjustments.len(); }; adjusted_pat @@ -371,7 +381,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { s.suggestion.push(( pat.span.with_lo(ident.span.lo()).shrink_to_lo(), sugg_str.to_owned(), - )) + )); + s.binding_mode_count += 1; } // A ref x pattern is the same node used for x, and as such it has diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed index 086671e69cba1..63e82eab8fb33 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed @@ -23,22 +23,22 @@ fn main() { assert_type_eq(x, &mut 0u8); let &Foo(mut x) = &Foo(0); - //~^ ERROR: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &mut Foo(mut x) = &mut Foo(0); - //~^ ERROR: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &Foo(ref x) = &Foo(0); - //~^ ERROR: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &0u8); let &mut Foo(ref x) = &mut Foo(0); - //~^ ERROR: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 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: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &Foo(&mut x) = &Foo(&mut 0); - //~^ ERROR: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &mut Foo(&x) = &mut Foo(&0); - //~^ ERROR: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &mut Foo(&mut x) = &mut Foo(&mut 0); - //~^ ERROR: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 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: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) { - //~^ ERROR: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) { - //~^ ERROR: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 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: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 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: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 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: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 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: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 //~| WARN: this changes meaning in Rust 2024 &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) }) { @@ -135,7 +135,7 @@ 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: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 assert_type_eq(x, 0u32); assert_type_eq(y, 0u32); } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs index acceafdb7ec06..4234192da519f 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs @@ -23,22 +23,22 @@ fn main() { assert_type_eq(x, &mut 0u8); let Foo(mut x) = &Foo(0); - //~^ ERROR: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(mut x) = &mut Foo(0); - //~^ ERROR: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(ref x) = &Foo(0); - //~^ ERROR: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &0u8); let Foo(ref x) = &mut Foo(0); - //~^ ERROR: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 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: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(&mut x) = &Foo(&mut 0); - //~^ ERROR: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(&x) = &mut Foo(&0); - //~^ ERROR: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(&mut x) = &mut Foo(&mut 0); - //~^ ERROR: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 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: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let Some(&mut x) = &&&&&Some(&mut 0u8) { - //~^ ERROR: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let Some(&x) = &&&&&mut Some(&0u8) { - //~^ ERROR: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 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: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 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: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 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: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 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: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 //~| WARN: this changes meaning in Rust 2024 &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) }) { @@ -135,7 +135,7 @@ 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: patterns are not allowed to reset the default binding mode + //~^ ERROR: pattern uses features incompatible with edition 2024 assert_type_eq(x, 0u32); assert_type_eq(y, 0u32); } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr index 91aa987c7371f..20c88d79e96b1 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr @@ -1,10 +1,8 @@ -error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/migration_lint.rs:25:9 +error: pattern uses features incompatible with edition 2024 + --> $DIR/migration_lint.rs:25:13 | LL | let Foo(mut x) = &Foo(0); - | -^^^^^^^^^ - | | - | help: desugar the match ergonomics: `&` + | ^^^ requires binding by-value, but the implicit default is by-reference | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -13,176 +11,210 @@ note: the lint level is defined here | LL | #![deny(rust_2024_incompatible_pat)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: make the implied reference pattern explicit + | +LL | let &Foo(mut x) = &Foo(0); + | + -error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/migration_lint.rs:30:9 +error: pattern uses features incompatible with edition 2024 + --> $DIR/migration_lint.rs:30:13 | LL | let Foo(mut x) = &mut Foo(0); - | -^^^^^^^^^ - | | - | help: desugar the match ergonomics: `&mut` + | ^^^ requires binding by-value, but the implicit default is by-reference | = warning: this changes meaning in Rust 2024 = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &mut Foo(mut x) = &mut Foo(0); + | ++++ -error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/migration_lint.rs:35:9 +error: pattern uses features incompatible with edition 2024 + --> $DIR/migration_lint.rs:35:13 | LL | let Foo(ref x) = &Foo(0); - | -^^^^^^^^^ - | | - | help: desugar the match ergonomics: `&` + | ^^^ cannot override to bind by-reference when that is the implicit default | = warning: this changes meaning in Rust 2024 = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &Foo(ref x) = &Foo(0); + | + -error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/migration_lint.rs:40:9 +error: pattern uses features incompatible with edition 2024 + --> $DIR/migration_lint.rs:40:13 | LL | let Foo(ref x) = &mut Foo(0); - | -^^^^^^^^^ - | | - | help: desugar the match ergonomics: `&mut` + | ^^^ cannot override to bind by-reference when that is the implicit default | = warning: this changes meaning in Rust 2024 = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &mut Foo(ref x) = &mut Foo(0); + | ++++ -error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/migration_lint.rs:57:9 +error: pattern uses features incompatible with edition 2024 + --> $DIR/migration_lint.rs:57:13 | LL | let Foo(&x) = &Foo(&0); - | -^^^^^^ - | | - | help: desugar the match ergonomics: `&` + | ^ cannot implicitly match against multiple layers of reference | = warning: this changes meaning in Rust 2024 = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &Foo(&x) = &Foo(&0); + | + -error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/migration_lint.rs:62:9 +error: pattern uses features incompatible with edition 2024 + --> $DIR/migration_lint.rs:62:13 | LL | let Foo(&mut x) = &Foo(&mut 0); - | -^^^^^^^^^^ - | | - | help: desugar the match ergonomics: `&` + | ^^^^ cannot implicitly match against multiple layers of reference | = warning: this changes meaning in Rust 2024 = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &Foo(&mut x) = &Foo(&mut 0); + | + -error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/migration_lint.rs:67:9 +error: pattern uses features incompatible with edition 2024 + --> $DIR/migration_lint.rs:67:13 | LL | let Foo(&x) = &mut Foo(&0); - | -^^^^^^ - | | - | help: desugar the match ergonomics: `&mut` + | ^ cannot implicitly match against multiple layers of reference | = warning: this changes meaning in Rust 2024 = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &mut Foo(&x) = &mut Foo(&0); + | ++++ -error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/migration_lint.rs:72:9 +error: pattern uses features incompatible with edition 2024 + --> $DIR/migration_lint.rs:72:13 | LL | let Foo(&mut x) = &mut Foo(&mut 0); - | -^^^^^^^^^^ - | | - | help: desugar the match ergonomics: `&mut` + | ^^^^ cannot implicitly match against multiple layers of reference | = warning: this changes meaning in Rust 2024 = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &mut Foo(&mut x) = &mut Foo(&mut 0); + | ++++ -error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/migration_lint.rs:81:12 +error: pattern uses features incompatible with edition 2024 + --> $DIR/migration_lint.rs:81:17 | LL | if let Some(&x) = &&&&&Some(&0u8) { - | -^^^^^^^ - | | - | help: desugar the match ergonomics: `&&&&&` + | ^ cannot implicitly match against multiple layers of reference | = warning: this changes meaning in Rust 2024 = note: for more information, see +help: make the implied reference patterns explicit + | +LL | if let &&&&&Some(&x) = &&&&&Some(&0u8) { + | +++++ -error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/migration_lint.rs:87:12 +error: pattern uses features incompatible with edition 2024 + --> $DIR/migration_lint.rs:87:17 | LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) { - | -^^^^^^^^^^^ - | | - | help: desugar the match ergonomics: `&&&&&` + | ^^^^ cannot implicitly match against multiple layers of reference | = warning: this changes meaning in Rust 2024 = note: for more information, see +help: make the implied reference patterns explicit + | +LL | if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) { + | +++++ -error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/migration_lint.rs:93:12 +error: pattern uses features incompatible with edition 2024 + --> $DIR/migration_lint.rs:93:17 | LL | if let Some(&x) = &&&&&mut Some(&0u8) { - | -^^^^^^^ - | | - | help: desugar the match ergonomics: `&&&&&mut` + | ^ cannot implicitly match against multiple layers of reference | = warning: this changes meaning in Rust 2024 = note: for more information, see +help: make the implied reference patterns explicit + | +LL | if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) { + | ++++++++ -error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/migration_lint.rs:99:12 +error: pattern uses features incompatible with edition 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 | = warning: this changes meaning in Rust 2024 = note: for more information, see -help: desugar the match ergonomics +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: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/migration_lint.rs:111:9 +error: pattern uses features incompatible with edition 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 | = warning: this changes meaning in Rust 2024 = note: for more information, see -help: desugar the match ergonomics +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: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/migration_lint.rs:117:9 +error: pattern uses features incompatible with edition 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 + | | + | cannot implicitly match against multiple layers of reference | = warning: this changes meaning in Rust 2024 = note: for more information, see -help: desugar the match ergonomics +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: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/migration_lint.rs:124:12 +error: pattern uses features incompatible with edition 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 + | | + | cannot implicitly match against multiple layers of reference | = warning: this changes meaning in Rust 2024 = note: for more information, see -help: desugar the match ergonomics +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: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/migration_lint.rs:137:9 +error: pattern uses features incompatible with edition 2024 + --> $DIR/migration_lint.rs:137:15 | LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { - | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | help: desugar the match ergonomics: `&` + | ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ default binding mode is reset within expansion + | | + | requires binding by-value, but the implicit default is by-reference + | + = 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 diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs index 50b716a111138..dbb2e2420505c 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs @@ -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 patterns are not allowed to reset the default binding mode +test_pat_on_type![(&x,): &(&T,)]; //~ ERROR pattern uses features incompatible with edition 2024 test_pat_on_type![(&x,): &(&mut T,)]; //~ ERROR mismatched types test_pat_on_type![(&mut x,): &(&T,)]; //~ ERROR mismatched types -test_pat_on_type![(&mut x,): &(&mut T,)]; //~ ERROR patterns are not allowed to reset the default binding mode +test_pat_on_type![(&mut x,): &(&mut T,)]; //~ ERROR pattern uses features incompatible with edition 2024 test_pat_on_type![(&x,): &&mut &(T,)]; //~ ERROR mismatched types test_pat_on_type![Foo { f: (&x,) }: Foo]; //~ ERROR mismatched types test_pat_on_type![Foo { f: (&x,) }: &mut Foo]; //~ ERROR mismatched types -test_pat_on_type![Foo { f: &(x,) }: &Foo]; //~ ERROR patterns are not allowed to reset the default binding mode -test_pat_on_type![(mut x,): &(T,)]; //~ ERROR patterns are not allowed to reset the default binding mode -test_pat_on_type![(ref x,): &(T,)]; //~ ERROR patterns are not allowed to reset the default binding mode -test_pat_on_type![(ref mut x,): &mut (T,)]; //~ ERROR patterns are not allowed to reset the default binding mode +test_pat_on_type![Foo { f: &(x,) }: &Foo]; //~ ERROR pattern uses features incompatible with edition 2024 +test_pat_on_type![(mut x,): &(T,)]; //~ ERROR pattern uses features incompatible with edition 2024 +test_pat_on_type![(ref x,): &(T,)]; //~ ERROR pattern uses features incompatible with edition 2024 +test_pat_on_type![(ref mut x,): &mut (T,)]; //~ ERROR pattern uses features incompatible with edition 2024 fn get() -> X { unimplemented!() @@ -40,6 +40,6 @@ fn get() -> X { // Make sure this works even when the underlying type is inferred. This test passes on rust stable. fn infer() -> X { match &get() { - (&x,) => x, //~ ERROR patterns are not allowed to reset the default binding mode + (&x,) => x, //~ ERROR pattern uses features incompatible with edition 2024 } } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr index 92058095f84a2..e99c77213f2ad 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr @@ -99,61 +99,82 @@ LL - test_pat_on_type![Foo { f: (&x,) }: &mut Foo]; LL + test_pat_on_type![Foo { f: (x,) }: &mut Foo]; | -error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/min_match_ergonomics_fail.rs:24:19 +error: pattern uses features incompatible with edition 2024 + --> $DIR/min_match_ergonomics_fail.rs:24:20 | LL | test_pat_on_type![(&x,): &(&T,)]; - | -^^^^ - | | - | help: desugar the match ergonomics: `&` + | ^ cannot implicitly match against multiple layers of reference + | +help: make the implied reference pattern explicit + | +LL | test_pat_on_type![&(&x,): &(&T,)]; + | + -error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/min_match_ergonomics_fail.rs:27:19 +error: pattern uses features incompatible with edition 2024 + --> $DIR/min_match_ergonomics_fail.rs:27:20 | LL | test_pat_on_type![(&mut x,): &(&mut T,)]; - | -^^^^^^^^ - | | - | help: desugar the match ergonomics: `&` + | ^^^^ cannot implicitly match against multiple layers of reference + | +help: make the implied reference pattern explicit + | +LL | test_pat_on_type![&(&mut x,): &(&mut T,)]; + | + -error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/min_match_ergonomics_fail.rs:31:19 +error: pattern uses features incompatible with edition 2024 + --> $DIR/min_match_ergonomics_fail.rs:31:28 | LL | test_pat_on_type![Foo { f: &(x,) }: &Foo]; - | -^^^^^^^^^^^^^^^ - | | - | help: desugar the match ergonomics: `&` + | ^ cannot implicitly match against multiple layers of reference + | +help: make the implied reference pattern explicit + | +LL | test_pat_on_type![&Foo { f: &(x,) }: &Foo]; + | + -error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/min_match_ergonomics_fail.rs:32:19 +error: pattern uses features incompatible with edition 2024 + --> $DIR/min_match_ergonomics_fail.rs:32:20 | LL | test_pat_on_type![(mut x,): &(T,)]; - | -^^^^^^^ - | | - | help: desugar the match ergonomics: `&` + | ^^^ requires binding by-value, but the implicit default is by-reference + | +help: make the implied reference pattern explicit + | +LL | test_pat_on_type![&(mut x,): &(T,)]; + | + -error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/min_match_ergonomics_fail.rs:33:19 +error: pattern uses features incompatible with edition 2024 + --> $DIR/min_match_ergonomics_fail.rs:33:20 | LL | test_pat_on_type![(ref x,): &(T,)]; - | -^^^^^^^ - | | - | help: desugar the match ergonomics: `&` + | ^^^ cannot override to bind by-reference when that is the implicit default + | +help: make the implied reference pattern explicit + | +LL | test_pat_on_type![&(ref x,): &(T,)]; + | + -error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/min_match_ergonomics_fail.rs:34:19 +error: pattern uses features incompatible with edition 2024 + --> $DIR/min_match_ergonomics_fail.rs:34:20 | LL | test_pat_on_type![(ref mut x,): &mut (T,)]; - | -^^^^^^^^^^^ - | | - | help: desugar the match ergonomics: `&mut` + | ^^^^^^^ cannot override to bind by-reference when that is the implicit default + | +help: make the implied reference pattern explicit + | +LL | test_pat_on_type![&mut (ref mut x,): &mut (T,)]; + | ++++ -error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/min_match_ergonomics_fail.rs:43:9 +error: pattern uses features incompatible with edition 2024 + --> $DIR/min_match_ergonomics_fail.rs:43:10 | LL | (&x,) => x, - | -^^^^ - | | - | help: desugar the match ergonomics: `&` + | ^ cannot implicitly match against multiple layers of reference + | +help: make the implied reference pattern explicit + | +LL | &(&x,) => x, + | + error: aborting due to 13 previous errors From 70b852737795fb6757893495a4f886756b8a7b4e Mon Sep 17 00:00:00 2001 From: dianne Date: Tue, 17 Dec 2024 09:49:20 -0800 Subject: [PATCH 2/4] Correctly check the edition of subpatterns in the pattern migration 2024 lint --- compiler/rustc_hir_typeck/src/pat.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index f20db5c65019e..e27a555eab530 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2641,12 +2641,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { detailed_label: &str, ) { // Try to trim the span we're labeling to just the `&` or binding mode that's an issue. - // If the subpattern span is a macro call site, no trimming will be done. + // 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) .unwrap_or(cutoff_span); - let trimmed_span = subpat_span.until(cutoff_span); + // 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()); // 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. From 77e9051e22c89585f0e96f3476edbe664a80ccc0 Mon Sep 17 00:00:00 2001 From: dianne Date: Tue, 17 Dec 2024 10:00:15 -0800 Subject: [PATCH 3/4] Improve the pattern migration 2024 migration lint's message --- compiler/rustc_mir_build/messages.ftl | 2 +- .../migration_lint.fixed | 32 +++++++++---------- .../migration_lint.rs | 32 +++++++++---------- .../migration_lint.stderr | 32 +++++++++---------- .../min_match_ergonomics_fail.rs | 14 ++++---- .../min_match_ergonomics_fail.stderr | 14 ++++---- 6 files changed, 63 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index f7f55821d4b6e..edba247c7b0df 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -285,7 +285,7 @@ mir_build_pointer_pattern = function pointers and raw pointers not derived from mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future -mir_build_rust_2024_incompatible_pat = pattern uses features incompatible with edition 2024 +mir_build_rust_2024_incompatible_pat = this pattern relies on behavior which may change in edition 2024 mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly .attributes = no other attributes may be applied diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed index 63e82eab8fb33..e2b2c98761046 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed @@ -23,22 +23,22 @@ fn main() { assert_type_eq(x, &mut 0u8); let &Foo(mut x) = &Foo(0); - //~^ ERROR: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &mut Foo(mut x) = &mut Foo(0); - //~^ ERROR: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &Foo(ref x) = &Foo(0); - //~^ ERROR: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &0u8); let &mut Foo(ref x) = &mut Foo(0); - //~^ ERROR: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 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: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &Foo(&mut x) = &Foo(&mut 0); - //~^ ERROR: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &mut Foo(&x) = &mut Foo(&0); - //~^ ERROR: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &mut Foo(&mut x) = &mut Foo(&mut 0); - //~^ ERROR: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 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: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) { - //~^ ERROR: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) { - //~^ ERROR: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 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: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 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: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 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: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 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: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 //~| WARN: this changes meaning in Rust 2024 &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) }) { @@ -135,7 +135,7 @@ 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: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 assert_type_eq(x, 0u32); assert_type_eq(y, 0u32); } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs index 4234192da519f..098540adfa2cf 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs @@ -23,22 +23,22 @@ fn main() { assert_type_eq(x, &mut 0u8); let Foo(mut x) = &Foo(0); - //~^ ERROR: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(mut x) = &mut Foo(0); - //~^ ERROR: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(ref x) = &Foo(0); - //~^ ERROR: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &0u8); let Foo(ref x) = &mut Foo(0); - //~^ ERROR: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 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: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(&mut x) = &Foo(&mut 0); - //~^ ERROR: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(&x) = &mut Foo(&0); - //~^ ERROR: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(&mut x) = &mut Foo(&mut 0); - //~^ ERROR: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 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: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let Some(&mut x) = &&&&&Some(&mut 0u8) { - //~^ ERROR: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let Some(&x) = &&&&&mut Some(&0u8) { - //~^ ERROR: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 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: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 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: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 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: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 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: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 //~| WARN: this changes meaning in Rust 2024 &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) }) { @@ -135,7 +135,7 @@ 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: pattern uses features incompatible with edition 2024 + //~^ ERROR: this pattern relies on behavior which may change in edition 2024 assert_type_eq(x, 0u32); assert_type_eq(y, 0u32); } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr index 20c88d79e96b1..73b0e4b67d919 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr @@ -1,4 +1,4 @@ -error: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/migration_lint.rs:25:13 | LL | let Foo(mut x) = &Foo(0); @@ -16,7 +16,7 @@ help: make the implied reference pattern explicit LL | let &Foo(mut x) = &Foo(0); | + -error: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/migration_lint.rs:30:13 | LL | let Foo(mut x) = &mut Foo(0); @@ -29,7 +29,7 @@ help: make the implied reference pattern explicit LL | let &mut Foo(mut x) = &mut Foo(0); | ++++ -error: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/migration_lint.rs:35:13 | LL | let Foo(ref x) = &Foo(0); @@ -42,7 +42,7 @@ help: make the implied reference pattern explicit LL | let &Foo(ref x) = &Foo(0); | + -error: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/migration_lint.rs:40:13 | LL | let Foo(ref x) = &mut Foo(0); @@ -55,7 +55,7 @@ help: make the implied reference pattern explicit LL | let &mut Foo(ref x) = &mut Foo(0); | ++++ -error: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/migration_lint.rs:57:13 | LL | let Foo(&x) = &Foo(&0); @@ -68,7 +68,7 @@ help: make the implied reference pattern explicit LL | let &Foo(&x) = &Foo(&0); | + -error: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/migration_lint.rs:62:13 | LL | let Foo(&mut x) = &Foo(&mut 0); @@ -81,7 +81,7 @@ help: make the implied reference pattern explicit LL | let &Foo(&mut x) = &Foo(&mut 0); | + -error: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/migration_lint.rs:67:13 | LL | let Foo(&x) = &mut Foo(&0); @@ -94,7 +94,7 @@ help: make the implied reference pattern explicit LL | let &mut Foo(&x) = &mut Foo(&0); | ++++ -error: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/migration_lint.rs:72:13 | LL | let Foo(&mut x) = &mut Foo(&mut 0); @@ -107,7 +107,7 @@ help: make the implied reference pattern explicit LL | let &mut Foo(&mut x) = &mut Foo(&mut 0); | ++++ -error: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/migration_lint.rs:81:17 | LL | if let Some(&x) = &&&&&Some(&0u8) { @@ -120,7 +120,7 @@ help: make the implied reference patterns explicit LL | if let &&&&&Some(&x) = &&&&&Some(&0u8) { | +++++ -error: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/migration_lint.rs:87:17 | LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) { @@ -133,7 +133,7 @@ help: make the implied reference patterns explicit LL | if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) { | +++++ -error: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/migration_lint.rs:93:17 | LL | if let Some(&x) = &&&&&mut Some(&0u8) { @@ -146,7 +146,7 @@ help: make the implied reference patterns explicit LL | if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) { | ++++++++ -error: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/migration_lint.rs:99:17 | LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) { @@ -159,7 +159,7 @@ 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: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/migration_lint.rs:111:21 | LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 }; @@ -172,7 +172,7 @@ 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: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/migration_lint.rs:117:21 | LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 }; @@ -187,7 +187,7 @@ 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: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/migration_lint.rs:124:24 | LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } = @@ -202,7 +202,7 @@ 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: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/migration_lint.rs:137:15 | LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs index dbb2e2420505c..5ba554fc6e5a4 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs @@ -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 pattern uses features incompatible with edition 2024 +test_pat_on_type![(&x,): &(&T,)]; //~ ERROR this pattern relies on behavior which may change in edition 2024 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 pattern uses features incompatible with edition 2024 +test_pat_on_type![(&mut x,): &(&mut T,)]; //~ ERROR this pattern relies on behavior which may change in edition 2024 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 pattern uses features incompatible with edition 2024 -test_pat_on_type![(mut x,): &(T,)]; //~ ERROR pattern uses features incompatible with edition 2024 -test_pat_on_type![(ref x,): &(T,)]; //~ ERROR pattern uses features incompatible with edition 2024 -test_pat_on_type![(ref mut x,): &mut (T,)]; //~ ERROR pattern uses features incompatible with edition 2024 +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 fn get() -> X { unimplemented!() @@ -40,6 +40,6 @@ fn get() -> X { // Make sure this works even when the underlying type is inferred. This test passes on rust stable. fn infer() -> X { match &get() { - (&x,) => x, //~ ERROR pattern uses features incompatible with edition 2024 + (&x,) => x, //~ ERROR this pattern relies on behavior which may change in edition 2024 } } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr index e99c77213f2ad..38de6e34cbcd8 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr @@ -99,7 +99,7 @@ LL - test_pat_on_type![Foo { f: (&x,) }: &mut Foo]; LL + test_pat_on_type![Foo { f: (x,) }: &mut Foo]; | -error: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/min_match_ergonomics_fail.rs:24:20 | LL | test_pat_on_type![(&x,): &(&T,)]; @@ -110,7 +110,7 @@ help: make the implied reference pattern explicit LL | test_pat_on_type![&(&x,): &(&T,)]; | + -error: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/min_match_ergonomics_fail.rs:27:20 | LL | test_pat_on_type![(&mut x,): &(&mut T,)]; @@ -121,7 +121,7 @@ help: make the implied reference pattern explicit LL | test_pat_on_type![&(&mut x,): &(&mut T,)]; | + -error: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/min_match_ergonomics_fail.rs:31:28 | LL | test_pat_on_type![Foo { f: &(x,) }: &Foo]; @@ -132,7 +132,7 @@ help: make the implied reference pattern explicit LL | test_pat_on_type![&Foo { f: &(x,) }: &Foo]; | + -error: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/min_match_ergonomics_fail.rs:32:20 | LL | test_pat_on_type![(mut x,): &(T,)]; @@ -143,7 +143,7 @@ help: make the implied reference pattern explicit LL | test_pat_on_type![&(mut x,): &(T,)]; | + -error: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/min_match_ergonomics_fail.rs:33:20 | LL | test_pat_on_type![(ref x,): &(T,)]; @@ -154,7 +154,7 @@ help: make the implied reference pattern explicit LL | test_pat_on_type![&(ref x,): &(T,)]; | + -error: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/min_match_ergonomics_fail.rs:34:20 | LL | test_pat_on_type![(ref mut x,): &mut (T,)]; @@ -165,7 +165,7 @@ help: make the implied reference pattern explicit LL | test_pat_on_type![&mut (ref mut x,): &mut (T,)]; | ++++ -error: pattern uses features incompatible with edition 2024 +error: this pattern relies on behavior which may change in edition 2024 --> $DIR/min_match_ergonomics_fail.rs:43:10 | LL | (&x,) => x, From 28c6d0b55ba4369ea8e1073228c1b9821ea231d2 Mon Sep 17 00:00:00 2001 From: dianne Date: Tue, 17 Dec 2024 12:35:45 -0800 Subject: [PATCH 4/4] Add the edition guide link from the match 2024 migration lint to the error as well --- compiler/rustc_mir_build/src/thir/pattern/mod.rs | 4 ++++ .../rfc-3627-match-ergonomics-2024/migration_lint.stderr | 1 + .../min_match_ergonomics_fail.stderr | 7 +++++++ 3 files changed, 12 insertions(+) diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 62bbb31440f83..bdf243c87b6f1 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -70,6 +70,10 @@ 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 { + // provide the same reference link as the lint + err.note(format!("for more information, see {}", info.reference)); + } err.subdiagnostic(sugg); err.emit(); } else { diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr index 73b0e4b67d919..83346b9dd4a84 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr @@ -210,6 +210,7 @@ LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { | | | requires binding by-value, but the implicit default is by-reference | + = note: for more information, see = 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 | diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr index 38de6e34cbcd8..affdca1d44906 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr @@ -105,6 +105,7 @@ error: this pattern relies on behavior which may change in edition 2024 LL | test_pat_on_type![(&x,): &(&T,)]; | ^ cannot implicitly match against multiple layers of reference | + = note: for more information, see help: make the implied reference pattern explicit | LL | test_pat_on_type![&(&x,): &(&T,)]; @@ -116,6 +117,7 @@ error: this pattern relies on behavior which may change in edition 2024 LL | test_pat_on_type![(&mut x,): &(&mut T,)]; | ^^^^ cannot implicitly match against multiple layers of reference | + = note: for more information, see help: make the implied reference pattern explicit | LL | test_pat_on_type![&(&mut x,): &(&mut T,)]; @@ -127,6 +129,7 @@ error: this pattern relies on behavior which may change in edition 2024 LL | test_pat_on_type![Foo { f: &(x,) }: &Foo]; | ^ cannot implicitly match against multiple layers of reference | + = note: for more information, see help: make the implied reference pattern explicit | LL | test_pat_on_type![&Foo { f: &(x,) }: &Foo]; @@ -138,6 +141,7 @@ error: this pattern relies on behavior which may change in edition 2024 LL | test_pat_on_type![(mut x,): &(T,)]; | ^^^ requires binding by-value, but the implicit default is by-reference | + = note: for more information, see help: make the implied reference pattern explicit | LL | test_pat_on_type![&(mut x,): &(T,)]; @@ -149,6 +153,7 @@ error: this pattern relies on behavior which may change in edition 2024 LL | test_pat_on_type![(ref x,): &(T,)]; | ^^^ cannot override to bind by-reference when that is the implicit default | + = note: for more information, see help: make the implied reference pattern explicit | LL | test_pat_on_type![&(ref x,): &(T,)]; @@ -160,6 +165,7 @@ error: this pattern relies on behavior which may change in edition 2024 LL | test_pat_on_type![(ref mut x,): &mut (T,)]; | ^^^^^^^ cannot override to bind by-reference when that is the implicit default | + = note: for more information, see help: make the implied reference pattern explicit | LL | test_pat_on_type![&mut (ref mut x,): &mut (T,)]; @@ -171,6 +177,7 @@ error: this pattern relies on behavior which may change in edition 2024 LL | (&x,) => x, | ^ cannot implicitly match against multiple layers of reference | + = note: for more information, see help: make the implied reference pattern explicit | LL | &(&x,) => x,