diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-03-18 22:24:36 +0100 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-18 22:24:36 +0100 | 
| commit | 2d3dcfaadea54c1a606787f3179b378af1ad0b0c (patch) | |
| tree | 360ac6c7eb95930bc9f2121ea614393aad8620b8 /compiler/rustc_pattern_analysis/src/constructor.rs | |
| parent | 05f763344d396fa59563da6aafb85c9f5e6716f4 (diff) | |
| parent | 1b31e14a3122d04080593f2f6ef31c18de8114d7 (diff) | |
| download | rust-2d3dcfaadea54c1a606787f3179b378af1ad0b0c.tar.gz rust-2d3dcfaadea54c1a606787f3179b378af1ad0b0c.zip  | |
Rollup merge of #121823 - Nadrieril:never-witnesses, r=compiler-errors
never patterns: suggest `!` patterns on non-exhaustive matches When a match is non-exhaustive we now suggest never patterns whenever it makes sense. r? ``@compiler-errors``
Diffstat (limited to 'compiler/rustc_pattern_analysis/src/constructor.rs')
| -rw-r--r-- | compiler/rustc_pattern_analysis/src/constructor.rs | 39 | 
1 files changed, 33 insertions, 6 deletions
diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs index bbb89576ef7..5b58d7f43b2 100644 --- a/compiler/rustc_pattern_analysis/src/constructor.rs +++ b/compiler/rustc_pattern_analysis/src/constructor.rs @@ -678,15 +678,19 @@ pub enum Constructor<Cx: PatCx> { Or, /// Wildcard pattern. Wildcard, + /// Never pattern. Only used in `WitnessPat`. An actual never pattern should be lowered as + /// `Wildcard`. + Never, /// Fake extra constructor for enums that aren't allowed to be matched exhaustively. Also used - /// for those types for which we cannot list constructors explicitly, like `f64` and `str`. + /// for those types for which we cannot list constructors explicitly, like `f64` and `str`. Only + /// used in `WitnessPat`. NonExhaustive, - /// Fake extra constructor for variants that should not be mentioned in diagnostics. - /// We use this for variants behind an unstable gate as well as - /// `#[doc(hidden)]` ones. + /// Fake extra constructor for variants that should not be mentioned in diagnostics. We use this + /// for variants behind an unstable gate as well as `#[doc(hidden)]` ones. Only used in + /// `WitnessPat`. Hidden, /// Fake extra constructor for constructors that are not seen in the matrix, as explained at the - /// top of the file. + /// top of the file. Only used for specialization. Missing, /// Fake extra constructor that indicates and empty field that is private. When we encounter one /// we skip the column entirely so we don't observe its emptiness. Only used for specialization. @@ -708,6 +712,7 @@ impl<Cx: PatCx> Clone for Constructor<Cx> { Constructor::Str(value) => Constructor::Str(value.clone()), Constructor::Opaque(inner) => Constructor::Opaque(inner.clone()), Constructor::Or => Constructor::Or, + Constructor::Never => Constructor::Never, Constructor::Wildcard => Constructor::Wildcard, Constructor::NonExhaustive => Constructor::NonExhaustive, Constructor::Hidden => Constructor::Hidden, @@ -1040,10 +1045,32 @@ impl<Cx: PatCx> ConstructorSet<Cx> { // In a `MaybeInvalid` place even an empty pattern may be reachable. We therefore // add a dummy empty constructor here, which will be ignored if the place is // `ValidOnly`. - missing_empty.push(NonExhaustive); + missing_empty.push(Never); } } SplitConstructorSet { present, missing, missing_empty } } + + /// Whether this set only contains empty constructors. + pub(crate) fn all_empty(&self) -> bool { + match self { + ConstructorSet::Bool + | ConstructorSet::Integers { .. } + | ConstructorSet::Ref + | ConstructorSet::Union + | ConstructorSet::Unlistable => false, + ConstructorSet::NoConstructors => true, + ConstructorSet::Struct { empty } => *empty, + ConstructorSet::Variants { variants, non_exhaustive } => { + !*non_exhaustive + && variants + .iter() + .all(|visibility| matches!(visibility, VariantVisibility::Empty)) + } + ConstructorSet::Slice { array_len, subtype_is_empty } => { + *subtype_is_empty && matches!(array_len, Some(1..)) + } + } + } }  | 
