Tweak how we record missing constructors

This is slower but also not a performance-sensitive path.
This commit is contained in:
Nadrieril 2024-02-06 01:14:12 +01:00
parent 1280928a99
commit 924d6cd1a6

View File

@ -1319,7 +1319,7 @@ impl<Cx: TypeCx> WitnessMatrix<Cx> {
fn apply_constructor( fn apply_constructor(
&mut self, &mut self,
pcx: &PlaceCtxt<'_, Cx>, pcx: &PlaceCtxt<'_, Cx>,
missing_ctors: &[Constructor<Cx>], mut missing_ctors: &[Constructor<Cx>],
ctor: &Constructor<Cx>, ctor: &Constructor<Cx>,
report_individual_missing_ctors: bool, report_individual_missing_ctors: bool,
) { ) {
@ -1329,20 +1329,16 @@ impl<Cx: TypeCx> WitnessMatrix<Cx> {
if matches!(ctor, Constructor::Missing) { if matches!(ctor, Constructor::Missing) {
// We got the special `Missing` constructor that stands for the constructors not present // We got the special `Missing` constructor that stands for the constructors not present
// in the match. // in the match.
if missing_ctors.is_empty() { if !missing_ctors.is_empty() && !report_individual_missing_ctors {
// Nothing to report.
*self = Self::empty();
} else if !report_individual_missing_ctors {
// Report `_` as missing. // Report `_` as missing.
let pat = pcx.wild_from_ctor(Constructor::Wildcard); missing_ctors = &[Constructor::Wildcard];
self.push_pattern(pat);
} else if missing_ctors.iter().any(|c| c.is_non_exhaustive()) { } else if missing_ctors.iter().any(|c| c.is_non_exhaustive()) {
// We need to report a `_` anyway, so listing other constructors would be redundant. // We need to report a `_` anyway, so listing other constructors would be redundant.
// `NonExhaustive` is displayed as `_` just like `Wildcard`, but it will be picked // `NonExhaustive` is displayed as `_` just like `Wildcard`, but it will be picked
// up by diagnostics to add a note about why `_` is required here. // up by diagnostics to add a note about why `_` is required here.
let pat = pcx.wild_from_ctor(Constructor::NonExhaustive); missing_ctors = &[Constructor::NonExhaustive];
self.push_pattern(pat); }
} else {
// For each missing constructor `c`, we add a `c(_, _, _)` witness appropriately // For each missing constructor `c`, we add a `c(_, _, _)` witness appropriately
// filled with wildcards. // filled with wildcards.
let mut ret = Self::empty(); let mut ret = Self::empty();
@ -1354,7 +1350,6 @@ impl<Cx: TypeCx> WitnessMatrix<Cx> {
ret.extend(wit_matrix); ret.extend(wit_matrix);
} }
*self = ret; *self = ret;
}
} else { } else {
// Any other constructor we unspecialize as expected. // Any other constructor we unspecialize as expected.
for witness in self.0.iter_mut() { for witness in self.0.iter_mut() {