Skip to content

Commit 47594d4

Browse files
committed
erase local enum paths in non-exhaustive match suggestions
1 parent 00f2459 commit 47594d4

File tree

1 file changed

+32
-5
lines changed

1 file changed

+32
-5
lines changed

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+32-5
Original file line numberDiff line numberDiff line change
@@ -538,8 +538,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
538538
self.error = Err(report_non_exhaustive_match(
539539
&cx,
540540
self.thir,
541-
scrut.ty,
542-
scrut.span,
541+
scrut,
543542
witnesses,
544543
arms,
545544
braces_span,
@@ -1205,12 +1204,13 @@ fn pat_is_catchall(pat: &DeconstructedPat<'_, '_>) -> bool {
12051204
fn report_non_exhaustive_match<'p, 'tcx>(
12061205
cx: &PatCtxt<'p, 'tcx>,
12071206
thir: &Thir<'tcx>,
1208-
scrut_ty: Ty<'tcx>,
1209-
sp: Span,
1207+
scrut: &Expr<'tcx>,
12101208
witnesses: Vec<WitnessPat<'p, 'tcx>>,
12111209
arms: &[ArmId],
12121210
braces_span: Option<Span>,
12131211
) -> ErrorGuaranteed {
1212+
let scrut_ty = scrut.ty;
1213+
let sp = scrut.span;
12141214
let is_empty_match = arms.is_empty();
12151215
let non_empty_enum = match scrut_ty.kind() {
12161216
ty::Adt(def, _) => def.is_enum() && !def.variants().is_empty(),
@@ -1323,7 +1323,7 @@ fn report_non_exhaustive_match<'p, 'tcx>(
13231323
let suggested_arm = if suggest_the_witnesses {
13241324
let pattern = witnesses
13251325
.iter()
1326-
.map(|witness| cx.print_witness_pat(witness))
1326+
.map(|witness| erase_path_if_local(cx, witness, scrut, cx.print_witness_pat(witness)))
13271327
.collect::<Vec<String>>()
13281328
.join(" | ");
13291329
if witnesses.iter().all(|p| p.is_never_pattern()) && cx.tcx.features().never_patterns() {
@@ -1436,6 +1436,33 @@ fn report_non_exhaustive_match<'p, 'tcx>(
14361436
err.emit()
14371437
}
14381438

1439+
fn erase_path_if_local<'p, 'tcx>(
1440+
cx: &PatCtxt<'p, 'tcx>,
1441+
pat: &WitnessPat<'p, 'tcx>,
1442+
scrut: &Expr<'tcx>,
1443+
mut pat_str: String,
1444+
) -> String {
1445+
if let ty::Adt(adt_def, _) = *pat.ty().kind()
1446+
&& adt_def.is_enum()
1447+
{
1448+
let enum_parent_def_id = cx.tcx.parent(adt_def.did());
1449+
let scrut_parent_def_id = if let ExprKind::Scope { region_scope: _, lint_level, value: _ } =
1450+
scrut.kind
1451+
&& let LintLevel::Explicit(hir_id) = lint_level
1452+
{
1453+
Some(hir_id.owner.to_def_id())
1454+
} else {
1455+
None
1456+
};
1457+
if scrut_parent_def_id == Some(enum_parent_def_id) {
1458+
let segments: Vec<&str> = pat_str.split("::").collect();
1459+
let enum_name = segments[segments.len() - 2];
1460+
let variant_name = segments[segments.len() - 1];
1461+
pat_str = String::from(format!("{}::{}", enum_name, variant_name));
1462+
}
1463+
}
1464+
pat_str
1465+
}
14391466
fn joined_uncovered_patterns<'p, 'tcx>(
14401467
cx: &PatCtxt<'p, 'tcx>,
14411468
witnesses: &[WitnessPat<'p, 'tcx>],

0 commit comments

Comments
 (0)