2023-01-24 17:48:05 +00:00
|
|
|
use rustc_middle::mir::{self, Body, Location, Terminator, TerminatorKind};
|
2020-06-30 00:20:41 +00:00
|
|
|
use rustc_target::abi::VariantIdx;
|
2024-05-22 04:45:14 +00:00
|
|
|
use tracing::debug;
|
2016-01-25 13:34:34 +00:00
|
|
|
|
2023-11-21 21:53:45 +00:00
|
|
|
use super::move_paths::{InitKind, LookupResult, MoveData, MovePathIndex};
|
2021-01-05 18:53:07 +00:00
|
|
|
use crate::elaborate_drops::DropFlagState;
|
2017-06-26 12:57:26 +00:00
|
|
|
|
|
|
|
pub fn move_path_children_matching<'tcx, F>(
|
|
|
|
move_data: &MoveData<'tcx>,
|
2016-05-16 23:26:18 +00:00
|
|
|
path: MovePathIndex,
|
|
|
|
mut cond: F,
|
|
|
|
) -> Option<MovePathIndex>
|
2019-08-24 23:49:08 +00:00
|
|
|
where
|
2020-05-23 10:02:54 +00:00
|
|
|
F: FnMut(mir::PlaceElem<'tcx>) -> bool,
|
2016-05-16 23:26:18 +00:00
|
|
|
{
|
2016-06-11 20:47:28 +00:00
|
|
|
let mut next_child = move_data.move_paths[path].first_child;
|
2016-05-16 23:26:18 +00:00
|
|
|
while let Some(child_index) = next_child {
|
2019-08-24 23:49:08 +00:00
|
|
|
let move_path_children = &move_data.move_paths[child_index];
|
2020-05-23 10:02:54 +00:00
|
|
|
if let Some(&elem) = move_path_children.place.projection.last() {
|
2019-08-24 23:49:08 +00:00
|
|
|
if cond(elem) {
|
|
|
|
return Some(child_index);
|
|
|
|
}
|
2016-05-16 23:26:18 +00:00
|
|
|
}
|
2019-08-24 23:49:08 +00:00
|
|
|
next_child = move_path_children.next_sibling;
|
2016-05-16 23:26:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
2021-01-01 00:53:25 +00:00
|
|
|
pub fn on_lookup_result_bits<'tcx, F>(
|
2016-06-11 20:47:28 +00:00
|
|
|
move_data: &MoveData<'tcx>,
|
|
|
|
lookup_result: LookupResult,
|
2019-06-11 21:11:55 +00:00
|
|
|
each_child: F,
|
|
|
|
) where
|
|
|
|
F: FnMut(MovePathIndex),
|
2016-06-11 20:47:28 +00:00
|
|
|
{
|
|
|
|
match lookup_result {
|
|
|
|
LookupResult::Parent(..) => {
|
|
|
|
// access to untracked value - do not touch children
|
|
|
|
}
|
2023-11-23 19:26:15 +00:00
|
|
|
LookupResult::Exact(e) => on_all_children_bits(move_data, e, each_child),
|
2016-06-11 20:47:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-01 00:53:25 +00:00
|
|
|
pub fn on_all_children_bits<'tcx, F>(
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 13:50:27 +00:00
|
|
|
move_data: &MoveData<'tcx>,
|
|
|
|
move_path_index: MovePathIndex,
|
2019-06-11 21:11:55 +00:00
|
|
|
mut each_child: F,
|
|
|
|
) where
|
|
|
|
F: FnMut(MovePathIndex),
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 13:50:27 +00:00
|
|
|
{
|
2019-06-13 21:48:52 +00:00
|
|
|
fn on_all_children_bits<'tcx, F>(
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 13:50:27 +00:00
|
|
|
move_data: &MoveData<'tcx>,
|
|
|
|
move_path_index: MovePathIndex,
|
2019-06-11 21:11:55 +00:00
|
|
|
each_child: &mut F,
|
|
|
|
) where
|
|
|
|
F: FnMut(MovePathIndex),
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 13:50:27 +00:00
|
|
|
{
|
|
|
|
each_child(move_path_index);
|
|
|
|
|
|
|
|
let mut next_child_index = move_data.move_paths[move_path_index].first_child;
|
|
|
|
while let Some(child_index) = next_child_index {
|
2023-11-23 19:26:15 +00:00
|
|
|
on_all_children_bits(move_data, child_index, each_child);
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 13:50:27 +00:00
|
|
|
next_child_index = move_data.move_paths[child_index].next_sibling;
|
|
|
|
}
|
|
|
|
}
|
2023-11-23 19:26:15 +00:00
|
|
|
on_all_children_bits(move_data, move_path_index, &mut each_child);
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 13:50:27 +00:00
|
|
|
}
|
|
|
|
|
2021-01-01 00:53:25 +00:00
|
|
|
pub fn drop_flag_effects_for_function_entry<'tcx, F>(
|
2019-06-03 22:26:48 +00:00
|
|
|
body: &Body<'tcx>,
|
2024-07-24 19:58:34 +00:00
|
|
|
move_data: &MoveData<'tcx>,
|
2019-06-11 21:11:55 +00:00
|
|
|
mut callback: F,
|
|
|
|
) where
|
|
|
|
F: FnMut(MovePathIndex, DropFlagState),
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 13:50:27 +00:00
|
|
|
{
|
2019-06-03 22:26:48 +00:00
|
|
|
for arg in body.args_iter() {
|
2019-06-24 15:46:09 +00:00
|
|
|
let place = mir::Place::from(arg);
|
2019-07-21 20:38:30 +00:00
|
|
|
let lookup_result = move_data.rev_lookup.find(place.as_ref());
|
2023-11-23 19:26:15 +00:00
|
|
|
on_lookup_result_bits(move_data, lookup_result, |mpi| {
|
2017-08-09 19:23:27 +00:00
|
|
|
callback(mpi, DropFlagState::Present)
|
|
|
|
});
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 13:50:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-01 00:53:25 +00:00
|
|
|
pub fn drop_flag_effects_for_location<'tcx, F>(
|
2019-06-03 22:26:48 +00:00
|
|
|
body: &Body<'tcx>,
|
2024-07-24 19:58:34 +00:00
|
|
|
move_data: &MoveData<'tcx>,
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 13:50:27 +00:00
|
|
|
loc: Location,
|
2019-06-11 21:11:55 +00:00
|
|
|
mut callback: F,
|
|
|
|
) where
|
|
|
|
F: FnMut(MovePathIndex, DropFlagState),
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 13:50:27 +00:00
|
|
|
{
|
|
|
|
debug!("drop_flag_effects_for_location({:?})", loc);
|
|
|
|
|
|
|
|
// first, move out of the RHS
|
|
|
|
for mi in &move_data.loc_map[loc] {
|
|
|
|
let path = mi.move_path_index(move_data);
|
|
|
|
debug!("moving out of path {:?}", move_data.move_paths[path]);
|
|
|
|
|
2023-11-23 19:26:15 +00:00
|
|
|
on_all_children_bits(move_data, path, |mpi| callback(mpi, DropFlagState::Absent))
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 13:50:27 +00:00
|
|
|
}
|
|
|
|
|
2023-01-24 17:48:05 +00:00
|
|
|
// Drop does not count as a move but we should still consider the variable uninitialized.
|
|
|
|
if let Some(Terminator { kind: TerminatorKind::Drop { place, .. }, .. }) =
|
|
|
|
body.stmt_at(loc).right()
|
|
|
|
{
|
|
|
|
if let LookupResult::Exact(mpi) = move_data.rev_lookup.find(place.as_ref()) {
|
2023-11-23 19:26:15 +00:00
|
|
|
on_all_children_bits(move_data, mpi, |mpi| callback(mpi, DropFlagState::Absent))
|
2023-01-24 17:48:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-27 08:06:36 +00:00
|
|
|
debug!("drop_flag_effects: assignment for location({:?})", loc);
|
|
|
|
|
2023-11-23 19:26:15 +00:00
|
|
|
for_location_inits(move_data, loc, |mpi| callback(mpi, DropFlagState::Present));
|
2017-11-27 08:06:36 +00:00
|
|
|
}
|
|
|
|
|
2023-11-23 19:26:15 +00:00
|
|
|
fn for_location_inits<'tcx, F>(move_data: &MoveData<'tcx>, loc: Location, mut callback: F)
|
|
|
|
where
|
2019-06-11 21:11:55 +00:00
|
|
|
F: FnMut(MovePathIndex),
|
2017-11-27 08:06:36 +00:00
|
|
|
{
|
|
|
|
for ii in &move_data.init_loc_map[loc] {
|
|
|
|
let init = move_data.inits[*ii];
|
|
|
|
match init.kind {
|
|
|
|
InitKind::Deep => {
|
|
|
|
let path = init.path;
|
|
|
|
|
2023-11-23 19:26:15 +00:00
|
|
|
on_all_children_bits(move_data, path, &mut callback)
|
2017-11-27 08:06:36 +00:00
|
|
|
}
|
|
|
|
InitKind::Shallow => {
|
|
|
|
let mpi = init.path;
|
|
|
|
callback(mpi);
|
2016-05-16 22:06:52 +00:00
|
|
|
}
|
2017-11-27 08:06:36 +00:00
|
|
|
InitKind::NonPanicPathOnly => (),
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 13:50:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-06-30 00:20:41 +00:00
|
|
|
|
|
|
|
/// Calls `handle_inactive_variant` for each descendant move path of `enum_place` that contains a
|
|
|
|
/// `Downcast` to a variant besides the `active_variant`.
|
|
|
|
///
|
|
|
|
/// NOTE: If there are no move paths corresponding to an inactive variant,
|
|
|
|
/// `handle_inactive_variant` will not be called for that variant.
|
|
|
|
pub(crate) fn on_all_inactive_variants<'tcx>(
|
|
|
|
move_data: &MoveData<'tcx>,
|
|
|
|
enum_place: mir::Place<'tcx>,
|
|
|
|
active_variant: VariantIdx,
|
|
|
|
mut handle_inactive_variant: impl FnMut(MovePathIndex),
|
|
|
|
) {
|
2022-02-18 23:48:49 +00:00
|
|
|
let LookupResult::Exact(enum_mpi) = move_data.rev_lookup.find(enum_place.as_ref()) else {
|
|
|
|
return;
|
2020-06-30 00:20:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
let enum_path = &move_data.move_paths[enum_mpi];
|
|
|
|
for (variant_mpi, variant_path) in enum_path.children(&move_data.move_paths) {
|
|
|
|
// Because of the way we build the `MoveData` tree, each child should have exactly one more
|
|
|
|
// projection than `enum_place`. This additional projection must be a downcast since the
|
|
|
|
// base is an enum.
|
|
|
|
let (downcast, base_proj) = variant_path.place.projection.split_last().unwrap();
|
|
|
|
assert_eq!(enum_place.projection.len(), base_proj.len());
|
|
|
|
|
2022-02-18 23:48:49 +00:00
|
|
|
let mir::ProjectionElem::Downcast(_, variant_idx) = *downcast else {
|
|
|
|
unreachable!();
|
2020-06-30 00:20:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
if variant_idx != active_variant {
|
2023-11-23 19:26:15 +00:00
|
|
|
on_all_children_bits(move_data, variant_mpi, |mpi| handle_inactive_variant(mpi));
|
2020-06-30 00:20:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|