Skip to content

Commit 9185bb3

Browse files
committed
Generate a direct assignment in MIR for let x = y;
1 parent 4aff10b commit 9185bb3

File tree

3 files changed

+34
-26
lines changed

3 files changed

+34
-26
lines changed

src/librustc_mir/build/expr/as_temp.rs

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
//! See docs in build/expr/mod.rs
1212
1313
use build::{BlockAnd, BlockAndExtension, Builder};
14-
use build::expr::category::Category;
1514
use hair::*;
1615
use rustc::middle::region;
1716
use rustc::mir::*;
@@ -57,23 +56,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
5756
});
5857
}
5958

60-
// Careful here not to cause an infinite cycle. If we always
61-
// called `into`, then for places like `x.f`, it would
62-
// eventually fallback to us, and we'd loop. There's a reason
63-
// for this: `as_temp` is the point where we bridge the "by
64-
// reference" semantics of `as_place` with the "by value"
65-
// semantics of `into`, `as_operand`, `as_rvalue`, and (of
66-
// course) `as_temp`.
67-
match Category::of(&expr.kind).unwrap() {
68-
Category::Place => {
69-
let place = unpack!(block = this.as_place(block, expr));
70-
let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place));
71-
this.cfg.push_assign(block, source_info, &Place::Local(temp), rvalue);
72-
}
73-
_ => {
74-
unpack!(block = this.into(&Place::Local(temp), block, expr));
75-
}
76-
}
59+
unpack!(block = this.into(&Place::Local(temp), block, expr));
7760

7861
// In constants, temp_lifetime is None. We should not need to drop
7962
// anything because no values with a destructor can be created in

src/librustc_mir/build/expr/into.rs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,37 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
288288
block.unit()
289289
}
290290

291+
// Avoid creating a temporary
292+
ExprKind::VarRef { .. } |
293+
ExprKind::SelfRef |
294+
ExprKind::StaticRef { .. } => {
295+
debug_assert!(Category::of(&expr.kind) == Some(Category::Place));
296+
297+
let place = unpack!(block = this.as_place(block, expr));
298+
let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place));
299+
this.cfg.push_assign(block, source_info, destination, rvalue);
300+
block.unit()
301+
}
302+
ExprKind::Index { .. } |
303+
ExprKind::Deref { .. } |
304+
ExprKind::Field { .. } => {
305+
debug_assert!(Category::of(&expr.kind) == Some(Category::Place));
306+
307+
// Create a "fake" temporary variable so that we check that the
308+
// value is Sized. Usually, this is caught in type checking, but
309+
// in the case of box expr there is no such check.
310+
if let Place::Projection(..) = destination {
311+
this.local_decls.push(LocalDecl::new_temp(expr.ty, expr.span));
312+
}
313+
314+
debug_assert!(Category::of(&expr.kind) == Some(Category::Place));
315+
316+
let place = unpack!(block = this.as_place(block, expr));
317+
let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place));
318+
this.cfg.push_assign(block, source_info, destination, rvalue);
319+
block.unit()
320+
}
321+
291322
// these are the cases that are more naturally handled by some other mode
292323
ExprKind::Unary { .. } |
293324
ExprKind::Binary { .. } |
@@ -300,18 +331,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
300331
ExprKind::Unsize { .. } |
301332
ExprKind::Repeat { .. } |
302333
ExprKind::Borrow { .. } |
303-
ExprKind::VarRef { .. } |
304-
ExprKind::SelfRef |
305-
ExprKind::StaticRef { .. } |
306334
ExprKind::Array { .. } |
307335
ExprKind::Tuple { .. } |
308336
ExprKind::Adt { .. } |
309337
ExprKind::Closure { .. } |
310-
ExprKind::Index { .. } |
311-
ExprKind::Deref { .. } |
312338
ExprKind::Literal { .. } |
313-
ExprKind::Yield { .. } |
314-
ExprKind::Field { .. } => {
339+
ExprKind::Yield { .. } => {
315340
debug_assert!(match Category::of(&expr.kind).unwrap() {
316341
Category::Rvalue(RvalueFunc::Into) => false,
317342
_ => true,

src/librustc_mir/build/expr/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
//! which can fallback to `into`. So if one of the `ExprKind` variants is not, in fact,
6666
//! implemented in the category where it is supposed to be, there will be a problem.
6767
//!
68-
//! Of those fallbacks, the most interesting one is `as_temp`, because
68+
//! Of those fallbacks, the most interesting one is `into`, because
6969
//! it discriminates based on the category of the expression. This is
7070
//! basically the point where the "by value" operations are bridged
7171
//! over to the "by reference" mode (`as_place`).

0 commit comments

Comments
 (0)