Skip to content

Commit 0131586

Browse files
committed
refactor struct pattern checking to get info for peeling
See the previous commit for details. This doesn't yet extract the struct pat's type's ADT def before peeling, but it should now be possible.
1 parent f279482 commit 0131586

File tree

1 file changed

+27
-21
lines changed
  • compiler/rustc_hir_typeck/src

1 file changed

+27
-21
lines changed

compiler/rustc_hir_typeck/src/pat.rs

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
361361
PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, span }) => {
362362
Some { 0: &self.check_pat_path(*hir_id, pat.hir_id, *span, qpath, &ti) }
363363
}
364+
PatKind::Struct(ref qpath, fields, has_rest_pat) => {
365+
Some { 0: &self.check_pat_struct(pat, qpath, fields, has_rest_pat) }
366+
}
364367
_ => None,
365368
};
366369
let adjust_mode = self.calc_adjust_mode(pat, resolved_pat.and_then(|r| r.path_res));
@@ -393,9 +396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
393396
PatKind::TupleStruct(ref qpath, subpats, ddpos) => {
394397
self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, pat_info)
395398
}
396-
PatKind::Struct(ref qpath, fields, has_rest_pat) => {
397-
self.check_pat_struct(pat, qpath, fields, has_rest_pat, expected, pat_info)
398-
}
399+
PatKind::Struct(..) => (resolved_pat.unwrap().check)(expected, pat_info),
399400
PatKind::Guard(pat, cond) => {
400401
self.check_pat(pat, expected, pat_info);
401402
self.check_expr_has_type_or_error(cond, self.tcx.types.bool, |_| {});
@@ -1234,29 +1235,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12341235
qpath: &hir::QPath<'tcx>,
12351236
fields: &'tcx [hir::PatField<'tcx>],
12361237
has_rest_pat: bool,
1237-
expected: Ty<'tcx>,
1238-
pat_info: PatInfo<'tcx>,
1239-
) -> Ty<'tcx> {
1238+
) -> ResolvedPat<impl Fn(Ty<'tcx>, PatInfo<'tcx>) -> Ty<'tcx>> {
12401239
// Resolve the path and check the definition for errors.
1241-
let (variant, pat_ty) = match self.check_struct_path(qpath, pat.hir_id) {
1242-
Ok(data) => data,
1243-
Err(guar) => {
1244-
let err = Ty::new_error(self.tcx, guar);
1245-
for field in fields {
1246-
self.check_pat(field.pat, err, pat_info);
1240+
let variant_and_pat_ty = self.check_struct_path(qpath, pat.hir_id);
1241+
1242+
let check = move |expected: Ty<'tcx>, pat_info: PatInfo<'tcx>| -> Ty<'tcx> {
1243+
let (variant, pat_ty) = match variant_and_pat_ty {
1244+
Ok(data) => data,
1245+
Err(guar) => {
1246+
let err = Ty::new_error(self.tcx, guar);
1247+
for field in fields {
1248+
self.check_pat(field.pat, err, pat_info);
1249+
}
1250+
return err;
12471251
}
1248-
return err;
1252+
};
1253+
1254+
// Type-check the path.
1255+
let _ = self.demand_eqtype_pat(pat.span, expected, pat_ty, &pat_info.top_info);
1256+
1257+
// Type-check subpatterns.
1258+
match self.check_struct_pat_fields(pat_ty, pat, variant, fields, has_rest_pat, pat_info)
1259+
{
1260+
Ok(()) => pat_ty,
1261+
Err(guar) => Ty::new_error(self.tcx, guar),
12491262
}
12501263
};
12511264

1252-
// Type-check the path.
1253-
let _ = self.demand_eqtype_pat(pat.span, expected, pat_ty, &pat_info.top_info);
1254-
1255-
// Type-check subpatterns.
1256-
match self.check_struct_pat_fields(pat_ty, pat, variant, fields, has_rest_pat, pat_info) {
1257-
Ok(()) => pat_ty,
1258-
Err(guar) => Ty::new_error(self.tcx, guar),
1259-
}
1265+
ResolvedPat { path_res: None, check }
12601266
}
12611267

12621268
fn check_pat_path(

0 commit comments

Comments
 (0)