Remove all instances of fragment_infos and fragment sets

This commit is contained in:
Paul Faria 2017-05-23 21:51:21 -04:00
parent 5b13bff520
commit fb9ca16b3b
5 changed files with 1 additions and 608 deletions

View file

@ -40,7 +40,7 @@ use ty::layout::{Layout, TargetDataLayout};
use ty::inhabitedness::DefIdForest;
use ty::maps;
use ty::steal::Steal;
use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
use util::nodemap::{NodeMap, NodeSet, DefIdSet};
use util::nodemap::{FxHashMap, FxHashSet};
use rustc_data_structures::accumulate_vec::AccumulateVec;
@ -499,33 +499,6 @@ pub struct GlobalCtxt<'tcx> {
/// Maps Expr NodeId's to `true` iff `&expr` can have 'static lifetime.
pub rvalue_promotable_to_static: RefCell<NodeMap<bool>>,
/// Maps Fn items to a collection of fragment infos.
///
/// The main goal is to identify data (each of which may be moved
/// or assigned) whose subparts are not moved nor assigned
/// (i.e. their state is *unfragmented*) and corresponding ast
/// nodes where the path to that data is moved or assigned.
///
/// In the long term, unfragmented values will have their
/// destructor entirely driven by a single stack-local drop-flag,
/// and their parents, the collections of the unfragmented values
/// (or more simply, "fragmented values"), are mapped to the
/// corresponding collections of stack-local drop-flags.
///
/// (However, in the short term that is not the case; e.g. some
/// unfragmented paths still need to be zeroed, namely when they
/// reference parent data from an outer scope that was not
/// entirely moved, and therefore that needs to be zeroed so that
/// we do not get double-drop when we hit the end of the parent
/// scope.)
///
/// Also: currently the table solely holds keys for node-ids of
/// unfragmented values (see `FragmentInfo` enum definition), but
/// longer-term we will need to also store mappings from
/// fragmented data to the set of unfragmented pieces that
/// constitute it.
pub fragment_infos: RefCell<DefIdMap<Vec<ty::FragmentInfo>>>,
/// The definite name of the current crate after taking into account
/// attributes, commandline parameters, etc.
pub crate_name: Symbol,
@ -730,7 +703,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
selection_cache: traits::SelectionCache::new(),
evaluation_cache: traits::EvaluationCache::new(),
rvalue_promotable_to_static: RefCell::new(NodeMap()),
fragment_infos: RefCell::new(DefIdMap()),
crate_name: Symbol::intern(crate_name),
data_layout: data_layout,
layout_cache: RefCell::new(FxHashMap()),

View file

@ -443,17 +443,6 @@ pub struct CReaderCacheKey {
pub pos: usize,
}
/// Describes the fragment-state associated with a NodeId.
///
/// Currently only unfragmented paths have entries in the table,
/// but longer-term this enum is expected to expand to also
/// include data for fragmented paths.
#[derive(Copy, Clone, Debug)]
pub enum FragmentInfo {
Moved { var: NodeId, move_expr: NodeId },
Assigned { var: NodeId, assign_expr: NodeId, assignee_id: NodeId },
}
// Flags that we track on types. These flags are propagated upwards
// through the type during type construction, so that we can quickly
// check whether the type has various kinds of types in it without

View file

