//! Contains checks that must be run to validate matches before performing usefulness analysis. use crate::constructor::Constructor::*; use crate::pat_column::PatternColumn; use crate::{MatchArm, PatCx}; /// Validate that deref patterns and normal constructors aren't used to match on the same place. pub(crate) fn detect_mixed_deref_pat_ctors<'p, Cx: PatCx>( cx: &Cx, arms: &[MatchArm<'p, Cx>], ) -> Result<(), Cx::Error> { let pat_column = PatternColumn::new(arms); detect_mixed_deref_pat_ctors_inner(cx, &pat_column) } fn detect_mixed_deref_pat_ctors_inner<'p, Cx: PatCx>( cx: &Cx, column: &PatternColumn<'p, Cx>, ) -> Result<(), Cx::Error> { let Some(ty) = column.head_ty() else { return Ok(()); }; // Check for a mix of deref patterns and normal constructors. let mut deref_pat = None; let mut normal_pat = None; for pat in column.iter() { match pat.ctor() { // The analysis can handle mixing deref patterns with wildcards and opaque patterns. Wildcard | Opaque(_) => {} DerefPattern(_) => deref_pat = Some(pat), // Nothing else can be compared to deref patterns in `Constructor::is_covered_by`. _ => normal_pat = Some(pat), } } if let Some(deref_pat) = deref_pat && let Some(normal_pat) = normal_pat { return Err(cx.report_mixed_deref_pat_ctors(deref_pat, normal_pat)); } // Specialize and recurse into the patterns' fields. let set = column.analyze_ctors(cx, &ty)?; for ctor in set.present { for specialized_column in column.specialize(cx, &ty, &ctor).iter() { detect_mixed_deref_pat_ctors_inner(cx, specialized_column)?; } } Ok(()) }