Skip to content

Commit 8e7edca

Browse files
committed
produce suggestions which remove reference patterns
1 parent 7458b29 commit 8e7edca

File tree

9 files changed

+264
-104
lines changed

9 files changed

+264
-104
lines changed

compiler/rustc_hir_typeck/src/pat.rs

+2-13
Original file line numberDiff line numberDiff line change
@@ -2797,13 +2797,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
27972797
// FIXME(ref_pat_eat_one_layer_2024): The migration diagnostic doesn't know how to track the
27982798
// default binding mode in the presence of Rule 3 or Rule 5. As a consequence, the labels it
27992799
// gives for default binding modes are wrong, as well as suggestions based on the default
2800-
// binding mode. This keeps it from making those suggestions, as doing so could panic.
2800+
// binding mode.
28012801
let info = table.entry(pat_id).or_insert_with(|| ty::Rust2024IncompatiblePatInfo {
28022802
primary_labels: Vec::new(),
28032803
bad_modifiers: false,
28042804
bad_ref_pats: false,
2805-
suggest_eliding_modes: !self.tcx.features().ref_pat_eat_one_layer_2024()
2806-
&& !self.tcx.features().ref_pat_eat_one_layer_2024_structural(),
28072805
});
28082806

28092807
// Only provide a detailed label if the problematic subpattern isn't from an expansion.
@@ -2815,20 +2813,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
28152813
// so, we may want to inspect the span's source callee or macro backtrace.
28162814
"occurs within macro expansion".to_owned()
28172815
} else {
2818-
let pat_kind = if let PatKind::Binding(user_bind_annot, _, _, _) = subpat.kind {
2816+
let pat_kind = if matches!(subpat.kind, PatKind::Binding(_, _, _, _)) {
28192817
info.bad_modifiers |= true;
2820-
// If the user-provided binding modifier doesn't match the default binding mode, we'll
2821-
// need to suggest reference patterns, which can affect other bindings.
2822-
// For simplicity, we opt to suggest making the pattern fully explicit.
2823-
info.suggest_eliding_modes &=
2824-
user_bind_annot == BindingMode(ByRef::Yes(def_br_mutbl), Mutability::Not);
28252818
"binding modifier"
28262819
} else {
28272820
info.bad_ref_pats |= true;
2828-
// For simplicity, we don't try to suggest eliding reference patterns. Thus, we'll
2829-
// suggest adding them instead, which can affect the types assigned to bindings.
2830-
// As such, we opt to suggest making the pattern fully explicit.
2831-
info.suggest_eliding_modes = false;
28322821
"reference pattern"
28332822
};
28342823
let dbm_str = match def_br_mutbl {

compiler/rustc_middle/src/ty/typeck_results.rs

-2
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,4 @@ pub struct Rust2024IncompatiblePatInfo {
822822
pub bad_modifiers: bool,
823823
/// Whether any `&` or `&mut` patterns occur under a non-`move` default binding mode.
824824
pub bad_ref_pats: bool,
825-
/// If `true`, we can give a simpler suggestion solely by eliding explicit binding modifiers.
826-
pub suggest_eliding_modes: bool,
827825
}

compiler/rustc_mir_build/src/errors.rs

+34-11
Original file line numberDiff line numberDiff line change
@@ -1107,22 +1107,29 @@ pub(crate) struct Rust2024IncompatiblePat<'m> {
11071107
}
11081108

11091109
pub(crate) struct Rust2024IncompatiblePatSugg<'m> {
1110-
/// If true, our suggestion is to elide explicit binding modifiers.
1111-
/// If false, our suggestion is to make the pattern fully explicit.
1112-
pub(crate) suggest_eliding_modes: bool,
11131110
pub(crate) suggestion: Vec<(Span, String)>,
1111+
/// If `Some(..)`, we provide a suggestion about either adding or removing syntax.
1112+
/// If `None`, we suggest both additions and removals; use a generic wording for simplicity.
1113+
pub(crate) kind: Option<Rust2024IncompatiblePatSuggKind>,
11141114
pub(crate) ref_pattern_count: usize,
11151115
pub(crate) binding_mode_count: usize,
11161116
/// Labels for where incompatibility-causing by-ref default binding modes were introduced.
11171117
pub(crate) default_mode_labels: &'m FxIndexMap<Span, ty::Mutability>,
11181118
}
11191119

1120+
pub(crate) enum Rust2024IncompatiblePatSuggKind {
1121+
Subtractive,
1122+
Additive,
1123+
}
1124+
11201125
impl<'m> Subdiagnostic for Rust2024IncompatiblePatSugg<'m> {
11211126
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
11221127
self,
11231128
diag: &mut Diag<'_, G>,
11241129
_f: &F,
11251130
) {
1131+
use Rust2024IncompatiblePatSuggKind::*;
1132+
11261133
// Format and emit explanatory notes about default binding modes. Reversing the spans' order
11271134
// means if we have nested spans, the innermost ones will be visited first.
11281135
for (&span, &def_br_mutbl) in self.default_mode_labels.iter().rev() {
@@ -1144,17 +1151,33 @@ impl<'m> Subdiagnostic for Rust2024IncompatiblePatSugg<'m> {
11441151
} else {
11451152
Applicability::MaybeIncorrect
11461153
};
1147-
let msg = if self.suggest_eliding_modes {
1148-
let plural_modes = pluralize!(self.binding_mode_count);
1149-
format!("remove the unnecessary binding modifier{plural_modes}")
1150-
} else {
1151-
let plural_derefs = pluralize!(self.ref_pattern_count);
1152-
let and_modes = if self.binding_mode_count > 0 {
1153-
format!(" and variable binding mode{}", pluralize!(self.binding_mode_count))
1154+
let msg = if let Some(kind) = self.kind {
1155+
let derefs = if self.ref_pattern_count > 0 {
1156+
format!("reference pattern{}", pluralize!(self.ref_pattern_count))
11541157
} else {
11551158
String::new()
11561159
};
1157-
format!("make the implied reference pattern{plural_derefs}{and_modes} explicit")
1160+
let modes = if self.binding_mode_count > 0 {
1161+
match kind {
1162+
Subtractive => {
1163+
format!("binding modifier{}", pluralize!(self.binding_mode_count))
1164+
}
1165+
Additive => {
1166+
format!("variable binding mode{}", pluralize!(self.binding_mode_count))
1167+
}
1168+
}
1169+
} else {
1170+
String::new()
1171+
};
1172+
let and = if !derefs.is_empty() && !modes.is_empty() { " and " } else { "" };
1173+
match kind {
1174+
Subtractive => format!("remove the unnecessary {derefs}{and}{modes}"),
1175+
Additive => {
1176+
format!("make the implied {derefs}{and}{modes} explicit")
1177+
}
1178+
}
1179+
} else {
1180+
"rewrite the pattern".to_owned()
11581181
};
11591182
// FIXME(dianne): for peace of mind, don't risk emitting a 0-part suggestion (that panics!)
11601183
if !self.suggestion.is_empty() {

0 commit comments

Comments
 (0)