@ -1,542 +0,0 @@
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Helper routines used for fragmenting structural paths due to moves for
//! tracking drop obligations. Please see the extensive comments in the
//! section "Structural fragments" in `README.md`.
use self::Fragment::*;
use borrowck::InteriorKind::{InteriorField, InteriorElement};
use borrowck::{self, LoanPath};
use borrowck::LoanPathKind::{LpVar, LpUpvar, LpDowncast, LpExtend};
use borrowck::LoanPathElem::{LpDeref, LpInterior};
use borrowck::move_data::InvalidMovePathIndex;
use borrowck::move_data::{MoveData, MovePathIndex};
use rustc::hir::def_id::{DefId};
use rustc::ty::{self, AdtKind, TyCtxt};
use rustc::middle::mem_categorization as mc;
use std::mem;
use std::rc::Rc;
use syntax::ast;
use syntax_pos::DUMMY_SP;
#[derive(PartialEq, Eq, PartialOrd, Ord)]
enum Fragment {
// This represents the path described by the move path index
Just(MovePathIndex),
// This represents the collection of all but one of the elements
// from an array at the path described by the move path index.
// Note that attached MovePathIndex should have mem_categorization
// of InteriorElement (i.e. array dereference `&foo[..]`).
AllButOneFrom(MovePathIndex),
}
impl Fragment {
fn loan_path_repr(&self, move_data: &MoveData) -> String {
let lp = |mpi| move_data.path_loan_path(mpi);
match *self {
Just(mpi) => format!("{:?}", lp(mpi)),
AllButOneFrom(mpi) => format!("$(allbutone {:?})", lp(mpi)),
}
}
fn loan_path_user_string(&self, move_data: &MoveData) -> String {
let lp = |mpi| move_data.path_loan_path(mpi);
match *self {
Just(mpi) => lp(mpi).to_string(),
AllButOneFrom(mpi) => format!("$(allbutone {})", lp(mpi)),
}
}
}
pub fn build_unfragmented_map(this: &mut borrowck::BorrowckCtxt,
move_data: &MoveData,
id: ast::NodeId) {
let fr = &move_data.fragments.borrow();
// For now, don't care about other kinds of fragments; the precise
// classfication of all paths for non-zeroing *drop* needs them,
// but the loose approximation used by non-zeroing moves does not.
let moved_leaf_paths = fr.moved_leaf_paths();
let assigned_leaf_paths = fr.assigned_leaf_paths();
let mut fragment_infos = Vec::with_capacity(moved_leaf_paths.len());
let find_var_id = |move_path_index: MovePathIndex| -> Option<ast::NodeId> {
let lp = move_data.path_loan_path(move_path_index);
match lp.kind {
LpVar(var_id) => Some(var_id),
LpUpvar(ty::UpvarId { var_id, closure_expr_id }) => {
// The `var_id` is unique *relative to* the current function.
// (Check that we are indeed talking about the same function.)
assert_eq!(id, closure_expr_id);
Some(var_id)
}
LpDowncast(..) | LpExtend(..) => {
// This simple implementation of non-zeroing move does
// not attempt to deal with tracking substructure
// accurately in the general case.
None
}
}
};
let moves = move_data.moves.borrow();
for &move_path_index in moved_leaf_paths {
let var_id = match find_var_id(move_path_index) {
None => continue,
Some(var_id) => var_id,
};
move_data.each_applicable_move(move_path_index, |move_index| {
let info = ty::FragmentInfo::Moved {
var: var_id,
move_expr: moves[move_index.get()].id,
};
debug!("fragment_infos push({:?} \
due to move_path_index: {} move_index: {}",
info, move_path_index.get(), move_index.get());
fragment_infos.push(info);
true
});
}
for &move_path_index in assigned_leaf_paths {
let var_id = match find_var_id(move_path_index) {
None => continue,
Some(var_id) => var_id,
};
let var_assigns = move_data.var_assignments.borrow();
for var_assign in var_assigns.iter()
.filter(|&assign| assign.path == move_path_index)
{
let info = ty::FragmentInfo::Assigned {
var: var_id,
assign_expr: var_assign.id,
assignee_id: var_assign.assignee_id,
};
debug!("fragment_infos push({:?} due to var_assignment", info);
fragment_infos.push(info);
}
}
let mut fraginfo_map = this.tcx.fragment_infos.borrow_mut();
let fn_did = this.tcx.hir.local_def_id(id);
let prev = fraginfo_map.insert(fn_did, fragment_infos);
assert!(prev.is_none());
}
pub struct FragmentSets {
/// During move_data construction, `moved_leaf_paths` tracks paths
/// that have been used directly by being moved out of. When
/// move_data construction has been completed, `moved_leaf_paths`
/// tracks such paths that are *leaf fragments* (e.g. `a.j` if we
/// never move out any child like `a.j.x`); any parent paths
/// (e.g. `a` for the `a.j` example) are moved over to
/// `parents_of_fragments`.
moved_leaf_paths: Vec<MovePathIndex>,
/// `assigned_leaf_paths` tracks paths that have been used
/// directly by being overwritten, but is otherwise much like
/// `moved_leaf_paths`.
assigned_leaf_paths: Vec<MovePathIndex>,
/// `parents_of_fragments` tracks paths that are definitely
/// parents of paths that have been moved.
///
/// FIXME(pnkfelix) probably do not want/need
/// `parents_of_fragments` at all, if we can avoid it.
///
/// Update: I do not see a way to avoid it. Maybe just remove
/// above fixme, or at least document why doing this may be hard.
parents_of_fragments: Vec<MovePathIndex>,
/// During move_data construction (specifically the
/// fixup_fragment_sets call), `unmoved_fragments` tracks paths
/// that have been "left behind" after a sibling has been moved or
/// assigned. When move_data construction has been completed,
/// `unmoved_fragments` tracks paths that were *only* results of
/// being left-behind, and never directly moved themselves.
unmoved_fragments: Vec<Fragment>,
}
impl FragmentSets {
pub fn new() -> FragmentSets {
FragmentSets {
unmoved_fragments: Vec::new(),
moved_leaf_paths: Vec::new(),
assigned_leaf_paths: Vec::new(),
parents_of_fragments: Vec::new(),
}
}
pub fn moved_leaf_paths(&self) -> &[MovePathIndex] {
&self.moved_leaf_paths
}
pub fn assigned_leaf_paths(&self) -> &[MovePathIndex] {
&self.assigned_leaf_paths
}
pub fn add_move(&mut self, path_index: MovePathIndex) {
self.moved_leaf_paths.push(path_index);
}
pub fn add_assignment(&mut self, path_index: MovePathIndex) {
self.assigned_leaf_paths.push(path_index);
}
}
pub fn instrument_move_fragments<'a, 'tcx>(this: &MoveData<'tcx>,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
id: ast::NodeId) {
let span_err = tcx.hir.attrs(id).iter()
.any(|a| a.check_name("rustc_move_fragments"));
let print = tcx.sess.opts.debugging_opts.print_move_fragments;
if !span_err && !print { return; }
let sp = tcx.hir.span(id);
let instrument_all_paths = |kind, vec_rc: &Vec<MovePathIndex>| {
for (i, mpi) in vec_rc.iter().enumerate() {
let lp = || this.path_loan_path(*mpi);
if span_err {
tcx.sess.span_err(sp, &format!("{}: `{}`", kind, lp()));
}
if print {
println!("id:{} {}[{}] `{}`", id, kind, i, lp());
}
}
};
let instrument_all_fragments = |kind, vec_rc: &Vec<Fragment>| {
for (i, f) in vec_rc.iter().enumerate() {
let render = || f.loan_path_user_string(this);
if span_err {
tcx.sess.span_err(sp, &format!("{}: `{}`", kind, render()));
}
if print {
println!("id:{} {}[{}] `{}`", id, kind, i, render());
}
}
};
let fragments = this.fragments.borrow();
instrument_all_paths("moved_leaf_path", &fragments.moved_leaf_paths);
instrument_all_fragments("unmoved_fragment", &fragments.unmoved_fragments);
instrument_all_paths("parent_of_fragments", &fragments.parents_of_fragments);
instrument_all_paths("assigned_leaf_path", &fragments.assigned_leaf_paths);
}
/// Normalizes the fragment sets in `this`; i.e., removes duplicate entries, constructs the set of
/// parents, and constructs the left-over fragments.
///
/// Note: "left-over fragments" means paths that were not directly referenced in moves nor
/// assignments, but must nonetheless be tracked as potential drop obligations.
pub fn fixup_fragment_sets<'a, 'tcx>(this: &MoveData<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let mut fragments = this.fragments.borrow_mut();
// Swap out contents of fragments so that we can modify the fields
// without borrowing the common fragments.
let mut unmoved = mem::replace(&mut fragments.unmoved_fragments, vec![]);
let mut parents = mem::replace(&mut fragments.parents_of_fragments, vec![]);
let mut moved = mem::replace(&mut fragments.moved_leaf_paths, vec![]);
let mut assigned = mem::replace(&mut fragments.assigned_leaf_paths, vec![]);
let path_lps = |mpis: &[MovePathIndex]| -> Vec<String> {
mpis.iter().map(|mpi| format!("{:?}", this.path_loan_path(*mpi))).collect()
};
let frag_lps = |fs: &[Fragment]| -> Vec<String> {
fs.iter().map(|f| f.loan_path_repr(this)).collect()
};
// First, filter out duplicates
moved.sort();
moved.dedup();
debug!("fragments 1 moved: {:?}", path_lps(&moved));
assigned.sort();
assigned.dedup();
debug!("fragments 1 assigned: {:?}", path_lps(&assigned));
// Second, build parents from the moved and assigned.
for m in &moved {
let mut p = this.path_parent(*m);
while p != InvalidMovePathIndex {
parents.push(p);
p = this.path_parent(p);
}
}
for a in &assigned {
let mut p = this.path_parent(*a);
while p != InvalidMovePathIndex {
parents.push(p);
p = this.path_parent(p);
}
}
parents.sort();
parents.dedup();
debug!("fragments 2 parents: {:?}", path_lps(&parents));
// Third, filter the moved and assigned fragments down to just the non-parents
moved.retain(|f| non_member(*f, &parents));
debug!("fragments 3 moved: {:?}", path_lps(&moved));
assigned.retain(|f| non_member(*f, &parents));
debug!("fragments 3 assigned: {:?}", path_lps(&assigned));
// Fourth, build the leftover from the moved, assigned, and parents.
for m in &moved {
let lp = this.path_loan_path(*m);
add_fragment_siblings(this, tcx, &mut unmoved, lp, None);
}
for a in &assigned {
let lp = this.path_loan_path(*a);
add_fragment_siblings(this, tcx, &mut unmoved, lp, None);
}
for p in &parents {
let lp = this.path_loan_path(*p);
add_fragment_siblings(this, tcx, &mut unmoved, lp, None);
}
unmoved.sort();
unmoved.dedup();
debug!("fragments 4 unmoved: {:?}", frag_lps(&unmoved));
// Fifth, filter the leftover fragments down to its core.
unmoved.retain(|f| match *f {
AllButOneFrom(_) => true,
Just(mpi) => non_member(mpi, &parents) &&
non_member(mpi, &moved) &&
non_member(mpi, &assigned)
});
debug!("fragments 5 unmoved: {:?}", frag_lps(&unmoved));
// Swap contents back in.
fragments.unmoved_fragments = unmoved;
fragments.parents_of_fragments = parents;
fragments.moved_leaf_paths = moved;
fragments.assigned_leaf_paths = assigned;
return;
fn non_member(elem: MovePathIndex, set: &[MovePathIndex]) -> bool {
match set.binary_search(&elem) {
Ok(_) => false,
Err(_) => true,
}
}
}
/// Adds all of the precisely-tracked siblings of `lp` as potential move paths of interest. For
/// example, if `lp` represents `s.x.j`, then adds moves paths for `s.x.i` and `s.x.k`, the
/// siblings of `s.x.j`.
fn add_fragment_siblings<'a, 'tcx>(this: &MoveData<'tcx>,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
gathered_fragments: &mut Vec<Fragment>,
lp: Rc<LoanPath<'tcx>>,
origin_id: Option<ast::NodeId>) {
match lp.kind {
LpVar(_) | LpUpvar(..) => {} // Local variables have no siblings.
// Consuming a downcast is like consuming the original value, so propage inward.
LpDowncast(ref loan_parent, _) => {
add_fragment_siblings(this, tcx, gathered_fragments, loan_parent.clone(), origin_id);
}
// *LV for Unique consumes the contents of the box (at
// least when it is non-copy...), so propagate inward.
LpExtend(ref loan_parent, _, LpDeref(mc::Unique)) => {
add_fragment_siblings(this, tcx, gathered_fragments, loan_parent.clone(), origin_id);
}
// *LV for unsafe and borrowed pointers do not consume their loan path, so stop here.
LpExtend(.., LpDeref(mc::UnsafePtr(..))) |
LpExtend(.., LpDeref(mc::Implicit(..))) |
LpExtend(.., LpDeref(mc::BorrowedPtr(..))) => {}
// FIXME (pnkfelix): LV[j] should be tracked, at least in the
// sense of we will track the remaining drop obligation of the
// rest of the array.
//
// Well, either that or LV[j] should be made illegal.
// But even then, we will need to deal with destructuring
// bind.
//
// Anyway, for now: LV[j] is not tracked precisely
LpExtend(.., LpInterior(_, InteriorElement(..))) => {
let mp = this.move_path(tcx, lp.clone());
gathered_fragments.push(AllButOneFrom(mp));
}
// field access LV.x and tuple access LV#k are the cases
// we are interested in
LpExtend(ref loan_parent, mc,
LpInterior(_, InteriorField(ref field_name))) => {
let enum_variant_info = match loan_parent.kind {
LpDowncast(ref loan_parent_2, variant_def_id) =>
Some((variant_def_id, loan_parent_2.clone())),
LpExtend(..) | LpVar(..) | LpUpvar(..) =>
None,
};
add_fragment_siblings_for_extension(
this,
tcx,
gathered_fragments,
loan_parent, mc, field_name, &lp, origin_id, enum_variant_info);
}
}
}
/// We have determined that `origin_lp` destructures to LpExtend(parent, original_field_name).
/// Based on this, add move paths for all of the siblings of `origin_lp`.
fn add_fragment_siblings_for_extension<'a, 'tcx>(this: &MoveData<'tcx>,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
gathered_fragments: &mut Vec<Fragment>,
parent_lp: &Rc<LoanPath<'tcx>>,
mc: mc::MutabilityCategory,
origin_field_name: &mc::FieldName,
origin_lp: &Rc<LoanPath<'tcx>>,
origin_id: Option<ast::NodeId>,
enum_variant_info: Option<(DefId,
Rc<LoanPath<'tcx>>)>) {
let parent_ty = parent_lp.to_type();
let mut add_fragment_sibling_local = |field_name, variant_did| {
add_fragment_sibling_core(
this, tcx, gathered_fragments, parent_lp.clone(), mc, field_name, origin_lp,
variant_did);
};
match parent_ty.sty {
ty::TyTuple(ref v, _) => {
let tuple_idx = match *origin_field_name {
mc::PositionalField(tuple_idx) => tuple_idx,
mc::NamedField(_) =>
bug!("tuple type {:?} should not have named fields.",
parent_ty),
};
let tuple_len = v.len();
for i in 0..tuple_len {
if i == tuple_idx { continue }
let field_name = mc::PositionalField(i);
add_fragment_sibling_local(field_name, None);
}
}
ty::TyAdt(def, ..) => match def.adt_kind() {
AdtKind::Struct => {
match *origin_field_name {
mc::NamedField(ast_name) => {
for f in &def.struct_variant().fields {
if f.name == ast_name {
continue;
}
let field_name = mc::NamedField(f.name);
add_fragment_sibling_local(field_name, None);
}
}
mc::PositionalField(tuple_idx) => {
for (i, _f) in def.struct_variant().fields.iter().enumerate() {
if i == tuple_idx {
continue
}
let field_name = mc::PositionalField(i);
add_fragment_sibling_local(field_name, None);
}
}
}
}
AdtKind::Union => {
// Do nothing, all union fields are moved/assigned together.
}
AdtKind::Enum => {
let variant = match enum_variant_info {
Some((vid, ref _lp2)) => def.variant_with_id(vid),
None => {
assert!(def.is_univariant());
&def.variants[0]
}
};
match *origin_field_name {
mc::NamedField(ast_name) => {
for field in &variant.fields {
if field.name == ast_name {
continue;
}
let field_name = mc::NamedField(field.name);
add_fragment_sibling_local(field_name, Some(variant.did));
}
}
mc::PositionalField(tuple_idx) => {
for (i, _f) in variant.fields.iter().enumerate() {
if tuple_idx == i {
continue;
}
let field_name = mc::PositionalField(i);
add_fragment_sibling_local(field_name, None);
}
}
}
}
},
ref ty => {
let span = origin_id.map_or(DUMMY_SP, |id| tcx.hir.span(id));
span_bug!(span,
"type {:?} ({:?}) is not fragmentable",
parent_ty, ty);
}
}
}
/// Adds the single sibling `LpExtend(parent, new_field_name)` of `origin_lp` (the original
/// loan-path).
fn add_fragment_sibling_core<'a, 'tcx>(this: &MoveData<'tcx>,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
gathered_fragments: &mut Vec<Fragment>,
parent: Rc<LoanPath<'tcx>>,
mc: mc::MutabilityCategory,
new_field_name: mc::FieldName,
origin_lp: &Rc<LoanPath<'tcx>>,
enum_variant_did: Option<DefId>)
-> MovePathIndex {
let opt_variant_did = match parent.kind {
LpDowncast(_, variant_did) => Some(variant_did),
LpVar(..) | LpUpvar(..) | LpExtend(..) => enum_variant_did,
};
let loan_path_elem = LpInterior(opt_variant_did, InteriorField(new_field_name));
let new_lp_type = match new_field_name {
mc::NamedField(ast_name) =>
tcx.named_element_ty(parent.to_type(), ast_name, opt_variant_did),
mc::PositionalField(idx) =>
tcx.positional_element_ty(parent.to_type(), idx, opt_variant_did),
};
let new_lp_variant = LpExtend(parent, mc, loan_path_elem);
let new_lp = LoanPath::new(new_lp_variant, new_lp_type.unwrap());
debug!("add_fragment_sibling_core(new_lp={:?}, origin_lp={:?})",
new_lp, origin_lp);
let mp = this.move_path(tcx, Rc::new(new_lp));
// Do not worry about checking for duplicates here; we will sort
// and dedup after all are added.
gathered_fragments.push(Just(mp));
mp
}

View file

@ -129,13 +129,6 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) {
move_data: flowed_moves } =
build_borrowck_dataflow_data(bccx, &cfg, body_id);
move_data::fragments::instrument_move_fragments(&flowed_moves.move_data,
bccx.tcx,
owner_id);
move_data::fragments::build_unfragmented_map(bccx,
&flowed_moves.move_data,
owner_id);
check_loans::check_loans(bccx, &loan_dfcx, &flowed_moves, &all_loans, body);
}

