Inline trans_switch to simplify code

This commit is contained in:
Mark Simulacrum 2017-01-02 13:05:42 -07:00
parent 426c558c5a
commit 81e8137b0d
2 changed files with 13 additions and 33 deletions

View File

@ -56,12 +56,6 @@ use monomorphize;
use type_::Type;
use type_of;
#[derive(Copy, Clone, PartialEq)]
pub enum BranchKind {
Switch,
Single
}
/// Given an enum, struct, closure, or tuple, extracts fields.
/// Treats closures as a struct with one variant.
/// `empty_if_no_variants` is a switch to deal with empty enums.
@ -273,28 +267,6 @@ fn struct_llfields<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, fields: &Vec<Ty<'tcx>>
}
}
/// Obtain a representation of the discriminant sufficient to translate
/// destructuring; this may or may not involve the actual discriminant.
pub fn trans_switch<'a, 'tcx>(
bcx: &Builder<'a, 'tcx>,
t: Ty<'tcx>,
scrutinee: ValueRef,
range_assert: bool
) -> (BranchKind, Option<ValueRef>) {
let l = bcx.ccx.layout_of(t);
match *l {
layout::CEnum { .. } | layout::General { .. } |
layout::RawNullablePointer { .. } | layout::StructWrappedNullablePointer { .. } => {
(BranchKind::Switch, Some(trans_get_discr(bcx, t, scrutinee, None, range_assert)))
}
layout::Univariant { .. } | layout::UntaggedUnion { .. } => {
// N.B.: Univariant means <= 1 enum variants (*not* == 1 variants).
(BranchKind::Single, None)
},
_ => bug!("{} is not an enum.", t)
}
}
pub fn is_discr_signed<'tcx>(l: &layout::Layout) -> bool {
match *l {
layout::CEnum { signed, .. }=> signed,

View File

@ -20,7 +20,7 @@ use llvm::{ValueRef, get_param};
use middle::lang_items::BoxFreeFnLangItem;
use rustc::ty::subst::{Substs};
use rustc::traits;
use rustc::ty::{self, AdtDef, AdtKind, Ty, TypeFoldable};
use rustc::ty::{self, layout, AdtDef, AdtKind, Ty, TypeFoldable};
use rustc::ty::subst::Kind;
use rustc::mir::tcx::LvalueTy;
use mir::lvalue::LvalueRef;
@ -471,14 +471,22 @@ fn drop_structural_ty<'a, 'tcx>(cx: Builder<'a, 'tcx>, ptr: LvalueRef<'tcx>) ->
// NB: we must hit the discriminant first so that structural
// comparison know not to proceed when the discriminants differ.
match adt::trans_switch(&cx, t, ptr.llval, false) {
(adt::BranchKind::Single, None) => {
// Obtain a representation of the discriminant sufficient to translate
// destructuring; this may or may not involve the actual discriminant.
let l = cx.ccx.layout_of(t);
match *l {
layout::Univariant { .. } |
layout::UntaggedUnion { .. } => {
if n_variants != 0 {
assert!(n_variants == 1);
iter_variant(&cx, ptr, &adt, 0, substs);
}
}
(adt::BranchKind::Switch, Some(lldiscrim_a)) => {
layout::CEnum { .. } |
layout::General { .. } |
layout::RawNullablePointer { .. } |
layout::StructWrappedNullablePointer { .. } => {
let lldiscrim_a = adt::trans_get_discr(&cx, t, ptr.llval, None, false);
let tcx = cx.tcx();
drop_ty(&cx, LvalueRef::new_sized_ty(lldiscrim_a, tcx.types.isize));
@ -511,7 +519,7 @@ fn drop_structural_ty<'a, 'tcx>(cx: Builder<'a, 'tcx>, ptr: LvalueRef<'tcx>) ->
}
cx = next_cx;
}
_ => cx.sess().unimpl("value from adt::trans_switch in drop_structural_ty"),
_ => bug!("{} is not an enum.", t),
}
}
},