1
Fork 0

Auto merge of #85195 - Mark-Simulacrum:variant-by-idx, r=petrochenkov

Store VariantIdx to distinguish enum variants

This saves ~24% of the instructions on the match-stress-enum benchmark, but I'm not 100% sure that this is OK - if we ever compare two constructors across enums (e.g., a Result and an Option), then this is obviously insufficient; I can experiment with continuing to store the DefId for comparison purposes in that case.
This commit is contained in:
bors 2021-05-14 00:59:01 +00:00
commit 754d17121d

View file

@ -52,7 +52,6 @@ use super::{FieldPat, Pat, PatKind, PatRange};
use rustc_data_structures::captures::Captures; use rustc_data_structures::captures::Captures;
use rustc_index::vec::Idx; use rustc_index::vec::Idx;
use rustc_hir::def_id::DefId;
use rustc_hir::{HirId, RangeEnd}; use rustc_hir::{HirId, RangeEnd};
use rustc_middle::mir::interpret::ConstValue; use rustc_middle::mir::interpret::ConstValue;
use rustc_middle::mir::Field; use rustc_middle::mir::Field;
@ -590,7 +589,7 @@ pub(super) enum Constructor<'tcx> {
/// and fixed-length arrays. /// and fixed-length arrays.
Single, Single,
/// Enum variants. /// Enum variants.
Variant(DefId), Variant(VariantIdx),
/// Ranges of integer literal values (`2`, `2..=5` or `2..5`). /// Ranges of integer literal values (`2`, `2..=5` or `2..5`).
IntRange(IntRange), IntRange(IntRange),
/// Ranges of floating-point literal values (`2.0..=5.2`). /// Ranges of floating-point literal values (`2.0..=5.2`).
@ -634,7 +633,7 @@ impl<'tcx> Constructor<'tcx> {
fn variant_index_for_adt(&self, adt: &'tcx ty::AdtDef) -> VariantIdx { fn variant_index_for_adt(&self, adt: &'tcx ty::AdtDef) -> VariantIdx {
match *self { match *self {
Variant(id) => adt.variant_index_with_id(id), Variant(idx) => idx,
Single => { Single => {
assert!(!adt.is_enum()); assert!(!adt.is_enum());
VariantIdx::new(0) VariantIdx::new(0)
@ -649,9 +648,7 @@ impl<'tcx> Constructor<'tcx> {
PatKind::AscribeUserType { .. } => bug!(), // Handled by `expand_pattern` PatKind::AscribeUserType { .. } => bug!(), // Handled by `expand_pattern`
PatKind::Binding { .. } | PatKind::Wild => Wildcard, PatKind::Binding { .. } | PatKind::Wild => Wildcard,
PatKind::Leaf { .. } | PatKind::Deref { .. } => Single, PatKind::Leaf { .. } | PatKind::Deref { .. } => Single,
&PatKind::Variant { adt_def, variant_index, .. } => { &PatKind::Variant { variant_index, .. } => Variant(variant_index),
Variant(adt_def.variants[variant_index].def_id)
}
PatKind::Constant { value } => { PatKind::Constant { value } => {
if let Some(int_range) = IntRange::from_const(cx.tcx, cx.param_env, value) { if let Some(int_range) = IntRange::from_const(cx.tcx, cx.param_env, value) {
IntRange(int_range) IntRange(int_range)
@ -928,15 +925,15 @@ impl<'tcx> SplitWildcard<'tcx> {
// If `exhaustive_patterns` is enabled, we exclude variants known to be // If `exhaustive_patterns` is enabled, we exclude variants known to be
// uninhabited. // uninhabited.
def.variants def.variants
.iter() .iter_enumerated()
.filter(|v| { .filter(|(_, v)| {
!v.uninhabited_from(cx.tcx, substs, def.adt_kind(), cx.param_env) !v.uninhabited_from(cx.tcx, substs, def.adt_kind(), cx.param_env)
.contains(cx.tcx, cx.module) .contains(cx.tcx, cx.module)
}) })
.map(|v| Variant(v.def_id)) .map(|(idx, _)| Variant(idx))
.collect() .collect()
} else { } else {
def.variants.iter().map(|v| Variant(v.def_id)).collect() def.variants.indices().map(|idx| Variant(idx)).collect()
} }
} }
ty::Char => { ty::Char => {