diff options
| author | bors <bors@rust-lang.org> | 2019-06-07 09:41:06 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-06-07 09:41:06 +0000 |
| commit | c1c60d292e2dd2deff7084208274f9a02f750d43 (patch) | |
| tree | 314fbfbd0ef2dc81db3674186d122b582b6cc7a6 /src/librustc_mir/transform | |
| parent | ca1bcfdde3f19afd68ef808cecf2ce56d08d5df4 (diff) | |
| parent | bcf836567560c2f31dac79aa0379c0f0e2740081 (diff) | |
| download | rust-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.rs | 68 | ||||
| -rw-r--r-- | src/librustc_mir/transform/mod.rs | 12 |
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); |
