// 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) => {
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);
},
Unit
}
+#[rustc_mir]
+fn t22() -> Option<u8> {
+ None
+}
+
fn main(){
unsafe {
assert_eq!(t1()(), regular());
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);
}
}