1
Fork 0

Handle match with non axhaustive variants in closures

This commit is contained in:
Roxane 2021-08-23 22:41:03 -04:00
parent 926f069950
commit 20de556a26
4 changed files with 131 additions and 2 deletions

View file

@ -15,7 +15,7 @@ use rustc_index::vec::Idx;
use rustc_infer::infer::InferCtxt;
use rustc_middle::hir::place::ProjectionKind;
use rustc_middle::mir::FakeReadCause;
use rustc_middle::ty::{self, adjustment, Ty, TyCtxt};
use rustc_middle::ty::{self, adjustment, AdtKind, Ty, TyCtxt};
use rustc_target::abi::VariantIdx;
use std::iter;
@ -845,5 +845,20 @@ fn delegate_consume<'a, 'tcx>(
}
fn is_multivariant_adt(ty: Ty<'tcx>) -> bool {
if let ty::Adt(def, _) = ty.kind() { def.variants.len() > 1 } else { false }
if let ty::Adt(def, _) = ty.kind() {
// Note that if a non-exhaustive SingleVariant is defined in another crate, we need
// to assume that more cases will be added to the variant in the future. This mean
// that we should handle non-exhaustive SingleVariant the same way we would handle
// a MultiVariant.
// If the variant is not local it must be defined in another crate.
let is_non_exhaustive = match def.adt_kind() {
AdtKind::Struct | AdtKind::Union => {
def.non_enum_variant().is_field_list_non_exhaustive()
}
AdtKind::Enum => def.is_variant_list_non_exhaustive(),
};
def.variants.len() > 1 || (!def.did.is_local() && is_non_exhaustive)
} else {
false
}
}