Skip to content

Commit 9e5ade0

Browse files
Don't show suggestion if slice pattern is enclosed by struct
1 parent 9afdb8d commit 9e5ade0

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

+48-13
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ struct PatInfo<'tcx, 'a> {
8484
binding_mode: BindingMode,
8585
top_info: TopInfo<'tcx>,
8686
decl_origin: Option<DeclOrigin<'a>>,
87+
88+
parent_kind: Option<PatKind<'tcx>>,
89+
current_kind: Option<PatKind<'tcx>>,
8790
}
8891

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

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

179194
let ty = match pat.kind {
180195
PatKind::Wild | PatKind::Err(_) => expected,
@@ -1047,14 +1062,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10471062
expected: Ty<'tcx>,
10481063
pat_info: PatInfo<'tcx, '_>,
10491064
) -> Ty<'tcx> {
1050-
let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin } = pat_info;
1065+
let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin, parent_kind, current_kind } =
1066+
pat_info;
10511067
let tcx = self.tcx;
10521068
let on_error = |e| {
10531069
for pat in subpats {
10541070
self.check_pat(
10551071
pat,
10561072
Ty::new_error(tcx, e),
1057-
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
1073+
PatInfo {
1074+
binding_mode: def_bm,
1075+
top_info: ti,
1076+
decl_origin,
1077+
parent_kind,
1078+
current_kind,
1079+
},
10581080
);
10591081
}
10601082
};
@@ -1121,7 +1143,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11211143
self.check_pat(
11221144
subpat,
11231145
field_ty,
1124-
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
1146+
PatInfo {
1147+
binding_mode: def_bm,
1148+
top_info: ti,
1149+
decl_origin,
1150+
parent_kind,
1151+
current_kind,
1152+
},
11251153
);
11261154

11271155
self.tcx.check_stability(
@@ -2135,7 +2163,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21352163
// The expected type must be an array or slice, but was neither, so error.
21362164
_ => {
21372165
let guar = expected.error_reported().err().unwrap_or_else(|| {
2138-
self.error_expected_array_or_slice(span, expected, pat_info.top_info)
2166+
self.error_expected_array_or_slice(span, expected, pat_info)
21392167
});
21402168
let err = Ty::new_error(self.tcx, guar);
21412169
(err, Some(err), err)
@@ -2274,8 +2302,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22742302
&self,
22752303
span: Span,
22762304
expected_ty: Ty<'tcx>,
2277-
ti: TopInfo<'tcx>,
2305+
pat_info: PatInfo<'tcx, '_>,
22782306
) -> ErrorGuaranteed {
2307+
let PatInfo { top_info: ti, parent_kind, .. } = pat_info;
2308+
22792309
let mut err = struct_span_code_err!(
22802310
self.dcx(),
22812311
span,
@@ -2293,9 +2323,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22932323
&& let Some(_) = ti.origin_expr
22942324
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
22952325
{
2296-
let ty = self.resolve_vars_if_possible(ti.expected);
2297-
let is_slice_or_array_or_vector = self.is_slice_or_array_or_vector(ty);
2298-
match is_slice_or_array_or_vector.1.kind() {
2326+
let resolved_ty = self.resolve_vars_if_possible(ti.expected);
2327+
let (is_slice_or_array_or_vector, resolved_ty) =
2328+
self.is_slice_or_array_or_vector(resolved_ty);
2329+
match resolved_ty.kind() {
22992330
ty::Adt(adt_def, _)
23002331
if self.tcx.is_diagnostic_item(sym::Option, adt_def.did())
23012332
|| self.tcx.is_diagnostic_item(sym::Result, adt_def.did()) =>
@@ -2310,7 +2341,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
23102341
}
23112342
_ => (),
23122343
}
2313-
if is_slice_or_array_or_vector.0 {
2344+
2345+
let enclosure_is_struct =
2346+
parent_kind.map_or(false, |enclosure| matches!(enclosure, PatKind::Struct(..)));
2347+
2348+
if is_slice_or_array_or_vector && !enclosure_is_struct {
23142349
err.span_suggestion(
23152350
span,
23162351
"consider slicing here",

0 commit comments

Comments
 (0)