diff options
Diffstat (limited to 'compiler/rustc_pattern_analysis/src')
| -rw-r--r-- | compiler/rustc_pattern_analysis/src/lib.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_pattern_analysis/src/lints.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_pattern_analysis/src/rustc.rs | 17 | ||||
| -rw-r--r-- | compiler/rustc_pattern_analysis/src/usefulness.rs | 4 |
4 files changed, 24 insertions, 11 deletions
diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index 4d2d66c88a5..b52643adcc9 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -77,7 +77,7 @@ pub trait TypeCx: Sized + fmt::Debug { /// The set of all the constructors for `ty`. /// /// This must follow the invariants of `ConstructorSet` - fn ctors_for_ty(&self, ty: Self::Ty) -> ConstructorSet<Self>; + fn ctors_for_ty(&self, ty: Self::Ty) -> Result<ConstructorSet<Self>, Self::Error>; /// Best-effort `Debug` implementation. fn debug_pat(f: &mut fmt::Formatter<'_>, pat: &DeconstructedPat<'_, Self>) -> fmt::Result; diff --git a/compiler/rustc_pattern_analysis/src/lints.rs b/compiler/rustc_pattern_analysis/src/lints.rs index f74e00342d0..08a1a6bcbc4 100644 --- a/compiler/rustc_pattern_analysis/src/lints.rs +++ b/compiler/rustc_pattern_analysis/src/lints.rs @@ -52,9 +52,13 @@ impl<'p, 'tcx> PatternColumn<'p, 'tcx> { } /// Do constructor splitting on the constructors of the column. - fn analyze_ctors(&self, pcx: &PlaceCtxt<'_, 'p, 'tcx>) -> SplitConstructorSet<'p, 'tcx> { + fn analyze_ctors( + &self, + pcx: &PlaceCtxt<'_, 'p, 'tcx>, + ) -> Result<SplitConstructorSet<'p, 'tcx>, ErrorGuaranteed> { let column_ctors = self.patterns.iter().map(|p| p.ctor()); - pcx.ctors_for_ty().split(pcx, column_ctors) + let ctors_for_ty = &pcx.ctors_for_ty()?; + Ok(ctors_for_ty.split(pcx, column_ctors)) } fn iter(&self) -> impl Iterator<Item = &'p DeconstructedPat<'p, 'tcx>> + Captures<'_> { @@ -116,7 +120,7 @@ fn collect_nonexhaustive_missing_variants<'a, 'p, 'tcx>( }; let pcx = &PlaceCtxt::new_dummy(cx, ty); - let set = column.analyze_ctors(pcx); + let set = column.analyze_ctors(pcx)?; if set.present.is_empty() { // We can't consistently handle the case where no constructors are present (since this would // require digging deep through any type in case there's a non_exhaustive enum somewhere), @@ -219,7 +223,7 @@ pub(crate) fn lint_overlapping_range_endpoints<'a, 'p, 'tcx>( let pcx = &PlaceCtxt::new_dummy(cx, ty); let rcx: &RustcMatchCheckCtxt<'_, '_> = cx.tycx; - let set = column.analyze_ctors(pcx); + let set = column.analyze_ctors(pcx)?; if matches!(ty.kind(), ty::Char | ty::Int(_) | ty::Uint(_)) { let emit_lint = |overlap: &IntRange, this_span: Span, overlapped_spans: &[Span]| { diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index d757c5be602..a8d1bece613 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -12,6 +12,7 @@ use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::{self, Const}; use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange, PatRangeBoundary}; use rustc_middle::ty::layout::IntegerExt; +use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, VariantDef}; use rustc_span::ErrorGuaranteed; use rustc_span::{Span, DUMMY_SP}; @@ -303,7 +304,10 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> { /// /// See [`crate::constructor`] for considerations of emptiness. #[instrument(level = "debug", skip(self), ret)] - pub fn ctors_for_ty(&self, ty: RevealedTy<'tcx>) -> ConstructorSet<'p, 'tcx> { + pub fn ctors_for_ty( + &self, + ty: RevealedTy<'tcx>, + ) -> Result<ConstructorSet<'p, 'tcx>, ErrorGuaranteed> { let cx = self; let make_uint_range = |start, end| { IntRange::from_range( @@ -312,9 +316,11 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> { RangeEnd::Included, ) }; + // Abort on type error. + ty.error_reported()?; // This determines the set of all possible constructors for the type `ty`. For numbers, // arrays and slices we use ranges and variable-length slices when appropriate. - match ty.kind() { + Ok(match ty.kind() { ty::Bool => ConstructorSet::Bool, ty::Char => { // The valid Unicode Scalar Value ranges. @@ -424,7 +430,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> { ty::CoroutineWitness(_, _) | ty::Bound(_, _) | ty::Placeholder(_) | ty::Infer(_) => { bug!("Encountered unexpected type in `ConstructorSet::for_ty`: {ty:?}") } - } + }) } pub(crate) fn lower_pat_range_bdy( @@ -965,7 +971,10 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> { ) -> &[Self::Ty] { self.ctor_sub_tys(ctor, ty) } - fn ctors_for_ty(&self, ty: Self::Ty) -> crate::constructor::ConstructorSet<Self> { + fn ctors_for_ty( + &self, + ty: Self::Ty, + ) -> Result<crate::constructor::ConstructorSet<Self>, Self::Error> { self.ctors_for_ty(ty) } diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs index 8d81a79b796..d227bca5022 100644 --- a/compiler/rustc_pattern_analysis/src/usefulness.rs +++ b/compiler/rustc_pattern_analysis/src/usefulness.rs @@ -753,7 +753,7 @@ impl<'a, 'p, Cx: TypeCx> PlaceCtxt<'a, 'p, Cx> { pub(crate) fn ctor_sub_tys(&self, ctor: &Constructor<Cx>) -> &[Cx::Ty] { self.mcx.tycx.ctor_sub_tys(ctor, self.ty) } - pub(crate) fn ctors_for_ty(&self) -> ConstructorSet<Cx> { + pub(crate) fn ctors_for_ty(&self) -> Result<ConstructorSet<Cx>, Cx::Error> { self.mcx.tycx.ctors_for_ty(self.ty) } } @@ -1383,7 +1383,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>( // Analyze the constructors present in this column. let ctors = matrix.heads().map(|p| p.ctor()); - let ctors_for_ty = pcx.ctors_for_ty(); + let ctors_for_ty = pcx.ctors_for_ty()?; let is_integers = matches!(ctors_for_ty, ConstructorSet::Integers { .. }); // For diagnostics. let split_set = ctors_for_ty.split(pcx, ctors); let all_missing = split_set.present.is_empty(); |
