Also fix MIRification of unit enum variants
This commit is contained in:
parent
3150dddb0f
commit
7b68b5fc2a
@ -520,26 +520,39 @@ fn convert_path_expr<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr)
|
||||
// Otherwise there may be def_map borrow conflicts
|
||||
let def = cx.tcx.def_map.borrow()[&expr.id].full_def();
|
||||
let (def_id, kind) = match def {
|
||||
// A variant constructor.
|
||||
def::DefVariant(_, def_id, false) => (def_id, ItemKind::Function),
|
||||
// A regular function.
|
||||
def::DefFn(def_id, _) => (def_id, ItemKind::Function),
|
||||
def::DefMethod(def_id) => (def_id, ItemKind::Method),
|
||||
def::DefStruct(def_id) => {
|
||||
match cx.tcx.node_id_to_type(expr.id).sty {
|
||||
// A tuple-struct constructor.
|
||||
ty::TyBareFn(..) => (def_id, ItemKind::Function),
|
||||
// This is a special case: a unit struct which is used as a value. We return a
|
||||
// completely different ExprKind here to account for this special case.
|
||||
ty::TyStruct(adt_def, substs) => return ExprKind::Adt {
|
||||
def::DefStruct(def_id) => match cx.tcx.node_id_to_type(expr.id).sty {
|
||||
// A tuple-struct constructor.
|
||||
ty::TyBareFn(..) => (def_id, ItemKind::Function),
|
||||
// This is a special case: a unit struct which is used as a value. We return a
|
||||
// completely different ExprKind here to account for this special case.
|
||||
ty::TyStruct(adt_def, substs) => return ExprKind::Adt {
|
||||
adt_def: adt_def,
|
||||
variant_index: 0,
|
||||
substs: substs,
|
||||
fields: vec![],
|
||||
base: None
|
||||
},
|
||||
ref sty => panic!("unexpected sty: {:?}", sty)
|
||||
},
|
||||
def::DefVariant(enum_id, variant_id, false) => match cx.tcx.node_id_to_type(expr.id).sty {
|
||||
// A variant constructor.
|
||||
ty::TyBareFn(..) => (variant_id, ItemKind::Function),
|
||||
// A unit variant, similar special case to the struct case above.
|
||||
ty::TyEnum(adt_def, substs) => {
|
||||
debug_assert!(adt_def.did == enum_id);
|
||||
let index = adt_def.variant_index_with_id(variant_id);
|
||||
return ExprKind::Adt {
|
||||
adt_def: adt_def,
|
||||
variant_index: 0,
|
||||
substs: substs,
|
||||
variant_index: index,
|
||||
fields: vec![],
|
||||
base: None
|
||||
},
|
||||
ref sty => panic!("unexpected sty: {:?}", sty)
|
||||
}
|
||||
};
|
||||
},
|
||||
ref sty => panic!("unexpected sty: {:?}", sty)
|
||||
},
|
||||
def::DefConst(def_id) |
|
||||
def::DefAssociatedConst(def_id) => {
|
||||
|
@ -97,10 +97,10 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
|
||||
|
||||
mir::Rvalue::Aggregate(ref kind, ref operands) => {
|
||||
match *kind {
|
||||
// Unit struct, which is translated very differently compared to any other
|
||||
// aggregate
|
||||
mir::AggregateKind::Adt(adt_def, 0, _)
|
||||
if adt_def.struct_variant().kind() == ty::VariantKind::Unit => {
|
||||
// Unit struct or variant; both are translated very differently compared to any
|
||||
// other aggregate
|
||||
mir::AggregateKind::Adt(adt_def, index, _)
|
||||
if adt_def.variants[index].kind() == ty::VariantKind::Unit => {
|
||||
let repr = adt::represent_type(bcx.ccx(), dest.ty.to_ty(bcx.tcx()));
|
||||
adt::trans_set_discr(bcx, &*repr, dest.llval, 0);
|
||||
},
|
||||
|
@ -182,6 +182,11 @@ fn t21() -> Unit {
|
||||
Unit
|
||||
}
|
||||
|
||||
#[rustc_mir]
|
||||
fn t22() -> Option<u8> {
|
||||
None
|
||||
}
|
||||
|
||||
fn main(){
|
||||
unsafe {
|
||||
assert_eq!(t1()(), regular());
|
||||
@ -222,5 +227,6 @@ fn main(){
|
||||
assert_eq!(t19()(322u64, 2u32), F::f(322u64, 2u32));
|
||||
assert_eq!(t20()(123u64, 38u32), <u32 as T<_, _>>::staticmeth(123, 38));
|
||||
assert_eq!(t21(), Unit);
|
||||
assert_eq!(t22(), None);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user