1 //! The move-analysis portion of borrowck needs to work in an abstract
2 //! domain of lifted `Place`s. Most of the `Place` variants fall into a
3 //! one-to-one mapping between the concrete and abstract (e.g., a
4 //! field-deref on a local variable, `x.field`, has the same meaning
5 //! in both domains). Indexed projections are the exception: `a[x]`
6 //! needs to be treated as mapping to the same move path as `a[y]` as
7 //! well as `a[13]`, etc.
9 //! (In theory, the analysis could be extended to work with sets of
10 //! paths, so that `a[0]` and `a[13]` could be kept distinct, while
11 //! `a[x]` would still overlap them both. But that is not this
12 //! representation does today.)
14 use rustc_middle
::mir
::{Local, Operand, PlaceElem, ProjectionElem}
;
15 use rustc_middle
::ty
::Ty
;
17 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
18 pub struct AbstractOperand
;
19 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
20 pub struct AbstractType
;
21 pub type AbstractElem
= ProjectionElem
<AbstractOperand
, AbstractType
>;
25 fn lift(&self) -> Self::Abstract
;
27 impl<'tcx
> Lift
for Operand
<'tcx
> {
28 type Abstract
= AbstractOperand
;
29 fn lift(&self) -> Self::Abstract
{
34 type Abstract
= AbstractOperand
;
35 fn lift(&self) -> Self::Abstract
{
39 impl<'tcx
> Lift
for Ty
<'tcx
> {
40 type Abstract
= AbstractType
;
41 fn lift(&self) -> Self::Abstract
{
45 impl<'tcx
> Lift
for PlaceElem
<'tcx
> {
46 type Abstract
= AbstractElem
;
47 fn lift(&self) -> Self::Abstract
{
49 ProjectionElem
::Deref
=> ProjectionElem
::Deref
,
50 ProjectionElem
::Field(f
, ty
) => ProjectionElem
::Field(f
, ty
.lift()),
51 ProjectionElem
::Index(ref i
) => ProjectionElem
::Index(i
.lift()),
52 ProjectionElem
::Subslice { from, to, from_end }
=> {
53 ProjectionElem
::Subslice { from, to, from_end }
55 ProjectionElem
::ConstantIndex { offset, min_length, from_end }
=> {
56 ProjectionElem
::ConstantIndex { offset, min_length, from_end }
58 ProjectionElem
::Downcast(a
, u
) => ProjectionElem
::Downcast(a
, u
),