Skip to content

Commit 399796d

Browse files
committed
Add comments to obscure code, remove unnesecary parameter from closure
1 parent 4ee2fe3 commit 399796d

File tree

1 file changed

+18
-6
lines changed

1 file changed

+18
-6
lines changed

compiler/rustc_typeck/src/check/check.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -1499,16 +1499,18 @@ fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, vs: &'tcx [hir::Variant<'tcx>], def_id: L
14991499
check_transparent(tcx, sp, def);
15001500
}
15011501

1502+
/// Part of enum check, errors if two or more discriminants are equal
15021503
fn detect_discriminant_duplicate<'tcx>(
15031504
tcx: TyCtxt<'tcx>,
15041505
mut discrs: Vec<(VariantIdx, Discr<'tcx>)>,
15051506
vs: &'tcx [hir::Variant<'tcx>],
15061507
self_span: Span,
15071508
) {
1508-
let report = |var: &hir::Variant<'_>,
1509-
dis: Discr<'tcx>,
1509+
// Helper closure to reduce duplicate code. This gets called everytime we detect a duplicate
1510+
let report = |dis: Discr<'tcx>,
15101511
idx: usize,
15111512
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>| {
1513+
let var = &vs[idx];
15121514
let (span, display_discr) = match var.disr_expr {
15131515
Some(ref expr) => {
15141516
// In the case the discriminant is both a duplicate and overflowed, let the user know
@@ -1517,11 +1519,16 @@ fn detect_discriminant_duplicate<'tcx>(
15171519
&& *lit_value != dis.val
15181520
{
15191521
(tcx.hir().span(expr.hir_id), format!("`{dis}` (overflowed from `{lit_value}`)"))
1522+
// Otherwise, format the value as-is
15201523
} else {
15211524
(tcx.hir().span(expr.hir_id), format!("`{dis}`"))
15221525
}
15231526
}
15241527
None => {
1528+
// At this point we know this discriminant is a duplicate, and was not explicitly
1529+
// assigned by the user. Here we iterate backwards to fetch the hir for the last
1530+
// explictly assigned discriminant, and letting the user know that this was the
1531+
// increment startpoint, and how many steps from there leading to the duplicate
15251532
if let Some((n, hir::Variant { span, ident, .. })) =
15261533
vs[..idx].iter().rev().enumerate().find(|v| v.1.disr_expr.is_some())
15271534
{
@@ -1542,16 +1549,20 @@ fn detect_discriminant_duplicate<'tcx>(
15421549
err.span_label(span, format!("{display_discr} assigned here"));
15431550
};
15441551

1552+
// Here we are looping through the discriminant vec, comparing each discriminant to oneanother.
1553+
// When a duplicate is detected, we instatiate an error and add a spanned note pointing to both
1554+
// initial and duplicate value. The duplicate discriminant is then discarded from the vec by swapping
1555+
// it with the last element and decrementing the vec.len by 1 (which is why we have to evaluate
1556+
// `discrs.len()` anew every iteration, and why this could be tricky to do in a functional style as
1557+
// we are mutating `discrs` on the fly).
15451558
let mut i = 0;
15461559
while i < discrs.len() {
15471560
let hir_var_i_idx = discrs[i].0.index();
1548-
let hir_var_i = &vs[hir_var_i_idx];
15491561
let mut error: Option<DiagnosticBuilder<'_, _>> = None;
15501562

15511563
let mut o = i + 1;
15521564
while o < discrs.len() {
15531565
let hir_var_o_idx = discrs[o].0.index();
1554-
let hir_var_o = &vs[hir_var_o_idx];
15551566

15561567
if discrs[i].1.val == discrs[o].1.val {
15571568
let err = error.get_or_insert_with(|| {
@@ -1563,13 +1574,14 @@ fn detect_discriminant_duplicate<'tcx>(
15631574
discrs[i].1,
15641575
);
15651576

1566-
report(hir_var_i, discrs[i].1, hir_var_i_idx, &mut ret);
1577+
report(discrs[i].1, hir_var_i_idx, &mut ret);
15671578

15681579
ret
15691580
});
15701581

1571-
report(hir_var_o, discrs[o].1, hir_var_o_idx, err);
1582+
report(discrs[o].1, hir_var_o_idx, err);
15721583

1584+
// Safe to unwrap here, as we wouldn't reach this point if `discrs` was empty
15731585
discrs[o] = *discrs.last().unwrap();
15741586
discrs.pop();
15751587
} else {

0 commit comments

Comments
 (0)