diff options
| author | dianne <diannes.gm@gmail.com> | 2025-02-03 22:18:00 -0800 |
|---|---|---|
| committer | dianne <diannes.gm@gmail.com> | 2025-02-03 22:23:35 -0800 |
| commit | 4331f55b729d1a41004305f85dfe4dbbcec3ee3f (patch) | |
| tree | b3ed9d2f2ac05e3c2b8b0a503f55dcfc39d96767 /compiler | |
| parent | 9202001c1c5c3bd9c1fce522744c8620e17d791a (diff) | |
| download | rust-4331f55b729d1a41004305f85dfe4dbbcec3ee3f.tar.gz rust-4331f55b729d1a41004305f85dfe4dbbcec3ee3f.zip | |
highlight the whole problem subpattern when pointing out the default binding mode
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_hir_typeck/src/pat.rs | 35 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/typeck_results.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/pattern/mod.rs | 4 |
3 files changed, 28 insertions, 17 deletions
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 1970040ec86..6b0a87f1aef 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 0dbbfee0cfa..a75a7fcd569 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<Span>, + /// 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 f12234723ec..cdabd283150 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. |
