From 77d36c7d44c85de78aa3041d3b6905740f3214df Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 23 Jan 2025 09:28:32 -0800 Subject: [PATCH 01/28] Remove rustc-dev-guide This is not tracked in toolstate. --- src/tools/publish_toolstate.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index a639dc20a6026..5ba2c6b17c51b 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -36,7 +36,6 @@ "rust-by-example": {"marioidival"}, "embedded-book": {"adamgreig", "andre-richter", "jamesmunns", "therealprof"}, "edition-guide": {"ehuss"}, - "rustc-dev-guide": {"spastorino", "amanjeev", "JohnTitor"}, } LABELS = { @@ -46,7 +45,6 @@ "rust-by-example": ["C-bug"], "embedded-book": ["C-bug"], "edition-guide": ["C-bug"], - "rustc-dev-guide": ["C-bug"], } REPOS = { @@ -56,7 +54,6 @@ "rust-by-example": "https://github.com/rust-lang/rust-by-example", "embedded-book": "https://github.com/rust-embedded/book", "edition-guide": "https://github.com/rust-lang/edition-guide", - "rustc-dev-guide": "https://github.com/rust-lang/rustc-dev-guide", } From af8c33d701db1e5afd5bfaacc787cefe075d9905 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 23 Jan 2025 09:30:44 -0800 Subject: [PATCH 02/28] Update toolstate maintainers This updates the toolstate maintainers to more closely match who is still active. I am adding myself to ensure these get resolved if they break, since otherwise it causes other problems. --- src/tools/publish_toolstate.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 5ba2c6b17c51b..3688513987dc8 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -30,11 +30,17 @@ # These should be collaborators of the rust-lang/rust repository (with at least # read privileges on it). CI will fail otherwise. MAINTAINERS = { - "book": {"carols10cents"}, - "nomicon": {"frewsxcv", "Gankra", "JohnTitor"}, - "reference": {"Havvy", "matthewjasper", "ehuss"}, - "rust-by-example": {"marioidival"}, - "embedded-book": {"adamgreig", "andre-richter", "jamesmunns", "therealprof"}, + "book": {"ehuss", "chriskrycho", "carols10cents"}, + "nomicon": {"ehuss", "JohnTitor"}, + "reference": {"ehuss"}, + "rust-by-example": {"ehuss", "marioidival"}, + "embedded-book": { + "ehuss", + "adamgreig", + "andre-richter", + "jamesmunns", + "therealprof", + }, "edition-guide": {"ehuss"}, } From 724b885b4e486a355d176dc78098e131f9c1b2ef Mon Sep 17 00:00:00 2001 From: dianne Date: Mon, 3 Feb 2025 01:26:49 -0800 Subject: [PATCH 03/28] pattern migration: move labels out of the suggestion struct --- compiler/rustc_mir_build/src/errors.rs | 10 ++++---- .../rustc_mir_build/src/thir/pattern/mod.rs | 24 +++++++++---------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index af6f33d9cdd4e..e8ba4a4b415fd 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -1097,20 +1097,18 @@ 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) struct Rust2024IncompatiblePatSugg<'a> { +pub(crate) struct Rust2024IncompatiblePatSugg { 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)], } -impl<'a> Subdiagnostic for Rust2024IncompatiblePatSugg<'a> { +impl Subdiagnostic for Rust2024IncompatiblePatSugg { fn add_to_diag_with>( self, diag: &mut Diag<'_, G>, diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 20a728d6d5b2c..4b8d0c2fb2f09 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -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>, + rust_2024_migration_suggestion: Option, } pub(super) fn pat_from_hir<'a, 'tcx>( @@ -44,25 +44,23 @@ pub(super) fn pat_from_hir<'a, 'tcx>( typeck_results: &'a ty::TypeckResults<'tcx>, pat: &'tcx hir::Pat<'tcx>, ) -> Box> { + let migration_labels = 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 { - suggestion: Vec::new(), - ref_pattern_count: 0, - binding_mode_count: 0, - labels: labels.as_slice(), - }), + rust_2024_migration_suggestion: migration_labels.and(Some(Rust2024IncompatiblePatSugg { + suggestion: Vec::new(), + ref_pattern_count: 0, + binding_mode_count: 0, + })), }; 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(labels) = migration_labels { + let sugg = pcx.rust_2024_migration_suggestion.expect("suggestion should be present"); + let mut spans = MultiSpan::from_spans(labels.iter().map(|(span, _)| *span).collect()); + for (span, label) in labels { spans.push_span_label(*span, label.clone()); } // If a relevant span is from at least edition 2024, this is a hard error. From bdc6c4d07b5ccb91df396e152deafc3a66b539ab Mon Sep 17 00:00:00 2001 From: dianne Date: Mon, 3 Feb 2025 01:50:14 -0800 Subject: [PATCH 04/28] reword pattern migration diagnostic to make sense in all editions This aligns the main error message a bit more with the phrasing in the Edition Guide and provides a bit more information on the labels to (hopefully!) aid in understanding. --- compiler/rustc_hir_typeck/src/pat.rs | 49 +++++++------ compiler/rustc_middle/src/ty/mod.rs | 2 +- .../rustc_middle/src/ty/typeck_results.rs | 22 ++++-- compiler/rustc_mir_build/messages.ftl | 11 ++- compiler/rustc_mir_build/src/errors.rs | 3 + .../rustc_mir_build/src/thir/pattern/mod.rs | 24 ++++--- ...nding-on-inh-ref-errors.classic2024.stderr | 28 ++++---- .../ref-binding-on-inh-ref-errors.rs | 33 +++------ ...inding-on-inh-ref-errors.stable2021.stderr | 6 +- ...ng-on-inh-ref-errors.structural2024.stderr | 66 ++++++++--------- .../migration_lint.fixed | 32 ++++----- .../migration_lint.rs | 32 ++++----- .../migration_lint.stderr | 70 +++++++++---------- .../min_match_ergonomics_fail.rs | 14 ++-- .../min_match_ergonomics_fail.stderr | 28 ++++---- 15 files changed, 224 insertions(+), 196 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index c947ecde65605..f5e7b1d9629de 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -804,7 +804,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() @@ -826,22 +826,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 @@ -2378,9 +2378,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, ) } } @@ -2770,9 +2770,9 @@ 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. @@ -2780,23 +2780,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let cutoff_span = source_map .span_extend_prev_while(cutoff_span, char::is_whitespace) .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()); // 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 desc = if subpat.span.from_expansion() { + "occurs within expansion" } else { - detailed_label + match def_br_mutbl { + Mutability::Not => "default binding mode is `ref`", + Mutability::Mut => "default binding mode is `ref mut`", + } }; - self.typeck_results - .borrow_mut() - .rust_2024_migration_desugared_pats_mut() - .entry(pat_id) - .or_default() - .push((trimmed_span, desc.to_owned())); + let mut typeck_results = self.typeck_results.borrow_mut(); + let mut table = typeck_results.rust_2024_migration_desugared_pats_mut(); + let info = table.entry(pat_id).or_default(); + + info.labels.push((trimmed_span, desc.to_owned())); + if matches!(subpat.kind, PatKind::Binding(_, _, _, _)) { + info.bad_modifiers |= true; + } else { + info.bad_ref_pats |= true; + } } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 88eea6101b5fc..6fe1502c66dd6 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -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}; diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index f94f52e4f6180..0dbbfee0cfa02 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -73,9 +73,9 @@ pub struct TypeckResults<'tcx> { /// Stores the actual binding mode for all instances of [`BindingMode`]. pat_binding_modes: ItemLocalMap, - /// 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>, + /// 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, /// 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,15 @@ 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, Default)] +pub struct Rust2024IncompatiblePatInfo { + /// Labels for subpatterns incompatible with Rust 2024. + pub 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, +} diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 3cf3c33289382..fae159103e70d 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -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 diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index e8ba4a4b415fd..0289a6c4073a0 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -1100,6 +1100,9 @@ pub(crate) enum MiscPatternSuggestion { pub(crate) struct Rust2024IncompatiblePat { #[subdiagnostic] 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 { diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 4b8d0c2fb2f09..f12234723ec01 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -44,12 +44,12 @@ pub(super) fn pat_from_hir<'a, 'tcx>( typeck_results: &'a ty::TypeckResults<'tcx>, pat: &'tcx hir::Pat<'tcx>, ) -> Box> { - let migration_labels = typeck_results.rust_2024_migration_desugared_pats().get(pat.hir_id); + 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: migration_labels.and(Some(Rust2024IncompatiblePatSugg { + rust_2024_migration_suggestion: migration_info.and(Some(Rust2024IncompatiblePatSugg { suggestion: Vec::new(), ref_pattern_count: 0, binding_mode_count: 0, @@ -57,10 +57,10 @@ pub(super) fn pat_from_hir<'a, 'tcx>( }; let result = pcx.lower_pattern(pat); debug!("pat_from_hir({:?}) = {:?}", pat, result); - if let Some(labels) = migration_labels { + if let Some(info) = migration_info { let sugg = pcx.rust_2024_migration_suggestion.expect("suggestion should be present"); - let mut spans = MultiSpan::from_spans(labels.iter().map(|(span, _)| *span).collect()); - for (span, label) in labels { + let mut spans = MultiSpan::from_spans(info.labels.iter().map(|(span, _)| *span).collect()); + for (span, label) in &info.labels { spans.push_span_label(*span, label.clone()); } // If a relevant span is from at least edition 2024, this is a hard error. @@ -68,10 +68,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 { @@ -79,7 +82,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, + }, ); } } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr index 70cdcbd62eb07..fbe1164c62504 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr @@ -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,11 +10,11 @@ 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 + | ^^^^^^^ default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -23,16 +23,16 @@ 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 + | ^^^ default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -40,11 +40,11 @@ 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 + | ^^^ default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit @@ -52,11 +52,11 @@ 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 + | ^^^^^^^ default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs index 4c88c0c63ae54..4e048570c33c2 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs @@ -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; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr index a21e4bb5b8f8f..26095d8460572 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr @@ -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 diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr index ee2c831bfcc80..f355b7c61a264 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr @@ -1,8 +1,8 @@ -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 + | ^^^ default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -10,11 +10,11 @@ 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 + | ^^^ default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -22,11 +22,11 @@ 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 + | ^^^ default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit @@ -34,11 +34,11 @@ 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 + | ^^^^^^^ default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit @@ -46,11 +46,11 @@ 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 + | ^^^ default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -58,11 +58,11 @@ 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 + | ^^^ default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -70,11 +70,11 @@ 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 + | ^^^ default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -82,11 +82,11 @@ 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 + | ^^^^^^^ default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -95,16 +95,16 @@ 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 + | ^^^ default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -112,11 +112,11 @@ 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 + | ^^^ default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit @@ -124,11 +124,11 @@ 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 + | ^^^^^^^ default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit 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 e2b2c98761046..fbca9149bc3af 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: 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 + //~^ 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,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: 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); } 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 098540adfa2cf..b9428ab8c8f77 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: 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,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: 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); } 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 83346b9dd4a84..8f675d2fb5703 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,8 +1,8 @@ -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 + | ^^^ default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -16,11 +16,11 @@ 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 + | ^^^ default binding mode is `ref mut` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -29,11 +29,11 @@ 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 + | ^^^ default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -42,11 +42,11 @@ help: make the implied reference pattern explicit 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 + | ^^^ default binding mode is `ref mut` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -55,11 +55,11 @@ 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 + | ^ default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -68,11 +68,11 @@ 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 + | ^^^^ default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -81,11 +81,11 @@ 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 + | ^ default binding mode is `ref mut` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -94,11 +94,11 @@ 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 + | ^^^^ default binding mode is `ref mut` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -107,11 +107,11 @@ 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 + | ^ default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -120,11 +120,11 @@ 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 + | ^^^^ default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -133,11 +133,11 @@ 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 + | ^ default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -146,11 +146,11 @@ 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 + | ^^^^ default binding mode is `ref mut` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -159,11 +159,11 @@ 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 + | ^^^ default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -172,13 +172,13 @@ 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 + | ^ ^^^ default binding mode is `ref` | | - | cannot implicitly match against multiple layers of reference + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -187,13 +187,13 @@ 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 + | ^ ^ default binding mode is `ref` | | - | cannot implicitly match against multiple layers of reference + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -202,13 +202,13 @@ 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 expansion | | - | requires binding by-value, but the implicit default is by-reference + | default binding mode is `ref` | = 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) 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 5ba554fc6e5a4..4dc04d90aaf5e 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 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 { 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 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` } } 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 affdca1d44906..89868a1f33371 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,11 +99,11 @@ 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 + | ^ default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -111,11 +111,11 @@ 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 + | ^^^^ default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -123,11 +123,11 @@ 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 + | ^ default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -135,11 +135,11 @@ 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 + | ^^^ default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -147,11 +147,11 @@ 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 + | ^^^ default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -159,11 +159,11 @@ help: make the implied reference pattern explicit 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 + | ^^^^^^^ default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit @@ -171,11 +171,11 @@ help: make the implied reference pattern explicit 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 + | ^ default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit From bbe40acb9a192ab2afec1f8adc45c3b72925caf2 Mon Sep 17 00:00:00 2001 From: dianne Date: Mon, 3 Feb 2025 19:56:46 -0800 Subject: [PATCH 05/28] use more specific wording for subpatterns from macro expansions --- compiler/rustc_hir_typeck/src/pat.rs | 5 ++++- .../rfc-3627-match-ergonomics-2024/migration_lint.stderr | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index f5e7b1d9629de..1970040ec86bb 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2787,7 +2787,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 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() { - "occurs within 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" } else { match def_br_mutbl { Mutability::Not => "default binding mode is `ref`", 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 8f675d2fb5703..53558e6891e06 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 @@ -206,7 +206,7 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/migration_lint.rs:137:15 | LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { - | ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ occurs within expansion + | ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ occurs within macro expansion | | | default binding mode is `ref` | From 9202001c1c5c3bd9c1fce522744c8620e17d791a Mon Sep 17 00:00:00 2001 From: dianne Date: Mon, 3 Feb 2025 22:06:42 -0800 Subject: [PATCH 06/28] add tests for label formatting --- .../migration_lint.fixed | 9 ++++++ .../migration_lint.rs | 9 ++++++ .../migration_lint.stderr | 30 ++++++++++++++++++- 3 files changed, 47 insertions(+), 1 deletion(-) 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 fbca9149bc3af..911b42c9ddfe6 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 @@ -141,4 +141,13 @@ fn main() { } _ => {} } + + 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 } 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 b9428ab8c8f77..bf5fd780404bc 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 @@ -141,4 +141,13 @@ fn main() { } _ => {} } + + 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 } 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 53558e6891e06..0a9d2cf223a92 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 @@ -217,5 +217,33 @@ 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]]; + | ^^^^ ^^^ default binding mode is `ref` + | | + | default binding mode is `ref mut` + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see +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]; + | ^^ default binding mode is `ref` + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &[&(_)] = &[&0]; + | + + +error: aborting due to 18 previous errors From 4331f55b729d1a41004305f85dfe4dbbcec3ee3f Mon Sep 17 00:00:00 2001 From: dianne Date: Mon, 3 Feb 2025 22:18:00 -0800 Subject: [PATCH 07/28] highlight the whole problem subpattern when pointing out the default binding mode --- compiler/rustc_hir_typeck/src/pat.rs | 35 ++++--- .../rustc_middle/src/ty/typeck_results.rs | 6 +- .../rustc_mir_build/src/thir/pattern/mod.rs | 4 +- ...nding-on-inh-ref-errors.classic2024.stderr | 20 +++- ...ng-on-inh-ref-errors.structural2024.stderr | 55 ++++++++--- .../migration_lint.stderr | 94 ++++++++++++++----- .../min_match_ergonomics_fail.stderr | 35 +++++-- 7 files changed, 189 insertions(+), 60 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 1970040ec86bb..6b0a87f1aefb3 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2784,29 +2784,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // error if the subpattern is of edition >= 2024. 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(); + let info = table.entry(pat_id).or_default(); + + info.primary_spans.push(trimmed_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() { + 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" } else { - match def_br_mutbl { - Mutability::Not => "default binding mode is `ref`", - Mutability::Mut => "default binding mode is `ref mut`", + if matches!(subpat.kind, PatKind::Binding(_, _, _, _)) { + info.bad_modifiers |= true; + "this binding modifier" + } else { + info.bad_ref_pats |= true; + "this reference pattern" } }; + info.span_labels.push((trimmed_span, primary_label.to_owned())); - let mut typeck_results = self.typeck_results.borrow_mut(); - let mut table = typeck_results.rust_2024_migration_desugared_pats_mut(); - let info = table.entry(pat_id).or_default(); - - info.labels.push((trimmed_span, desc.to_owned())); - if matches!(subpat.kind, PatKind::Binding(_, _, _, _)) { - info.bad_modifiers |= true; - } else { - info.bad_ref_pats |= true; + if !from_expansion { + // Add a secondary label covering the whole pattern noting the default binding mode + let def_br_desc = match def_br_mutbl { + Mutability::Not => "default binding mode is `ref`", + Mutability::Mut => "default binding mode is `ref mut`", + }; + info.span_labels.push((subpat.span, def_br_desc.to_owned())); } } } diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 0dbbfee0cfa02..a75a7fcd56956 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -816,8 +816,10 @@ impl<'tcx> std::fmt::Display for UserTypeKind<'tcx> { /// emitted during THIR construction. #[derive(TyEncodable, TyDecodable, Debug, HashStable, Default)] pub struct Rust2024IncompatiblePatInfo { - /// Labels for subpatterns incompatible with Rust 2024. - pub labels: Vec<(Span, String)>, + /// Spans for `&`s, `&mut`s, and binding modifiers incompatible with Rust 2024. + pub primary_spans: Vec, + /// Labels for the primary spans and their patterns, to provide additional context. + pub span_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. diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index f12234723ec01..cdabd283150d7 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -59,8 +59,8 @@ pub(super) fn pat_from_hir<'a, 'tcx>( debug!("pat_from_hir({:?}) = {:?}", pat, result); if let Some(info) = migration_info { let sugg = pcx.rust_2024_migration_suggestion.expect("suggestion should be present"); - let mut spans = MultiSpan::from_spans(info.labels.iter().map(|(span, _)| *span).collect()); - for (span, label) in &info.labels { + let mut spans = MultiSpan::from_spans(info.primary_spans.clone()); + for (span, label) in &info.span_labels { spans.push_span_label(*span, label.clone()); } // If a relevant span is from at least edition 2024, this is a hard error. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr index fbe1164c62504..d4313f915df3d 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr @@ -14,7 +14,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:67:10 | LL | let [ref mut x] = &[0]; - | ^^^^^^^ default binding mode is `ref` + | ^^^^^^^-- + | | + | this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -32,7 +35,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:75:10 | LL | let [ref x] = &[0]; - | ^^^ default binding mode is `ref` + | ^^^-- + | | + | this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -44,7 +50,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:79:10 | LL | let [ref x] = &mut [0]; - | ^^^ default binding mode is `ref mut` + | ^^^-- + | | + | this binding modifier + | default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit @@ -56,7 +65,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:83:10 | LL | let [ref mut x] = &mut [0]; - | ^^^^^^^ default binding mode is `ref mut` + | ^^^^^^^-- + | | + | this binding modifier + | default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr index f355b7c61a264..8edb6511f230f 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr @@ -2,7 +2,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:15:11 | LL | let [&ref x] = &[&0]; - | ^^^ default binding mode is `ref` + | ^^^-- + | | + | this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -14,7 +17,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:20:11 | LL | let [&ref x] = &mut [&0]; - | ^^^ default binding mode is `ref` + | ^^^-- + | | + | this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -26,7 +32,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:25:15 | LL | let [&mut ref x] = &mut [&mut 0]; - | ^^^ default binding mode is `ref mut` + | ^^^-- + | | + | this binding modifier + | default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit @@ -38,7 +47,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:30:15 | LL | let [&mut ref mut x] = &mut [&mut 0]; - | ^^^^^^^ default binding mode is `ref mut` + | ^^^^^^^-- + | | + | this binding modifier + | default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit @@ -50,7 +62,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:39:11 | LL | let [&ref x] = &[&mut 0]; - | ^^^ default binding mode is `ref` + | ^^^-- + | | + | this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -62,7 +77,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:45:11 | LL | let [&ref x] = &mut [&mut 0]; - | ^^^ default binding mode is `ref` + | ^^^-- + | | + | this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -74,7 +92,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:54:15 | LL | let [&mut ref x] = &[&mut 0]; - | ^^^ default binding mode is `ref` + | ^^^-- + | | + | this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -86,7 +107,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:67:10 | LL | let [ref mut x] = &[0]; - | ^^^^^^^ default binding mode is `ref` + | ^^^^^^^-- + | | + | this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -104,7 +128,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:75:10 | LL | let [ref x] = &[0]; - | ^^^ default binding mode is `ref` + | ^^^-- + | | + | this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -116,7 +143,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:79:10 | LL | let [ref x] = &mut [0]; - | ^^^ default binding mode is `ref mut` + | ^^^-- + | | + | this binding modifier + | default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit @@ -128,7 +158,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:83:10 | LL | let [ref mut x] = &mut [0]; - | ^^^^^^^ default binding mode is `ref mut` + | ^^^^^^^-- + | | + | this binding modifier + | default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit 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 0a9d2cf223a92..cbb94a52878ed 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 @@ -2,7 +2,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/migration_lint.rs:25:13 | LL | let Foo(mut x) = &Foo(0); - | ^^^ default binding mode is `ref` + | ^^^-- + | | + | this binding modifier + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -20,7 +23,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/migration_lint.rs:30:13 | LL | let Foo(mut x) = &mut Foo(0); - | ^^^ default binding mode is `ref mut` + | ^^^-- + | | + | this binding modifier + | default binding mode is `ref mut` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -33,7 +39,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/migration_lint.rs:35:13 | LL | let Foo(ref x) = &Foo(0); - | ^^^ default binding mode is `ref` + | ^^^-- + | | + | this binding modifier + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -46,7 +55,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/migration_lint.rs:40:13 | LL | let Foo(ref x) = &mut Foo(0); - | ^^^ default binding mode is `ref mut` + | ^^^-- + | | + | this binding modifier + | default binding mode is `ref mut` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -59,7 +71,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:57:13 | LL | let Foo(&x) = &Foo(&0); - | ^ default binding mode is `ref` + | ^- + | | + | this reference pattern + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -72,7 +87,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:62:13 | LL | let Foo(&mut x) = &Foo(&mut 0); - | ^^^^ default binding mode is `ref` + | ^^^^-- + | | + | this reference pattern + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -85,7 +103,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:67:13 | LL | let Foo(&x) = &mut Foo(&0); - | ^ default binding mode is `ref mut` + | ^- + | | + | this reference pattern + | default binding mode is `ref mut` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -98,7 +119,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:72:13 | LL | let Foo(&mut x) = &mut Foo(&mut 0); - | ^^^^ default binding mode is `ref mut` + | ^^^^-- + | | + | this reference pattern + | default binding mode is `ref mut` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -111,7 +135,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:81:17 | LL | if let Some(&x) = &&&&&Some(&0u8) { - | ^ default binding mode is `ref` + | ^- + | | + | this reference pattern + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -124,7 +151,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:87:17 | LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) { - | ^^^^ default binding mode is `ref` + | ^^^^-- + | | + | this reference pattern + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -137,7 +167,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:93:17 | LL | if let Some(&x) = &&&&&mut Some(&0u8) { - | ^ default binding mode is `ref` + | ^- + | | + | this reference pattern + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -150,7 +183,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:99:17 | LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) { - | ^^^^ default binding mode is `ref mut` + | ^^^^-------------- + | | + | this reference pattern + | default binding mode is `ref mut` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -163,7 +199,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/migration_lint.rs:111:21 | LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 }; - | ^^^ default binding mode is `ref` + | ^^^-- + | | + | this binding modifier + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -176,8 +215,11 @@ error: binding modifiers and reference patterns may only be written when the def --> $DIR/migration_lint.rs:117:21 | LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 }; - | ^ ^^^ default binding mode is `ref` - | | + | ^- ^^^-- + | | | + | | this binding modifier + | | default binding mode is `ref` + | this reference pattern | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 @@ -191,8 +233,11 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:124:24 | LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } = - | ^ ^ default binding mode is `ref` - | | + | ^------- ^- + | | | + | | this reference pattern + | | default binding mode is `ref` + | this reference pattern | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 @@ -206,8 +251,9 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/migration_lint.rs:137:15 | LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { - | ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ occurs within macro expansion + | ^^^-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ occurs within macro expansion | | + | this binding modifier | default binding mode is `ref` | = note: for more information, see @@ -221,8 +267,11 @@ error: binding modifiers and reference patterns may only be written when the def --> $DIR/migration_lint.rs:145:10 | LL | let [&mut [ref a]] = &mut [&mut &[0]]; - | ^^^^ ^^^ default binding mode is `ref` - | | + | ^^^^--^^^--- + | | | + | | this binding modifier + | | default binding mode is `ref` + | this reference pattern | default binding mode is `ref mut` | = warning: this changes meaning in Rust 2024 @@ -236,7 +285,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:150:10 | LL | let [&(_)] = &[&0]; - | ^^ default binding mode is `ref` + | ^^-- + | | + | this reference pattern + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see 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 89868a1f33371..ce93199b18643 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 @@ -103,7 +103,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/min_match_ergonomics_fail.rs:24:20 | LL | test_pat_on_type![(&x,): &(&T,)]; - | ^ default binding mode is `ref` + | ^- + | | + | this reference pattern + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -115,7 +118,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/min_match_ergonomics_fail.rs:27:20 | LL | test_pat_on_type![(&mut x,): &(&mut T,)]; - | ^^^^ default binding mode is `ref` + | ^^^^-- + | | + | this reference pattern + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -127,7 +133,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/min_match_ergonomics_fail.rs:31:28 | LL | test_pat_on_type![Foo { f: &(x,) }: &Foo]; - | ^ default binding mode is `ref` + | ^---- + | | + | this reference pattern + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -139,7 +148,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/min_match_ergonomics_fail.rs:32:20 | LL | test_pat_on_type![(mut x,): &(T,)]; - | ^^^ default binding mode is `ref` + | ^^^-- + | | + | this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -151,7 +163,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/min_match_ergonomics_fail.rs:33:20 | LL | test_pat_on_type![(ref x,): &(T,)]; - | ^^^ default binding mode is `ref` + | ^^^-- + | | + | this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -163,7 +178,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/min_match_ergonomics_fail.rs:34:20 | LL | test_pat_on_type![(ref mut x,): &mut (T,)]; - | ^^^^^^^ default binding mode is `ref mut` + | ^^^^^^^-- + | | + | this binding modifier + | default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit @@ -175,7 +193,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/min_match_ergonomics_fail.rs:43:10 | LL | (&x,) => x, - | ^ default binding mode is `ref` + | ^- + | | + | this reference pattern + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit From 203d3109d8e96a6a4075205e836216d7cd281d5b Mon Sep 17 00:00:00 2001 From: dianne Date: Tue, 4 Feb 2025 03:18:10 -0800 Subject: [PATCH 08/28] experimentally label the spans for default binding modes --- compiler/rustc_hir_typeck/src/pat.rs | 21 +-- .../rustc_middle/src/ty/typeck_results.rs | 6 +- compiler/rustc_mir_build/src/errors.rs | 6 + .../rustc_mir_build/src/thir/pattern/mod.rs | 123 ++++++++++---- ...nding-on-inh-ref-errors.classic2024.stderr | 32 ++-- ...ng-on-inh-ref-errors.structural2024.stderr | 88 +++++----- .../migration_lint.stderr | 155 +++++++++--------- .../min_match_ergonomics_fail.stderr | 56 +++---- 8 files changed, 264 insertions(+), 223 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 6b0a87f1aefb3..672e81a4c2aa1 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -804,7 +804,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Determine the binding mode... let bm = match user_bind_annot { - BindingMode(ByRef::No, Mutability::Mut) if let ByRef::Yes(def_br_mutbl) = def_br => { + BindingMode(ByRef::No, Mutability::Mut) if matches!(def_br, ByRef::Yes(_)) => { // 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() @@ -828,20 +828,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat_info.top_info.hir_id, pat, ident.span, - def_br_mutbl, ); BindingMode(ByRef::No, Mutability::Mut) } } BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl), BindingMode(ByRef::Yes(_), _) => { - if let ByRef::Yes(def_br_mutbl) = def_br { + if matches!(def_br, ByRef::Yes(_)) { // `ref`/`ref mut` overrides the binding mode on edition <= 2021 self.add_rust_2024_migration_desugared_pat( pat_info.top_info.hir_id, pat, ident.span, - def_br_mutbl, ); } user_bind_annot @@ -2380,7 +2378,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat_info.top_info.hir_id, pat, inner.span, - inh_mut, ) } } @@ -2772,7 +2769,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat_id: HirId, subpat: &'tcx Pat<'tcx>, cutoff_span: Span, - 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. @@ -2788,8 +2784,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut table = typeck_results.rust_2024_migration_desugared_pats_mut(); let info = table.entry(pat_id).or_default(); - info.primary_spans.push(trimmed_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 from_expansion = subpat.span.from_expansion(); @@ -2807,15 +2801,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "this reference pattern" } }; - info.span_labels.push((trimmed_span, primary_label.to_owned())); - - if !from_expansion { - // Add a secondary label covering the whole pattern noting the default binding mode - let def_br_desc = match def_br_mutbl { - Mutability::Not => "default binding mode is `ref`", - Mutability::Mut => "default binding mode is `ref mut`", - }; - info.span_labels.push((subpat.span, def_br_desc.to_owned())); - } + info.primary_labels.push((trimmed_span, primary_label.to_owned())); } } diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index a75a7fcd56956..c09418c0ef15b 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -816,10 +816,8 @@ impl<'tcx> std::fmt::Display for UserTypeKind<'tcx> { /// emitted during THIR construction. #[derive(TyEncodable, TyDecodable, Debug, HashStable, Default)] pub struct Rust2024IncompatiblePatInfo { - /// Spans for `&`s, `&mut`s, and binding modifiers incompatible with Rust 2024. - pub primary_spans: Vec, - /// Labels for the primary spans and their patterns, to provide additional context. - pub span_labels: Vec<(Span, String)>, + /// 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. diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 0289a6c4073a0..e37fe82678425 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -1,3 +1,4 @@ +use rustc_data_structures::fx::FxIndexMap; use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, @@ -1109,6 +1110,11 @@ pub(crate) struct Rust2024IncompatiblePatSugg { pub(crate) suggestion: Vec<(Span, String)>, pub(crate) ref_pattern_count: usize, pub(crate) binding_mode_count: usize, + /// 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, } impl Subdiagnostic for Rust2024IncompatiblePatSugg { diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index cdabd283150d7..5edaa748f6a79 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -53,16 +53,29 @@ pub(super) fn pat_from_hir<'a, 'tcx>( suggestion: Vec::new(), ref_pattern_count: 0, binding_mode_count: 0, + default_mode_span: None, + default_mode_labels: Default::default(), })), }; let result = pcx.lower_pattern(pat); debug!("pat_from_hir({:?}) = {:?}", pat, result); if let Some(info) = migration_info { let sugg = pcx.rust_2024_migration_suggestion.expect("suggestion should be present"); - let mut spans = MultiSpan::from_spans(info.primary_spans.clone()); - for (span, label) in &info.span_labels { + 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()); } + for (span, label_mutbl) in &sugg.default_mode_labels { + // Don't point to a macro call site. + if !span.from_expansion() { + let label = match label_mutbl { + Mutability::Not => "default binding mode is `ref`", + Mutability::Mut => "default binding mode is `ref mut`", + }; + spans.push_span_label(*span, label.to_owned()) + } + } // 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 { @@ -96,6 +109,40 @@ 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> { + 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 mut min_mutbl = Mutability::Mut; + 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 { + Mutability::Not => { + min_mutbl = Mutability::Not; + "&" + } + Mutability::Mut => "&mut ", + } + }) + .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. + 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: // @@ -124,8 +171,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 { @@ -136,24 +181,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 ", - } - }) - .collect(); - s.suggestion.push((pat.span.shrink_to_lo(), suggestion_str)); - s.ref_pattern_count += adjustments.len(); - }; + s.default_mode_span = old_mode_span; + } adjusted_pat } @@ -343,7 +374,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) } } @@ -370,19 +416,26 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { .get(pat.hir_id) .expect("missing binding mode"); - if let Some(s) = &mut self.rust_2024_migration_suggestion - && explicit_ba.0 == ByRef::No - && let ByRef::Yes(mutbl) = mode.0 - { - let sugg_str = match mutbl { - Mutability::Not => "ref ", - Mutability::Mut => "ref mut ", - }; - s.suggestion.push(( - pat.span.with_lo(ident.span.lo()).shrink_to_lo(), - sugg_str.to_owned(), - )); - s.binding_mode_count += 1; + 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 explicit_ba.0 == ByRef::No + && let ByRef::Yes(mutbl) = mode.0 + { + let sugg_str = match mutbl { + Mutability::Not => "ref ", + Mutability::Mut => "ref mut ", + }; + 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/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr index d4313f915df3d..3dbdda3356673 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr @@ -14,10 +14,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:67:10 | LL | let [ref mut x] = &[0]; - | ^^^^^^^-- - | | - | this binding modifier - | default binding mode is `ref` + | -^^^^^^^--- + | || + | |this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -35,10 +35,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:75:10 | LL | let [ref x] = &[0]; - | ^^^-- - | | - | this binding modifier - | default binding mode is `ref` + | -^^^--- + | || + | |this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -50,10 +50,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:79:10 | LL | let [ref x] = &mut [0]; - | ^^^-- - | | - | this binding modifier - | default binding mode is `ref mut` + | -^^^--- + | || + | |this binding modifier + | default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit @@ -65,10 +65,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:83:10 | LL | let [ref mut x] = &mut [0]; - | ^^^^^^^-- - | | - | this binding modifier - | default binding mode is `ref mut` + | -^^^^^^^--- + | || + | |this binding modifier + | default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr index 8edb6511f230f..14e367f7ee074 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr @@ -2,10 +2,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:15:11 | LL | let [&ref x] = &[&0]; - | ^^^-- - | | - | this binding modifier - | default binding mode is `ref` + | --^^^--- + | | | + | | this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -17,10 +17,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:20:11 | LL | let [&ref x] = &mut [&0]; - | ^^^-- - | | - | this binding modifier - | default binding mode is `ref` + | --^^^--- + | | | + | | this binding modifier + | default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit @@ -32,10 +32,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:25:15 | LL | let [&mut ref x] = &mut [&mut 0]; - | ^^^-- - | | - | this binding modifier - | default binding mode is `ref mut` + | ------^^^--- + | | | + | | this binding modifier + | default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit @@ -47,10 +47,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:30:15 | LL | let [&mut ref mut x] = &mut [&mut 0]; - | ^^^^^^^-- - | | - | this binding modifier - | default binding mode is `ref mut` + | ------^^^^^^^--- + | | | + | | this binding modifier + | default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit @@ -62,10 +62,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:39:11 | LL | let [&ref x] = &[&mut 0]; - | ^^^-- - | | - | this binding modifier - | default binding mode is `ref` + | --^^^--- + | | | + | | this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -77,10 +77,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:45:11 | LL | let [&ref x] = &mut [&mut 0]; - | ^^^-- - | | - | this binding modifier - | default binding mode is `ref` + | --^^^--- + | | | + | | this binding modifier + | default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit @@ -92,10 +92,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:54:15 | LL | let [&mut ref x] = &[&mut 0]; - | ^^^-- - | | - | this binding modifier - | default binding mode is `ref` + | ------^^^--- + | | | + | | this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -107,10 +107,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:67:10 | LL | let [ref mut x] = &[0]; - | ^^^^^^^-- - | | - | this binding modifier - | default binding mode is `ref` + | -^^^^^^^--- + | || + | |this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -128,10 +128,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:75:10 | LL | let [ref x] = &[0]; - | ^^^-- - | | - | this binding modifier - | default binding mode is `ref` + | -^^^--- + | || + | |this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -143,10 +143,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:79:10 | LL | let [ref x] = &mut [0]; - | ^^^-- - | | - | this binding modifier - | default binding mode is `ref mut` + | -^^^--- + | || + | |this binding modifier + | default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit @@ -158,10 +158,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:83:10 | LL | let [ref mut x] = &mut [0]; - | ^^^^^^^-- - | | - | this binding modifier - | default binding mode is `ref mut` + | -^^^^^^^--- + | || + | |this binding modifier + | default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit 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 cbb94a52878ed..febf10cd1f35d 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 @@ -2,10 +2,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/migration_lint.rs:25:13 | LL | let Foo(mut x) = &Foo(0); - | ^^^-- - | | - | this binding modifier - | default binding mode is `ref` + | ----^^^--- + | | | + | | this binding modifier + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -23,10 +23,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/migration_lint.rs:30:13 | LL | let Foo(mut x) = &mut Foo(0); - | ^^^-- - | | - | this binding modifier - | default binding mode is `ref mut` + | ----^^^--- + | | | + | | this binding modifier + | default binding mode is `ref mut` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -39,10 +39,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/migration_lint.rs:35:13 | LL | let Foo(ref x) = &Foo(0); - | ^^^-- - | | - | this binding modifier - | default binding mode is `ref` + | ----^^^--- + | | | + | | this binding modifier + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -55,10 +55,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/migration_lint.rs:40:13 | LL | let Foo(ref x) = &mut Foo(0); - | ^^^-- - | | - | this binding modifier - | default binding mode is `ref mut` + | ----^^^--- + | | | + | | this binding modifier + | default binding mode is `ref mut` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -71,10 +71,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:57:13 | LL | let Foo(&x) = &Foo(&0); - | ^- - | | - | this reference pattern - | default binding mode is `ref` + | ----^-- + | | | + | | this reference pattern + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -87,10 +87,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:62:13 | LL | let Foo(&mut x) = &Foo(&mut 0); - | ^^^^-- - | | - | this reference pattern - | default binding mode is `ref` + | ----^^^^--- + | | | + | | this reference pattern + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -103,10 +103,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:67:13 | LL | let Foo(&x) = &mut Foo(&0); - | ^- - | | - | this reference pattern - | default binding mode is `ref mut` + | ----^-- + | | | + | | this reference pattern + | default binding mode is `ref mut` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -119,10 +119,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:72:13 | LL | let Foo(&mut x) = &mut Foo(&mut 0); - | ^^^^-- - | | - | this reference pattern - | default binding mode is `ref mut` + | ----^^^^--- + | | | + | | this reference pattern + | default binding mode is `ref mut` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -135,10 +135,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:81:17 | LL | if let Some(&x) = &&&&&Some(&0u8) { - | ^- - | | - | this reference pattern - | default binding mode is `ref` + | -----^-- + | | | + | | this reference pattern + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -151,10 +151,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:87:17 | LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) { - | ^^^^-- - | | - | this reference pattern - | default binding mode is `ref` + | -----^^^^--- + | | | + | | this reference pattern + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -167,10 +167,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:93:17 | LL | if let Some(&x) = &&&&&mut Some(&0u8) { - | ^- - | | - | this reference pattern - | default binding mode is `ref` + | -----^-- + | | | + | | this reference pattern + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -183,10 +183,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:99:17 | LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) { - | ^^^^-------------- - | | - | this reference pattern - | default binding mode is `ref mut` + | -----^^^^--------------- + | | | + | | this reference pattern + | default binding mode is `ref mut` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -199,10 +199,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/migration_lint.rs:111:21 | LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 }; - | ^^^-- - | | - | this binding modifier - | default binding mode is `ref` + | ------------^^^------- + | | | + | | this binding modifier + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -215,12 +215,11 @@ error: binding modifiers and reference patterns may only be written when the def --> $DIR/migration_lint.rs:117:21 | LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 }; - | ^- ^^^-- - | | | - | | this binding modifier - | | default binding mode is `ref` - | this reference pattern - | default binding mode is `ref` + | ------------^------^^^---- + | | | | + | | | this binding modifier + | | this reference pattern + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -233,12 +232,11 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:124:24 | LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } = - | ^------- ^- - | | | - | | this reference pattern - | | default binding mode is `ref` - | this reference pattern - | default binding mode is `ref` + | ------------^-----------------^---------------- + | | | | + | | | this reference pattern + | | this reference pattern + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -251,10 +249,11 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/migration_lint.rs:137:15 | LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { - | ^^^-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ occurs within macro expansion - | | - | this binding modifier - | default binding mode is `ref` + | ------^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | | | + | | | occurs within macro expansion + | | this binding modifier + | default binding mode is `ref` | = 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) @@ -267,12 +266,12 @@ error: binding modifiers and reference patterns may only be written when the def --> $DIR/migration_lint.rs:145:10 | LL | let [&mut [ref a]] = &mut [&mut &[0]]; - | ^^^^--^^^--- - | | | - | | this binding modifier - | | default binding mode is `ref` - | this reference pattern - | default binding mode is `ref mut` + | -^^^^--^^^---- + | || || + | || |this binding modifier + | || default binding mode is `ref` + | |this reference pattern + | default binding mode is `ref mut` | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -285,10 +284,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:150:10 | LL | let [&(_)] = &[&0]; - | ^^-- - | | - | this reference pattern - | default binding mode is `ref` + | -^^--- + | || + | |this reference pattern + | default binding mode is `ref` | = warning: this changes meaning in Rust 2024 = note: for more information, see 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 ce93199b18643..ca1749074c190 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 @@ -103,10 +103,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/min_match_ergonomics_fail.rs:24:20 | LL | test_pat_on_type![(&x,): &(&T,)]; - | ^- - | | - | this reference pattern - | default binding mode is `ref` + | -^--- + | || + | |this reference pattern + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -118,10 +118,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/min_match_ergonomics_fail.rs:27:20 | LL | test_pat_on_type![(&mut x,): &(&mut T,)]; - | ^^^^-- - | | - | this reference pattern - | default binding mode is `ref` + | -^^^^---- + | || + | |this reference pattern + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -133,10 +133,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/min_match_ergonomics_fail.rs:31:28 | LL | test_pat_on_type![Foo { f: &(x,) }: &Foo]; - | ^---- - | | - | this reference pattern - | default binding mode is `ref` + | ---------^------ + | | | + | | this reference pattern + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -148,10 +148,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/min_match_ergonomics_fail.rs:32:20 | LL | test_pat_on_type![(mut x,): &(T,)]; - | ^^^-- - | | - | this binding modifier - | default binding mode is `ref` + | -^^^---- + | || + | |this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -163,10 +163,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/min_match_ergonomics_fail.rs:33:20 | LL | test_pat_on_type![(ref x,): &(T,)]; - | ^^^-- - | | - | this binding modifier - | default binding mode is `ref` + | -^^^---- + | || + | |this binding modifier + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit @@ -178,10 +178,10 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/min_match_ergonomics_fail.rs:34:20 | LL | test_pat_on_type![(ref mut x,): &mut (T,)]; - | ^^^^^^^-- - | | - | this binding modifier - | default binding mode is `ref mut` + | -^^^^^^^---- + | || + | |this binding modifier + | default binding mode is `ref mut` | = note: for more information, see help: make the implied reference pattern explicit @@ -193,10 +193,10 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/min_match_ergonomics_fail.rs:43:10 | LL | (&x,) => x, - | ^- - | | - | this reference pattern - | default binding mode is `ref` + | -^--- + | || + | |this reference pattern + | default binding mode is `ref` | = note: for more information, see help: make the implied reference pattern explicit From a064e786633ac81c35abcf00abd9dc57a40ad9bf Mon Sep 17 00:00:00 2001 From: dianne Date: Tue, 4 Feb 2025 03:27:59 -0800 Subject: [PATCH 09/28] don't include trailing open parens in labels for reference patterns --- compiler/rustc_hir_typeck/src/pat.rs | 2 +- .../rfc-3627-match-ergonomics-2024/migration_lint.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 672e81a4c2aa1..d0b7c09507fd3 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2774,7 +2774,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 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 // error if the subpattern is of edition >= 2024. 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 febf10cd1f35d..eaba337f06bb4 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 @@ -284,7 +284,7 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:150:10 | LL | let [&(_)] = &[&0]; - | -^^--- + | -^---- | || | |this reference pattern | default binding mode is `ref` From 767f82039c221fa609f752d2a2ea4ffd664f8138 Mon Sep 17 00:00:00 2001 From: dianne Date: Wed, 5 Feb 2025 01:12:40 -0800 Subject: [PATCH 10/28] separate labels for default binding mode spans into their own notes --- compiler/rustc_hir_typeck/src/pat.rs | 25 ++- compiler/rustc_mir_build/src/errors.rs | 21 ++ .../rustc_mir_build/src/thir/pattern/mod.rs | 10 - ...nding-on-inh-ref-errors.classic2024.stderr | 40 ++-- ...ng-on-inh-ref-errors.structural2024.stderr | 110 ++++++---- .../migration_lint.stderr | 198 +++++++++++------- .../min_match_ergonomics_fail.stderr | 70 ++++--- 7 files changed, 291 insertions(+), 183 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index d0b7c09507fd3..0c20a98059c4d 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -804,7 +804,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() @@ -828,18 +828,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat_info.top_info.hir_id, pat, ident.span, + 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, ident.span, + def_br_mutbl, ); } user_bind_annot @@ -2378,6 +2380,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat_info.top_info.hir_id, pat, inner.span, + inh_mut, ) } } @@ -2769,6 +2772,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat_id: HirId, subpat: &'tcx Pat<'tcx>, cutoff_span: Span, + 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. @@ -2791,16 +2795,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 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" + "occurs within macro expansion".to_owned() } else { - if matches!(subpat.kind, PatKind::Binding(_, _, _, _)) { + let pat_kind = if matches!(subpat.kind, PatKind::Binding(_, _, _, _)) { info.bad_modifiers |= true; - "this binding modifier" + "binding modifier" } else { info.bad_ref_pats |= true; - "this reference pattern" - } + "reference pattern" + }; + 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.to_owned())); + info.primary_labels.push((trimmed_span, primary_label)); } } diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index e37fe82678425..e83901e175d1c 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -1123,6 +1123,27 @@ impl Subdiagnostic for Rust2024IncompatiblePatSugg { 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 dbm_str = match def_br_mutbl { + ty::Mutability::Not => "ref", + ty::Mutability::Mut => "ref mut", + }; + let note_msg = format!( + "the default binding mode changed to `{dbm_str}` because this has type `{}_`", + def_br_mutbl.ref_prefix_str() + ); + let label_msg = format!("the default binding mode is `{dbm_str}`, introduced here"); + 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 diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 5edaa748f6a79..f72ce2fe6fbf7 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -66,16 +66,6 @@ pub(super) fn pat_from_hir<'a, 'tcx>( for (span, label) in &info.primary_labels { spans.push_span_label(*span, label.clone()); } - for (span, label_mutbl) in &sugg.default_mode_labels { - // Don't point to a macro call site. - if !span.from_expansion() { - let label = match label_mutbl { - Mutability::Not => "default binding mode is `ref`", - Mutability::Mut => "default binding mode is `ref mut`", - }; - spans.push_span_label(*span, label.to_owned()) - } - } // 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 { diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr index 3dbdda3356673..74e164619fa96 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr @@ -14,12 +14,14 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:67:10 | LL | let [ref mut x] = &[0]; - | -^^^^^^^--- - | || - | |this binding modifier - | default binding mode is `ref` + | ^^^^^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/ref-binding-on-inh-ref-errors.rs:67:9 + | +LL | let [ref mut x] = &[0]; + | ^^^^^^^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference pattern explicit | LL | let &[ref mut x] = &[0]; @@ -35,12 +37,14 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:75:10 | LL | let [ref x] = &[0]; - | -^^^--- - | || - | |this binding modifier - | default binding mode is `ref` + | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/ref-binding-on-inh-ref-errors.rs:75:9 + | +LL | let [ref x] = &[0]; + | ^^^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference pattern explicit | LL | let &[ref x] = &[0]; @@ -50,12 +54,14 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:79:10 | LL | let [ref x] = &mut [0]; - | -^^^--- - | || - | |this binding modifier - | default binding mode is `ref mut` + | ^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref mut` because this has type `&mut _` + --> $DIR/ref-binding-on-inh-ref-errors.rs:79:9 + | +LL | let [ref x] = &mut [0]; + | ^^^^^^^ the default binding mode is `ref mut`, introduced here help: make the implied reference pattern explicit | LL | let &mut [ref x] = &mut [0]; @@ -65,12 +71,14 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:83:10 | LL | let [ref mut x] = &mut [0]; - | -^^^^^^^--- - | || - | |this binding modifier - | default binding mode is `ref mut` + | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref mut` because this has type `&mut _` + --> $DIR/ref-binding-on-inh-ref-errors.rs:83:9 + | +LL | let [ref mut x] = &mut [0]; + | ^^^^^^^^^^^ the default binding mode is `ref mut`, introduced here help: make the implied reference pattern explicit | LL | let &mut [ref mut x] = &mut [0]; diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr index 14e367f7ee074..422c169d7fd14 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr @@ -2,12 +2,14 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:15:11 | LL | let [&ref x] = &[&0]; - | --^^^--- - | | | - | | this binding modifier - | default binding mode is `ref` + | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/ref-binding-on-inh-ref-errors.rs:15:9 + | +LL | let [&ref x] = &[&0]; + | ^^^^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference pattern explicit | LL | let &[&ref x] = &[&0]; @@ -17,12 +19,14 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:20:11 | LL | let [&ref x] = &mut [&0]; - | --^^^--- - | | | - | | this binding modifier - | default binding mode is `ref mut` + | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref mut` because this has type `&mut _` + --> $DIR/ref-binding-on-inh-ref-errors.rs:20:9 + | +LL | let [&ref x] = &mut [&0]; + | ^^^^^^^^ the default binding mode is `ref mut`, introduced here help: make the implied reference pattern explicit | LL | let &mut [&ref x] = &mut [&0]; @@ -32,12 +36,14 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:25:15 | LL | let [&mut ref x] = &mut [&mut 0]; - | ------^^^--- - | | | - | | this binding modifier - | default binding mode is `ref mut` + | ^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref mut` because this has type `&mut _` + --> $DIR/ref-binding-on-inh-ref-errors.rs:25:9 + | +LL | let [&mut ref x] = &mut [&mut 0]; + | ^^^^^^^^^^^^ the default binding mode is `ref mut`, introduced here help: make the implied reference pattern explicit | LL | let &mut [&mut ref x] = &mut [&mut 0]; @@ -47,12 +53,14 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:30:15 | LL | let [&mut ref mut x] = &mut [&mut 0]; - | ------^^^^^^^--- - | | | - | | this binding modifier - | default binding mode is `ref mut` + | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref mut` because this has type `&mut _` + --> $DIR/ref-binding-on-inh-ref-errors.rs:30:9 + | +LL | let [&mut ref mut x] = &mut [&mut 0]; + | ^^^^^^^^^^^^^^^^ the default binding mode is `ref mut`, introduced here help: make the implied reference pattern explicit | LL | let &mut [&mut ref mut x] = &mut [&mut 0]; @@ -62,12 +70,14 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:39:11 | LL | let [&ref x] = &[&mut 0]; - | --^^^--- - | | | - | | this binding modifier - | default binding mode is `ref` + | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/ref-binding-on-inh-ref-errors.rs:39:9 + | +LL | let [&ref x] = &[&mut 0]; + | ^^^^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference pattern explicit | LL | let &[&ref x] = &[&mut 0]; @@ -77,12 +87,14 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:45:11 | LL | let [&ref x] = &mut [&mut 0]; - | --^^^--- - | | | - | | this binding modifier - | default binding mode is `ref mut` + | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref mut` because this has type `&mut _` + --> $DIR/ref-binding-on-inh-ref-errors.rs:45:9 + | +LL | let [&ref x] = &mut [&mut 0]; + | ^^^^^^^^ the default binding mode is `ref mut`, introduced here help: make the implied reference pattern explicit | LL | let &mut [&ref x] = &mut [&mut 0]; @@ -92,12 +104,14 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:54:15 | LL | let [&mut ref x] = &[&mut 0]; - | ------^^^--- - | | | - | | this binding modifier - | default binding mode is `ref` + | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/ref-binding-on-inh-ref-errors.rs:54:9 + | +LL | let [&mut ref x] = &[&mut 0]; + | ^^^^^^^^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference pattern explicit | LL | let &[&mut ref x] = &[&mut 0]; @@ -107,12 +121,14 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:67:10 | LL | let [ref mut x] = &[0]; - | -^^^^^^^--- - | || - | |this binding modifier - | default binding mode is `ref` + | ^^^^^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/ref-binding-on-inh-ref-errors.rs:67:9 + | +LL | let [ref mut x] = &[0]; + | ^^^^^^^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference pattern explicit | LL | let &[ref mut x] = &[0]; @@ -128,12 +144,14 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:75:10 | LL | let [ref x] = &[0]; - | -^^^--- - | || - | |this binding modifier - | default binding mode is `ref` + | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/ref-binding-on-inh-ref-errors.rs:75:9 + | +LL | let [ref x] = &[0]; + | ^^^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference pattern explicit | LL | let &[ref x] = &[0]; @@ -143,12 +161,14 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:79:10 | LL | let [ref x] = &mut [0]; - | -^^^--- - | || - | |this binding modifier - | default binding mode is `ref mut` + | ^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref mut` because this has type `&mut _` + --> $DIR/ref-binding-on-inh-ref-errors.rs:79:9 + | +LL | let [ref x] = &mut [0]; + | ^^^^^^^ the default binding mode is `ref mut`, introduced here help: make the implied reference pattern explicit | LL | let &mut [ref x] = &mut [0]; @@ -158,12 +178,14 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/ref-binding-on-inh-ref-errors.rs:83:10 | LL | let [ref mut x] = &mut [0]; - | -^^^^^^^--- - | || - | |this binding modifier - | default binding mode is `ref mut` + | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref mut` because this has type `&mut _` + --> $DIR/ref-binding-on-inh-ref-errors.rs:83:9 + | +LL | let [ref mut x] = &mut [0]; + | ^^^^^^^^^^^ the default binding mode is `ref mut`, introduced here help: make the implied reference pattern explicit | LL | let &mut [ref mut x] = &mut [0]; 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 eaba337f06bb4..cfbd260e0e9a1 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 @@ -2,13 +2,15 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/migration_lint.rs:25:13 | LL | let Foo(mut x) = &Foo(0); - | ----^^^--- - | | | - | | this binding modifier - | default binding mode is `ref` + | ^^^ binding modifier not allowed under `ref` default binding mode | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/migration_lint.rs:25:9 + | +LL | let Foo(mut x) = &Foo(0); + | ^^^^^^^^^^ the default binding mode is `ref`, introduced here note: the lint level is defined here --> $DIR/migration_lint.rs:7:9 | @@ -23,13 +25,15 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/migration_lint.rs:30:13 | LL | let Foo(mut x) = &mut Foo(0); - | ----^^^--- - | | | - | | this binding modifier - | default binding mode is `ref mut` + | ^^^ binding modifier not allowed under `ref mut` default binding mode | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: the default binding mode changed to `ref mut` because this has type `&mut _` + --> $DIR/migration_lint.rs:30:9 + | +LL | let Foo(mut x) = &mut Foo(0); + | ^^^^^^^^^^ the default binding mode is `ref mut`, introduced here help: make the implied reference pattern explicit | LL | let &mut Foo(mut x) = &mut Foo(0); @@ -39,13 +43,15 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/migration_lint.rs:35:13 | LL | let Foo(ref x) = &Foo(0); - | ----^^^--- - | | | - | | this binding modifier - | default binding mode is `ref` + | ^^^ binding modifier not allowed under `ref` default binding mode | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/migration_lint.rs:35:9 + | +LL | let Foo(ref x) = &Foo(0); + | ^^^^^^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference pattern explicit | LL | let &Foo(ref x) = &Foo(0); @@ -55,13 +61,15 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/migration_lint.rs:40:13 | LL | let Foo(ref x) = &mut Foo(0); - | ----^^^--- - | | | - | | this binding modifier - | default binding mode is `ref mut` + | ^^^ binding modifier not allowed under `ref mut` default binding mode | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: the default binding mode changed to `ref mut` because this has type `&mut _` + --> $DIR/migration_lint.rs:40:9 + | +LL | let Foo(ref x) = &mut Foo(0); + | ^^^^^^^^^^ the default binding mode is `ref mut`, introduced here help: make the implied reference pattern explicit | LL | let &mut Foo(ref x) = &mut Foo(0); @@ -71,13 +79,15 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:57:13 | LL | let Foo(&x) = &Foo(&0); - | ----^-- - | | | - | | this reference pattern - | default binding mode is `ref` + | ^ reference pattern not allowed under `ref` default binding mode | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/migration_lint.rs:57:9 + | +LL | let Foo(&x) = &Foo(&0); + | ^^^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference pattern explicit | LL | let &Foo(&x) = &Foo(&0); @@ -87,13 +97,15 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:62:13 | LL | let Foo(&mut x) = &Foo(&mut 0); - | ----^^^^--- - | | | - | | this reference pattern - | default binding mode is `ref` + | ^^^^ reference pattern not allowed under `ref` default binding mode | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/migration_lint.rs:62:9 + | +LL | let Foo(&mut x) = &Foo(&mut 0); + | ^^^^^^^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference pattern explicit | LL | let &Foo(&mut x) = &Foo(&mut 0); @@ -103,13 +115,15 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:67:13 | LL | let Foo(&x) = &mut Foo(&0); - | ----^-- - | | | - | | this reference pattern - | default binding mode is `ref mut` + | ^ reference pattern not allowed under `ref mut` default binding mode | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: the default binding mode changed to `ref mut` because this has type `&mut _` + --> $DIR/migration_lint.rs:67:9 + | +LL | let Foo(&x) = &mut Foo(&0); + | ^^^^^^^ the default binding mode is `ref mut`, introduced here help: make the implied reference pattern explicit | LL | let &mut Foo(&x) = &mut Foo(&0); @@ -119,13 +133,15 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:72:13 | LL | let Foo(&mut x) = &mut Foo(&mut 0); - | ----^^^^--- - | | | - | | this reference pattern - | default binding mode is `ref mut` + | ^^^^ reference pattern not allowed under `ref mut` default binding mode | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: the default binding mode changed to `ref mut` because this has type `&mut _` + --> $DIR/migration_lint.rs:72:9 + | +LL | let Foo(&mut x) = &mut Foo(&mut 0); + | ^^^^^^^^^^^ the default binding mode is `ref mut`, introduced here help: make the implied reference pattern explicit | LL | let &mut Foo(&mut x) = &mut Foo(&mut 0); @@ -135,13 +151,15 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:81:17 | LL | if let Some(&x) = &&&&&Some(&0u8) { - | -----^-- - | | | - | | this reference pattern - | default binding mode is `ref` + | ^ reference pattern not allowed under `ref` default binding mode | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/migration_lint.rs:81:12 + | +LL | if let Some(&x) = &&&&&Some(&0u8) { + | ^^^^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference patterns explicit | LL | if let &&&&&Some(&x) = &&&&&Some(&0u8) { @@ -151,13 +169,15 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:87:17 | LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) { - | -----^^^^--- - | | | - | | this reference pattern - | default binding mode is `ref` + | ^^^^ reference pattern not allowed under `ref` default binding mode | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/migration_lint.rs:87:12 + | +LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) { + | ^^^^^^^^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference patterns explicit | LL | if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) { @@ -167,13 +187,15 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:93:17 | LL | if let Some(&x) = &&&&&mut Some(&0u8) { - | -----^-- - | | | - | | this reference pattern - | default binding mode is `ref` + | ^ reference pattern not allowed under `ref` default binding mode | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/migration_lint.rs:93:12 + | +LL | if let Some(&x) = &&&&&mut Some(&0u8) { + | ^^^^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference patterns explicit | LL | if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) { @@ -183,13 +205,15 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:99:17 | LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) { - | -----^^^^--------------- - | | | - | | this reference pattern - | default binding mode is `ref mut` + | ^^^^ reference pattern not allowed under `ref mut` default binding mode | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: the default binding mode changed to `ref mut` because this has type `&mut _` + --> $DIR/migration_lint.rs:99:12 + | +LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ the default binding mode is `ref mut`, introduced here 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))) { @@ -199,13 +223,15 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/migration_lint.rs:111:21 | LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 }; - | ------------^^^------- - | | | - | | this binding modifier - | default binding mode is `ref` + | ^^^ binding modifier not allowed under `ref` default binding mode | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/migration_lint.rs:111:9 + | +LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 }; + | ^^^^^^^^^^^^^^^^^^^^^^ the default binding mode is `ref`, introduced here 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 }; @@ -215,14 +241,17 @@ error: binding modifiers and reference patterns may only be written when the def --> $DIR/migration_lint.rs:117:21 | LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 }; - | ------------^------^^^---- - | | | | - | | | this binding modifier - | | this reference pattern - | default binding mode is `ref` + | ^ ^^^ binding modifier 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 +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/migration_lint.rs:117:9 + | +LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the default binding mode is `ref`, introduced here 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 }; @@ -232,14 +261,17 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:124:24 | LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } = - | ------------^-----------------^---------------- - | | | | - | | | this reference pattern - | | this reference pattern - | default binding mode is `ref` + | ^ ^ 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 +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/migration_lint.rs:124:12 + | +LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } = + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the default binding mode is `ref`, introduced here 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) } = @@ -249,13 +281,16 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/migration_lint.rs:137:15 | LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { - | ------^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- - | | | | - | | | occurs within macro expansion - | | this binding modifier - | default binding mode is `ref` + | ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ occurs within macro expansion + | | + | binding modifier not allowed under `ref` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/migration_lint.rs:137:9 + | +LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the default binding mode is `ref`, introduced here = 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 | @@ -266,15 +301,22 @@ error: binding modifiers and reference patterns may only be written when the def --> $DIR/migration_lint.rs:145:10 | LL | let [&mut [ref a]] = &mut [&mut &[0]]; - | -^^^^--^^^---- - | || || - | || |this binding modifier - | || default binding mode is `ref` - | |this reference pattern - | default binding mode is `ref mut` + | ^^^^ ^^^ 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 +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/migration_lint.rs:145:15 + | +LL | let [&mut [ref a]] = &mut [&mut &[0]]; + | ^^^^^^^ the default binding mode is `ref`, introduced here +note: the default binding mode changed to `ref mut` because this has type `&mut _` + --> $DIR/migration_lint.rs:145:9 + | +LL | let [&mut [ref a]] = &mut [&mut &[0]]; + | ^^^^^^^^^^^^^^ the default binding mode is `ref mut`, introduced here help: make the implied reference patterns explicit | LL | let &mut [&mut &[ref a]] = &mut [&mut &[0]]; @@ -284,13 +326,15 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/migration_lint.rs:150:10 | LL | let [&(_)] = &[&0]; - | -^---- - | || - | |this reference pattern - | default binding mode is `ref` + | ^ reference pattern not allowed under `ref` default binding mode | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/migration_lint.rs:150:9 + | +LL | let [&(_)] = &[&0]; + | ^^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference pattern explicit | LL | let &[&(_)] = &[&0]; 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 ca1749074c190..1d13723370e7f 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 @@ -103,12 +103,14 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/min_match_ergonomics_fail.rs:24:20 | LL | test_pat_on_type![(&x,): &(&T,)]; - | -^--- - | || - | |this reference pattern - | default binding mode is `ref` + | ^ reference pattern not allowed under `ref` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/min_match_ergonomics_fail.rs:24:19 + | +LL | test_pat_on_type![(&x,): &(&T,)]; + | ^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference pattern explicit | LL | test_pat_on_type![&(&x,): &(&T,)]; @@ -118,12 +120,14 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/min_match_ergonomics_fail.rs:27:20 | LL | test_pat_on_type![(&mut x,): &(&mut T,)]; - | -^^^^---- - | || - | |this reference pattern - | default binding mode is `ref` + | ^^^^ reference pattern not allowed under `ref` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/min_match_ergonomics_fail.rs:27:19 + | +LL | test_pat_on_type![(&mut x,): &(&mut T,)]; + | ^^^^^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference pattern explicit | LL | test_pat_on_type![&(&mut x,): &(&mut T,)]; @@ -133,12 +137,14 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/min_match_ergonomics_fail.rs:31:28 | LL | test_pat_on_type![Foo { f: &(x,) }: &Foo]; - | ---------^------ - | | | - | | this reference pattern - | default binding mode is `ref` + | ^ reference pattern not allowed under `ref` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/min_match_ergonomics_fail.rs:31:19 + | +LL | test_pat_on_type![Foo { f: &(x,) }: &Foo]; + | ^^^^^^^^^^^^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference pattern explicit | LL | test_pat_on_type![&Foo { f: &(x,) }: &Foo]; @@ -148,12 +154,14 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/min_match_ergonomics_fail.rs:32:20 | LL | test_pat_on_type![(mut x,): &(T,)]; - | -^^^---- - | || - | |this binding modifier - | default binding mode is `ref` + | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/min_match_ergonomics_fail.rs:32:19 + | +LL | test_pat_on_type![(mut x,): &(T,)]; + | ^^^^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference pattern explicit | LL | test_pat_on_type![&(mut x,): &(T,)]; @@ -163,12 +171,14 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/min_match_ergonomics_fail.rs:33:20 | LL | test_pat_on_type![(ref x,): &(T,)]; - | -^^^---- - | || - | |this binding modifier - | default binding mode is `ref` + | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/min_match_ergonomics_fail.rs:33:19 + | +LL | test_pat_on_type![(ref x,): &(T,)]; + | ^^^^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference pattern explicit | LL | test_pat_on_type![&(ref x,): &(T,)]; @@ -178,12 +188,14 @@ error: binding modifiers may only be written when the default binding mode is `m --> $DIR/min_match_ergonomics_fail.rs:34:20 | LL | test_pat_on_type![(ref mut x,): &mut (T,)]; - | -^^^^^^^---- - | || - | |this binding modifier - | default binding mode is `ref mut` + | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref mut` because this has type `&mut _` + --> $DIR/min_match_ergonomics_fail.rs:34:19 + | +LL | test_pat_on_type![(ref mut x,): &mut (T,)]; + | ^^^^^^^^^^^^ the default binding mode is `ref mut`, introduced here help: make the implied reference pattern explicit | LL | test_pat_on_type![&mut (ref mut x,): &mut (T,)]; @@ -193,12 +205,14 @@ error: reference patterns may only be written when the default binding mode is ` --> $DIR/min_match_ergonomics_fail.rs:43:10 | LL | (&x,) => x, - | -^--- - | || - | |this reference pattern - | default binding mode is `ref` + | ^ reference pattern not allowed under `ref` default binding mode | = note: for more information, see +note: the default binding mode changed to `ref` because this has type `&_` + --> $DIR/min_match_ergonomics_fail.rs:43:9 + | +LL | (&x,) => x, + | ^^^^^ the default binding mode is `ref`, introduced here help: make the implied reference pattern explicit | LL | &(&x,) => x, From a5cc4cbe64876c339cc1fb47fb962792bc142146 Mon Sep 17 00:00:00 2001 From: dianne Date: Wed, 5 Feb 2025 09:05:39 -0800 Subject: [PATCH 11/28] reword default binding mode notes --- compiler/rustc_mir_build/src/errors.rs | 12 +-- ...nding-on-inh-ref-errors.classic2024.stderr | 16 ++-- ...ng-on-inh-ref-errors.structural2024.stderr | 44 +++++------ .../migration_lint.stderr | 76 +++++++++---------- .../min_match_ergonomics_fail.stderr | 28 +++---- 5 files changed, 85 insertions(+), 91 deletions(-) diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index e83901e175d1c..55fd42457b7e7 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -1128,15 +1128,9 @@ impl Subdiagnostic for Rust2024IncompatiblePatSugg { 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 dbm_str = match def_br_mutbl { - ty::Mutability::Not => "ref", - ty::Mutability::Mut => "ref mut", - }; - let note_msg = format!( - "the default binding mode changed to `{dbm_str}` because this has type `{}_`", - def_br_mutbl.ref_prefix_str() - ); - let label_msg = format!("the default binding mode is `{dbm_str}`, introduced here"); + 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); diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr index 74e164619fa96..b7fb70dfd2469 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr @@ -17,11 +17,11 @@ LL | let [ref mut x] = &[0]; | ^^^^^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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]; - | ^^^^^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^^^^^ this matches on type `&_` help: make the implied reference pattern explicit | LL | let &[ref mut x] = &[0]; @@ -40,11 +40,11 @@ LL | let [ref x] = &[0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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]; - | ^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^ this matches on type `&_` help: make the implied reference pattern explicit | LL | let &[ref x] = &[0]; @@ -57,11 +57,11 @@ LL | let [ref x] = &mut [0]; | ^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref mut` because this has type `&mut _` +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]; - | ^^^^^^^ the default binding mode is `ref mut`, introduced here + | ^^^^^^^ this matches on type `&mut _` help: make the implied reference pattern explicit | LL | let &mut [ref x] = &mut [0]; @@ -74,11 +74,11 @@ LL | let [ref mut x] = &mut [0]; | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref mut` because this has type `&mut _` +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]; - | ^^^^^^^^^^^ the default binding mode is `ref mut`, introduced here + | ^^^^^^^^^^^ this matches on type `&mut _` help: make the implied reference pattern explicit | LL | let &mut [ref mut x] = &mut [0]; diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr index 422c169d7fd14..31930e8c03371 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr @@ -5,11 +5,11 @@ LL | let [&ref x] = &[&0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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]; - | ^^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^^ this matches on type `&_` help: make the implied reference pattern explicit | LL | let &[&ref x] = &[&0]; @@ -22,11 +22,11 @@ LL | let [&ref x] = &mut [&0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref mut` because this has type `&mut _` +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]; - | ^^^^^^^^ the default binding mode is `ref mut`, introduced here + | ^^^^^^^^ this matches on type `&mut _` help: make the implied reference pattern explicit | LL | let &mut [&ref x] = &mut [&0]; @@ -39,11 +39,11 @@ LL | let [&mut ref x] = &mut [&mut 0]; | ^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref mut` because this has type `&mut _` +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]; - | ^^^^^^^^^^^^ the default binding mode is `ref mut`, introduced here + | ^^^^^^^^^^^^ this matches on type `&mut _` help: make the implied reference pattern explicit | LL | let &mut [&mut ref x] = &mut [&mut 0]; @@ -56,11 +56,11 @@ LL | let [&mut ref mut x] = &mut [&mut 0]; | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref mut` because this has type `&mut _` +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]; - | ^^^^^^^^^^^^^^^^ the default binding mode is `ref mut`, introduced here + | ^^^^^^^^^^^^^^^^ this matches on type `&mut _` help: make the implied reference pattern explicit | LL | let &mut [&mut ref mut x] = &mut [&mut 0]; @@ -73,11 +73,11 @@ LL | let [&ref x] = &[&mut 0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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]; - | ^^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^^ this matches on type `&_` help: make the implied reference pattern explicit | LL | let &[&ref x] = &[&mut 0]; @@ -90,11 +90,11 @@ LL | let [&ref x] = &mut [&mut 0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref mut` because this has type `&mut _` +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]; - | ^^^^^^^^ the default binding mode is `ref mut`, introduced here + | ^^^^^^^^ this matches on type `&mut _` help: make the implied reference pattern explicit | LL | let &mut [&ref x] = &mut [&mut 0]; @@ -107,11 +107,11 @@ LL | let [&mut ref x] = &[&mut 0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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]; - | ^^^^^^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^^^^^^ this matches on type `&_` help: make the implied reference pattern explicit | LL | let &[&mut ref x] = &[&mut 0]; @@ -124,11 +124,11 @@ LL | let [ref mut x] = &[0]; | ^^^^^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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]; - | ^^^^^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^^^^^ this matches on type `&_` help: make the implied reference pattern explicit | LL | let &[ref mut x] = &[0]; @@ -147,11 +147,11 @@ LL | let [ref x] = &[0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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]; - | ^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^ this matches on type `&_` help: make the implied reference pattern explicit | LL | let &[ref x] = &[0]; @@ -164,11 +164,11 @@ LL | let [ref x] = &mut [0]; | ^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref mut` because this has type `&mut _` +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]; - | ^^^^^^^ the default binding mode is `ref mut`, introduced here + | ^^^^^^^ this matches on type `&mut _` help: make the implied reference pattern explicit | LL | let &mut [ref x] = &mut [0]; @@ -181,11 +181,11 @@ LL | let [ref mut x] = &mut [0]; | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref mut` because this has type `&mut _` +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]; - | ^^^^^^^^^^^ the default binding mode is `ref mut`, introduced here + | ^^^^^^^^^^^ this matches on type `&mut _` help: make the implied reference pattern explicit | LL | let &mut [ref mut x] = &mut [0]; 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 cfbd260e0e9a1..ea3283d3a9213 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 @@ -6,11 +6,11 @@ LL | let Foo(mut x) = &Foo(0); | = warning: this changes meaning in Rust 2024 = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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); - | ^^^^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^^^^ this matches on type `&_` note: the lint level is defined here --> $DIR/migration_lint.rs:7:9 | @@ -29,11 +29,11 @@ LL | let Foo(mut x) = &mut Foo(0); | = warning: this changes meaning in Rust 2024 = note: for more information, see -note: the default binding mode changed to `ref mut` because this has type `&mut _` +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); - | ^^^^^^^^^^ the default binding mode is `ref mut`, introduced here + | ^^^^^^^^^^ this matches on type `&mut _` help: make the implied reference pattern explicit | LL | let &mut Foo(mut x) = &mut Foo(0); @@ -47,11 +47,11 @@ LL | let Foo(ref x) = &Foo(0); | = warning: this changes meaning in Rust 2024 = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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); - | ^^^^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^^^^ this matches on type `&_` help: make the implied reference pattern explicit | LL | let &Foo(ref x) = &Foo(0); @@ -65,11 +65,11 @@ LL | let Foo(ref x) = &mut Foo(0); | = warning: this changes meaning in Rust 2024 = note: for more information, see -note: the default binding mode changed to `ref mut` because this has type `&mut _` +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); - | ^^^^^^^^^^ the default binding mode is `ref mut`, introduced here + | ^^^^^^^^^^ this matches on type `&mut _` help: make the implied reference pattern explicit | LL | let &mut Foo(ref x) = &mut Foo(0); @@ -83,11 +83,11 @@ LL | let Foo(&x) = &Foo(&0); | = warning: this changes meaning in Rust 2024 = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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); - | ^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^ this matches on type `&_` help: make the implied reference pattern explicit | LL | let &Foo(&x) = &Foo(&0); @@ -101,11 +101,11 @@ LL | let Foo(&mut x) = &Foo(&mut 0); | = warning: this changes meaning in Rust 2024 = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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); - | ^^^^^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^^^^^ this matches on type `&_` help: make the implied reference pattern explicit | LL | let &Foo(&mut x) = &Foo(&mut 0); @@ -119,11 +119,11 @@ LL | let Foo(&x) = &mut Foo(&0); | = warning: this changes meaning in Rust 2024 = note: for more information, see -note: the default binding mode changed to `ref mut` because this has type `&mut _` +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); - | ^^^^^^^ the default binding mode is `ref mut`, introduced here + | ^^^^^^^ this matches on type `&mut _` help: make the implied reference pattern explicit | LL | let &mut Foo(&x) = &mut Foo(&0); @@ -137,11 +137,11 @@ LL | let Foo(&mut x) = &mut Foo(&mut 0); | = warning: this changes meaning in Rust 2024 = note: for more information, see -note: the default binding mode changed to `ref mut` because this has type `&mut _` +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); - | ^^^^^^^^^^^ the default binding mode is `ref mut`, introduced here + | ^^^^^^^^^^^ this matches on type `&mut _` help: make the implied reference pattern explicit | LL | let &mut Foo(&mut x) = &mut Foo(&mut 0); @@ -155,11 +155,11 @@ LL | if let Some(&x) = &&&&&Some(&0u8) { | = warning: this changes meaning in Rust 2024 = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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) { - | ^^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^^ this matches on type `&_` help: make the implied reference patterns explicit | LL | if let &&&&&Some(&x) = &&&&&Some(&0u8) { @@ -173,11 +173,11 @@ LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) { | = warning: this changes meaning in Rust 2024 = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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) { - | ^^^^^^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^^^^^^ this matches on type `&_` help: make the implied reference patterns explicit | LL | if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) { @@ -191,11 +191,11 @@ LL | if let Some(&x) = &&&&&mut Some(&0u8) { | = warning: this changes meaning in Rust 2024 = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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) { - | ^^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^^ this matches on type `&_` help: make the implied reference patterns explicit | LL | if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) { @@ -209,11 +209,11 @@ LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) | = warning: this changes meaning in Rust 2024 = note: for more information, see -note: the default binding mode changed to `ref mut` because this has type `&mut _` +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))) { - | ^^^^^^^^^^^^^^^^^^^^^^^^ the default binding mode is `ref mut`, introduced here + | ^^^^^^^^^^^^^^^^^^^^^^^^ 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))) { @@ -227,11 +227,11 @@ LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 }; | = warning: this changes meaning in Rust 2024 = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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 }; - | ^^^^^^^^^^^^^^^^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^^^^^^^^^^^^^^^^ 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 }; @@ -247,11 +247,11 @@ LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 }; | = warning: this changes meaning in Rust 2024 = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 }; @@ -267,11 +267,11 @@ LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } = | = warning: this changes meaning in Rust 2024 = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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) } = - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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) } = @@ -286,11 +286,11 @@ LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { | binding modifier not allowed under `ref` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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)) => { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 | @@ -307,16 +307,16 @@ LL | let [&mut [ref a]] = &mut [&mut &[0]]; | = warning: this changes meaning in Rust 2024 = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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]]; - | ^^^^^^^ the default binding mode is `ref`, introduced here -note: the default binding mode changed to `ref mut` because this has type `&mut _` + | ^^^^^^^ 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]]; - | ^^^^^^^^^^^^^^ the default binding mode is `ref mut`, introduced here + | ^^^^^^^^^^^^^^ this matches on type `&mut _` help: make the implied reference patterns explicit | LL | let &mut [&mut &[ref a]] = &mut [&mut &[0]]; @@ -330,11 +330,11 @@ LL | let [&(_)] = &[&0]; | = warning: this changes meaning in Rust 2024 = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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]; - | ^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^ this matches on type `&_` help: make the implied reference pattern explicit | LL | let &[&(_)] = &[&0]; 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 1d13723370e7f..aaa448ea334f9 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 @@ -106,11 +106,11 @@ LL | test_pat_on_type![(&x,): &(&T,)]; | ^ reference pattern not allowed under `ref` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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,)]; - | ^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^ this matches on type `&_` help: make the implied reference pattern explicit | LL | test_pat_on_type![&(&x,): &(&T,)]; @@ -123,11 +123,11 @@ LL | test_pat_on_type![(&mut x,): &(&mut T,)]; | ^^^^ reference pattern not allowed under `ref` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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,)]; - | ^^^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^^^ this matches on type `&_` help: make the implied reference pattern explicit | LL | test_pat_on_type![&(&mut x,): &(&mut T,)]; @@ -140,11 +140,11 @@ LL | test_pat_on_type![Foo { f: &(x,) }: &Foo]; | ^ reference pattern not allowed under `ref` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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]; - | ^^^^^^^^^^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^^^^^^^^^^ this matches on type `&_` help: make the implied reference pattern explicit | LL | test_pat_on_type![&Foo { f: &(x,) }: &Foo]; @@ -157,11 +157,11 @@ LL | test_pat_on_type![(mut x,): &(T,)]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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,)]; - | ^^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^^ this matches on type `&_` help: make the implied reference pattern explicit | LL | test_pat_on_type![&(mut x,): &(T,)]; @@ -174,11 +174,11 @@ LL | test_pat_on_type![(ref x,): &(T,)]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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,)]; - | ^^^^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^^^^ this matches on type `&_` help: make the implied reference pattern explicit | LL | test_pat_on_type![&(ref x,): &(T,)]; @@ -191,11 +191,11 @@ LL | test_pat_on_type![(ref mut x,): &mut (T,)]; | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref mut` because this has type `&mut _` +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,)]; - | ^^^^^^^^^^^^ the default binding mode is `ref mut`, introduced here + | ^^^^^^^^^^^^ this matches on type `&mut _` help: make the implied reference pattern explicit | LL | test_pat_on_type![&mut (ref mut x,): &mut (T,)]; @@ -208,11 +208,11 @@ LL | (&x,) => x, | ^ reference pattern not allowed under `ref` default binding mode | = note: for more information, see -note: the default binding mode changed to `ref` because this has type `&_` +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, - | ^^^^^ the default binding mode is `ref`, introduced here + | ^^^^^ this matches on type `&_` help: make the implied reference pattern explicit | LL | &(&x,) => x, From 060cc37f3225dd69b5d0df089eec52ff92953b01 Mon Sep 17 00:00:00 2001 From: dianne Date: Wed, 5 Feb 2025 09:09:42 -0800 Subject: [PATCH 12/28] peace of mind: remove a call to `Option::expect` --- compiler/rustc_mir_build/src/thir/pattern/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index f72ce2fe6fbf7..d4a3d1516c899 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -59,8 +59,9 @@ pub(super) fn pat_from_hir<'a, 'tcx>( }; let result = pcx.lower_pattern(pat); debug!("pat_from_hir({:?}) = {:?}", pat, result); - if let Some(info) = migration_info { - let sugg = pcx.rust_2024_migration_suggestion.expect("suggestion should be present"); + 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 { From b32a5331dcdcc1993fefeff412a20766557e558d Mon Sep 17 00:00:00 2001 From: dianne Date: Wed, 5 Feb 2025 04:05:01 -0800 Subject: [PATCH 13/28] try to suggest eliding redundant binding modifiers --- compiler/rustc_hir_typeck/src/pat.rs | 23 +++++++- .../rustc_middle/src/ty/typeck_results.rs | 4 +- compiler/rustc_mir_build/src/errors.rs | 23 +++++--- .../rustc_mir_build/src/thir/pattern/mod.rs | 58 ++++++++++--------- .../migration_lint.fixed | 2 +- .../migration_lint.stderr | 7 ++- .../min_match_ergonomics_fail.stderr | 14 +++-- 7 files changed, 82 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 0c20a98059c4d..080a519023cef 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2786,7 +2786,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut typeck_results = self.typeck_results.borrow_mut(); let mut table = typeck_results.rust_2024_migration_desugared_pats_mut(); - let info = table.entry(pat_id).or_default(); + // 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. @@ -2797,11 +2807,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // so, we may want to inspect the span's source callee or macro backtrace. "occurs within macro expansion".to_owned() } else { - let pat_kind = if matches!(subpat.kind, PatKind::Binding(_, _, _, _)) { + 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" }; let dbm_str = match def_br_mutbl { diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index c09418c0ef15b..df34133520896 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -814,7 +814,7 @@ 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, Default)] +#[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)>, @@ -822,4 +822,6 @@ pub struct Rust2024IncompatiblePatInfo { 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, } diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 55fd42457b7e7..3707685b3add9 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -1107,6 +1107,9 @@ pub(crate) struct Rust2024IncompatiblePat { } 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, @@ -1144,16 +1147,18 @@ impl Subdiagnostic for Rust2024IncompatiblePatSugg { } else { Applicability::MaybeIncorrect }; - 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)) + let msg = if self.suggest_eliding_modes { + let plural_modes = pluralize!(self.binding_mode_count); + format!("remove the unnecessary binding modifier{plural_modes}") } else { - String::new() + 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() + }; + format!("make the implied reference pattern{plural_derefs}{and_modes} explicit") }; - diag.multipart_suggestion_verbose( - format!("make the implied reference pattern{plural_derefs}{and_modes} explicit"), - self.suggestion, - applicability, - ); + diag.multipart_suggestion_verbose(msg, 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 d4a3d1516c899..dde571f671a46 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -49,13 +49,16 @@ pub(super) fn pat_from_hir<'a, 'tcx>( tcx, typing_env, typeck_results, - rust_2024_migration_suggestion: migration_info.and(Some(Rust2024IncompatiblePatSugg { - suggestion: Vec::new(), - ref_pattern_count: 0, - binding_mode_count: 0, - default_mode_span: None, - default_mode_labels: Default::default(), - })), + 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, + default_mode_span: None, + default_mode_labels: Default::default(), + }) + }), }; let result = pcx.lower_pattern(pat); debug!("pat_from_hir({:?}) = {:?}", pat, result); @@ -107,27 +110,22 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { if let Some(s) = &mut self.rust_2024_migration_suggestion && !adjustments.is_empty() { - let mut min_mutbl = Mutability::Mut; - 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 { - Mutability::Not => { - min_mutbl = Mutability::Not; - "&" - } - Mutability::Mut => "&mut ", - } - }) - .collect(); - s.suggestion.push((pat.span.shrink_to_lo(), suggestion_str)); - s.ref_pattern_count += adjustments.len(); + 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)); @@ -413,8 +411,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { { // 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 explicit_ba.0 == ByRef::No + if !s.suggest_eliding_modes + && explicit_ba.0 == ByRef::No && let ByRef::Yes(mutbl) = mode.0 { let sugg_str = match mutbl { 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 911b42c9ddfe6..9ddc8912a5140 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 @@ -32,7 +32,7 @@ fn main() { //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); - let &Foo(ref x) = &Foo(0); + 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); 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 ea3283d3a9213..c36f92ecc7e08 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 @@ -52,10 +52,11 @@ note: matching on a reference type with a non-reference pattern changes the defa | LL | let Foo(ref x) = &Foo(0); | ^^^^^^^^^^ this matches on type `&_` -help: make the implied reference pattern explicit +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: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 --> $DIR/migration_lint.rs:40:13 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 aaa448ea334f9..0c6b2ff3a2f09 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 @@ -179,10 +179,11 @@ note: matching on a reference type with a non-reference pattern changes the defa | LL | test_pat_on_type![(ref x,): &(T,)]; | ^^^^^^^^ this matches on type `&_` -help: make the implied reference pattern explicit +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: binding modifiers may only be written when the default binding mode is `move` --> $DIR/min_match_ergonomics_fail.rs:34:20 @@ -196,10 +197,11 @@ note: matching on a reference type with a non-reference pattern changes the defa | LL | test_pat_on_type![(ref mut x,): &mut (T,)]; | ^^^^^^^^^^^^ this matches on type `&mut _` -help: make the implied reference pattern explicit +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: reference patterns may only be written when the default binding mode is `move` --> $DIR/min_match_ergonomics_fail.rs:43:10 From 8dcdb3eb3c28428267bd7bf4cb63e06f9e4330c1 Mon Sep 17 00:00:00 2001 From: dianne Date: Wed, 5 Feb 2025 09:27:59 -0800 Subject: [PATCH 14/28] peace of mind: be absolutely sure we don't try to emit a 0-part suggestion --- compiler/rustc_mir_build/src/errors.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 3707685b3add9..07bdc59756aa7 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -1159,6 +1159,9 @@ impl Subdiagnostic for Rust2024IncompatiblePatSugg { }; format!("make the implied reference pattern{plural_derefs}{and_modes} explicit") }; - diag.multipart_suggestion_verbose(msg, self.suggestion, applicability); + // 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); + } } } From cac63ffc0fe4d963f902311d5938e03a0a8437aa Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 5 Feb 2025 18:59:07 +0000 Subject: [PATCH 15/28] Only suggest unit for unit fallback when spans dont come from macro expansion --- compiler/rustc_hir_typeck/src/fallback.rs | 12 ++++++++-- .../dont-suggest-turbofish-from-expansion.rs | 20 +++++++++++++++++ ...nt-suggest-turbofish-from-expansion.stderr | 22 +++++++++++++++++++ ...-fallback-flowing-into-unsafe.e2015.stderr | 4 ---- ...-fallback-flowing-into-unsafe.e2024.stderr | 4 ---- 5 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 tests/ui/never_type/dont-suggest-turbofish-from-expansion.rs create mode 100644 tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 1f3f03b992997..b09649f006d79 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -651,6 +651,7 @@ impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> { if let Some(ty) = self.fcx.typeck_results.borrow().node_type_opt(inf_id) && let Some(vid) = self.fcx.root_vid(ty) && self.reachable_vids.contains(&vid) + && inf_span.can_be_used_for_suggestions() { return ControlFlow::Break(errors::SuggestAnnotation::Unit(inf_span)); } @@ -662,7 +663,7 @@ impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> { &mut self, qpath: &'tcx rustc_hir::QPath<'tcx>, id: HirId, - _span: Span, + span: Span, ) -> Self::Result { let arg_segment = match qpath { hir::QPath::Resolved(_, path) => { @@ -674,7 +675,9 @@ impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> { } }; // Alternatively, try to turbofish `::<_, (), _>`. - if let Some(def_id) = self.fcx.typeck_results.borrow().qpath_res(qpath, id).opt_def_id() { + if let Some(def_id) = self.fcx.typeck_results.borrow().qpath_res(qpath, id).opt_def_id() + && span.can_be_used_for_suggestions() + { self.suggest_for_segment(arg_segment, def_id, id)?; } hir::intravisit::walk_qpath(self, qpath, id) @@ -691,17 +694,21 @@ impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> { && let Some(vid) = self.fcx.root_vid(self_ty) && self.reachable_vids.contains(&vid) && let [.., trait_segment, _method_segment] = path.segments + && expr.span.can_be_used_for_suggestions() { let span = path.span.shrink_to_lo().to(trait_segment.ident.span); return ControlFlow::Break(errors::SuggestAnnotation::Path(span)); } + // Or else, try suggesting turbofishing the method args. if let hir::ExprKind::MethodCall(segment, ..) = expr.kind && let Some(def_id) = self.fcx.typeck_results.borrow().type_dependent_def_id(expr.hir_id) + && expr.span.can_be_used_for_suggestions() { self.suggest_for_segment(segment, def_id, expr.hir_id)?; } + hir::intravisit::walk_expr(self, expr) } @@ -712,6 +719,7 @@ impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> { && let Some(ty) = self.fcx.typeck_results.borrow().node_type_opt(local.hir_id) && let Some(vid) = self.fcx.root_vid(ty) && self.reachable_vids.contains(&vid) + && local.span.can_be_used_for_suggestions() { return ControlFlow::Break(errors::SuggestAnnotation::Local( local.pat.span.shrink_to_hi(), diff --git a/tests/ui/never_type/dont-suggest-turbofish-from-expansion.rs b/tests/ui/never_type/dont-suggest-turbofish-from-expansion.rs new file mode 100644 index 0000000000000..9a53358464d8c --- /dev/null +++ b/tests/ui/never_type/dont-suggest-turbofish-from-expansion.rs @@ -0,0 +1,20 @@ +#![deny(dependency_on_unit_never_type_fallback)] + +fn create_ok_default() -> Result +where + C: Default, +{ + Ok(C::default()) +} + +fn main() -> Result<(), ()> { + //~^ ERROR this function depends on never type fallback being `()` + //~| WARN this was previously accepted by the compiler but is being phased out + let (returned_value, _) = (|| { + let created = create_ok_default()?; + Ok((created, ())) + })()?; + + let _ = format_args!("{:?}", returned_value); + Ok(()) +} diff --git a/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr b/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr new file mode 100644 index 0000000000000..b72324129e588 --- /dev/null +++ b/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr @@ -0,0 +1,22 @@ +error: this function depends on never type fallback being `()` + --> $DIR/dont-suggest-turbofish-from-expansion.rs:10:1 + | +LL | fn main() -> Result<(), ()> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! + = note: for more information, see + = help: specify the types explicitly +note: in edition 2024, the requirement `!: Default` will fail + --> $DIR/dont-suggest-turbofish-from-expansion.rs:14:23 + | +LL | let created = create_ok_default()?; + | ^^^^^^^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/dont-suggest-turbofish-from-expansion.rs:1:9 + | +LL | #![deny(dependency_on_unit_never_type_fallback)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr index 04cd2fcafd673..49b966f32ced5 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr @@ -130,10 +130,6 @@ LL | msg_send!(); = note: for more information, see = help: specify the type explicitly = note: this warning originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) -help: use `()` annotations to avoid fallback changes - | -LL | match send_message::<() /* ?0 */>() { - | ~~ warning: 10 warnings emitted diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr index 7adba2cc709c0..4d3692a7b0432 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr @@ -130,10 +130,6 @@ LL | msg_send!(); = note: for more information, see = help: specify the type explicitly = note: this error originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) -help: use `()` annotations to avoid fallback changes - | -LL | match send_message::<() /* ?0 */>() { - | ~~ warning: the type `!` does not permit zero-initialization --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:12:18 From eb9bba879a33995ae6769cbb906d45370f0af018 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 5 Feb 2025 19:01:26 +0000 Subject: [PATCH 16/28] Walk into nested bodies when suggesting unit for unit fallback --- compiler/rustc_hir_typeck/src/fallback.rs | 6 ++++++ .../never_type/dont-suggest-turbofish-from-expansion.stderr | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index b09649f006d79..4618c5d3849b3 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -684,6 +684,12 @@ impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> { } fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Self::Result { + if let hir::ExprKind::Closure(&hir::Closure { body, .. }) + | hir::ExprKind::ConstBlock(hir::ConstBlock { body, .. }) = expr.kind + { + self.visit_body(self.fcx.tcx.hir().body(body))?; + } + // Try to suggest adding an explicit qself `()` to a trait method path. // i.e. changing `Default::default()` to `<() as Default>::default()`. if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind diff --git a/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr b/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr index b72324129e588..3fe642a8401a2 100644 --- a/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr +++ b/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr @@ -17,6 +17,10 @@ note: the lint level is defined here | LL | #![deny(dependency_on_unit_never_type_fallback)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: use `()` annotations to avoid fallback changes + | +LL | let created: () = create_ok_default()?; + | ++++ error: aborting due to 1 previous error From f1e4d94fa4bd253c26610e8d79d5da8b52bad99f Mon Sep 17 00:00:00 2001 From: dianne Date: Thu, 30 Jan 2025 21:42:31 -0800 Subject: [PATCH 17/28] add more pattern migration tests Most of these are meant to test possible future improvements, but since they cover cases the existing test suite didn't, I figure including them now may be helpful. --- .../migration_lint.fixed | 89 +++++++ .../migration_lint.rs | 89 +++++++ .../migration_lint.stderr | 223 +++++++++++++++++- 3 files changed, 400 insertions(+), 1 deletion(-) 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 9ddc8912a5140..0a22e939496e5 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 @@ -150,4 +150,93 @@ fn main() { 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); } 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 bf5fd780404bc..7a6f2269d44a2 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 @@ -150,4 +150,93 @@ fn main() { 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); } 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 c36f92ecc7e08..191800df07a2e 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 @@ -341,5 +341,226 @@ help: make the implied reference pattern explicit LL | let &[&(_)] = &[&0]; | + -error: aborting due to 18 previous errors +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 From d4914a7719cf19e3851df65f54d8a495a6f0027d Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 6 Feb 2025 23:12:33 +0100 Subject: [PATCH 18/28] replace one `.map_or(true, ...)` with `.is_none_or(...)` --- .../rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs index 39e365806cb08..4cb8fcfee0aff 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs @@ -142,7 +142,7 @@ where // Remove any trivial region constraints once we've resolved regions external_constraints .region_constraints - .retain(|outlives| outlives.0.as_region().map_or(true, |re| re != outlives.1)); + .retain(|outlives| outlives.0.as_region().is_none_or(|re| re != outlives.1)); let canonical = Canonicalizer::canonicalize_response( self.delegate, From 3815ed63ed0e1bfa2026e9a54b64a69e16f123ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 23 Jan 2025 18:40:41 +0000 Subject: [PATCH 19/28] Remove some unnecessary parens in `assert!` conditions While working on #122661, some of these started triggering our "unnecessary parens" lints due to a change in the `assert!` desugaring. A cursory search identified a few more. Some of these have been carried from before 1.0, were a bulk rename from the previous name of `assert!` left them in that state. I went and removed as many of these unnecessary parens as possible in order to have fewer annoyances in the future if we make the lint smarter. --- library/alloc/tests/str.rs | 22 +++++++------- library/coretests/tests/bool.rs | 8 ++--- library/coretests/tests/ptr.rs | 6 ++-- library/std/tests/istr.rs | 4 +-- library/std/tests/seq-compare.rs | 22 +++++++------- src/tools/miri/tests/pass/binops.rs | 30 +++++++++---------- tests/ui/binding/expr-match-generic.rs | 2 +- tests/ui/binding/expr-match.rs | 13 ++++---- tests/ui/binop/binops.rs | 30 +++++++++---------- tests/ui/binop/structured-compare.rs | 14 ++++----- tests/ui/cfg/conditional-compile.rs | 2 +- tests/ui/expr/block.rs | 2 +- tests/ui/expr/if/expr-if.rs | 18 +++++------ tests/ui/for-loop-while/break.rs | 8 ++--- tests/ui/for-loop-while/while-cont.rs | 2 +- .../while-loop-constraints-2.rs | 2 +- tests/ui/generics/generic-tag-match.rs | 2 +- tests/ui/iterators/iter-range.rs | 2 +- .../macros/syntax-extension-source-utils.rs | 4 +-- tests/ui/numbers-arithmetic/arith-unsigned.rs | 24 +++++++-------- tests/ui/numbers-arithmetic/float-nan.rs | 2 +- tests/ui/numbers-arithmetic/float2.rs | 10 +++---- tests/ui/numbers-arithmetic/floatlits.rs | 8 ++--- .../class-impl-very-parameterized-trait.rs | 2 +- .../class-implement-trait-cross-crate.rs | 4 +-- .../structs-enums/class-implement-traits.rs | 2 +- tests/ui/structs-enums/classes-cross-crate.rs | 4 +-- tests/ui/structs-enums/classes.rs | 4 +-- tests/ui/structs-enums/tag.rs | 2 +- tests/ui/tail-cps.rs | 2 +- tests/ui/weird-exprs.rs | 6 ++-- 31 files changed, 130 insertions(+), 133 deletions(-) diff --git a/library/alloc/tests/str.rs b/library/alloc/tests/str.rs index 6f930ab08535c..5720d3ffd97b6 100644 --- a/library/alloc/tests/str.rs +++ b/library/alloc/tests/str.rs @@ -2297,21 +2297,21 @@ fn utf8_chars() { assert_eq!(schs.len(), 4); assert_eq!(schs.iter().cloned().collect::(), s); - assert!((from_utf8(s.as_bytes()).is_ok())); + assert!(from_utf8(s.as_bytes()).is_ok()); // invalid prefix - assert!((!from_utf8(&[0x80]).is_ok())); + assert!(!from_utf8(&[0x80]).is_ok()); // invalid 2 byte prefix - assert!((!from_utf8(&[0xc0]).is_ok())); - assert!((!from_utf8(&[0xc0, 0x10]).is_ok())); + assert!(!from_utf8(&[0xc0]).is_ok()); + assert!(!from_utf8(&[0xc0, 0x10]).is_ok()); // invalid 3 byte prefix - assert!((!from_utf8(&[0xe0]).is_ok())); - assert!((!from_utf8(&[0xe0, 0x10]).is_ok())); - assert!((!from_utf8(&[0xe0, 0xff, 0x10]).is_ok())); + assert!(!from_utf8(&[0xe0]).is_ok()); + assert!(!from_utf8(&[0xe0, 0x10]).is_ok()); + assert!(!from_utf8(&[0xe0, 0xff, 0x10]).is_ok()); // invalid 4 byte prefix - assert!((!from_utf8(&[0xf0]).is_ok())); - assert!((!from_utf8(&[0xf0, 0x10]).is_ok())); - assert!((!from_utf8(&[0xf0, 0xff, 0x10]).is_ok())); - assert!((!from_utf8(&[0xf0, 0xff, 0xff, 0x10]).is_ok())); + assert!(!from_utf8(&[0xf0]).is_ok()); + assert!(!from_utf8(&[0xf0, 0x10]).is_ok()); + assert!(!from_utf8(&[0xf0, 0xff, 0x10]).is_ok()); + assert!(!from_utf8(&[0xf0, 0xff, 0xff, 0x10]).is_ok()); } #[test] diff --git a/library/coretests/tests/bool.rs b/library/coretests/tests/bool.rs index 47f6459915b3e..bcd6dc2abac6c 100644 --- a/library/coretests/tests/bool.rs +++ b/library/coretests/tests/bool.rs @@ -71,14 +71,14 @@ fn test_bool() { #[test] pub fn test_bool_not() { if !false { - assert!((true)); + assert!(true); } else { - assert!((false)); + assert!(false); } if !true { - assert!((false)); + assert!(false); } else { - assert!((true)); + assert!(true); } } diff --git a/library/coretests/tests/ptr.rs b/library/coretests/tests/ptr.rs index 7cefb615d0371..345bec345d128 100644 --- a/library/coretests/tests/ptr.rs +++ b/library/coretests/tests/ptr.rs @@ -42,11 +42,11 @@ fn test() { let mut v1 = vec![0u16, 0u16, 0u16]; copy(v0.as_ptr().offset(1), v1.as_mut_ptr().offset(1), 1); - assert!((v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16)); + assert!(v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16); copy(v0.as_ptr().offset(2), v1.as_mut_ptr(), 1); - assert!((v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16)); + assert!(v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16); copy(v0.as_ptr(), v1.as_mut_ptr().offset(2), 1); - assert!((v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16)); + assert!(v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16); } } diff --git a/library/std/tests/istr.rs b/library/std/tests/istr.rs index 9a127ae803e77..e481872977abf 100644 --- a/library/std/tests/istr.rs +++ b/library/std/tests/istr.rs @@ -5,7 +5,7 @@ fn test_stack_assign() { let t: String = "a".to_string(); assert_eq!(s, t); let u: String = "b".to_string(); - assert!((s != u)); + assert!(s != u); } #[test] @@ -19,7 +19,7 @@ fn test_heap_assign() { let t: String = "a big ol' string".to_string(); assert_eq!(s, t); let u: String = "a bad ol' string".to_string(); - assert!((s != u)); + assert!(s != u); } #[test] diff --git a/library/std/tests/seq-compare.rs b/library/std/tests/seq-compare.rs index 221f1c7cabde5..ec39c5b603ccc 100644 --- a/library/std/tests/seq-compare.rs +++ b/library/std/tests/seq-compare.rs @@ -1,15 +1,15 @@ #[test] fn seq_compare() { - assert!(("hello".to_string() < "hellr".to_string())); - assert!(("hello ".to_string() > "hello".to_string())); - assert!(("hello".to_string() != "there".to_string())); - assert!((vec![1, 2, 3, 4] > vec![1, 2, 3])); - assert!((vec![1, 2, 3] < vec![1, 2, 3, 4])); - assert!((vec![1, 2, 4, 4] > vec![1, 2, 3, 4])); - assert!((vec![1, 2, 3, 4] < vec![1, 2, 4, 4])); - assert!((vec![1, 2, 3] <= vec![1, 2, 3])); - assert!((vec![1, 2, 3] <= vec![1, 2, 3, 3])); - assert!((vec![1, 2, 3, 4] > vec![1, 2, 3])); + assert!("hello".to_string() < "hellr".to_string()); + assert!("hello ".to_string() > "hello".to_string()); + assert!("hello".to_string() != "there".to_string()); + assert!(vec![1, 2, 3, 4] > vec![1, 2, 3]); + assert!(vec![1, 2, 3] < vec![1, 2, 3, 4]); + assert!(vec![1, 2, 4, 4] > vec![1, 2, 3, 4]); + assert!(vec![1, 2, 3, 4] < vec![1, 2, 4, 4]); + assert!(vec![1, 2, 3] <= vec![1, 2, 3]); + assert!(vec![1, 2, 3] <= vec![1, 2, 3, 3]); + assert!(vec![1, 2, 3, 4] > vec![1, 2, 3]); assert_eq!(vec![1, 2, 3], vec![1, 2, 3]); - assert!((vec![1, 2, 3] != vec![1, 1, 3])); + assert!(vec![1, 2, 3] != vec![1, 1, 3]); } diff --git a/src/tools/miri/tests/pass/binops.rs b/src/tools/miri/tests/pass/binops.rs index 0988d7ccc4c6e..0aff7acb29d44 100644 --- a/src/tools/miri/tests/pass/binops.rs +++ b/src/tools/miri/tests/pass/binops.rs @@ -2,23 +2,23 @@ fn test_nil() { assert_eq!((), ()); - assert!((!(() != ()))); - assert!((!(() < ()))); - assert!((() <= ())); - assert!((!(() > ()))); - assert!((() >= ())); + assert!(!(() != ())); + assert!(!(() < ())); + assert!(() <= ()); + assert!(!(() > ())); + assert!(() >= ()); } fn test_bool() { - assert!((!(true < false))); - assert!((!(true <= false))); - assert!((true > false)); - assert!((true >= false)); + assert!(!(true < false)); + assert!(!(true <= false)); + assert!(true > false); + assert!(true >= false); - assert!((false < true)); - assert!((false <= true)); - assert!((!(false > true))); - assert!((!(false >= true))); + assert!(false < true); + assert!(false <= true); + assert!(!(false > true)); + assert!(!(false >= true)); // Bools support bitwise binops assert_eq!(false & false, false); @@ -65,9 +65,9 @@ fn test_class() { assert_eq!(q, r); r.y = 17; - assert!((r.y != q.y)); + assert!(r.y != q.y); assert_eq!(r.y, 17); - assert!((q != r)); + assert!(q != r); } pub fn main() { diff --git a/tests/ui/binding/expr-match-generic.rs b/tests/ui/binding/expr-match-generic.rs index 975eec42fd054..dcc069b9fb329 100644 --- a/tests/ui/binding/expr-match-generic.rs +++ b/tests/ui/binding/expr-match-generic.rs @@ -5,7 +5,7 @@ type compare = extern "Rust" fn(T, T) -> bool; fn test_generic(expected: T, eq: compare) { let actual: T = match true { true => { expected.clone() }, _ => panic!("wat") }; - assert!((eq(expected, actual))); + assert!(eq(expected, actual)); } fn test_bool() { diff --git a/tests/ui/binding/expr-match.rs b/tests/ui/binding/expr-match.rs index 049beaaf51bf6..ce502ae149033 100644 --- a/tests/ui/binding/expr-match.rs +++ b/tests/ui/binding/expr-match.rs @@ -1,20 +1,17 @@ //@ run-pass - - - // Tests for using match as an expression fn test_basic() { let mut rs: bool = match true { true => { true } false => { false } }; - assert!((rs)); + assert!(rs); rs = match false { true => { false } false => { true } }; - assert!((rs)); + assert!(rs); } fn test_inferrence() { let rs = match true { true => { true } false => { false } }; - assert!((rs)); + assert!(rs); } fn test_alt_as_alt_head() { @@ -25,7 +22,7 @@ fn test_alt_as_alt_head() { true => { false } false => { true } }; - assert!((rs)); + assert!(rs); } fn test_alt_as_block_result() { @@ -34,7 +31,7 @@ fn test_alt_as_block_result() { true => { false } false => { match true { true => { true } false => { false } } } }; - assert!((rs)); + assert!(rs); } pub fn main() { diff --git a/tests/ui/binop/binops.rs b/tests/ui/binop/binops.rs index 0adbb49b14a37..7142190a45b9a 100644 --- a/tests/ui/binop/binops.rs +++ b/tests/ui/binop/binops.rs @@ -5,23 +5,23 @@ fn test_nil() { assert_eq!((), ()); - assert!((!(() != ()))); - assert!((!(() < ()))); - assert!((() <= ())); - assert!((!(() > ()))); - assert!((() >= ())); + assert!(!(() != ())); + assert!(!(() < ())); + assert!(() <= ()); + assert!(!(() > ())); + assert!(() >= ()); } fn test_bool() { - assert!((!(true < false))); - assert!((!(true <= false))); - assert!((true > false)); - assert!((true >= false)); + assert!(!(true < false)); + assert!(!(true <= false)); + assert!(true > false); + assert!(true >= false); - assert!((false < true)); - assert!((false <= true)); - assert!((!(false > true))); - assert!((!(false >= true))); + assert!(false < true); + assert!(false <= true); + assert!(!(false > true)); + assert!(!(false >= true)); // Bools support bitwise binops assert_eq!(false & false, false); @@ -76,9 +76,9 @@ fn test_class() { } assert_eq!(q, r); r.y = 17; - assert!((r.y != q.y)); + assert!(r.y != q.y); assert_eq!(r.y, 17); - assert!((q != r)); + assert!(q != r); } pub fn main() { diff --git a/tests/ui/binop/structured-compare.rs b/tests/ui/binop/structured-compare.rs index 164760cd7a040..7d1eff453028a 100644 --- a/tests/ui/binop/structured-compare.rs +++ b/tests/ui/binop/structured-compare.rs @@ -17,14 +17,14 @@ pub fn main() { let a = (1, 2, 3); let b = (1, 2, 3); assert_eq!(a, b); - assert!((a != (1, 2, 4))); - assert!((a < (1, 2, 4))); - assert!((a <= (1, 2, 4))); - assert!(((1, 2, 4) > a)); - assert!(((1, 2, 4) >= a)); + assert!(a != (1, 2, 4)); + assert!(a < (1, 2, 4)); + assert!(a <= (1, 2, 4)); + assert!((1, 2, 4) > a); + assert!((1, 2, 4) >= a); let x = foo::large; let y = foo::small; - assert!((x != y)); + assert!(x != y); assert_eq!(x, foo::large); - assert!((x != foo::small)); + assert!(x != foo::small); } diff --git a/tests/ui/cfg/conditional-compile.rs b/tests/ui/cfg/conditional-compile.rs index a4f334dd696ab..dff280054d659 100644 --- a/tests/ui/cfg/conditional-compile.rs +++ b/tests/ui/cfg/conditional-compile.rs @@ -85,7 +85,7 @@ pub fn main() { pub fn main() { // Exercise some of the configured items in ways that wouldn't be possible // if they had the FALSE definition - assert!((b)); + assert!(b); let _x: t = true; let _y: tg = tg::bar; diff --git a/tests/ui/expr/block.rs b/tests/ui/expr/block.rs index bf626c9ead372..70f5c274c214d 100644 --- a/tests/ui/expr/block.rs +++ b/tests/ui/expr/block.rs @@ -4,7 +4,7 @@ // Tests for standalone blocks as expressions -fn test_basic() { let rs: bool = { true }; assert!((rs)); } +fn test_basic() { let rs: bool = { true }; assert!(rs); } struct RS { v1: isize, v2: isize } diff --git a/tests/ui/expr/if/expr-if.rs b/tests/ui/expr/if/expr-if.rs index ae869c4b77a38..68c2fc2213015 100644 --- a/tests/ui/expr/if/expr-if.rs +++ b/tests/ui/expr/if/expr-if.rs @@ -1,43 +1,43 @@ //@ run-pass // Tests for if as expressions -fn test_if() { let rs: bool = if true { true } else { false }; assert!((rs)); } +fn test_if() { let rs: bool = if true { true } else { false }; assert!(rs); } fn test_else() { let rs: bool = if false { false } else { true }; - assert!((rs)); + assert!(rs); } fn test_elseif1() { let rs: bool = if true { true } else if true { false } else { false }; - assert!((rs)); + assert!(rs); } fn test_elseif2() { let rs: bool = if false { false } else if true { true } else { false }; - assert!((rs)); + assert!(rs); } fn test_elseif3() { let rs: bool = if false { false } else if false { false } else { true }; - assert!((rs)); + assert!(rs); } fn test_inferrence() { let rs = if true { true } else { false }; - assert!((rs)); + assert!(rs); } fn test_if_as_if_condition() { let rs1 = if if false { false } else { true } { true } else { false }; - assert!((rs1)); + assert!(rs1); let rs2 = if if true { false } else { true } { false } else { true }; - assert!((rs2)); + assert!(rs2); } fn test_if_as_block_result() { let rs = if true { if false { false } else { true } } else { false }; - assert!((rs)); + assert!(rs); } pub fn main() { diff --git a/tests/ui/for-loop-while/break.rs b/tests/ui/for-loop-while/break.rs index 77774792262cd..442e07e148c57 100644 --- a/tests/ui/for-loop-while/break.rs +++ b/tests/ui/for-loop-while/break.rs @@ -8,18 +8,18 @@ pub fn main() { assert_eq!(i, 20); let xs = [1, 2, 3, 4, 5, 6]; for x in &xs { - if *x == 3 { break; } assert!((*x <= 3)); + if *x == 3 { break; } assert!(*x <= 3); } i = 0; - while i < 10 { i += 1; if i % 2 == 0 { continue; } assert!((i % 2 != 0)); } + while i < 10 { i += 1; if i % 2 == 0 { continue; } assert!(i % 2 != 0); } i = 0; loop { - i += 1; if i % 2 == 0 { continue; } assert!((i % 2 != 0)); + i += 1; if i % 2 == 0 { continue; } assert!(i % 2 != 0); if i >= 10 { break; } } let ys = vec![1, 2, 3, 4, 5, 6]; for x in &ys { if *x % 2 == 0 { continue; } - assert!((*x % 2 != 0)); + assert!(*x % 2 != 0); } } diff --git a/tests/ui/for-loop-while/while-cont.rs b/tests/ui/for-loop-while/while-cont.rs index 1640b7e1803bd..73a08c26f9af6 100644 --- a/tests/ui/for-loop-while/while-cont.rs +++ b/tests/ui/for-loop-while/while-cont.rs @@ -3,7 +3,7 @@ pub fn main() { let mut i = 1; while i > 0 { - assert!((i > 0)); + assert!(i > 0); println!("{}", i); i -= 1; continue; diff --git a/tests/ui/for-loop-while/while-loop-constraints-2.rs b/tests/ui/for-loop-while/while-loop-constraints-2.rs index 654f6769902bd..1d2d9c2ecfe60 100644 --- a/tests/ui/for-loop-while/while-loop-constraints-2.rs +++ b/tests/ui/for-loop-while/while-loop-constraints-2.rs @@ -11,5 +11,5 @@ pub fn main() { while false { x = y; y = z; } println!("{}", y); } - assert!((y == 42 && z == 50)); + assert!(y == 42 && z == 50); } diff --git a/tests/ui/generics/generic-tag-match.rs b/tests/ui/generics/generic-tag-match.rs index dd0291e9d8736..378b51df287b3 100644 --- a/tests/ui/generics/generic-tag-match.rs +++ b/tests/ui/generics/generic-tag-match.rs @@ -7,7 +7,7 @@ enum foo { arm(T), } fn altfoo(f: foo) { let mut hit = false; match f { foo::arm::(_x) => { println!("in arm"); hit = true; } } - assert!((hit)); + assert!(hit); } pub fn main() { altfoo::(foo::arm::(10)); } diff --git a/tests/ui/iterators/iter-range.rs b/tests/ui/iterators/iter-range.rs index 9594729c06cf0..ec99331753989 100644 --- a/tests/ui/iterators/iter-range.rs +++ b/tests/ui/iterators/iter-range.rs @@ -2,7 +2,7 @@ fn range_(a: isize, b: isize, mut it: F) where F: FnMut(isize) { - assert!((a < b)); + assert!(a < b); let mut i: isize = a; while i < b { it(i); i += 1; } } diff --git a/tests/ui/macros/syntax-extension-source-utils.rs b/tests/ui/macros/syntax-extension-source-utils.rs index a16ebdc750424..2f88e508058c1 100644 --- a/tests/ui/macros/syntax-extension-source-utils.rs +++ b/tests/ui/macros/syntax-extension-source-utils.rs @@ -16,7 +16,7 @@ pub fn main() { assert_eq!(line!(), 16); assert_eq!(column!(), 16); assert_eq!(indirect_line!(), 18); - assert!((file!().ends_with("syntax-extension-source-utils.rs"))); + assert!(file!().ends_with("syntax-extension-source-utils.rs")); assert_eq!(stringify!((2*3) + 5).to_string(), "(2*3) + 5".to_string()); assert!(include!("syntax-extension-source-utils-files/includeme.\ fragment").to_string() @@ -30,7 +30,7 @@ pub fn main() { include_bytes!("syntax-extension-source-utils-files/includeme.fragment") [1] == (42 as u8)); // '*' // The Windows tests are wrapped in an extra module for some reason - assert!((m1::m2::where_am_i().ends_with("m1::m2"))); + assert!(m1::m2::where_am_i().ends_with("m1::m2")); assert_eq!((35, "(2*3) + 5"), (line!(), stringify!((2*3) + 5))); } diff --git a/tests/ui/numbers-arithmetic/arith-unsigned.rs b/tests/ui/numbers-arithmetic/arith-unsigned.rs index 5a285ceca32db..4a1bae438ca2e 100644 --- a/tests/ui/numbers-arithmetic/arith-unsigned.rs +++ b/tests/ui/numbers-arithmetic/arith-unsigned.rs @@ -3,22 +3,22 @@ // Unsigned integer operations pub fn main() { - assert!((0u8 < 255u8)); - assert!((0u8 <= 255u8)); - assert!((255u8 > 0u8)); - assert!((255u8 >= 0u8)); + assert!(0u8 < 255u8); + assert!(0u8 <= 255u8); + assert!(255u8 > 0u8); + assert!(255u8 >= 0u8); assert_eq!(250u8 / 10u8, 25u8); assert_eq!(255u8 % 10u8, 5u8); - assert!((0u16 < 60000u16)); - assert!((0u16 <= 60000u16)); - assert!((60000u16 > 0u16)); - assert!((60000u16 >= 0u16)); + assert!(0u16 < 60000u16); + assert!(0u16 <= 60000u16); + assert!(60000u16 > 0u16); + assert!(60000u16 >= 0u16); assert_eq!(60000u16 / 10u16, 6000u16); assert_eq!(60005u16 % 10u16, 5u16); - assert!((0u32 < 4000000000u32)); - assert!((0u32 <= 4000000000u32)); - assert!((4000000000u32 > 0u32)); - assert!((4000000000u32 >= 0u32)); + assert!(0u32 < 4000000000u32); + assert!(0u32 <= 4000000000u32); + assert!(4000000000u32 > 0u32); + assert!(4000000000u32 >= 0u32); assert_eq!(4000000000u32 / 10u32, 400000000u32); assert_eq!(4000000005u32 % 10u32, 5u32); // 64-bit numbers have some flakiness yet. Not tested diff --git a/tests/ui/numbers-arithmetic/float-nan.rs b/tests/ui/numbers-arithmetic/float-nan.rs index 7d1af0155da53..ee3718f6f939b 100644 --- a/tests/ui/numbers-arithmetic/float-nan.rs +++ b/tests/ui/numbers-arithmetic/float-nan.rs @@ -2,7 +2,7 @@ pub fn main() { let nan: f64 = f64::NAN; - assert!((nan).is_nan()); + assert!(nan.is_nan()); let inf: f64 = f64::INFINITY; let neg_inf: f64 = -f64::INFINITY; diff --git a/tests/ui/numbers-arithmetic/float2.rs b/tests/ui/numbers-arithmetic/float2.rs index 1b7add01cc631..515220fee9ffe 100644 --- a/tests/ui/numbers-arithmetic/float2.rs +++ b/tests/ui/numbers-arithmetic/float2.rs @@ -15,12 +15,12 @@ pub fn main() { let j = 3.1e+9f64; let k = 3.2e-10f64; assert_eq!(a, b); - assert!((c < b)); + assert!(c < b); assert_eq!(c, d); - assert!((e < g)); - assert!((f < h)); + assert!(e < g); + assert!(f < h); assert_eq!(g, 1000000.0f32); assert_eq!(h, i); - assert!((j > k)); - assert!((k < a)); + assert!(j > k); + assert!(k < a); } diff --git a/tests/ui/numbers-arithmetic/floatlits.rs b/tests/ui/numbers-arithmetic/floatlits.rs index 21f19b69c49e7..2dab224201193 100644 --- a/tests/ui/numbers-arithmetic/floatlits.rs +++ b/tests/ui/numbers-arithmetic/floatlits.rs @@ -4,9 +4,9 @@ pub fn main() { let f = 4.999999999999f64; - assert!((f > 4.90f64)); - assert!((f < 5.0f64)); + assert!(f > 4.90f64); + assert!(f < 5.0f64); let g = 4.90000000001e-10f64; - assert!((g > 5e-11f64)); - assert!((g < 5e-9f64)); + assert!(g > 5e-11f64); + assert!(g < 5e-9f64); } diff --git a/tests/ui/structs-enums/class-impl-very-parameterized-trait.rs b/tests/ui/structs-enums/class-impl-very-parameterized-trait.rs index 0b37192fc3b34..6caec1e2034ef 100644 --- a/tests/ui/structs-enums/class-impl-very-parameterized-trait.rs +++ b/tests/ui/structs-enums/class-impl-very-parameterized-trait.rs @@ -102,6 +102,6 @@ pub fn main() { let mut spotty: cat = cat::new(2, 57, cat_type::tuxedo); for _ in 0_usize..6 { spotty.speak(); } assert_eq!(spotty.len(), 8); - assert!((spotty.contains_key(&2))); + assert!(spotty.contains_key(&2)); assert_eq!(spotty.get(&3), &cat_type::tuxedo); } diff --git a/tests/ui/structs-enums/class-implement-trait-cross-crate.rs b/tests/ui/structs-enums/class-implement-trait-cross-crate.rs index 7a5969451cb52..781ac6ad10d2c 100644 --- a/tests/ui/structs-enums/class-implement-trait-cross-crate.rs +++ b/tests/ui/structs-enums/class-implement-trait-cross-crate.rs @@ -53,7 +53,7 @@ fn cat(in_x : usize, in_y : isize, in_name: String) -> cat { pub fn main() { let mut nyan = cat(0_usize, 2, "nyan".to_string()); nyan.eat(); - assert!((!nyan.eat())); + assert!(!nyan.eat()); for _ in 1_usize..10_usize { nyan.speak(); }; - assert!((nyan.eat())); + assert!(nyan.eat()); } diff --git a/tests/ui/structs-enums/class-implement-traits.rs b/tests/ui/structs-enums/class-implement-traits.rs index 04a7b706edbce..3a514ff9d7581 100644 --- a/tests/ui/structs-enums/class-implement-traits.rs +++ b/tests/ui/structs-enums/class-implement-traits.rs @@ -57,7 +57,7 @@ fn make_speak(mut c: C) { pub fn main() { let mut nyan = cat(0_usize, 2, "nyan".to_string()); nyan.eat(); - assert!((!nyan.eat())); + assert!(!nyan.eat()); for _ in 1_usize..10_usize { make_speak(nyan.clone()); } diff --git a/tests/ui/structs-enums/classes-cross-crate.rs b/tests/ui/structs-enums/classes-cross-crate.rs index 0160d3fd85c08..6fb5f2e3cc9d7 100644 --- a/tests/ui/structs-enums/classes-cross-crate.rs +++ b/tests/ui/structs-enums/classes-cross-crate.rs @@ -7,7 +7,7 @@ use cci_class_4::kitties::cat; pub fn main() { let mut nyan = cat(0_usize, 2, "nyan".to_string()); nyan.eat(); - assert!((!nyan.eat())); + assert!(!nyan.eat()); for _ in 1_usize..10_usize { nyan.speak(); }; - assert!((nyan.eat())); + assert!(nyan.eat()); } diff --git a/tests/ui/structs-enums/classes.rs b/tests/ui/structs-enums/classes.rs index d1c1922f4b547..05976f6a759af 100644 --- a/tests/ui/structs-enums/classes.rs +++ b/tests/ui/structs-enums/classes.rs @@ -45,7 +45,7 @@ fn cat(in_x : usize, in_y : isize, in_name: String) -> cat { pub fn main() { let mut nyan = cat(0_usize, 2, "nyan".to_string()); nyan.eat(); - assert!((!nyan.eat())); + assert!(!nyan.eat()); for _ in 1_usize..10_usize { nyan.speak(); }; - assert!((nyan.eat())); + assert!(nyan.eat()); } diff --git a/tests/ui/structs-enums/tag.rs b/tests/ui/structs-enums/tag.rs index 16e6b2341cf61..542b517e66db7 100644 --- a/tests/ui/structs-enums/tag.rs +++ b/tests/ui/structs-enums/tag.rs @@ -25,6 +25,6 @@ impl PartialEq for colour { fn ne(&self, other: &colour) -> bool { !(*self).eq(other) } } -fn f() { let x = colour::red(1, 2); let y = colour::green; assert!((x != y)); } +fn f() { let x = colour::red(1, 2); let y = colour::green; assert!(x != y); } pub fn main() { f(); } diff --git a/tests/ui/tail-cps.rs b/tests/ui/tail-cps.rs index 6305e9ecdbcf1..fe99dadf7951c 100644 --- a/tests/ui/tail-cps.rs +++ b/tests/ui/tail-cps.rs @@ -1,6 +1,6 @@ //@ run-pass -fn checktrue(rs: bool) -> bool { assert!((rs)); return true; } +fn checktrue(rs: bool) -> bool { assert!(rs); return true; } pub fn main() { let k = checktrue; evenk(42, k); oddk(45, k); } diff --git a/tests/ui/weird-exprs.rs b/tests/ui/weird-exprs.rs index 08b5517aae22f..55a8d580a8b7b 100644 --- a/tests/ui/weird-exprs.rs +++ b/tests/ui/weird-exprs.rs @@ -34,7 +34,7 @@ fn what() { let i = &Cell::new(false); let dont = {||the(i)}; dont(); - assert!((i.get())); + assert!(i.get()); } fn zombiejesus() { @@ -69,8 +69,8 @@ fn notsure() { fn canttouchthis() -> usize { fn p() -> bool { true } - let _a = (assert!((true)) == (assert!(p()))); - let _c = (assert!((p())) == ()); + let _a = (assert!(true) == (assert!(p()))); + let _c = (assert!(p()) == ()); let _b: bool = (println!("{}", 0) == (return 0)); } From da9a85a1a6ef4f8b3b4cb1829ed35cd6c975d9f6 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Mon, 16 Dec 2024 01:35:51 +0100 Subject: [PATCH 20/28] stabilize `feature(trait_upcasting)` --- compiler/rustc_feature/src/accepted.rs | 3 + compiler/rustc_feature/src/unstable.rs | 3 - compiler/rustc_hir_typeck/src/coercion.rs | 23 ------- compiler/rustc_lint/src/lib.rs | 2 +- compiler/rustc_middle/src/lib.rs | 2 +- .../src/traits/select/candidate_assembly.rs | 63 +------------------ 6 files changed, 6 insertions(+), 90 deletions(-) diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 217a7aeb2d7f7..6c9c475ea2625 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -400,6 +400,9 @@ declare_features! ( /// Allows `#[track_caller]` to be used which provides /// accurate caller location reporting during panic (RFC 2091). (accepted, track_caller, "1.46.0", Some(47809)), + /// Allows dyn upcasting trait objects via supertraits. + /// Dyn upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`. + (accepted, trait_upcasting, "CURRENT_RUSTC_VERSION", Some(65991)), /// Allows #[repr(transparent)] on univariant enums (RFC 2645). (accepted, transparent_enums, "1.42.0", Some(60405)), /// Allows indexing tuples. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 115b3eabbaa73..ae29334975b2a 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -634,9 +634,6 @@ declare_features! ( (unstable, thread_local, "1.0.0", Some(29594)), /// Allows defining `trait X = A + B;` alias items. (unstable, trait_alias, "1.24.0", Some(41517)), - /// Allows dyn upcasting trait objects via supertraits. - /// Dyn upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`. - (unstable, trait_upcasting, "1.56.0", Some(65991)), /// Allows for transmuting between arrays with sizes that contain generic consts. (unstable, transmute_generic_consts, "1.70.0", Some(109929)), /// Allows #[repr(transparent)] on unions (RFC 2645). diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 83acc7dd6afc5..56cc9b6d5514b 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -605,7 +605,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { )]; let mut has_unsized_tuple_coercion = false; - let mut has_trait_upcasting_coercion = None; // Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid // emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where @@ -690,13 +689,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // these here and emit a feature error if coercion doesn't fail // due to another reason. match impl_source { - traits::ImplSource::Builtin( - BuiltinImplSource::TraitUpcasting { .. }, - _, - ) => { - has_trait_upcasting_coercion = - Some((trait_pred.self_ty(), trait_pred.trait_ref.args.type_at(1))); - } traits::ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => { has_unsized_tuple_coercion = true; } @@ -707,21 +699,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { } } - if let Some((sub, sup)) = has_trait_upcasting_coercion - && !self.tcx().features().trait_upcasting() - { - // Renders better when we erase regions, since they're not really the point here. - let (sub, sup) = self.tcx.erase_regions((sub, sup)); - let mut err = feature_err( - &self.tcx.sess, - sym::trait_upcasting, - self.cause.span, - format!("cannot cast `{sub}` to `{sup}`, trait upcasting coercion is experimental"), - ); - err.note(format!("required when coercing `{source}` into `{target}`")); - err.emit(); - } - if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion() { feature_err( &self.tcx.sess, diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index fd6c17735c5a2..3e97f4c86ba32 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -21,6 +21,7 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(bootstrap, feature(trait_upcasting))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(array_windows)] @@ -32,7 +33,6 @@ #![feature(let_chains)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] -#![feature(trait_upcasting)] #![warn(unreachable_pub)] // tidy-alphabetical-end diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 7a6d329fd4753..95128a5d903bb 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -29,6 +29,7 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::potential_query_instability)] #![allow(rustc::untranslatable_diagnostic)] +#![cfg_attr(bootstrap, feature(trait_upcasting))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(allocator_api)] @@ -56,7 +57,6 @@ #![feature(ptr_alignment_type)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] -#![feature(trait_upcasting)] #![feature(trusted_len)] #![feature(try_blocks)] #![feature(try_trait_v2)] diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 13a6744c2e9b5..e495bdbf7825c 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -12,9 +12,7 @@ use hir::LangItem; use hir::def_id::DefId; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_hir as hir; -use rustc_infer::traits::{ - Obligation, ObligationCause, PolyTraitObligation, PredicateObligations, SelectionError, -}; +use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError}; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::{self, Ty, TypeVisitableExt, TypingMode}; use rustc_middle::{bug, span_bug}; @@ -23,8 +21,6 @@ use tracing::{debug, instrument, trace}; use super::SelectionCandidate::*; use super::{BuiltinImplConditions, SelectionCandidateSet, SelectionContext, TraitObligationStack}; -use crate::traits; -use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::util; impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { @@ -904,54 +900,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }) } - /// Temporary migration for #89190 - fn need_migrate_deref_output_trait_object( - &mut self, - ty: Ty<'tcx>, - param_env: ty::ParamEnv<'tcx>, - cause: &ObligationCause<'tcx>, - ) -> Option> { - // Don't drop any candidates in intercrate mode, as it's incomplete. - // (Not that it matters, since `Unsize` is not a stable trait.) - // - // FIXME(@lcnr): This should probably only trigger during analysis, - // disabling candidates during codegen is also questionable. - if let TypingMode::Coherence = self.infcx.typing_mode() { - return None; - } - - let tcx = self.tcx(); - if tcx.features().trait_upcasting() { - return None; - } - - // - let trait_ref = ty::TraitRef::new(tcx, tcx.lang_items().deref_trait()?, [ty]); - - let obligation = - traits::Obligation::new(tcx, cause.clone(), param_env, ty::Binder::dummy(trait_ref)); - if !self.infcx.predicate_may_hold(&obligation) { - return None; - } - - self.infcx.probe(|_| { - let ty = traits::normalize_projection_ty( - self, - param_env, - ty::AliasTy::new_from_args(tcx, tcx.lang_items().deref_target()?, trait_ref.args), - cause.clone(), - 0, - // We're *intentionally* throwing these away, - // since we don't actually use them. - &mut PredicateObligations::new(), - ) - .as_type() - .unwrap(); - - if let ty::Dynamic(data, ..) = ty.kind() { data.principal() } else { None } - }) - } - /// Searches for unsizing that might apply to `obligation`. fn assemble_candidates_for_unsizing( &mut self, @@ -1019,15 +967,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let principal_a = a_data.principal().unwrap(); let target_trait_did = principal_def_id_b.unwrap(); let source_trait_ref = principal_a.with_self_ty(self.tcx(), source); - if let Some(deref_trait_ref) = self.need_migrate_deref_output_trait_object( - source, - obligation.param_env, - &obligation.cause, - ) { - if deref_trait_ref.def_id() == target_trait_did { - return; - } - } for (idx, upcast_trait_ref) in util::supertraits(self.tcx(), source_trait_ref).enumerate() From a970a0d77e05d6303d86054c047795305618334c Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Mon, 16 Dec 2024 01:55:08 +0100 Subject: [PATCH 21/28] change `deref_into_dyn_supertrait` lint wording (so that it doesn't talk about trait upcasting stabilization in the future tense) --- compiler/rustc_lint/src/deref_into_dyn_supertrait.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs index 657642e093ccd..07f46aba05b34 100644 --- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs +++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs @@ -12,8 +12,9 @@ declare_lint! { /// The `deref_into_dyn_supertrait` lint is output whenever there is a use of the /// `Deref` implementation with a `dyn SuperTrait` type as `Output`. /// - /// These implementations will become shadowed when the `trait_upcasting` feature is stabilized. - /// The `deref` functions will no longer be called implicitly, so there might be behavior change. + /// These implementations are shadowed by the `trait_upcasting` feature (stabilized since + /// CURRENT_RUSTC_VERSION). The `deref` functions is no longer called implicitly, which might + /// be behavior change compared to previous rustc versions. /// /// ### Example /// @@ -43,11 +44,11 @@ declare_lint! { /// /// ### Explanation /// - /// The dyn upcasting coercion feature adds new coercion rules, taking priority - /// over certain other coercion rules, which will cause some behavior change. + /// The dyn upcasting coercion feature added a new coercion rules, taking priority + /// over certain other coercion rules, which caused some behavior change. pub DEREF_INTO_DYN_SUPERTRAIT, Warn, - "`Deref` implementation usage with a supertrait trait object for output might be shadowed in the future", + "`Deref` implementation usage with a supertrait trait object for output is shadowed by trait upcasting", @future_incompatible = FutureIncompatibleInfo { reason: FutureIncompatibilityReason::FutureReleaseSemanticsChange, reference: "issue #89460 ", From e9d5d1113f9a5ca0ace2d1b13b1525f43ec97211 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Mon, 16 Dec 2024 02:29:00 +0100 Subject: [PATCH 22/28] remove `feature(trait_upcasting)` from tests and bless them --- tests/codegen/vtable-upcast.rs | 1 - tests/crashes/131886.rs | 2 +- tests/ui/codegen/issue-99551.rs | 1 - .../ui/dyn-star/no-unsize-coerce-dyn-trait.rs | 4 +-- .../no-unsize-coerce-dyn-trait.stderr | 11 +----- tests/ui/dyn-star/upcast.rs | 2 +- tests/ui/dyn-star/upcast.stderr | 2 +- .../feature-gate-trait_upcasting.rs | 13 ------- .../feature-gate-trait_upcasting.stderr | 14 -------- .../impl-trait/unsized_coercion5.old.stderr | 2 +- tests/ui/impl-trait/unsized_coercion5.rs | 2 -- tests/ui/sanitizer/cfi/supertraits.rs | 1 - .../normalize/normalize-unsize-rhs.rs | 1 - .../trait-upcast-lhs-needs-normalization.rs | 1 - .../traits/next-solver/upcast-right-substs.rs | 1 - .../add-supertrait-auto-traits.rs | 2 -- .../alias-where-clause-isnt-supertrait.rs | 1 - .../alias-where-clause-isnt-supertrait.stderr | 2 +- tests/ui/traits/trait-upcasting/basic.rs | 2 -- .../correct-supertrait-substitution.rs | 1 - .../deref-upcast-behavioral-change.rs | 35 ------------------- .../deref-upcast-behavioral-change.stderr | 19 ---------- tests/ui/traits/trait-upcasting/diamond.rs | 2 -- .../trait-upcasting/fewer-associated.rs | 2 -- .../higher-ranked-upcasting-ok.rs | 2 -- .../higher-ranked-upcasting-ub.rs | 2 +- .../illegal-upcast-from-impl.current.stderr | 2 +- .../illegal-upcast-from-impl.next.stderr | 2 +- .../illegal-upcast-from-impl.rs | 2 -- .../illegal-upcast-to-impl-opaque.rs | 2 -- .../inference-behavior-change-deref.rs | 5 +-- .../inference-behavior-change-deref.stderr | 2 +- .../traits/trait-upcasting/invalid-upcast.rs | 2 -- .../trait-upcasting/invalid-upcast.stderr | 30 ++++++++-------- .../issue-11515-upcast-fn_mut-fn.rs | 1 - .../issue-11515.current.stderr | 14 -------- .../trait-upcasting/issue-11515.next.stderr | 14 -------- .../ui/traits/trait-upcasting/issue-11515.rs | 3 +- tests/ui/traits/trait-upcasting/lifetime.rs | 2 -- .../ui/traits/trait-upcasting/lifetime.stderr | 4 +-- .../traits/trait-upcasting/mono-impossible.rs | 2 -- .../multiple-occurrence-ambiguousity.rs | 1 - .../multiple-occurrence-ambiguousity.stderr | 2 +- .../multiple-supertraits-modulo-binder.rs | 6 ++-- ...supertraits-modulo-normalization-vtable.rs | 1 - ...rtraits-modulo-normalization-vtable.stderr | 4 +-- ...ltiple-supertraits-modulo-normalization.rs | 6 ++-- .../traits/trait-upcasting/normalization.rs | 2 -- .../prefer-lower-candidates.rs | 2 -- .../ui/traits/trait-upcasting/replace-vptr.rs | 2 -- .../trait-upcasting/replace-vptr.stderr | 4 +-- tests/ui/traits/trait-upcasting/struct.rs | 2 -- .../traits/trait-upcasting/subtrait-method.rs | 2 -- .../trait-upcasting/subtrait-method.stderr | 20 +++++------ .../supertraits-modulo-inner-binder.rs | 2 -- .../type-checking-test-1.current.stderr | 2 +- .../type-checking-test-1.next.stderr | 2 +- .../trait-upcasting/type-checking-test-1.rs | 2 -- .../trait-upcasting/type-checking-test-2.rs | 2 -- .../type-checking-test-2.stderr | 4 +-- .../trait-upcasting/type-checking-test-3.rs | 2 -- .../type-checking-test-3.stderr | 4 +-- .../trait-upcasting/type-checking-test-4.rs | 2 -- .../type-checking-test-4.stderr | 12 +++---- .../type-checking-test-opaques.rs | 2 +- .../trait-upcasting/upcast-defining-opaque.rs | 2 +- .../upcast-through-struct-tail.current.stderr | 14 -------- .../upcast-through-struct-tail.next.stderr | 14 -------- .../upcast-through-struct-tail.rs | 2 +- tests/ui/traits/upcast_reorder.rs | 2 -- tests/ui/traits/upcast_soundness_bug.rs | 1 - tests/ui/traits/upcast_soundness_bug.stderr | 2 +- 72 files changed, 67 insertions(+), 275 deletions(-) delete mode 100644 tests/ui/feature-gates/feature-gate-trait_upcasting.rs delete mode 100644 tests/ui/feature-gates/feature-gate-trait_upcasting.stderr delete mode 100644 tests/ui/traits/trait-upcasting/deref-upcast-behavioral-change.rs delete mode 100644 tests/ui/traits/trait-upcasting/deref-upcast-behavioral-change.stderr delete mode 100644 tests/ui/traits/trait-upcasting/issue-11515.current.stderr delete mode 100644 tests/ui/traits/trait-upcasting/issue-11515.next.stderr delete mode 100644 tests/ui/traits/trait-upcasting/upcast-through-struct-tail.current.stderr delete mode 100644 tests/ui/traits/trait-upcasting/upcast-through-struct-tail.next.stderr diff --git a/tests/codegen/vtable-upcast.rs b/tests/codegen/vtable-upcast.rs index ae7b4bf7aee9a..9e13e8dd68ac6 100644 --- a/tests/codegen/vtable-upcast.rs +++ b/tests/codegen/vtable-upcast.rs @@ -2,7 +2,6 @@ //@ compile-flags: -C no-prepopulate-passes -Copt-level=0 #![crate_type = "lib"] -#![feature(trait_upcasting)] pub trait Base { fn base(&self); diff --git a/tests/crashes/131886.rs b/tests/crashes/131886.rs index c31c2d6aa8bd7..2c692dfb7771b 100644 --- a/tests/crashes/131886.rs +++ b/tests/crashes/131886.rs @@ -1,6 +1,6 @@ //@ known-bug: #131886 //@ compile-flags: -Zvalidate-mir --crate-type=lib -#![feature(trait_upcasting, type_alias_impl_trait)] +#![feature(type_alias_impl_trait)] type Tait = impl Sized; diff --git a/tests/ui/codegen/issue-99551.rs b/tests/ui/codegen/issue-99551.rs index 9bacbaa6edc72..f498718310d82 100644 --- a/tests/ui/codegen/issue-99551.rs +++ b/tests/ui/codegen/issue-99551.rs @@ -1,5 +1,4 @@ //@ build-pass -#![feature(trait_upcasting)] pub trait A {} pub trait B {} diff --git a/tests/ui/dyn-star/no-unsize-coerce-dyn-trait.rs b/tests/ui/dyn-star/no-unsize-coerce-dyn-trait.rs index a4eb669e32104..1702fc1ed490e 100644 --- a/tests/ui/dyn-star/no-unsize-coerce-dyn-trait.rs +++ b/tests/ui/dyn-star/no-unsize-coerce-dyn-trait.rs @@ -1,5 +1,5 @@ -#![feature(dyn_star, trait_upcasting)] -//~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes +#![expect(incomplete_features)] +#![feature(dyn_star)] trait A: B {} trait B {} diff --git a/tests/ui/dyn-star/no-unsize-coerce-dyn-trait.stderr b/tests/ui/dyn-star/no-unsize-coerce-dyn-trait.stderr index 1f7bfb1d5bdc5..289d85072e615 100644 --- a/tests/ui/dyn-star/no-unsize-coerce-dyn-trait.stderr +++ b/tests/ui/dyn-star/no-unsize-coerce-dyn-trait.stderr @@ -1,12 +1,3 @@ -warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/no-unsize-coerce-dyn-trait.rs:1:12 - | -LL | #![feature(dyn_star, trait_upcasting)] - | ^^^^^^^^ - | - = note: see issue #102425 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types --> $DIR/no-unsize-coerce-dyn-trait.rs:11:26 | @@ -18,6 +9,6 @@ LL | let y: Box = x; = note: expected struct `Box` found struct `Box` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/dyn-star/upcast.rs b/tests/ui/dyn-star/upcast.rs index e8e89fc5101b1..01e1b94f87e27 100644 --- a/tests/ui/dyn-star/upcast.rs +++ b/tests/ui/dyn-star/upcast.rs @@ -1,6 +1,6 @@ //@ known-bug: #104800 -#![feature(dyn_star, trait_upcasting)] +#![feature(dyn_star)] trait Foo: Bar { fn hello(&self); diff --git a/tests/ui/dyn-star/upcast.stderr b/tests/ui/dyn-star/upcast.stderr index 801e1c233c1ae..3f244d4b6ae8d 100644 --- a/tests/ui/dyn-star/upcast.stderr +++ b/tests/ui/dyn-star/upcast.stderr @@ -1,7 +1,7 @@ warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/upcast.rs:3:12 | -LL | #![feature(dyn_star, trait_upcasting)] +LL | #![feature(dyn_star)] | ^^^^^^^^ | = note: see issue #102425 for more information diff --git a/tests/ui/feature-gates/feature-gate-trait_upcasting.rs b/tests/ui/feature-gates/feature-gate-trait_upcasting.rs deleted file mode 100644 index e4102f1cfa75d..0000000000000 --- a/tests/ui/feature-gates/feature-gate-trait_upcasting.rs +++ /dev/null @@ -1,13 +0,0 @@ -trait Foo {} - -trait Bar: Foo {} - -impl Foo for () {} - -impl Bar for () {} - -fn main() { - let bar: &dyn Bar = &(); - let foo: &dyn Foo = bar; - //~^ ERROR trait upcasting coercion is experimental [E0658] -} diff --git a/tests/ui/feature-gates/feature-gate-trait_upcasting.stderr b/tests/ui/feature-gates/feature-gate-trait_upcasting.stderr deleted file mode 100644 index 6fd277ae8cc3e..0000000000000 --- a/tests/ui/feature-gates/feature-gate-trait_upcasting.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0658]: cannot cast `dyn Bar` to `dyn Foo`, trait upcasting coercion is experimental - --> $DIR/feature-gate-trait_upcasting.rs:11:25 - | -LL | let foo: &dyn Foo = bar; - | ^^^ - | - = note: see issue #65991 for more information - = help: add `#![feature(trait_upcasting)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: required when coercing `&dyn Bar` into `&dyn Foo` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/impl-trait/unsized_coercion5.old.stderr b/tests/ui/impl-trait/unsized_coercion5.old.stderr index e56c026b037c6..72aa92ef6b9c8 100644 --- a/tests/ui/impl-trait/unsized_coercion5.old.stderr +++ b/tests/ui/impl-trait/unsized_coercion5.old.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time - --> $DIR/unsized_coercion5.rs:17:32 + --> $DIR/unsized_coercion5.rs:15:32 | LL | let y: Box = x as Box; | ^ doesn't have a size known at compile-time diff --git a/tests/ui/impl-trait/unsized_coercion5.rs b/tests/ui/impl-trait/unsized_coercion5.rs index 81f8a6afe9ac1..51ae4f20671e0 100644 --- a/tests/ui/impl-trait/unsized_coercion5.rs +++ b/tests/ui/impl-trait/unsized_coercion5.rs @@ -5,8 +5,6 @@ //@[next] compile-flags: -Znext-solver //@[next] check-pass -#![feature(trait_upcasting)] - trait Trait {} impl Trait for u32 {} diff --git a/tests/ui/sanitizer/cfi/supertraits.rs b/tests/ui/sanitizer/cfi/supertraits.rs index 4bb6177577f7c..f80b316918804 100644 --- a/tests/ui/sanitizer/cfi/supertraits.rs +++ b/tests/ui/sanitizer/cfi/supertraits.rs @@ -1,4 +1,3 @@ -#![feature(trait_upcasting)] // Check that super-traits are callable. //@ revisions: cfi kcfi diff --git a/tests/ui/traits/next-solver/normalize/normalize-unsize-rhs.rs b/tests/ui/traits/next-solver/normalize/normalize-unsize-rhs.rs index dc5912b123a46..bbf9bafde9ff0 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-unsize-rhs.rs +++ b/tests/ui/traits/next-solver/normalize/normalize-unsize-rhs.rs @@ -1,6 +1,5 @@ //@ compile-flags: -Znext-solver //@ check-pass -#![feature(trait_upcasting)] trait A {} trait B: A {} diff --git a/tests/ui/traits/next-solver/trait-upcast-lhs-needs-normalization.rs b/tests/ui/traits/next-solver/trait-upcast-lhs-needs-normalization.rs index ee6a7a0986dd6..c6094b4577553 100644 --- a/tests/ui/traits/next-solver/trait-upcast-lhs-needs-normalization.rs +++ b/tests/ui/traits/next-solver/trait-upcast-lhs-needs-normalization.rs @@ -1,6 +1,5 @@ //@ check-pass //@ compile-flags: -Znext-solver -#![feature(trait_upcasting)] pub trait A {} pub trait B: A {} diff --git a/tests/ui/traits/next-solver/upcast-right-substs.rs b/tests/ui/traits/next-solver/upcast-right-substs.rs index bbb8a039aa7fe..7a566b59b837c 100644 --- a/tests/ui/traits/next-solver/upcast-right-substs.rs +++ b/tests/ui/traits/next-solver/upcast-right-substs.rs @@ -1,6 +1,5 @@ //@ compile-flags: -Znext-solver //@ check-pass -#![feature(trait_upcasting)] trait Foo: Bar + Bar {} diff --git a/tests/ui/traits/trait-upcasting/add-supertrait-auto-traits.rs b/tests/ui/traits/trait-upcasting/add-supertrait-auto-traits.rs index ffc21a4a9ea50..5b22fce6311bd 100644 --- a/tests/ui/traits/trait-upcasting/add-supertrait-auto-traits.rs +++ b/tests/ui/traits/trait-upcasting/add-supertrait-auto-traits.rs @@ -3,8 +3,6 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(trait_upcasting)] - trait Target {} trait Source: Send + Target {} diff --git a/tests/ui/traits/trait-upcasting/alias-where-clause-isnt-supertrait.rs b/tests/ui/traits/trait-upcasting/alias-where-clause-isnt-supertrait.rs index 4a5e445d1efbe..927a9d6b94f8a 100644 --- a/tests/ui/traits/trait-upcasting/alias-where-clause-isnt-supertrait.rs +++ b/tests/ui/traits/trait-upcasting/alias-where-clause-isnt-supertrait.rs @@ -1,4 +1,3 @@ -#![feature(trait_upcasting)] #![feature(trait_alias)] // Although we *elaborate* `T: Alias` to `i32: B`, we should diff --git a/tests/ui/traits/trait-upcasting/alias-where-clause-isnt-supertrait.stderr b/tests/ui/traits/trait-upcasting/alias-where-clause-isnt-supertrait.stderr index 99c82b88d9c38..1a410519a4edc 100644 --- a/tests/ui/traits/trait-upcasting/alias-where-clause-isnt-supertrait.stderr +++ b/tests/ui/traits/trait-upcasting/alias-where-clause-isnt-supertrait.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/alias-where-clause-isnt-supertrait.rs:27:5 + --> $DIR/alias-where-clause-isnt-supertrait.rs:26:5 | LL | fn test(x: &dyn C) -> &dyn B { | ------ expected `&dyn B` because of return type diff --git a/tests/ui/traits/trait-upcasting/basic.rs b/tests/ui/traits/trait-upcasting/basic.rs index 9b9669565bac4..0a8d16a42dd4d 100644 --- a/tests/ui/traits/trait-upcasting/basic.rs +++ b/tests/ui/traits/trait-upcasting/basic.rs @@ -1,7 +1,5 @@ //@ run-pass -#![feature(trait_upcasting)] - trait Foo: PartialEq + std::fmt::Debug + Send + Sync { fn a(&self) -> i32 { 10 diff --git a/tests/ui/traits/trait-upcasting/correct-supertrait-substitution.rs b/tests/ui/traits/trait-upcasting/correct-supertrait-substitution.rs index 7f4343dbd2f16..0a02784f29cb7 100644 --- a/tests/ui/traits/trait-upcasting/correct-supertrait-substitution.rs +++ b/tests/ui/traits/trait-upcasting/correct-supertrait-substitution.rs @@ -1,5 +1,4 @@ //@ run-pass -#![feature(trait_upcasting)] trait Foo: Bar + Bar {} trait Bar { diff --git a/tests/ui/traits/trait-upcasting/deref-upcast-behavioral-change.rs b/tests/ui/traits/trait-upcasting/deref-upcast-behavioral-change.rs deleted file mode 100644 index e4784fa41011b..0000000000000 --- a/tests/ui/traits/trait-upcasting/deref-upcast-behavioral-change.rs +++ /dev/null @@ -1,35 +0,0 @@ -#![deny(deref_into_dyn_supertrait)] -use std::ops::Deref; - -trait Bar {} -impl Bar for T {} - -trait Foo: Bar { - fn as_dyn_bar_u32<'a>(&self) -> &(dyn Bar + 'a); -} - -impl Foo for () { - fn as_dyn_bar_u32<'a>(&self) -> &(dyn Bar + 'a) { - self - } -} - -impl<'a> Deref for dyn Foo + 'a { - //~^ ERROR this `Deref` implementation is covered by an implicit supertrait coercion - //~| WARN this will change its meaning in a future release! - type Target = dyn Bar + 'a; - - fn deref(&self) -> &Self::Target { - self.as_dyn_bar_u32() - } -} - -fn take_dyn(x: &dyn Bar) -> T { - todo!() -} - -fn main() { - let x: &dyn Foo = &(); - let y = take_dyn(x); - let z: u32 = y; -} diff --git a/tests/ui/traits/trait-upcasting/deref-upcast-behavioral-change.stderr b/tests/ui/traits/trait-upcasting/deref-upcast-behavioral-change.stderr deleted file mode 100644 index fa93e28c73bce..0000000000000 --- a/tests/ui/traits/trait-upcasting/deref-upcast-behavioral-change.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error: this `Deref` implementation is covered by an implicit supertrait coercion - --> $DIR/deref-upcast-behavioral-change.rs:17:1 - | -LL | impl<'a> Deref for dyn Foo + 'a { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo` implements `Deref>` which conflicts with supertrait `Bar` -... -LL | type Target = dyn Bar + 'a; - | -------------------------------- target type is a supertrait of `dyn Foo` - | - = warning: this will change its meaning in a future release! - = note: for more information, see issue #89460 -note: the lint level is defined here - --> $DIR/deref-upcast-behavioral-change.rs:1:9 - | -LL | #![deny(deref_into_dyn_supertrait)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/traits/trait-upcasting/diamond.rs b/tests/ui/traits/trait-upcasting/diamond.rs index 303c99b67bd00..c3f15a6d5822b 100644 --- a/tests/ui/traits/trait-upcasting/diamond.rs +++ b/tests/ui/traits/trait-upcasting/diamond.rs @@ -1,7 +1,5 @@ //@ run-pass -#![feature(trait_upcasting)] - trait Foo: PartialEq + std::fmt::Debug + Send + Sync { fn a(&self) -> i32 { 10 diff --git a/tests/ui/traits/trait-upcasting/fewer-associated.rs b/tests/ui/traits/trait-upcasting/fewer-associated.rs index 45e8673b85955..c2ea2a09d3a22 100644 --- a/tests/ui/traits/trait-upcasting/fewer-associated.rs +++ b/tests/ui/traits/trait-upcasting/fewer-associated.rs @@ -4,8 +4,6 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(trait_upcasting)] - trait A: B { type Assoc; } diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs index c4c070e49fdb7..9f9bf21b5a991 100644 --- a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs +++ b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs @@ -6,8 +6,6 @@ // Check that we are able to instantiate a binder during trait upcasting, // and that it doesn't cause any issues with codegen either. -#![feature(trait_upcasting)] - trait Supertrait<'a, 'b> {} trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {} diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.rs b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.rs index 2cf6fc75e7779..af2594b95f3d2 100644 --- a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.rs +++ b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.rs @@ -5,7 +5,7 @@ // We previously wrongly instantiated binders during trait upcasting, // allowing the super trait to be more generic than the sub trait. // This was unsound. -#![feature(trait_upcasting)] + trait Supertrait<'a, 'b> { fn cast(&self, x: &'a str) -> &'b str; } diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.current.stderr b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.current.stderr index 28be189ff1e1c..596380b0dbb99 100644 --- a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.current.stderr +++ b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.current.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/illegal-upcast-from-impl.rs:17:66 + --> $DIR/illegal-upcast-from-impl.rs:15:66 | LL | fn illegal(x: &dyn Sub) -> &dyn Super { x } | ----------------------- ^ expected trait `Super`, found trait `Sub` diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.next.stderr b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.next.stderr index 28be189ff1e1c..596380b0dbb99 100644 --- a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.next.stderr +++ b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.next.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/illegal-upcast-from-impl.rs:17:66 + --> $DIR/illegal-upcast-from-impl.rs:15:66 | LL | fn illegal(x: &dyn Sub) -> &dyn Super { x } | ----------------------- ^ expected trait `Super`, found trait `Sub` diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs index 0c771db412157..43ec4ece42977 100644 --- a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs +++ b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs @@ -2,8 +2,6 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(trait_upcasting)] - trait Super { type Assoc; } diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs b/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs index d0418e75fab21..2760c1696b56d 100644 --- a/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs +++ b/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs @@ -9,8 +9,6 @@ //@[next] rustc-env:RUST_BACKTRACE=0 //@ check-pass -#![feature(trait_upcasting)] - trait Super { type Assoc; } diff --git a/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.rs b/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.rs index 79fb643eacd01..0103aaa2ac996 100644 --- a/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.rs +++ b/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.rs @@ -1,6 +1,3 @@ -#![deny(deref_into_dyn_supertrait)] -#![feature(trait_upcasting)] // remove this and the test compiles - use std::ops::Deref; trait Bar {} @@ -32,5 +29,5 @@ fn main() { let x: &dyn Foo = &(); let y = take_dyn(x); let z: u32 = y; - //~^ ERROR mismatched types + //~^ error: mismatched types } diff --git a/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.stderr b/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.stderr index 6b6a26d1593fb..45eabbc723a6b 100644 --- a/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.stderr +++ b/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/inference-behavior-change-deref.rs:34:18 + --> $DIR/inference-behavior-change-deref.rs:31:18 | LL | let z: u32 = y; | --- ^ expected `u32`, found `i32` diff --git a/tests/ui/traits/trait-upcasting/invalid-upcast.rs b/tests/ui/traits/trait-upcasting/invalid-upcast.rs index e634bbd5ac6f5..9269a5e3e9ff6 100644 --- a/tests/ui/traits/trait-upcasting/invalid-upcast.rs +++ b/tests/ui/traits/trait-upcasting/invalid-upcast.rs @@ -1,5 +1,3 @@ -#![feature(trait_upcasting)] - trait Foo { fn a(&self) -> i32 { 10 diff --git a/tests/ui/traits/trait-upcasting/invalid-upcast.stderr b/tests/ui/traits/trait-upcasting/invalid-upcast.stderr index 3aa21ee3dddfb..e70b99d28c7e4 100644 --- a/tests/ui/traits/trait-upcasting/invalid-upcast.stderr +++ b/tests/ui/traits/trait-upcasting/invalid-upcast.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:53:35 + --> $DIR/invalid-upcast.rs:51:35 | LL | let _: &dyn std::fmt::Debug = baz; | -------------------- ^^^ expected trait `Debug`, found trait `Baz` @@ -10,7 +10,7 @@ LL | let _: &dyn std::fmt::Debug = baz; found reference `&dyn Baz` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:55:24 + --> $DIR/invalid-upcast.rs:53:24 | LL | let _: &dyn Send = baz; | --------- ^^^ expected trait `Send`, found trait `Baz` @@ -21,7 +21,7 @@ LL | let _: &dyn Send = baz; found reference `&dyn Baz` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:57:24 + --> $DIR/invalid-upcast.rs:55:24 | LL | let _: &dyn Sync = baz; | --------- ^^^ expected trait `Sync`, found trait `Baz` @@ -32,7 +32,7 @@ LL | let _: &dyn Sync = baz; found reference `&dyn Baz` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:60:25 + --> $DIR/invalid-upcast.rs:58:25 | LL | let bar: &dyn Bar = baz; | -------- ^^^ expected trait `Bar`, found trait `Baz` @@ -43,7 +43,7 @@ LL | let bar: &dyn Bar = baz; found reference `&dyn Baz` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:62:35 + --> $DIR/invalid-upcast.rs:60:35 | LL | let _: &dyn std::fmt::Debug = bar; | -------------------- ^^^ expected trait `Debug`, found trait `Bar` @@ -54,7 +54,7 @@ LL | let _: &dyn std::fmt::Debug = bar; found reference `&dyn Bar` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:64:24 + --> $DIR/invalid-upcast.rs:62:24 | LL | let _: &dyn Send = bar; | --------- ^^^ expected trait `Send`, found trait `Bar` @@ -65,7 +65,7 @@ LL | let _: &dyn Send = bar; found reference `&dyn Bar` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:66:24 + --> $DIR/invalid-upcast.rs:64:24 | LL | let _: &dyn Sync = bar; | --------- ^^^ expected trait `Sync`, found trait `Bar` @@ -76,7 +76,7 @@ LL | let _: &dyn Sync = bar; found reference `&dyn Bar` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:69:25 + --> $DIR/invalid-upcast.rs:67:25 | LL | let foo: &dyn Foo = baz; | -------- ^^^ expected trait `Foo`, found trait `Baz` @@ -87,7 +87,7 @@ LL | let foo: &dyn Foo = baz; found reference `&dyn Baz` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:71:35 + --> $DIR/invalid-upcast.rs:69:35 | LL | let _: &dyn std::fmt::Debug = foo; | -------------------- ^^^ expected trait `Debug`, found trait `Foo` @@ -98,7 +98,7 @@ LL | let _: &dyn std::fmt::Debug = foo; found reference `&dyn Foo` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:73:24 + --> $DIR/invalid-upcast.rs:71:24 | LL | let _: &dyn Send = foo; | --------- ^^^ expected trait `Send`, found trait `Foo` @@ -109,7 +109,7 @@ LL | let _: &dyn Send = foo; found reference `&dyn Foo` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:75:24 + --> $DIR/invalid-upcast.rs:73:24 | LL | let _: &dyn Sync = foo; | --------- ^^^ expected trait `Sync`, found trait `Foo` @@ -120,7 +120,7 @@ LL | let _: &dyn Sync = foo; found reference `&dyn Foo` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:78:25 + --> $DIR/invalid-upcast.rs:76:25 | LL | let foo: &dyn Foo = bar; | -------- ^^^ expected trait `Foo`, found trait `Bar` @@ -131,7 +131,7 @@ LL | let foo: &dyn Foo = bar; found reference `&dyn Bar` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:80:35 + --> $DIR/invalid-upcast.rs:78:35 | LL | let _: &dyn std::fmt::Debug = foo; | -------------------- ^^^ expected trait `Debug`, found trait `Foo` @@ -142,7 +142,7 @@ LL | let _: &dyn std::fmt::Debug = foo; found reference `&dyn Foo` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:82:24 + --> $DIR/invalid-upcast.rs:80:24 | LL | let _: &dyn Send = foo; | --------- ^^^ expected trait `Send`, found trait `Foo` @@ -153,7 +153,7 @@ LL | let _: &dyn Send = foo; found reference `&dyn Foo` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:84:24 + --> $DIR/invalid-upcast.rs:82:24 | LL | let _: &dyn Sync = foo; | --------- ^^^ expected trait `Sync`, found trait `Foo` diff --git a/tests/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs b/tests/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs index ef3d366c38139..8bf32efbe2e91 100644 --- a/tests/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs +++ b/tests/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs @@ -1,5 +1,4 @@ //@ run-pass -#![feature(trait_upcasting)] struct Test { func: Box, diff --git a/tests/ui/traits/trait-upcasting/issue-11515.current.stderr b/tests/ui/traits/trait-upcasting/issue-11515.current.stderr deleted file mode 100644 index 8ce7d46012fd6..0000000000000 --- a/tests/ui/traits/trait-upcasting/issue-11515.current.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0658]: cannot cast `dyn Fn()` to `dyn FnMut()`, trait upcasting coercion is experimental - --> $DIR/issue-11515.rs:11:38 - | -LL | let test = Box::new(Test { func: closure }); - | ^^^^^^^ - | - = note: see issue #65991 for more information - = help: add `#![feature(trait_upcasting)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: required when coercing `Box<(dyn Fn() + 'static)>` into `Box<(dyn FnMut() + 'static)>` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/trait-upcasting/issue-11515.next.stderr b/tests/ui/traits/trait-upcasting/issue-11515.next.stderr deleted file mode 100644 index 8ce7d46012fd6..0000000000000 --- a/tests/ui/traits/trait-upcasting/issue-11515.next.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0658]: cannot cast `dyn Fn()` to `dyn FnMut()`, trait upcasting coercion is experimental - --> $DIR/issue-11515.rs:11:38 - | -LL | let test = Box::new(Test { func: closure }); - | ^^^^^^^ - | - = note: see issue #65991 for more information - = help: add `#![feature(trait_upcasting)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: required when coercing `Box<(dyn Fn() + 'static)>` into `Box<(dyn FnMut() + 'static)>` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/trait-upcasting/issue-11515.rs b/tests/ui/traits/trait-upcasting/issue-11515.rs index d251e804c3ea2..3b1f0a19cb9c4 100644 --- a/tests/ui/traits/trait-upcasting/issue-11515.rs +++ b/tests/ui/traits/trait-upcasting/issue-11515.rs @@ -1,3 +1,4 @@ +//@ check-pass //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver @@ -8,5 +9,5 @@ struct Test { fn main() { let closure: Box = Box::new(|| ()); - let test = Box::new(Test { func: closure }); //~ ERROR trait upcasting coercion is experimental [E0658] + let test = Box::new(Test { func: closure }); } diff --git a/tests/ui/traits/trait-upcasting/lifetime.rs b/tests/ui/traits/trait-upcasting/lifetime.rs index ab006f8bedcea..a3cbfd777a0f9 100644 --- a/tests/ui/traits/trait-upcasting/lifetime.rs +++ b/tests/ui/traits/trait-upcasting/lifetime.rs @@ -1,7 +1,5 @@ //@ run-pass -#![feature(trait_upcasting)] - trait Foo: PartialEq + std::fmt::Debug + Send + Sync { fn a(&self) -> i32 { 10 diff --git a/tests/ui/traits/trait-upcasting/lifetime.stderr b/tests/ui/traits/trait-upcasting/lifetime.stderr index ca8f9cf63f3e7..589e9816d5adc 100644 --- a/tests/ui/traits/trait-upcasting/lifetime.stderr +++ b/tests/ui/traits/trait-upcasting/lifetime.stderr @@ -1,5 +1,5 @@ warning: methods `z` and `y` are never used - --> $DIR/lifetime.rs:10:8 + --> $DIR/lifetime.rs:8:8 | LL | trait Foo: PartialEq + std::fmt::Debug + Send + Sync { | --- methods in this trait @@ -13,7 +13,7 @@ LL | fn y(&self) -> i32 { = note: `#[warn(dead_code)]` on by default warning: method `w` is never used - --> $DIR/lifetime.rs:24:8 + --> $DIR/lifetime.rs:22:8 | LL | trait Bar: Foo { | --- method in this trait diff --git a/tests/ui/traits/trait-upcasting/mono-impossible.rs b/tests/ui/traits/trait-upcasting/mono-impossible.rs index 88f19e1c95f8e..f19f0538efa70 100644 --- a/tests/ui/traits/trait-upcasting/mono-impossible.rs +++ b/tests/ui/traits/trait-upcasting/mono-impossible.rs @@ -1,7 +1,5 @@ //@ build-pass -#![feature(trait_upcasting)] - trait Supertrait { fn method(&self) {} } diff --git a/tests/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs b/tests/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs index 754437a3bec77..0bf0d14c259da 100644 --- a/tests/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs +++ b/tests/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs @@ -1,5 +1,4 @@ //@ check-fail -#![feature(trait_upcasting)] trait Bar { fn bar(&self, _: T) {} diff --git a/tests/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr b/tests/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr index 70ba1fcaf3838..c888ccc1ebb0d 100644 --- a/tests/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr +++ b/tests/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/multiple-occurrence-ambiguousity.rs:20:26 + --> $DIR/multiple-occurrence-ambiguousity.rs:19:26 | LL | let t: &dyn Bar<_> = s; | ----------- ^ expected trait `Bar`, found trait `Foo` diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder.rs b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder.rs index 510a1471af293..a0bb1c57adbc0 100644 --- a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder.rs +++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder.rs @@ -1,10 +1,8 @@ +// Test for . +// //@ run-pass //@ check-run-results -// Test for . - -#![feature(trait_upcasting)] - trait Supertrait { fn _print_numbers(&self, mem: &[usize; 100]) { println!("{mem:?}"); diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.rs b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.rs index 69a71859a5cc7..6b9ddf9bedcd5 100644 --- a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.rs +++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.rs @@ -1,5 +1,4 @@ #![feature(rustc_attrs)] -#![feature(trait_upcasting)] // Test for . diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.stderr b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.stderr index 757e2dc69390c..04b1afae7beca 100644 --- a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.stderr +++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.stderr @@ -5,7 +5,7 @@ error: vtable entries: [ Method(<() as Supertrait<()>>::_print_numbers), Method(<() as Middle<()>>::say_hello), ] - --> $DIR/multiple-supertraits-modulo-normalization-vtable.rs:30:1 + --> $DIR/multiple-supertraits-modulo-normalization-vtable.rs:29:1 | LL | impl Trait for () {} | ^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ error: vtable entries: [ Method( as Supertrait<()>>::_print_numbers - shim(reify)), Method( as Middle<()>>::say_hello - shim(reify)), ] - --> $DIR/multiple-supertraits-modulo-normalization-vtable.rs:34:1 + --> $DIR/multiple-supertraits-modulo-normalization-vtable.rs:33:1 | LL | type Virtual = dyn Middle<()>; | ^^^^^^^^^^^^ diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization.rs b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization.rs index c744e6e64f575..08ec49971ac4a 100644 --- a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization.rs +++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization.rs @@ -1,10 +1,8 @@ +// Test for . +// //@ run-pass //@ check-run-results -#![feature(trait_upcasting)] - -// Test for . - trait Supertrait { fn _print_numbers(&self, mem: &[usize; 100]) { println!("{mem:?}"); diff --git a/tests/ui/traits/trait-upcasting/normalization.rs b/tests/ui/traits/trait-upcasting/normalization.rs index ae5a6a5243c86..b714479961ff8 100644 --- a/tests/ui/traits/trait-upcasting/normalization.rs +++ b/tests/ui/traits/trait-upcasting/normalization.rs @@ -4,8 +4,6 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(trait_upcasting)] - trait Mirror { type Assoc; } diff --git a/tests/ui/traits/trait-upcasting/prefer-lower-candidates.rs b/tests/ui/traits/trait-upcasting/prefer-lower-candidates.rs index 4bc59b09fb5af..09557ba0260d5 100644 --- a/tests/ui/traits/trait-upcasting/prefer-lower-candidates.rs +++ b/tests/ui/traits/trait-upcasting/prefer-lower-candidates.rs @@ -6,8 +6,6 @@ // Ensure we don't have ambiguity when upcasting to two supertraits // that are identical modulo normalization. -#![feature(trait_upcasting)] - trait Supertrait { fn method(&self) {} } diff --git a/tests/ui/traits/trait-upcasting/replace-vptr.rs b/tests/ui/traits/trait-upcasting/replace-vptr.rs index 4829e3c5c1240..6ca5864669bc3 100644 --- a/tests/ui/traits/trait-upcasting/replace-vptr.rs +++ b/tests/ui/traits/trait-upcasting/replace-vptr.rs @@ -1,7 +1,5 @@ //@ run-pass -#![feature(trait_upcasting)] - trait A { fn foo_a(&self); //~ WARN method `foo_a` is never used } diff --git a/tests/ui/traits/trait-upcasting/replace-vptr.stderr b/tests/ui/traits/trait-upcasting/replace-vptr.stderr index 823094761b385..1a8bfd1bfa6e5 100644 --- a/tests/ui/traits/trait-upcasting/replace-vptr.stderr +++ b/tests/ui/traits/trait-upcasting/replace-vptr.stderr @@ -1,5 +1,5 @@ warning: method `foo_a` is never used - --> $DIR/replace-vptr.rs:6:8 + --> $DIR/replace-vptr.rs:4:8 | LL | trait A { | - method in this trait @@ -9,7 +9,7 @@ LL | fn foo_a(&self); = note: `#[warn(dead_code)]` on by default warning: method `foo_c` is never used - --> $DIR/replace-vptr.rs:14:8 + --> $DIR/replace-vptr.rs:12:8 | LL | trait C: A + B { | - method in this trait diff --git a/tests/ui/traits/trait-upcasting/struct.rs b/tests/ui/traits/trait-upcasting/struct.rs index 39da20259a043..51e6f006fbff9 100644 --- a/tests/ui/traits/trait-upcasting/struct.rs +++ b/tests/ui/traits/trait-upcasting/struct.rs @@ -1,7 +1,5 @@ //@ run-pass -#![feature(trait_upcasting)] - use std::rc::Rc; use std::sync::Arc; diff --git a/tests/ui/traits/trait-upcasting/subtrait-method.rs b/tests/ui/traits/trait-upcasting/subtrait-method.rs index 136d15af0e8b2..20277280440c5 100644 --- a/tests/ui/traits/trait-upcasting/subtrait-method.rs +++ b/tests/ui/traits/trait-upcasting/subtrait-method.rs @@ -1,5 +1,3 @@ -#![feature(trait_upcasting)] - trait Foo: PartialEq + std::fmt::Debug + Send + Sync { fn a(&self) -> i32 { 10 diff --git a/tests/ui/traits/trait-upcasting/subtrait-method.stderr b/tests/ui/traits/trait-upcasting/subtrait-method.stderr index 0408be6986bd7..a7658a7bcd3e4 100644 --- a/tests/ui/traits/trait-upcasting/subtrait-method.stderr +++ b/tests/ui/traits/trait-upcasting/subtrait-method.stderr @@ -1,12 +1,12 @@ error[E0599]: no method named `c` found for reference `&dyn Bar` in the current scope - --> $DIR/subtrait-method.rs:55:9 + --> $DIR/subtrait-method.rs:53:9 | LL | bar.c(); | ^ | = help: items from traits can only be used if the trait is implemented and in scope note: `Baz` defines an item `c`, perhaps you need to implement it - --> $DIR/subtrait-method.rs:27:1 + --> $DIR/subtrait-method.rs:25:1 | LL | trait Baz: Bar { | ^^^^^^^^^^^^^^ @@ -16,14 +16,14 @@ LL | bar.a(); | ~ error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope - --> $DIR/subtrait-method.rs:59:9 + --> $DIR/subtrait-method.rs:57:9 | LL | foo.b(); | ^ | = help: items from traits can only be used if the trait is implemented and in scope note: `Bar` defines an item `b`, perhaps you need to implement it - --> $DIR/subtrait-method.rs:17:1 + --> $DIR/subtrait-method.rs:15:1 | LL | trait Bar: Foo { | ^^^^^^^^^^^^^^ @@ -33,14 +33,14 @@ LL | foo.a(); | ~ error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope - --> $DIR/subtrait-method.rs:61:9 + --> $DIR/subtrait-method.rs:59:9 | LL | foo.c(); | ^ | = help: items from traits can only be used if the trait is implemented and in scope note: `Baz` defines an item `c`, perhaps you need to implement it - --> $DIR/subtrait-method.rs:27:1 + --> $DIR/subtrait-method.rs:25:1 | LL | trait Baz: Bar { | ^^^^^^^^^^^^^^ @@ -50,14 +50,14 @@ LL | foo.a(); | ~ error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope - --> $DIR/subtrait-method.rs:65:9 + --> $DIR/subtrait-method.rs:63:9 | LL | foo.b(); | ^ | = help: items from traits can only be used if the trait is implemented and in scope note: `Bar` defines an item `b`, perhaps you need to implement it - --> $DIR/subtrait-method.rs:17:1 + --> $DIR/subtrait-method.rs:15:1 | LL | trait Bar: Foo { | ^^^^^^^^^^^^^^ @@ -67,14 +67,14 @@ LL | foo.a(); | ~ error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope - --> $DIR/subtrait-method.rs:67:9 + --> $DIR/subtrait-method.rs:65:9 | LL | foo.c(); | ^ | = help: items from traits can only be used if the trait is implemented and in scope note: `Baz` defines an item `c`, perhaps you need to implement it - --> $DIR/subtrait-method.rs:27:1 + --> $DIR/subtrait-method.rs:25:1 | LL | trait Baz: Bar { | ^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/trait-upcasting/supertraits-modulo-inner-binder.rs b/tests/ui/traits/trait-upcasting/supertraits-modulo-inner-binder.rs index 6cd74b6c7f75f..e65cb60d993d9 100644 --- a/tests/ui/traits/trait-upcasting/supertraits-modulo-inner-binder.rs +++ b/tests/ui/traits/trait-upcasting/supertraits-modulo-inner-binder.rs @@ -1,7 +1,5 @@ //@ run-pass -#![feature(trait_upcasting)] - trait Super { fn call(&self) where diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.current.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-1.current.stderr index 9a9ad9bbf7739..2f27d1522a6e9 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-1.current.stderr +++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.current.stderr @@ -1,5 +1,5 @@ error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>` - --> $DIR/type-checking-test-1.rs:20:13 + --> $DIR/type-checking-test-1.rs:18:13 | LL | let _ = x as &dyn Bar<_>; // Ambiguous | ^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.next.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-1.next.stderr index 9a9ad9bbf7739..2f27d1522a6e9 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-1.next.stderr +++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.next.stderr @@ -1,5 +1,5 @@ error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>` - --> $DIR/type-checking-test-1.rs:20:13 + --> $DIR/type-checking-test-1.rs:18:13 | LL | let _ = x as &dyn Bar<_>; // Ambiguous | ^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.rs b/tests/ui/traits/trait-upcasting/type-checking-test-1.rs index fd902fd87e07c..b06f5e0452806 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-1.rs +++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.rs @@ -2,8 +2,6 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(trait_upcasting)] - trait Foo: Bar + Bar {} trait Bar { fn bar(&self) -> Option { diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-2.rs b/tests/ui/traits/trait-upcasting/type-checking-test-2.rs index b024b27750bc6..b4df0f5a90258 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-2.rs +++ b/tests/ui/traits/trait-upcasting/type-checking-test-2.rs @@ -1,5 +1,3 @@ -#![feature(trait_upcasting)] - trait Foo: Bar + Bar {} trait Bar { fn bar(&self) -> Option { diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr index 3e59b9d33634a..f84ea93dc6792 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr +++ b/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr @@ -1,11 +1,11 @@ error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar` - --> $DIR/type-checking-test-2.rs:19:13 + --> $DIR/type-checking-test-2.rs:17:13 | LL | let _ = x as &dyn Bar; // Error | ^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>` - --> $DIR/type-checking-test-2.rs:24:13 + --> $DIR/type-checking-test-2.rs:22:13 | LL | let a = x as &dyn Bar<_>; // Ambiguous | ^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-3.rs b/tests/ui/traits/trait-upcasting/type-checking-test-3.rs index b2db3a127974c..3685569d98d1a 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-3.rs +++ b/tests/ui/traits/trait-upcasting/type-checking-test-3.rs @@ -1,5 +1,3 @@ -#![feature(trait_upcasting)] - trait Foo<'a>: Bar<'a> {} trait Bar<'a> {} diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-3.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-3.stderr index 01b8da645f31a..d80649638ae33 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-3.stderr +++ b/tests/ui/traits/trait-upcasting/type-checking-test-3.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/type-checking-test-3.rs:11:13 + --> $DIR/type-checking-test-3.rs:9:13 | LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { | -- lifetime `'a` defined here @@ -7,7 +7,7 @@ LL | let _ = x as &dyn Bar<'a>; // Error | ^^^^^^^^^^^^^^^^^ cast requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-3.rs:16:18 + --> $DIR/type-checking-test-3.rs:14:18 | LL | fn test_wrong2<'a>(x: &dyn Foo<'a>) { | -- lifetime `'a` defined here diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-4.rs b/tests/ui/traits/trait-upcasting/type-checking-test-4.rs index 01759ec7a93c6..20de722ee9b7c 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-4.rs +++ b/tests/ui/traits/trait-upcasting/type-checking-test-4.rs @@ -1,5 +1,3 @@ -#![feature(trait_upcasting)] - trait Foo<'a>: Bar<'a, 'a> {} trait Bar<'a, 'b> { fn get_b(&self) -> Option<&'a u32> { diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr index e91ea193a0104..55a5e4cd4971f 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr +++ b/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:19:13 + --> $DIR/type-checking-test-4.rs:17:13 | LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { | -- lifetime `'a` defined here @@ -7,7 +7,7 @@ LL | let _ = x as &dyn Bar<'static, 'a>; // Error | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:24:18 + --> $DIR/type-checking-test-4.rs:22:18 | LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) { | -- lifetime `'a` defined here @@ -15,7 +15,7 @@ LL | let _ = x as &dyn Bar<'a, 'static>; // Error | ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:30:5 + --> $DIR/type-checking-test-4.rs:28:5 | LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | -- lifetime `'a` defined here @@ -24,7 +24,7 @@ LL | y.get_b() // ERROR | ^^^^^^^^^ returning this value requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:35:5 + --> $DIR/type-checking-test-4.rs:33:5 | LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | -- lifetime `'a` defined here @@ -32,7 +32,7 @@ LL | <_ as Bar>::get_b(x) // ERROR | ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:40:5 + --> $DIR/type-checking-test-4.rs:38:5 | LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | -- lifetime `'a` defined here @@ -40,7 +40,7 @@ LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:48:5 + --> $DIR/type-checking-test-4.rs:46:5 | LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | -- lifetime `'a` defined here diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs b/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs index a3a1ce29465b1..ab3817da28b1e 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs +++ b/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs @@ -1,4 +1,4 @@ -#![feature(trait_upcasting, type_alias_impl_trait)] +#![feature(type_alias_impl_trait)] //@ check-pass diff --git a/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs b/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs index 07f1549e177fb..0548eda046842 100644 --- a/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs +++ b/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs @@ -3,7 +3,7 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@check-pass -#![feature(trait_upcasting, type_alias_impl_trait)] +#![feature(type_alias_impl_trait)] trait Super { type Assoc; diff --git a/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.current.stderr b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.current.stderr deleted file mode 100644 index 239f82791944a..0000000000000 --- a/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.current.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0658]: cannot cast `dyn A` to `dyn B`, trait upcasting coercion is experimental - --> $DIR/upcast-through-struct-tail.rs:11:5 - | -LL | x - | ^ - | - = note: see issue #65991 for more information - = help: add `#![feature(trait_upcasting)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: required when coercing `Box>` into `Box>` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.next.stderr b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.next.stderr deleted file mode 100644 index 239f82791944a..0000000000000 --- a/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.next.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0658]: cannot cast `dyn A` to `dyn B`, trait upcasting coercion is experimental - --> $DIR/upcast-through-struct-tail.rs:11:5 - | -LL | x - | ^ - | - = note: see issue #65991 for more information - = help: add `#![feature(trait_upcasting)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: required when coercing `Box>` into `Box>` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs index e40cca4e0a837..dd4d91f8d4f24 100644 --- a/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs +++ b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs @@ -1,3 +1,4 @@ +//@ check-pass //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver @@ -9,7 +10,6 @@ trait B {} fn test<'a>(x: Box>) -> Box> { x - //~^ ERROR cannot cast `dyn A` to `dyn B`, trait upcasting coercion is experimental } fn main() {} diff --git a/tests/ui/traits/upcast_reorder.rs b/tests/ui/traits/upcast_reorder.rs index 55e6ad4c368d1..43fc1517a3b31 100644 --- a/tests/ui/traits/upcast_reorder.rs +++ b/tests/ui/traits/upcast_reorder.rs @@ -2,8 +2,6 @@ // // issue: -#![feature(trait_upcasting)] - trait Pollable { #[allow(unused)] fn poll(&self) {} diff --git a/tests/ui/traits/upcast_soundness_bug.rs b/tests/ui/traits/upcast_soundness_bug.rs index 0ddae1d1417c7..4c89fa135e788 100644 --- a/tests/ui/traits/upcast_soundness_bug.rs +++ b/tests/ui/traits/upcast_soundness_bug.rs @@ -1,4 +1,3 @@ -#![feature(trait_upcasting)] //@ check-fail // // issue: diff --git a/tests/ui/traits/upcast_soundness_bug.stderr b/tests/ui/traits/upcast_soundness_bug.stderr index 19d1a5e5926e0..f5fa6bdc9995b 100644 --- a/tests/ui/traits/upcast_soundness_bug.stderr +++ b/tests/ui/traits/upcast_soundness_bug.stderr @@ -1,5 +1,5 @@ error[E0606]: casting `*const dyn Trait` as `*const dyn Trait` is invalid - --> $DIR/upcast_soundness_bug.rs:59:13 + --> $DIR/upcast_soundness_bug.rs:58:13 | LL | let p = p as *const dyn Trait; // <- this is bad! | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 9e6d0b3700891b8a99ad762ba3de9e08dfb60b1d Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Mon, 16 Dec 2024 03:51:01 +0100 Subject: [PATCH 23/28] remove unstable book entry for `feature(trait_upcasting)` --- .../src/language-features/trait-upcasting.md | 26 ------------------- 1 file changed, 26 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/trait-upcasting.md diff --git a/src/doc/unstable-book/src/language-features/trait-upcasting.md b/src/doc/unstable-book/src/language-features/trait-upcasting.md deleted file mode 100644 index a5f99cc86f270..0000000000000 --- a/src/doc/unstable-book/src/language-features/trait-upcasting.md +++ /dev/null @@ -1,26 +0,0 @@ -# `trait_upcasting` - -The tracking issue for this feature is: [#65991] - -[#65991]: https://github.com/rust-lang/rust/issues/65991 - ------------------------- - -The `trait_upcasting` feature adds support for trait upcasting coercion. This allows a -trait object of type `dyn Bar` to be cast to a trait object of type `dyn Foo` -so long as `Bar: Foo`. - -```rust,edition2018 -#![feature(trait_upcasting)] - -trait Foo {} - -trait Bar: Foo {} - -impl Foo for i32 {} - -impl Bar for T {} - -let bar: &dyn Bar = &123; -let foo: &dyn Foo = bar; -``` From 3c94d3e60f86354f2adf3e7a621256bcec17afaa Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Mon, 16 Dec 2024 15:36:59 +0100 Subject: [PATCH 24/28] remove use of `feature(trait_upcasting)` from core tests --- library/coretests/tests/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 7fe7286260858..f1bbed3de3017 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -81,7 +81,6 @@ #![feature(strict_provenance_atomic_ptr)] #![feature(strict_provenance_lints)] #![feature(test)] -#![feature(trait_upcasting)] #![feature(trusted_len)] #![feature(trusted_random_access)] #![feature(try_blocks)] From fd945425d1ce5735d282f3780776474171c657e8 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Mon, 16 Dec 2024 14:57:22 +0100 Subject: [PATCH 25/28] remove use of `feature(trait_upcasting)` from miri --- src/tools/miri/src/lib.rs | 2 +- src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.rs | 3 --- src/tools/miri/tests/pass/box-custom-alloc.rs | 3 +-- src/tools/miri/tests/pass/dyn-upcast.rs | 3 --- 4 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 45054c37c40e9..a717d8ccf281a 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -1,3 +1,4 @@ +#![cfg_attr(bootstrap, feature(trait_upcasting))] #![feature(rustc_private)] #![feature(cell_update)] #![feature(float_gamma)] @@ -9,7 +10,6 @@ #![feature(yeet_expr)] #![feature(nonzero_ops)] #![feature(let_chains)] -#![feature(trait_upcasting)] #![feature(strict_overflow_ops)] #![feature(pointer_is_aligned_to)] #![feature(unqualified_local_imports)] diff --git a/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.rs b/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.rs index f450e7e652c51..1fd791a91f0f3 100644 --- a/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.rs +++ b/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.rs @@ -1,9 +1,6 @@ // Validation stops this too early. //@compile-flags: -Zmiri-disable-validation -#![feature(trait_upcasting)] -#![allow(incomplete_features)] - trait Foo: PartialEq + std::fmt::Debug + Send + Sync { #[allow(dead_code)] fn a(&self) -> i32 { diff --git a/src/tools/miri/tests/pass/box-custom-alloc.rs b/src/tools/miri/tests/pass/box-custom-alloc.rs index 71ce019187c44..f0614313e502e 100644 --- a/src/tools/miri/tests/pass/box-custom-alloc.rs +++ b/src/tools/miri/tests/pass/box-custom-alloc.rs @@ -1,7 +1,6 @@ //@revisions: stack tree //@[tree]compile-flags: -Zmiri-tree-borrows -#![allow(incomplete_features)] // for trait upcasting -#![feature(allocator_api, trait_upcasting)] +#![feature(allocator_api)] use std::alloc::{AllocError, Allocator, Layout}; use std::cell::Cell; diff --git a/src/tools/miri/tests/pass/dyn-upcast.rs b/src/tools/miri/tests/pass/dyn-upcast.rs index f100c4d6a869e..6f8adc09640ce 100644 --- a/src/tools/miri/tests/pass/dyn-upcast.rs +++ b/src/tools/miri/tests/pass/dyn-upcast.rs @@ -1,6 +1,3 @@ -#![feature(trait_upcasting)] -#![allow(incomplete_features)] - use std::fmt; fn main() { From bc1d68e389d000730084b8e3bfc3ba23b9450dd8 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 16 Jan 2025 15:45:59 +0100 Subject: [PATCH 26/28] adjust a comment We can't remove `TraitUpcasting` variant, since we need to use the index in winnowing. --- compiler/rustc_type_ir/src/solve/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index c06004d4d0f6c..a562b751d8a9c 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -179,9 +179,7 @@ pub enum BuiltinImplSource { Object(usize), /// A built-in implementation of `Upcast` for trait objects to other trait objects. /// - /// This can be removed when `feature(dyn_upcasting)` is stabilized, since we only - /// use it to detect when upcasting traits in hir typeck. The index is only used - /// for winnowing. + /// The index is only used for winnowing. TraitUpcasting(usize), /// Unsizing a tuple like `(A, B, ..., X)` to `(A, B, ..., Y)` if `X` unsizes to `Y`. /// From 491599569c081985d6cc3eb4ab55d692e380e938 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 6 Feb 2025 21:57:50 +0100 Subject: [PATCH 27/28] allow+update `deref_into_dyn_supertrait` this commit makes `deref_into_dyn_supertrait` lint allow-by-default, removes future incompatibility (we finally live in a broken world), and changes the wording in the documentation. previously documentation erroneously said that it lints against *usage* of the deref impl, while it actually (since 104742) lints on the impl itself (oooops, my oversight, should have updated it 2+ years ago...) --- .../src/deref_into_dyn_supertrait.rs | 24 ++++++++---------- .../deref-upcast-shadowing-lint.rs | 17 +++++++++++++ .../deref-upcast-shadowing-lint.stderr | 17 +++++++++++++ .../migrate-lint-deny-regions.rs | 6 ++--- .../migrate-lint-deny-regions.stderr | 14 +++++------ .../trait-upcasting/migrate-lint-deny.rs | 25 ------------------- .../trait-upcasting/migrate-lint-deny.stderr | 19 -------------- .../migrate-lint-different-substs.rs | 4 +-- .../migrate-lint-different-substs.stderr | 12 +++++---- 9 files changed, 63 insertions(+), 75 deletions(-) create mode 100644 tests/ui/traits/trait-upcasting/deref-upcast-shadowing-lint.rs create mode 100644 tests/ui/traits/trait-upcasting/deref-upcast-shadowing-lint.stderr delete mode 100644 tests/ui/traits/trait-upcasting/migrate-lint-deny.rs delete mode 100644 tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr diff --git a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs index 07f46aba05b34..181f44fb4de30 100644 --- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs +++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs @@ -1,6 +1,5 @@ use rustc_hir::{self as hir, LangItem}; use rustc_middle::ty; -use rustc_session::lint::FutureIncompatibilityReason; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::sym; use rustc_trait_selection::traits::supertraits; @@ -9,12 +8,12 @@ use crate::lints::{SupertraitAsDerefTarget, SupertraitAsDerefTargetLabel}; use crate::{LateContext, LateLintPass, LintContext}; declare_lint! { - /// The `deref_into_dyn_supertrait` lint is output whenever there is a use of the - /// `Deref` implementation with a `dyn SuperTrait` type as `Output`. + /// The `deref_into_dyn_supertrait` lint is emitted whenever there is a `Deref` implementation + /// for `dyn SubTrait` with a `dyn SuperTrait` type as the `Output` type. /// - /// These implementations are shadowed by the `trait_upcasting` feature (stabilized since + /// These implementations are "shadowed" by trait upcasting (stabilized since /// CURRENT_RUSTC_VERSION). The `deref` functions is no longer called implicitly, which might - /// be behavior change compared to previous rustc versions. + /// change behavior compared to previous rustc versions. /// /// ### Example /// @@ -44,15 +43,14 @@ declare_lint! { /// /// ### Explanation /// - /// The dyn upcasting coercion feature added a new coercion rules, taking priority - /// over certain other coercion rules, which caused some behavior change. + /// The trait upcasting coercion added a new coercion rule, taking priority over certain other + /// coercion rules, which causes some behavior change compared to older `rustc` versions. + /// + /// `deref` can be still called explicitly, it just isn't called as part of a deref coercion + /// (since trait upcasting coercion takes priority). pub DEREF_INTO_DYN_SUPERTRAIT, - Warn, - "`Deref` implementation usage with a supertrait trait object for output is shadowed by trait upcasting", - @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseSemanticsChange, - reference: "issue #89460 ", - }; + Allow, + "`Deref` implementation with a supertrait trait object for output is shadowed by trait upcasting", } declare_lint_pass!(DerefIntoDynSupertrait => [DEREF_INTO_DYN_SUPERTRAIT]); diff --git a/tests/ui/traits/trait-upcasting/deref-upcast-shadowing-lint.rs b/tests/ui/traits/trait-upcasting/deref-upcast-shadowing-lint.rs new file mode 100644 index 0000000000000..ab84527edcff9 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/deref-upcast-shadowing-lint.rs @@ -0,0 +1,17 @@ +//@ check-pass +#![warn(deref_into_dyn_supertrait)] +use std::ops::Deref; + +trait Bar {} +trait Foo: Bar {} + +impl<'a> Deref for dyn Foo + 'a { + //~^ warn: this `Deref` implementation is covered by an implicit supertrait coercion + type Target = dyn Bar + 'a; + + fn deref(&self) -> &Self::Target { + todo!() + } +} + +fn main() {} diff --git a/tests/ui/traits/trait-upcasting/deref-upcast-shadowing-lint.stderr b/tests/ui/traits/trait-upcasting/deref-upcast-shadowing-lint.stderr new file mode 100644 index 0000000000000..0d7f957a50ebd --- /dev/null +++ b/tests/ui/traits/trait-upcasting/deref-upcast-shadowing-lint.stderr @@ -0,0 +1,17 @@ +warning: this `Deref` implementation is covered by an implicit supertrait coercion + --> $DIR/deref-upcast-shadowing-lint.rs:8:1 + | +LL | impl<'a> Deref for dyn Foo + 'a { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo` implements `Deref>` which conflicts with supertrait `Bar` +LL | +LL | type Target = dyn Bar + 'a; + | -------------------------------- target type is a supertrait of `dyn Foo` + | +note: the lint level is defined here + --> $DIR/deref-upcast-shadowing-lint.rs:2:9 + | +LL | #![warn(deref_into_dyn_supertrait)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 1 warning emitted + diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.rs b/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.rs index da1a9cc2775d0..d33d3bfd5dc20 100644 --- a/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.rs +++ b/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.rs @@ -1,4 +1,5 @@ -#![deny(deref_into_dyn_supertrait)] +//@ check-pass +#![warn(deref_into_dyn_supertrait)] use std::ops::Deref; @@ -6,8 +7,7 @@ trait Bar<'a> {} trait Foo<'a>: Bar<'a> {} impl<'a> Deref for dyn Foo<'a> { - //~^ ERROR this `Deref` implementation is covered by an implicit supertrait coercion - //~| WARN this will change its meaning in a future release! + //~^ warn: this `Deref` implementation is covered by an implicit supertrait coercion type Target = dyn Bar<'a>; fn deref(&self) -> &Self::Target { diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.stderr b/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.stderr index a5f3660d4bcb0..806c57e44a2bf 100644 --- a/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.stderr +++ b/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.stderr @@ -1,19 +1,17 @@ -error: this `Deref` implementation is covered by an implicit supertrait coercion - --> $DIR/migrate-lint-deny-regions.rs:8:1 +warning: this `Deref` implementation is covered by an implicit supertrait coercion + --> $DIR/migrate-lint-deny-regions.rs:9:1 | LL | impl<'a> Deref for dyn Foo<'a> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo<'_>` implements `Deref>` which conflicts with supertrait `Bar<'_>` -... +LL | LL | type Target = dyn Bar<'a>; | -------------------------- target type is a supertrait of `dyn Foo<'_>` | - = warning: this will change its meaning in a future release! - = note: for more information, see issue #89460 note: the lint level is defined here - --> $DIR/migrate-lint-deny-regions.rs:1:9 + --> $DIR/migrate-lint-deny-regions.rs:2:9 | -LL | #![deny(deref_into_dyn_supertrait)] +LL | #![warn(deref_into_dyn_supertrait)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +warning: 1 warning emitted diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-deny.rs b/tests/ui/traits/trait-upcasting/migrate-lint-deny.rs deleted file mode 100644 index 926b3649e01b3..0000000000000 --- a/tests/ui/traits/trait-upcasting/migrate-lint-deny.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![deny(deref_into_dyn_supertrait)] - -use std::ops::Deref; - -// issue 89190 -trait A {} -trait B: A {} - -impl<'a> Deref for dyn 'a + B { - //~^ ERROR this `Deref` implementation is covered by an implicit supertrait coercion - //~| WARN this will change its meaning in a future release! - - type Target = dyn A; - fn deref(&self) -> &Self::Target { - todo!() - } -} - -fn take_a(_: &dyn A) {} - -fn whoops(b: &dyn B) { - take_a(b) -} - -fn main() {} diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr b/tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr deleted file mode 100644 index 29997a9b3d9c3..0000000000000 --- a/tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error: this `Deref` implementation is covered by an implicit supertrait coercion - --> $DIR/migrate-lint-deny.rs:9:1 - | -LL | impl<'a> Deref for dyn 'a + B { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn B` implements `Deref` which conflicts with supertrait `A` -... -LL | type Target = dyn A; - | -------------------- target type is a supertrait of `dyn B` - | - = warning: this will change its meaning in a future release! - = note: for more information, see issue #89460 -note: the lint level is defined here - --> $DIR/migrate-lint-deny.rs:1:9 - | -LL | #![deny(deref_into_dyn_supertrait)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.rs b/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.rs index 8e62c4b95b06c..20806f22886c0 100644 --- a/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.rs +++ b/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.rs @@ -1,4 +1,5 @@ //@ check-pass +#![warn(deref_into_dyn_supertrait)] use std::ops::Deref; @@ -9,8 +10,7 @@ trait Foo: Bar { } impl<'a> Deref for dyn Foo + 'a { - //~^ WARN this `Deref` implementation is covered by an implicit supertrait coercion - //~| WARN this will change its meaning in a future release! + //~^ warn: this `Deref` implementation is covered by an implicit supertrait coercion type Target = dyn Bar + 'a; fn deref(&self) -> &Self::Target { diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.stderr b/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.stderr index 6245da5a17604..86cff5233ff49 100644 --- a/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.stderr +++ b/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.stderr @@ -1,15 +1,17 @@ warning: this `Deref` implementation is covered by an implicit supertrait coercion - --> $DIR/migrate-lint-different-substs.rs:11:1 + --> $DIR/migrate-lint-different-substs.rs:12:1 | LL | impl<'a> Deref for dyn Foo + 'a { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo` implements `Deref>` which conflicts with supertrait `Bar` -... +LL | LL | type Target = dyn Bar + 'a; | -------------------------------- target type is a supertrait of `dyn Foo` | - = warning: this will change its meaning in a future release! - = note: for more information, see issue #89460 - = note: `#[warn(deref_into_dyn_supertrait)]` on by default +note: the lint level is defined here + --> $DIR/migrate-lint-different-substs.rs:2:9 + | +LL | #![warn(deref_into_dyn_supertrait)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: 1 warning emitted From 2a6b27444ae8246c4fc1e49e8aa7aa24832efc82 Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Thu, 6 Feb 2025 11:39:55 -0800 Subject: [PATCH 28/28] Remove dead code from rustc_codegen_llvm and the LLVM wrapper --- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 29 ----------------- .../rustc_llvm/llvm-wrapper/RustWrapper.cpp | 31 ------------------- 2 files changed, 60 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 0d04f770bc694..50a40c9c30927 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -69,19 +69,6 @@ pub enum LLVMRustResult { Failure, } -/// Translation of LLVM's MachineTypes enum, defined in llvm\include\llvm\BinaryFormat\COFF.h. -/// -/// We include only architectures supported on Windows. -#[derive(Copy, Clone, PartialEq)] -#[repr(C)] -pub enum LLVMMachineType { - AMD64 = 0x8664, - I386 = 0x14c, - ARM64 = 0xaa64, - ARM64EC = 0xa641, - ARM = 0x01c0, -} - /// Must match the layout of `LLVMRustModuleFlagMergeBehavior`. /// /// When merging modules (e.g. during LTO), their metadata flags are combined. Conflicts are @@ -645,16 +632,6 @@ pub enum ThreadLocalMode { LocalExec, } -/// LLVMRustTailCallKind -#[derive(Copy, Clone)] -#[repr(C)] -pub enum TailCallKind { - None, - Tail, - MustTail, - NoTail, -} - /// LLVMRustChecksumKind #[derive(Copy, Clone)] #[repr(C)] @@ -773,7 +750,6 @@ pub struct Builder<'a>(InvariantOpaque<'a>); #[repr(C)] pub struct PassManager<'a>(InvariantOpaque<'a>); unsafe extern "C" { - pub type Pass; pub type TargetMachine; pub type Archive; } @@ -799,7 +775,6 @@ unsafe extern "C" { } pub type DiagnosticHandlerTy = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void); -pub type InlineAsmDiagHandlerTy = unsafe extern "C" fn(&SMDiagnostic, *const c_void, c_uint); pub mod debuginfo { use std::ptr; @@ -853,7 +828,6 @@ pub mod debuginfo { pub type DIFile = DIScope; pub type DILexicalBlock = DIScope; pub type DISubprogram = DIScope; - pub type DINameSpace = DIScope; pub type DIType = DIDescriptor; pub type DIBasicType = DIType; pub type DIDerivedType = DIType; @@ -1809,7 +1783,6 @@ unsafe extern "C" { Name: *const c_char, NameLen: size_t, ) -> Option<&Value>; - pub fn LLVMRustSetTailCallKind(CallInst: &Value, TKC: TailCallKind); // Operations on attributes pub fn LLVMRustCreateAttrNoValue(C: &Context, attr: AttributeKind) -> &Attribute; @@ -2586,8 +2559,6 @@ unsafe extern "C" { pub fn LLVMRustGetElementTypeArgIndex(CallSite: &Value) -> i32; - pub fn LLVMRustIsBitcode(ptr: *const u8, len: usize) -> bool; - pub fn LLVMRustLLVMHasZlibCompressionForDebugSymbols() -> bool; pub fn LLVMRustLLVMHasZstdCompressionForDebugSymbols() -> bool; diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 76ad7fc890911..b8cef6a7e250e 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -195,33 +195,6 @@ LLVMRustVerifyFunction(LLVMValueRef Fn, LLVMRustVerifierFailureAction Action) { return LLVMVerifyFunction(Fn, fromRust(Action)); } -enum class LLVMRustTailCallKind { - None, - Tail, - MustTail, - NoTail, -}; - -static CallInst::TailCallKind fromRust(LLVMRustTailCallKind Kind) { - switch (Kind) { - case LLVMRustTailCallKind::None: - return CallInst::TailCallKind::TCK_None; - case LLVMRustTailCallKind::Tail: - return CallInst::TailCallKind::TCK_Tail; - case LLVMRustTailCallKind::MustTail: - return CallInst::TailCallKind::TCK_MustTail; - case LLVMRustTailCallKind::NoTail: - return CallInst::TailCallKind::TCK_NoTail; - default: - report_fatal_error("bad CallInst::TailCallKind."); - } -} - -extern "C" void LLVMRustSetTailCallKind(LLVMValueRef Call, - LLVMRustTailCallKind TCK) { - unwrap(Call)->setTailCallKind(fromRust(TCK)); -} - extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M, const char *Name, size_t NameLen, @@ -1976,10 +1949,6 @@ extern "C" int32_t LLVMRustGetElementTypeArgIndex(LLVMValueRef CallSite) { return -1; } -extern "C" bool LLVMRustIsBitcode(char *ptr, size_t len) { - return identify_magic(StringRef(ptr, len)) == file_magic::bitcode; -} - extern "C" bool LLVMRustIsNonGVFunctionPointerTy(LLVMValueRef V) { if (unwrap(V)->getType()->isPointerTy()) { if (auto *GV = dyn_cast(unwrap(V))) {