From 64d98f8ee037282c35007b64c2649055c56af1db Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:03 +0200 Subject: Merging upstream version 1.68.2+dfsg1. Signed-off-by: Daniel Baumann --- .../src/thir/pattern/deconstruct_pat.rs | 67 +++++++++------------- 1 file changed, 26 insertions(+), 41 deletions(-) (limited to 'compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs') diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index d60e8722c..aba5429da 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -45,7 +45,7 @@ use std::cell::Cell; use std::cmp::{self, max, min, Ordering}; use std::fmt; -use std::iter::{once, IntoIterator}; +use std::iter::once; use std::ops::RangeInclusive; use smallvec::{smallvec, SmallVec}; @@ -67,6 +67,7 @@ use self::SliceKind::*; use super::compare_const_vals; use super::usefulness::{MatchCheckCtxt, PatCtxt}; +use crate::errors::{Overlap, OverlappingRangeEndpoints}; /// Recursively expand this pattern into its subpatterns. Only useful for or-patterns. fn expand_or_pat<'p, 'tcx>(pat: &'p Pat<'tcx>) -> Vec<&'p Pat<'tcx>> { @@ -96,7 +97,7 @@ fn expand_or_pat<'p, 'tcx>(pat: &'p Pat<'tcx>) -> Vec<&'p Pat<'tcx>> { /// `IntRange` is never used to encode an empty range or a "range" that wraps /// around the (offset) space: i.e., `range.lo <= range.hi`. #[derive(Clone, PartialEq, Eq)] -pub(super) struct IntRange { +pub(crate) struct IntRange { range: RangeInclusive, /// Keeps the bias used for encoding the range. It depends on the type of the range and /// possibly the pointer size of the current architecture. The algorithm ensures we never @@ -140,27 +141,22 @@ impl IntRange { ) -> Option { let ty = value.ty(); if let Some((target_size, bias)) = Self::integral_size_and_signed_bias(tcx, ty) { - let val = (|| { - match value { - mir::ConstantKind::Val(ConstValue::Scalar(scalar), _) => { - // For this specific pattern we can skip a lot of effort and go - // straight to the result, after doing a bit of checking. (We - // could remove this branch and just fall through, which - // is more general but much slower.) - return scalar.to_bits_or_ptr_internal(target_size).unwrap().left(); - } - mir::ConstantKind::Ty(c) => match c.kind() { - ty::ConstKind::Value(_) => bug!( - "encountered ConstValue in mir::ConstantKind::Ty, whereas this is expected to be in ConstantKind::Val" - ), - _ => {} - }, - _ => {} + let val = if let mir::ConstantKind::Val(ConstValue::Scalar(scalar), _) = value { + // For this specific pattern we can skip a lot of effort and go + // straight to the result, after doing a bit of checking. (We + // could remove this branch and just fall through, which + // is more general but much slower.) + scalar.to_bits_or_ptr_internal(target_size).unwrap().left()? + } else { + if let mir::ConstantKind::Ty(c) = value + && let ty::ConstKind::Value(_) = c.kind() + { + bug!("encountered ConstValue in mir::ConstantKind::Ty, whereas this is expected to be in ConstantKind::Val"); } // This is a more general form of the previous case. - value.try_eval_bits(tcx, param_env, ty) - })()?; + value.try_eval_bits(tcx, param_env, ty)? + }; let val = val ^ bias; Some(IntRange { range: val..=val, bias }) } else { @@ -284,32 +280,21 @@ impl IntRange { return; } - let overlaps: Vec<_> = pats + let overlap: Vec<_> = pats .filter_map(|pat| Some((pat.ctor().as_int_range()?, pat.span()))) .filter(|(range, _)| self.suspicious_intersection(range)) - .map(|(range, span)| (self.intersection(&range).unwrap(), span)) + .map(|(range, span)| Overlap { + range: self.intersection(&range).unwrap().to_pat(pcx.cx.tcx, pcx.ty), + span, + }) .collect(); - if !overlaps.is_empty() { - pcx.cx.tcx.struct_span_lint_hir( + if !overlap.is_empty() { + pcx.cx.tcx.emit_spanned_lint( lint::builtin::OVERLAPPING_RANGE_ENDPOINTS, hir_id, pcx.span, - "multiple patterns overlap on their endpoints", - |lint| { - for (int_range, span) in overlaps { - lint.span_label( - span, - &format!( - "this range overlaps on `{}`...", - int_range.to_pat(pcx.cx.tcx, pcx.ty) - ), - ); - } - lint.span_label(pcx.span, "... with this range"); - lint.note("you likely meant to write mutually exclusive ranges"); - lint - }, + OverlappingRangeEndpoints { overlap, range: pcx.span }, ); } } @@ -404,7 +389,7 @@ impl SplitIntRange { } /// Iterate over the contained ranges. - fn iter<'a>(&'a self) -> impl Iterator + Captures<'a> { + fn iter(&self) -> impl Iterator + Captures<'_> { use IntBorder::*; let self_range = Self::to_borders(self.range.clone()); @@ -612,7 +597,7 @@ impl SplitVarLenSlice { } /// Iterate over the partition of this slice. - fn iter<'a>(&'a self) -> impl Iterator + Captures<'a> { + fn iter(&self) -> impl Iterator + Captures<'_> { let smaller_lengths = match self.array_len { // The only admissible fixed-length slice is one of the array size. Whether `max_slice` // is fixed-length or variable-length, it will be the only relevant slice to output -- cgit v1.2.3