Skip to content

Commit 505fbf4

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

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

Lines changed: 44 additions & 22 deletions
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> {
@@ -383,6 +384,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
383384
Some(self.resolve_pat_path(*hir_id, *span, qpath))
384385
}
385386
PatKind::Struct(ref qpath, ..) => Some(self.resolve_pat_struct(pat, qpath)),
387+
PatKind::TupleStruct(ref qpath, ..) => Some(self.resolve_pat_tuple_struct(pat, qpath)),
386388
_ => None,
387389
};
388390
let opt_res_pat = opt_res_pat_or_err.map(Result::ok).flatten();
@@ -419,9 +421,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
419421
PatKind::Binding(ba, var_id, ident, sub) => {
420422
self.check_pat_ident(pat, ba, var_id, ident, sub, expected, pat_info)
421423
}
422-
PatKind::TupleStruct(ref qpath, subpats, ddpos) => {
423-
self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, pat_info)
424-
}
424+
PatKind::TupleStruct(ref qpath, subpats, ddpos) => match opt_res_pat_or_err.unwrap() {
425+
Ok(ResolvedPat { ty, kind: ResolvedPatKind::TupleStruct { res, variant } }) => self
426+
.check_pat_tuple_struct(
427+
pat, qpath, subpats, ddpos, res, ty, variant, expected, pat_info,
428+
),
429+
Err(guar) => {
430+
let ty_err = Ty::new_error(self.tcx, guar);
431+
for subpat in subpats {
432+
self.check_pat(subpat, ty_err, pat_info);
433+
}
434+
ty_err
435+
}
436+
Ok(r) => span_bug!(pat.span, "tuple struct pattern resolved to {r:?}"),
437+
},
425438
PatKind::Struct(_, fields, has_rest_pat) => match opt_res_pat_or_err.unwrap() {
426439
Ok(ResolvedPat { ty, kind: ResolvedPatKind::Struct { variant } }) => self
427440
.check_pat_struct(pat, fields, has_rest_pat, ty, variant, expected, pat_info),
@@ -1469,26 +1482,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14691482
e.emit();
14701483
}
14711484

1472-
fn check_pat_tuple_struct(
1485+
fn resolve_pat_tuple_struct(
14731486
&self,
14741487
pat: &'tcx Pat<'tcx>,
14751488
qpath: &'tcx hir::QPath<'tcx>,
1476-
subpats: &'tcx [Pat<'tcx>],
1477-
ddpos: hir::DotDotPos,
1478-
expected: Ty<'tcx>,
1479-
pat_info: PatInfo<'tcx>,
1480-
) -> Ty<'tcx> {
1489+
) -> Result<ResolvedPat<'tcx>, ErrorGuaranteed> {
14811490
let tcx = self.tcx;
1482-
let on_error = |e| {
1483-
for pat in subpats {
1484-
self.check_pat(pat, Ty::new_error(tcx, e), pat_info);
1485-
}
1486-
};
14871491
let report_unexpected_res = |res: Res| {
14881492
let expected = "tuple struct or tuple variant";
14891493
let e = report_unexpected_variant_res(tcx, res, None, qpath, pat.span, E0164, expected);
1490-
on_error(e);
1491-
e
1494+
Err(e)
14921495
};
14931496

14941497
// Resolve the path and check the definition for errors.
@@ -1497,25 +1500,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14971500
if res == Res::Err {
14981501
let e = self.dcx().span_delayed_bug(pat.span, "`Res::Err` but no error emitted");
14991502
self.set_tainted_by_errors(e);
1500-
on_error(e);
1501-
return Ty::new_error(tcx, e);
1503+
return Err(e);
15021504
}
15031505

15041506
// Type-check the path.
15051507
let (pat_ty, res) =
15061508
self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.span, pat.hir_id);
15071509
if !pat_ty.is_fn() {
1508-
let e = report_unexpected_res(res);
1509-
return Ty::new_error(tcx, e);
1510+
return report_unexpected_res(res);
15101511
}
15111512

15121513
let variant = match res {
15131514
Res::Err => {
15141515
self.dcx().span_bug(pat.span, "`Res::Err` but no error emitted");
15151516
}
15161517
Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) => {
1517-
let e = report_unexpected_res(res);
1518-
return Ty::new_error(tcx, e);
1518+
return report_unexpected_res(res);
15191519
}
15201520
Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => tcx.expect_variant_res(res),
15211521
_ => bug!("unexpected pattern resolution: {:?}", res),
@@ -1525,6 +1525,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15251525
let pat_ty = pat_ty.fn_sig(tcx).output();
15261526
let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
15271527

1528+
Ok(ResolvedPat { ty: pat_ty, kind: ResolvedPatKind::TupleStruct { res, variant } })
1529+
}
1530+
1531+
fn check_pat_tuple_struct(
1532+
&self,
1533+
pat: &'tcx Pat<'tcx>,
1534+
qpath: &'tcx hir::QPath<'tcx>,
1535+
subpats: &'tcx [Pat<'tcx>],
1536+
ddpos: hir::DotDotPos,
1537+
res: Res,
1538+
pat_ty: Ty<'tcx>,
1539+
variant: &'tcx VariantDef,
1540+
expected: Ty<'tcx>,
1541+
pat_info: PatInfo<'tcx>,
1542+
) -> Ty<'tcx> {
1543+
let tcx = self.tcx;
1544+
let on_error = |e| {
1545+
for pat in subpats {
1546+
self.check_pat(pat, Ty::new_error(tcx, e), pat_info);
1547+
}
1548+
};
1549+
15281550
// Type-check the tuple struct pattern against the expected type.
15291551
let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, &pat_info.top_info);
15301552
let had_err = diag.map_err(|diag| diag.emit());

0 commit comments

Comments
 (0)