mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Add comments to obscure code, remove unnesecary parameter from closure
This commit is contained in:
parent
4ee2fe308b
commit
399796d2b3
@ -1499,16 +1499,18 @@ fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, vs: &'tcx [hir::Variant<'tcx>], def_id: L
|
|||||||
check_transparent(tcx, sp, def);
|
check_transparent(tcx, sp, def);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Part of enum check, errors if two or more discriminants are equal
|
||||||
fn detect_discriminant_duplicate<'tcx>(
|
fn detect_discriminant_duplicate<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
mut discrs: Vec<(VariantIdx, Discr<'tcx>)>,
|
mut discrs: Vec<(VariantIdx, Discr<'tcx>)>,
|
||||||
vs: &'tcx [hir::Variant<'tcx>],
|
vs: &'tcx [hir::Variant<'tcx>],
|
||||||
self_span: Span,
|
self_span: Span,
|
||||||
) {
|
) {
|
||||||
let report = |var: &hir::Variant<'_>,
|
// Helper closure to reduce duplicate code. This gets called everytime we detect a duplicate
|
||||||
dis: Discr<'tcx>,
|
let report = |dis: Discr<'tcx>,
|
||||||
idx: usize,
|
idx: usize,
|
||||||
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>| {
|
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>| {
|
||||||
|
let var = &vs[idx];
|
||||||
let (span, display_discr) = match var.disr_expr {
|
let (span, display_discr) = match var.disr_expr {
|
||||||
Some(ref expr) => {
|
Some(ref expr) => {
|
||||||
// In the case the discriminant is both a duplicate and overflowed, let the user know
|
// In the case the discriminant is both a duplicate and overflowed, let the user know
|
||||||
@ -1517,11 +1519,16 @@ fn detect_discriminant_duplicate<'tcx>(
|
|||||||
&& *lit_value != dis.val
|
&& *lit_value != dis.val
|
||||||
{
|
{
|
||||||
(tcx.hir().span(expr.hir_id), format!("`{dis}` (overflowed from `{lit_value}`)"))
|
(tcx.hir().span(expr.hir_id), format!("`{dis}` (overflowed from `{lit_value}`)"))
|
||||||
|
// Otherwise, format the value as-is
|
||||||
} else {
|
} else {
|
||||||
(tcx.hir().span(expr.hir_id), format!("`{dis}`"))
|
(tcx.hir().span(expr.hir_id), format!("`{dis}`"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
// At this point we know this discriminant is a duplicate, and was not explicitly
|
||||||
|
// assigned by the user. Here we iterate backwards to fetch the hir for the last
|
||||||
|
// explictly assigned discriminant, and letting the user know that this was the
|
||||||
|
// increment startpoint, and how many steps from there leading to the duplicate
|
||||||
if let Some((n, hir::Variant { span, ident, .. })) =
|
if let Some((n, hir::Variant { span, ident, .. })) =
|
||||||
vs[..idx].iter().rev().enumerate().find(|v| v.1.disr_expr.is_some())
|
vs[..idx].iter().rev().enumerate().find(|v| v.1.disr_expr.is_some())
|
||||||
{
|
{
|
||||||
@ -1542,16 +1549,20 @@ fn detect_discriminant_duplicate<'tcx>(
|
|||||||
err.span_label(span, format!("{display_discr} assigned here"));
|
err.span_label(span, format!("{display_discr} assigned here"));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Here we are looping through the discriminant vec, comparing each discriminant to oneanother.
|
||||||
|
// When a duplicate is detected, we instatiate an error and add a spanned note pointing to both
|
||||||
|
// initial and duplicate value. The duplicate discriminant is then discarded from the vec by swapping
|
||||||
|
// it with the last element and decrementing the vec.len by 1 (which is why we have to evaluate
|
||||||
|
// `discrs.len()` anew every iteration, and why this could be tricky to do in a functional style as
|
||||||
|
// we are mutating `discrs` on the fly).
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
while i < discrs.len() {
|
while i < discrs.len() {
|
||||||
let hir_var_i_idx = discrs[i].0.index();
|
let hir_var_i_idx = discrs[i].0.index();
|
||||||
let hir_var_i = &vs[hir_var_i_idx];
|
|
||||||
let mut error: Option<DiagnosticBuilder<'_, _>> = None;
|
let mut error: Option<DiagnosticBuilder<'_, _>> = None;
|
||||||
|
|
||||||
let mut o = i + 1;
|
let mut o = i + 1;
|
||||||
while o < discrs.len() {
|
while o < discrs.len() {
|
||||||
let hir_var_o_idx = discrs[o].0.index();
|
let hir_var_o_idx = discrs[o].0.index();
|
||||||
let hir_var_o = &vs[hir_var_o_idx];
|
|
||||||
|
|
||||||
if discrs[i].1.val == discrs[o].1.val {
|
if discrs[i].1.val == discrs[o].1.val {
|
||||||
let err = error.get_or_insert_with(|| {
|
let err = error.get_or_insert_with(|| {
|
||||||
@ -1563,13 +1574,14 @@ fn detect_discriminant_duplicate<'tcx>(
|
|||||||
discrs[i].1,
|
discrs[i].1,
|
||||||
);
|
);
|
||||||
|
|
||||||
report(hir_var_i, discrs[i].1, hir_var_i_idx, &mut ret);
|
report(discrs[i].1, hir_var_i_idx, &mut ret);
|
||||||
|
|
||||||
ret
|
ret
|
||||||
});
|
});
|
||||||
|
|
||||||
report(hir_var_o, discrs[o].1, hir_var_o_idx, err);
|
report(discrs[o].1, hir_var_o_idx, err);
|
||||||
|
|
||||||
|
// Safe to unwrap here, as we wouldn't reach this point if `discrs` was empty
|
||||||
discrs[o] = *discrs.last().unwrap();
|
discrs[o] = *discrs.last().unwrap();
|
||||||
discrs.pop();
|
discrs.pop();
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user