Skip to content

Commit 31f9d29

Browse files
Don't show suggestion if slice pattern is enclosed by struct
1 parent da02fff commit 31f9d29

File tree

1 file changed

+48
-13
lines changed
  • compiler/rustc_hir_typeck/src

1 file changed

+48
-13
lines changed

compiler/rustc_hir_typeck/src/pat.rs

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ struct PatInfo<'tcx, 'a> {
8383
binding_mode: BindingMode,
8484
top_info: TopInfo<'tcx>,
8585
decl_origin: Option<DeclOrigin<'a>>,
86+
87+
parent_kind: Option<PatKind<'tcx>>,
88+
current_kind: Option<PatKind<'tcx>>,
8689
}
8790

8891
impl<'tcx> FnCtxt<'_, 'tcx> {
@@ -152,7 +155,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
152155
decl_origin: Option<DeclOrigin<'tcx>>,
153156
) {
154157
let info = TopInfo { expected, origin_expr, span };
155-
let pat_info = PatInfo { binding_mode: INITIAL_BM, top_info: info, decl_origin };
158+
let pat_info = PatInfo {
159+
binding_mode: INITIAL_BM,
160+
top_info: info,
161+
decl_origin,
162+
parent_kind: None,
163+
current_kind: None,
164+
};
156165
self.check_pat(pat, expected, pat_info);
157166
}
158167

@@ -163,7 +172,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
163172
/// Conversely, inside this module, `check_pat_top` should never be used.
164173
#[instrument(level = "debug", skip(self, pat_info))]
165174
fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>) {
166-
let PatInfo { binding_mode: def_bm, top_info: ti, .. } = pat_info;
175+
let PatInfo { binding_mode: def_bm, top_info: ti, current_kind, .. } = pat_info;
176+
167177
let path_res = match &pat.kind {
168178
PatKind::Path(qpath) => Some(
169179
self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span, None),
@@ -172,8 +182,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
172182
};
173183
let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res));
174184
let (expected, def_bm) = self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode);
175-
let pat_info =
176-
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin: pat_info.decl_origin };
185+
let pat_info = PatInfo {
186+
binding_mode: def_bm,
187+
top_info: ti,
188+
decl_origin: pat_info.decl_origin,
189+
parent_kind: current_kind,
190+
current_kind: Some(pat.kind),
191+
};
177192

178193
let ty = match pat.kind {
179194
PatKind::Wild | PatKind::Err(_) => expected,
@@ -1046,14 +1061,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10461061
expected: Ty<'tcx>,
10471062
pat_info: PatInfo<'tcx, '_>,
10481063
) -> Ty<'tcx> {
1049-
let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin } = pat_info;
1064+
let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin, parent_kind, current_kind } =
1065+
pat_info;
10501066
let tcx = self.tcx;
10511067
let on_error = |e| {
10521068
for pat in subpats {
10531069
self.check_pat(
10541070
pat,
10551071
Ty::new_error(tcx, e),
1056-
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
1072+
PatInfo {
1073+
binding_mode: def_bm,
1074+
top_info: ti,
1075+
decl_origin,
1076+
parent_kind,
1077+
current_kind,
1078+
},
10571079
);
10581080
}
10591081
};
@@ -1120,7 +1142,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11201142
self.check_pat(
11211143
subpat,
11221144
field_ty,
1123-
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
1145+
PatInfo {
1146+
binding_mode: def_bm,
1147+
top_info: ti,
1148+
decl_origin,
1149+
parent_kind,
1150+
current_kind,
1151+
},
11241152
);
11251153

11261154
self.tcx.check_stability(
@@ -2134,7 +2162,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21342162
// The expected type must be an array or slice, but was neither, so error.
21352163
_ => {
21362164
let guar = expected.error_reported().err().unwrap_or_else(|| {
2137-
self.error_expected_array_or_slice(span, expected, pat_info.top_info)
2165+
self.error_expected_array_or_slice(span, expected, pat_info)
21382166
});
21392167
let err = Ty::new_error(self.tcx, guar);
21402168
(err, Some(err), err)
@@ -2273,8 +2301,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22732301
&self,
22742302
span: Span,
22752303
expected_ty: Ty<'tcx>,
2276-
ti: TopInfo<'tcx>,
2304+
pat_info: PatInfo<'tcx, '_>,
22772305
) -> ErrorGuaranteed {
2306+
let PatInfo { top_info: ti, parent_kind, .. } = pat_info;
2307+
22782308
let mut err = struct_span_code_err!(
22792309
self.dcx(),
22802310
span,
@@ -2292,9 +2322,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22922322
&& let Some(_) = ti.origin_expr
22932323
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
22942324
{
2295-
let ty = self.resolve_vars_if_possible(ti.expected);
2296-
let is_slice_or_array_or_vector = self.is_slice_or_array_or_vector(ty);
2297-
match is_slice_or_array_or_vector.1.kind() {
2325+
let resolved_ty = self.resolve_vars_if_possible(ti.expected);
2326+
let (is_slice_or_array_or_vector, resolved_ty) =
2327+
self.is_slice_or_array_or_vector(resolved_ty);
2328+
match resolved_ty.kind() {
22982329
ty::Adt(adt_def, _)
22992330
if self.tcx.is_diagnostic_item(sym::Option, adt_def.did())
23002331
|| self.tcx.is_diagnostic_item(sym::Result, adt_def.did()) =>
@@ -2309,7 +2340,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
23092340
}
23102341
_ => (),
23112342
}
2312-
if is_slice_or_array_or_vector.0 {
2343+
2344+
let enclosure_is_struct =
2345+
parent_kind.map_or(false, |enclosure| matches!(enclosure, PatKind::Struct(..)));
2346+
2347+
if is_slice_or_array_or_vector && !enclosure_is_struct {
23132348
err.span_suggestion(
23142349
span,
23152350
"consider slicing here",

0 commit comments

Comments
 (0)