From b4dd765e6884820bb9b5c46d18215657abb7ef22 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Tue, 28 Jul 2015 16:07:05 +0200 Subject: [PATCH] comments and code-cleanup in response to reviews. --- src/librustc_trans/trans/_match.rs | 21 ++++++++++++++++++--- src/librustc_trans/trans/datum.rs | 21 ++++++++++++++++++++- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index d5305b29d75..7d7fd111fe9 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -952,9 +952,24 @@ fn insert_lllocals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, Lvalue::new("_match::insert_lllocals"), TrByMoveIntoCopy(..) => { // match_input moves from the input into a - // separate stack slot; it must zero (at least - // until we track drop flags for a fragmented - // parent match input expression). + // separate stack slot. + // + // E.g. consider moving the value `D(A)` out + // of the tuple `(D(A), D(B))` and into the + // local variable `x` via the pattern `(x,_)`, + // leaving the remainder of the tuple `(_, + // D(B))` still to be dropped in the future. + // + // Thus, here we must must zero the place that + // we are moving *from*, because we do not yet + // track drop flags for a fragmented parent + // match input expression. + // + // Longer term we will be able to map the move + // into `(x, _)` up to the parent path that + // owns the whole tuple, and mark the + // corresponding stack-local drop-flag + // tracking the first component of the tuple. let hint_kind = HintKind::ZeroAndMaintain; Lvalue::new_with_hint("_match::insert_lllocals (match_input)", bcx, binding_info.id, hint_kind) diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs index d2daca816b7..77ac43ac172 100644 --- a/src/librustc_trans/trans/datum.rs +++ b/src/librustc_trans/trans/datum.rs @@ -189,9 +189,27 @@ pub struct Rvalue { pub mode: RvalueMode } +/// Classifies what action we should take when a value is moved away +/// with respect to its drop-flag. +/// +/// Long term there will be no need for this classification: all flags +/// (which will be stored on the stack frame) will have the same +/// interpretation and maintenance code associated with them. #[derive(Copy, Clone, Debug)] pub enum HintKind { + /// When the value is moved, set the drop-flag to "dropped" + /// (i.e. "zero the flag", even when the specific representation + /// is not literally 0) and when it is reinitialized, set the + /// drop-flag back to "initialized". ZeroAndMaintain, + + /// When the value is moved, do not set the drop-flag to "dropped" + /// However, continue to read the drop-flag in deciding whether to + /// drop. (In essence, the path/fragment in question will never + /// need to be dropped at the points where it is moved away by + /// this code, but we are defending against the scenario where + /// some *other* code could move away (or drop) the value and thus + /// zero-the-flag, which is why we will still read from it. DontZeroJustUse, } @@ -218,7 +236,8 @@ pub fn new_with_hint<'blk, 'tcx>(source: &'static str, DropFlagInfo::ZeroAndMaintain(id), HintKind::DontZeroJustUse if hint_available => DropFlagInfo::DontZeroJustUse(id), - _ => DropFlagInfo::None, + _ => + DropFlagInfo::None, }; (Some(id), info) };