Skip to content

Commit 3eb7dd7

Browse files
committed
Prep for dropflag-hints: Clarify trans bindings MoveByRef and MoveIntoCopy.
1 parent 4c371bb commit 3eb7dd7

File tree

2 files changed

+49
-18
lines changed

2 files changed

+49
-18
lines changed

src/librustc_trans/trans/_match.rs

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -330,11 +330,35 @@ pub enum OptResult<'blk, 'tcx: 'blk> {
330330

331331
#[derive(Clone, Copy, PartialEq)]
332332
pub enum TransBindingMode {
333+
/// By-value binding for a copy type: copies from matched data
334+
/// into a fresh LLVM alloca.
333335
TrByCopy(/* llbinding */ ValueRef),
334-
TrByMove,
336+
337+
/// By-value binding for a non-copy type where we copy into a
338+
/// fresh LLVM alloca; this most accurately reflects the language
339+
/// semantics (e.g. it properly handles overwrites of the matched
340+
/// input), but potentially injects an unwanted copy.
341+
TrByMoveIntoCopy(/* llbinding */ ValueRef),
342+
343+
/// Binding a non-copy type by reference under the hood; this is
344+
/// a codegen optimization to avoid unnecessary memory traffic.
345+
TrByMoveRef,
346+
347+
/// By-ref binding exposed in the original source input.
335348
TrByRef,
336349
}
337350

351+
impl TransBindingMode {
352+
/// if binding by making a fresh copy; returns the alloca that it
353+
/// will copy into; otherwise None.
354+
fn alloca_if_copy(&self) -> Option<ValueRef> {
355+
match *self {
356+
TrByCopy(llbinding) | TrByMoveIntoCopy(llbinding) => Some(llbinding),
357+
TrByMoveRef | TrByRef => None,
358+
}
359+
}
360+
}
361+
338362
/// Information about a pattern binding:
339363
/// - `llmatch` is a pointer to a stack slot. The stack slot contains a
340364
/// pointer into the value being matched. Hence, llmatch has type `T**`
@@ -891,7 +915,8 @@ fn insert_lllocals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
891915
let llval = match binding_info.trmode {
892916
// By value mut binding for a copy type: load from the ptr
893917
// into the matched value and copy to our alloca
894-
TrByCopy(llbinding) => {
918+
TrByCopy(llbinding) |
919+
TrByMoveIntoCopy(llbinding) => {
895920
let llval = Load(bcx, binding_info.llmatch);
896921
let datum = Datum::new(llval, binding_info.ty, Lvalue);
897922
call_lifetime_start(bcx, llbinding);
@@ -904,7 +929,7 @@ fn insert_lllocals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
904929
},
905930

906931
// By value move bindings: load from the ptr into the matched value
907-
TrByMove => Load(bcx, binding_info.llmatch),
932+
TrByMoveRef => Load(bcx, binding_info.llmatch),
908933

909934
// By ref binding: use the ptr into the matched value
910935
TrByRef => binding_info.llmatch
@@ -944,8 +969,8 @@ fn compile_guard<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
944969
let val = val.to_llbool(bcx);
945970

946971
for (_, &binding_info) in &data.bindings_map {
947-
if let TrByCopy(llbinding) = binding_info.trmode {
948-
call_lifetime_end(bcx, llbinding);
972+
if let Some(llbinding) = binding_info.trmode.alloca_if_copy() {
973+
call_lifetime_end(bcx, llbinding)
949974
}
950975
}
951976

@@ -1415,16 +1440,21 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat,
14151440

14161441
let llmatch;
14171442
let trmode;
1443+
let moves_by_default = variable_ty.moves_by_default(&param_env, span);
14181444
match bm {
1419-
ast::BindByValue(_)
1420-
if !variable_ty.moves_by_default(&param_env, span) || reassigned =>
1445+
ast::BindByValue(_) if !moves_by_default || reassigned =>
14211446
{
14221447
llmatch = alloca_no_lifetime(bcx,
1423-
llvariable_ty.ptr_to(),
1424-
"__llmatch");
1425-
trmode = TrByCopy(alloca_no_lifetime(bcx,
1426-
llvariable_ty,
1427-
&bcx.name(name)));
1448+
llvariable_ty.ptr_to(),
1449+
"__llmatch");
1450+
let llcopy = alloca_no_lifetime(bcx,
1451+
llvariable_ty,
1452+
&bcx.name(name));
1453+
trmode = if moves_by_default {
1454+
TrByMoveIntoCopy(llcopy)
1455+
} else {
1456+
TrByCopy(llcopy)
1457+
};
14281458
}
14291459
ast::BindByValue(_) => {
14301460
// in this case, the final type of the variable will be T,
@@ -1433,11 +1463,11 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat,
14331463
llmatch = alloca_no_lifetime(bcx,
14341464
llvariable_ty.ptr_to(),
14351465
&bcx.name(name));
1436-
trmode = TrByMove;
1466+
trmode = TrByMoveRef;
14371467
}
14381468
ast::BindByRef(_) => {
14391469
llmatch = alloca_no_lifetime(bcx,
1440-
llvariable_ty,
1470+
llvariable_ty,
14411471
&bcx.name(name));
14421472
trmode = TrByRef;
14431473
}

src/librustc_trans/trans/debuginfo/metadata.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use middle::infer;
3030
use rustc::ast_map;
3131
use trans::{type_of, adt, machine, monomorphize};
3232
use trans::common::{self, CrateContext, FunctionContext, Block};
33-
use trans::_match::{BindingInfo, TrByCopy, TrByMove, TrByRef};
33+
use trans::_match::{BindingInfo, TransBindingMode};
3434
use trans::type_::Type;
3535
use middle::ty::{self, Ty};
3636
use session::config::{self, FullDebugInfo};
@@ -2082,14 +2082,15 @@ pub fn create_match_binding_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
20822082
// dereference once more. For ByCopy we just use the stack slot we created
20832083
// for the binding.
20842084
let var_access = match binding.trmode {
2085-
TrByCopy(llbinding) => VariableAccess::DirectVariable {
2085+
TransBindingMode::TrByCopy(llbinding) |
2086+
TransBindingMode::TrByMoveIntoCopy(llbinding) => VariableAccess::DirectVariable {
20862087
alloca: llbinding
20872088
},
2088-
TrByMove => VariableAccess::IndirectVariable {
2089+
TransBindingMode::TrByMoveRef => VariableAccess::IndirectVariable {
20892090
alloca: binding.llmatch,
20902091
address_operations: &aops
20912092
},
2092-
TrByRef => VariableAccess::DirectVariable {
2093+
TransBindingMode::TrByRef => VariableAccess::DirectVariable {
20932094
alloca: binding.llmatch
20942095
}
20952096
};

0 commit comments

Comments
 (0)