Skip to content

Commit 1f40e9a

Browse files
committed
refactor tuple struct pattern checking to get info for peeling
See the previous two commits.
1 parent 9196048 commit 1f40e9a

File tree

1 file changed

+44
-22
lines changed
  • compiler/rustc_hir_typeck/src

1 file changed

+44
-22
lines changed

compiler/rustc_hir_typeck/src/pat.rs

+44-22
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ struct ResolvedPat<'tcx> {
278278
enum ResolvedPatKind<'tcx> {
279279
Path { res: Res, pat_res: Res, segments: &'tcx [hir::PathSegment<'tcx>] },
280280
Struct { variant: &'tcx VariantDef },
281+
TupleStruct { res: Res, variant: &'tcx VariantDef },
281282
}
282283

283284
impl<'tcx> ResolvedPat<'tcx> {
@@ -381,6 +382,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
381382
Some(self.resolve_pat_path(*hir_id, *span, qpath))
382383
}
383384
PatKind::Struct(ref qpath, ..) => Some(self.resolve_pat_struct(pat, qpath)),
385+
PatKind::TupleStruct(ref qpath, ..) => Some(self.resolve_pat_tuple_struct(pat, qpath)),
384386
_ => None,
385387
};
386388
let adjust_mode = self.calc_adjust_mode(pat, opt_path_res);
@@ -575,9 +577,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
575577
PatKind::Binding(ba, var_id, ident, sub) => {
576578
self.check_pat_ident(pat, ba, var_id, ident, sub, expected, pat_info)
577579
}
578-
PatKind::TupleStruct(ref qpath, subpats, ddpos) => {
579-
self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, pat_info)
580-
}
580+
PatKind::TupleStruct(ref qpath, subpats, ddpos) => match opt_path_res.unwrap() {
581+
Ok(ResolvedPat { ty, kind: ResolvedPatKind::TupleStruct { res, variant } }) => self
582+
.check_pat_tuple_struct(
583+
pat, qpath, subpats, ddpos, res, ty, variant, expected, pat_info,
584+
),
585+
Err(guar) => {
586+
let ty_err = Ty::new_error(self.tcx, guar);
587+
for subpat in subpats {
588+
self.check_pat(subpat, ty_err, pat_info);
589+
}
590+
ty_err
591+
}
592+
Ok(pr) => span_bug!(pat.span, "tuple struct pattern resolved to {pr:?}"),
593+
},
581594
PatKind::Struct(_, fields, has_rest_pat) => match opt_path_res.unwrap() {
582595
Ok(ResolvedPat { ty, kind: ResolvedPatKind::Struct { variant } }) => self
583596
.check_pat_struct(pat, fields, has_rest_pat, ty, variant, expected, pat_info),
@@ -1443,26 +1456,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14431456
e.emit();
14441457
}
14451458

1446-
fn check_pat_tuple_struct(
1459+
fn resolve_pat_tuple_struct(
14471460
&self,
14481461
pat: &'tcx Pat<'tcx>,
14491462
qpath: &'tcx hir::QPath<'tcx>,
1450-
subpats: &'tcx [Pat<'tcx>],
1451-
ddpos: hir::DotDotPos,
1452-
expected: Ty<'tcx>,
1453-
pat_info: PatInfo<'tcx>,
1454-
) -> Ty<'tcx> {
1463+
) -> Result<ResolvedPat<'tcx>, ErrorGuaranteed> {
14551464
let tcx = self.tcx;
1456-
let on_error = |e| {
1457-
for pat in subpats {
1458-
self.check_pat(pat, Ty::new_error(tcx, e), pat_info);
1459-
}
1460-
};
14611465
let report_unexpected_res = |res: Res| {
14621466
let expected = "tuple struct or tuple variant";
14631467
let e = report_unexpected_variant_res(tcx, res, None, qpath, pat.span, E0164, expected);
1464-
on_error(e);
1465-
e
1468+
Err(e)
14661469
};
14671470

14681471
// Resolve the path and check the definition for errors.
@@ -1471,25 +1474,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14711474
if res == Res::Err {
14721475
let e = self.dcx().span_delayed_bug(pat.span, "`Res::Err` but no error emitted");
14731476
self.set_tainted_by_errors(e);
1474-
on_error(e);
1475-
return Ty::new_error(tcx, e);
1477+
return Err(e);
14761478
}
14771479

14781480
// Type-check the path.
14791481
let (pat_ty, res) =
14801482
self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.span, pat.hir_id);
14811483
if !pat_ty.is_fn() {
1482-
let e = report_unexpected_res(res);
1483-
return Ty::new_error(tcx, e);
1484+
return report_unexpected_res(res);
14841485
}
14851486

14861487
let variant = match res {
14871488
Res::Err => {
14881489
self.dcx().span_bug(pat.span, "`Res::Err` but no error emitted");
14891490
}
14901491
Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) => {
1491-
let e = report_unexpected_res(res);
1492-
return Ty::new_error(tcx, e);
1492+
return report_unexpected_res(res);
14931493
}
14941494
Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => tcx.expect_variant_res(res),
14951495
_ => bug!("unexpected pattern resolution: {:?}", res),
@@ -1499,6 +1499,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14991499
let pat_ty = pat_ty.fn_sig(tcx).output();
15001500
let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
15011501

1502+
Ok(ResolvedPat { ty: pat_ty, kind: ResolvedPatKind::TupleStruct { res, variant } })
1503+
}
1504+
1505+
fn check_pat_tuple_struct(
1506+
&self,
1507+
pat: &'tcx Pat<'tcx>,
1508+
qpath: &'tcx hir::QPath<'tcx>,
1509+
subpats: &'tcx [Pat<'tcx>],
1510+
ddpos: hir::DotDotPos,
1511+
res: Res,
1512+
pat_ty: Ty<'tcx>,
1513+
variant: &'tcx VariantDef,
1514+
expected: Ty<'tcx>,
1515+
pat_info: PatInfo<'tcx>,
1516+
) -> Ty<'tcx> {
1517+
let tcx = self.tcx;
1518+
let on_error = |e| {
1519+
for pat in subpats {
1520+
self.check_pat(pat, Ty::new_error(tcx, e), pat_info);
1521+
}
1522+
};
1523+
15021524
// Type-check the tuple struct pattern against the expected type.
15031525
let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, &pat_info.top_info);
15041526
let had_err = diag.map_err(|diag| diag.emit());

0 commit comments

Comments
 (0)