Skip to content

Commit 215bfdd

Browse files
committed
separate labels for default binding mode spans into their own notes
(cherry picked from commit 767f820)
1 parent 97cb2d5 commit 215bfdd

File tree

5 files changed

+202
-124
lines changed

5 files changed

+202
-124
lines changed

compiler/rustc_hir_typeck/src/pat.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
699699

700700
// Determine the binding mode...
701701
let bm = match user_bind_annot {
702-
BindingMode(ByRef::No, Mutability::Mut) if matches!(def_br, ByRef::Yes(_)) => {
702+
BindingMode(ByRef::No, Mutability::Mut) if let ByRef::Yes(def_br_mutbl) = def_br => {
703703
if pat.span.at_least_rust_2024()
704704
&& (self.tcx.features().ref_pat_eat_one_layer_2024()
705705
|| self.tcx.features().ref_pat_eat_one_layer_2024_structural())
@@ -721,18 +721,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
721721
pat_info.top_info.hir_id,
722722
pat,
723723
ident.span,
724+
def_br_mutbl,
724725
);
725726
BindingMode(ByRef::No, Mutability::Mut)
726727
}
727728
}
728729
BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl),
729730
BindingMode(ByRef::Yes(_), _) => {
730-
if matches!(def_br, ByRef::Yes(_)) {
731+
if let ByRef::Yes(def_br_mutbl) = def_br {
731732
// `ref`/`ref mut` overrides the binding mode on edition <= 2021
732733
self.add_rust_2024_migration_desugared_pat(
733734
pat_info.top_info.hir_id,
734735
pat,
735736
ident.span,
737+
def_br_mutbl,
736738
);
737739
}
738740
user_bind_annot
@@ -2261,12 +2263,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22612263
}
22622264
} else {
22632265
// Reset binding mode on old editions
2264-
if pat_info.binding_mode != ByRef::No {
2266+
if let ByRef::Yes(inh_mut) = pat_info.binding_mode {
22652267
pat_info.binding_mode = ByRef::No;
22662268
self.add_rust_2024_migration_desugared_pat(
22672269
pat_info.top_info.hir_id,
22682270
pat,
22692271
inner.span,
2272+
inh_mut,
22702273
)
22712274
}
22722275
}
@@ -2634,6 +2637,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26342637
pat_id: HirId,
26352638
subpat: &'tcx Pat<'tcx>,
26362639
cutoff_span: Span,
2640+
def_br_mutbl: Mutability,
26372641
) {
26382642
// Try to trim the span we're labeling to just the `&` or binding mode that's an issue.
26392643
// If the subpattern's span is is from an expansion, the emitted label will not be trimmed.
@@ -2656,16 +2660,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26562660
// NB: This wording assumes the only expansions that can produce problematic reference
26572661
// patterns and bindings are macros. If a desugaring or AST pass is added that can do
26582662
// so, we may want to inspect the span's source callee or macro backtrace.
2659-
"occurs within macro expansion"
2663+
"occurs within macro expansion".to_owned()
26602664
} else {
2661-
if matches!(subpat.kind, PatKind::Binding(_, _, _, _)) {
2665+
let pat_kind = if matches!(subpat.kind, PatKind::Binding(_, _, _, _)) {
26622666
info.bad_modifiers |= true;
2663-
"this binding modifier"
2667+
"binding modifier"
26642668
} else {
26652669
info.bad_ref_pats |= true;
2666-
"this reference pattern"
2667-
}
2670+
"reference pattern"
2671+
};
2672+
let dbm_str = match def_br_mutbl {
2673+
Mutability::Not => "ref",
2674+
Mutability::Mut => "ref mut",
2675+
};
2676+
format!("{pat_kind} not allowed under `{dbm_str}` default binding mode")
26682677
};
2669-
info.primary_labels.push((trimmed_span, primary_label.to_owned()));
2678+
info.primary_labels.push((trimmed_span, primary_label));
26702679
}
26712680
}

compiler/rustc_mir_build/src/errors.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,27 @@ impl Subdiagnostic for Rust2024IncompatiblePatSugg {
11141114
diag: &mut Diag<'_, G>,
11151115
_f: &F,
11161116
) {
1117+
// Format and emit explanatory notes about default binding modes. Reversing the spans' order
1118+
// means if we have nested spans, the innermost ones will be visited first.
1119+
for (span, def_br_mutbl) in self.default_mode_labels.into_iter().rev() {
1120+
// Don't point to a macro call site.
1121+
if !span.from_expansion() {
1122+
let dbm_str = match def_br_mutbl {
1123+
ty::Mutability::Not => "ref",
1124+
ty::Mutability::Mut => "ref mut",
1125+
};
1126+
let note_msg = format!(
1127+
"the default binding mode changed to `{dbm_str}` because this has type `{}_`",
1128+
def_br_mutbl.ref_prefix_str()
1129+
);
1130+
let label_msg = format!("the default binding mode is `{dbm_str}`, introduced here");
1131+
let mut label = MultiSpan::from(span);
1132+
label.push_span_label(span, label_msg);
1133+
diag.span_note(label, note_msg);
1134+
}
1135+
}
1136+
1137+
// Format and emit the suggestion.
11171138
let applicability =
11181139
if self.suggestion.iter().all(|(span, _)| span.can_be_used_for_suggestions()) {
11191140
Applicability::MachineApplicable

compiler/rustc_mir_build/src/thir/pattern/mod.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,6 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
6666
for (span, label) in &info.primary_labels {
6767
spans.push_span_label(*span, label.clone());
6868
}
69-
for (span, label_mutbl) in &sugg.default_mode_labels {
70-
// Don't point to a macro call site.
71-
if !span.from_expansion() {
72-
let label = match label_mutbl {
73-
Mutability::Not => "default binding mode is `ref`",
74-
Mutability::Mut => "default binding mode is `ref mut`",
75-
};
76-
spans.push_span_label(*span, label.to_owned())
77-
}
78-
}
7969
// If a relevant span is from at least edition 2024, this is a hard error.
8070
let is_hard_error = spans.primary_spans().iter().any(|span| span.at_least_rust_2024());
8171
if is_hard_error {

0 commit comments

Comments
 (0)