Skip to content

Commit 9196048

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 d6df469 commit 9196048

File tree

1 file changed

+32
-19
lines changed
  • compiler/rustc_hir_typeck/src

1 file changed

+32
-19
lines changed

compiler/rustc_hir_typeck/src/pat.rs

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -277,12 +277,14 @@ struct ResolvedPat<'tcx> {
277277
#[derive(Clone, Copy, Debug)]
278278
enum ResolvedPatKind<'tcx> {
279279
Path { res: Res, pat_res: Res, segments: &'tcx [hir::PathSegment<'tcx>] },
280+
Struct { variant: &'tcx VariantDef },
280281
}
281282

282283
impl<'tcx> ResolvedPat<'tcx> {
283284
fn adjust_mode(&self) -> AdjustMode {
284-
let ResolvedPatKind::Path { res, .. } = self.kind;
285-
if matches!(res, Res::Def(DefKind::Const | DefKind::AssocConst, _)) {
285+
if let ResolvedPatKind::Path { res, .. } = self.kind
286+
&& matches!(res, Res::Def(DefKind::Const | DefKind::AssocConst, _))
287+
{
286288
// These constants can be of a reference type, e.g. `const X: &u8 = &0;`.
287289
// Peeling the reference types too early will cause type checking failures.
288290
// Although it would be possible to *also* peel the types of the constants too.
@@ -378,6 +380,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
378380
PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, span }) => {
379381
Some(self.resolve_pat_path(*hir_id, *span, qpath))
380382
}
383+
PatKind::Struct(ref qpath, ..) => Some(self.resolve_pat_struct(pat, qpath)),
381384
_ => None,
382385
};
383386
let adjust_mode = self.calc_adjust_mode(pat, opt_path_res);
@@ -575,9 +578,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
575578
PatKind::TupleStruct(ref qpath, subpats, ddpos) => {
576579
self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, pat_info)
577580
}
578-
PatKind::Struct(ref qpath, fields, has_rest_pat) => {
579-
self.check_pat_struct(pat, qpath, fields, has_rest_pat, expected, pat_info)
580-
}
581+
PatKind::Struct(_, fields, has_rest_pat) => match opt_path_res.unwrap() {
582+
Ok(ResolvedPat { ty, kind: ResolvedPatKind::Struct { variant } }) => self
583+
.check_pat_struct(pat, fields, has_rest_pat, ty, variant, expected, pat_info),
584+
Err(guar) => {
585+
let ty_err = Ty::new_error(self.tcx, guar);
586+
for field in fields {
587+
self.check_pat(field.pat, ty_err, pat_info);
588+
}
589+
ty_err
590+
}
591+
Ok(pr) => span_bug!(pat.span, "struct pattern resolved to {pr:?}"),
592+
},
581593
PatKind::Guard(pat, cond) => {
582594
self.check_pat(pat, expected, pat_info);
583595
self.check_expr_has_type_or_error(cond, self.tcx.types.bool, |_| {});
@@ -1220,27 +1232,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12201232
Ok(())
12211233
}
12221234

1223-
fn check_pat_struct(
1235+
fn resolve_pat_struct(
12241236
&self,
12251237
pat: &'tcx Pat<'tcx>,
12261238
qpath: &hir::QPath<'tcx>,
1239+
) -> Result<ResolvedPat<'tcx>, ErrorGuaranteed> {
1240+
// Resolve the path and check the definition for errors.
1241+
let (variant, pat_ty) = self.check_struct_path(qpath, pat.hir_id)?;
1242+
Ok(ResolvedPat { ty: pat_ty, kind: ResolvedPatKind::Struct { variant } })
1243+
}
1244+
1245+
fn check_pat_struct(
1246+
&self,
1247+
pat: &'tcx Pat<'tcx>,
12271248
fields: &'tcx [hir::PatField<'tcx>],
12281249
has_rest_pat: bool,
1250+
pat_ty: Ty<'tcx>,
1251+
variant: &'tcx VariantDef,
12291252
expected: Ty<'tcx>,
12301253
pat_info: PatInfo<'tcx>,
12311254
) -> Ty<'tcx> {
1232-
// Resolve the path and check the definition for errors.
1233-
let (variant, pat_ty) = match self.check_struct_path(qpath, pat.hir_id) {
1234-
Ok(data) => data,
1235-
Err(guar) => {
1236-
let err = Ty::new_error(self.tcx, guar);
1237-
for field in fields {
1238-
self.check_pat(field.pat, err, pat_info);
1239-
}
1240-
return err;
1241-
}
1242-
};
1243-
12441255
// Type-check the path.
12451256
let _ = self.demand_eqtype_pat(pat.span, expected, pat_ty, &pat_info.top_info);
12461257

@@ -1366,7 +1377,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13661377
pat_span: Span,
13671378
resolved_pat: &ResolvedPat<'tcx>,
13681379
) {
1369-
let ResolvedPatKind::Path { res, pat_res, segments } = resolved_pat.kind;
1380+
let ResolvedPatKind::Path { res, pat_res, segments } = resolved_pat.kind else {
1381+
span_bug!(pat_span, "unexpected resolution for path pattern: {resolved_pat:?}");
1382+
};
13701383

13711384
if let Some(span) = self.tcx.hir_res_span(pat_res) {
13721385
e.span_label(span, format!("{} defined here", res.descr()));

0 commit comments

Comments
 (0)