]> git.lizzy.rs Git - rust.git/commitdiff
Also fix MIRification of unit enum variants
authorSimonas Kazlauskas <git@kazlauskas.me>
Sat, 26 Dec 2015 12:39:10 +0000 (14:39 +0200)
committerSimonas Kazlauskas <git@kazlauskas.me>
Sat, 26 Dec 2015 12:44:36 +0000 (14:44 +0200)
src/librustc_mir/hair/cx/expr.rs
src/librustc_trans/trans/mir/rvalue.rs
src/test/run-pass/mir_refs_correct.rs

index 46e6243c8bf30c205ecd21a0dbbf7edd556207e8..ce78a39d599a518d6bd4cf6d2600f249bc61f11b 100644 (file)
@@ -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) => {
index 55a41201b2ba17c849236fbf26c55dd53bb2bee4..a08ec123895df0cf2d164d670b69e1a266fa418f 100644 (file)
@@ -97,10 +97,10 @@ pub fn trans_rvalue(&mut self,
 
             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);
                     },
index 9b349c0e4e21bee0719deec86ea46e02501f3df1..2c0cd5d6c8ad66c424b1f537d886ca114452d0be 100644 (file)
@@ -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);
     }
 }