View file

@ -33,9 +33,6 @@ use syntax_pos::Span;
use rustc::hir;
use rustc::hir::intravisit::IdRange;
#[path="fragments.rs"]
pub mod fragments;
pub struct MoveData<'tcx> {
/// Move paths. See section "Move paths" in `README.md`.
pub paths: RefCell<Vec<MovePath<'tcx>>>,
@ -62,9 +59,6 @@ pub struct MoveData<'tcx> {
/// Assignments to a variable or path, like `x = foo`, but not `x += foo`.
pub assignee_ids: RefCell<NodeSet>,
/// Path-fragments from moves in to or out of parts of structured data.
pub fragments: RefCell<fragments::FragmentSets>,
}
pub struct FlowedMoveData<'a, 'tcx: 'a> {
@ -223,7 +217,6 @@ impl<'a, 'tcx> MoveData<'tcx> {
var_assignments: RefCell::new(Vec::new()),
variant_matches: RefCell::new(Vec::new()),
assignee_ids: RefCell::new(NodeSet()),
fragments: RefCell::new(fragments::FragmentSets::new()),
}
}
@ -401,8 +394,6 @@ impl<'a, 'tcx> MoveData<'tcx> {
let path_index = self.move_path(tcx, lp.clone());
let move_index = MoveIndex(self.moves.borrow().len());
self.fragments.borrow_mut().add_move(path_index);
let next_move = self.path_first_move(path_index);
self.set_path_first_move(path_index, move_index);
@ -458,8 +449,6 @@ impl<'a, 'tcx> MoveData<'tcx> {
let path_index = self.move_path(tcx, lp.clone());
self.fragments.borrow_mut().add_assignment(path_index);
match mode {
MutateMode::Init | MutateMode::JustWrite => {
self.assignee_ids.borrow_mut().insert(assignee_id);
@ -502,8 +491,6 @@ impl<'a, 'tcx> MoveData<'tcx> {
let path_index = self.move_path(tcx, lp.clone());
let base_path_index = self.move_path(tcx, base_lp.clone());
self.fragments.borrow_mut().add_assignment(path_index);
let variant_match = VariantMatch {
path: path_index,
base_path: base_path_index,
@ -514,10 +501,6 @@ impl<'a, 'tcx> MoveData<'tcx> {
self.variant_matches.borrow_mut().push(variant_match);
}
fn fixup_fragment_sets(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) {
fragments::fixup_fragment_sets(self, tcx)
}
/// Adds the gen/kills for the various moves and
/// assignments into the provided data flow contexts.
/// Moves are generated by moves and killed by assignments and
@ -677,8 +660,6 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
id_range,
move_data.var_assignments.borrow().len());
move_data.fixup_fragment_sets(tcx);
move_data.add_gen_kills(bccx,
&mut dfcx_moves,
&mut dfcx_assign);