about summary refs log tree commit diff
path: root/src/librustc_mir/transform
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-06-07 09:41:06 +0000
committerbors <bors@rust-lang.org>2019-06-07 09:41:06 +0000
commitc1c60d292e2dd2deff7084208274f9a02f750d43 (patch)
tree314fbfbd0ef2dc81db3674186d122b582b6cc7a6 /src/librustc_mir/transform
parentca1bcfdde3f19afd68ef808cecf2ce56d08d5df4 (diff)
parentbcf836567560c2f31dac79aa0379c0f0e2740081 (diff)
downloadrust-c1c60d292e2dd2deff7084208274f9a02f750d43.tar.gz
rust-c1c60d292e2dd2deff7084208274f9a02f750d43.zip
Auto merge of #61209 - matthewjasper:const-tuple-constructors, r=oli-obk
Make tuple constructors real const fns

Mir construction special cases `Ctor(...)` to be lowered as `Ctor { 0: ... }`, which means this doesn't come up much in practice, but it seems inconsistent not to allow this.

r? @oli-obk
Diffstat (limited to 'src/librustc_mir/transform')
-rw-r--r--src/librustc_mir/transform/deaggregator.rs68
-rw-r--r--src/librustc_mir/transform/mod.rs12
2 files changed, 20 insertions, 60 deletions
diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs
index 7da37f956ce..286c412622d 100644
--- a/src/librustc_mir/transform/deaggregator.rs
+++ b/src/librustc_mir/transform/deaggregator.rs
@@ -1,8 +1,7 @@
 use rustc::mir::*;
 use rustc::ty::TyCtxt;
-use rustc::ty::layout::VariantIdx;
-use rustc_data_structures::indexed_vec::Idx;
 use crate::transform::{MirPass, MirSource};
+use crate::util::expand_aggregate;
 
 pub struct Deaggregator;
 
@@ -31,7 +30,7 @@ impl MirPass for Deaggregator {
 
                 let stmt = stmt.replace_nop();
                 let source_info = stmt.source_info;
-                let (mut lhs, kind, operands) = match stmt.kind {
+                let (lhs, kind, operands) = match stmt.kind {
                     StatementKind::Assign(lhs, box rvalue) => {
                         match rvalue {
                             Rvalue::Aggregate(kind, operands) => (lhs, kind, operands),
@@ -41,62 +40,15 @@ impl MirPass for Deaggregator {
                     _ => bug!()
                 };
 
-                let mut set_discriminant = None;
-                let active_field_index = match *kind {
-                    AggregateKind::Adt(adt_def, variant_index, _, _, active_field_index) => {
-                        if adt_def.is_enum() {
-                            set_discriminant = Some(Statement {
-                                kind: StatementKind::SetDiscriminant {
-                                    place: lhs.clone(),
-                                    variant_index,
-                                },
-                                source_info,
-                            });
-                            lhs = lhs.downcast(adt_def, variant_index);
-                        }
-                        active_field_index
-                    }
-                    AggregateKind::Generator(..) => {
-                        // Right now we only support initializing generators to
-                        // variant 0 (Unresumed).
-                        let variant_index = VariantIdx::new(0);
-                        set_discriminant = Some(Statement {
-                            kind: StatementKind::SetDiscriminant {
-                                place: lhs.clone(),
-                                variant_index,
-                            },
-                            source_info,
-                        });
-
-                        // Operands are upvars stored on the base place, so no
-                        // downcast is necessary.
-
-                        None
-                    }
-                    _ => None
-                };
-
-                Some(operands.into_iter().enumerate().map(move |(i, op)| {
-                    let lhs_field = if let AggregateKind::Array(_) = *kind {
-                        // FIXME(eddyb) `offset` should be u64.
-                        let offset = i as u32;
-                        assert_eq!(offset as usize, i);
-                        lhs.clone().elem(ProjectionElem::ConstantIndex {
-                            offset,
-                            // FIXME(eddyb) `min_length` doesn't appear to be used.
-                            min_length: offset + 1,
-                            from_end: false
-                        })
-                    } else {
+                Some(expand_aggregate(
+                    lhs,
+                    operands.into_iter().map(|op| {
                         let ty = op.ty(local_decls, tcx);
-                        let field = Field::new(active_field_index.unwrap_or(i));
-                        lhs.clone().field(field, ty)
-                    };
-                    Statement {
-                        source_info,
-                        kind: StatementKind::Assign(lhs_field, box Rvalue::Use(op)),
-                    }
-                }).chain(set_discriminant))
+                        (op, ty)
+                    }),
+                    *kind,
+                    source_info,
+                ))
             });
         }
     }
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index 82193d98655..cc8aaa1c97f 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -1,4 +1,4 @@
-use crate::build;
+use crate::{build, shim};
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc::mir::{Body, MirPhase, Promoted};
 use rustc::ty::{TyCtxt, InstanceDef};
@@ -228,7 +228,15 @@ fn mir_validated<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
 }
 
 fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Body<'tcx> {
-    // `mir_borrowck` uses `mir_validated`, so we have to force it to
+    if tcx.is_constructor(def_id) {
+        // There's no reason to run all of the MIR passes on constructors when
+        // we can just output the MIR we want directly. This also saves const
+        // qualification and borrow checking the trouble of special casing
+        // constructors.
+        return shim::build_adt_ctor(tcx, def_id);
+    }
+
+    // (Mir-)Borrowck uses `mir_validated`, so we have to force it to
     // execute before we can steal.
     tcx.ensure().mir_borrowck(def_id);