]>
Commit | Line | Data |
---|---|---|
54a0048b | 1 | //! The move-analysis portion of borrowck needs to work in an abstract |
9fa01778 | 2 | //! domain of lifted `Place`s. Most of the `Place` variants fall into a |
0731742a | 3 | //! one-to-one mapping between the concrete and abstract (e.g., a |
9fa01778 XL |
4 | //! field-deref on a local variable, `x.field`, has the same meaning |
5 | //! in both domains). Indexed projections are the exception: `a[x]` | |
54a0048b | 6 | //! needs to be treated as mapping to the same move path as `a[y]` as |
9fa01778 | 7 | //! well as `a[13]`, etc. |
54a0048b | 8 | //! |
9fa01778 | 9 | //! (In theory, the analysis could be extended to work with sets of |
54a0048b SL |
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.) | |
13 | ||
e1599b0c | 14 | use rustc::mir::{Local, Operand, PlaceElem, ProjectionElem}; |
3b2f2976 | 15 | use rustc::ty::Ty; |
54a0048b SL |
16 | |
17 | #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] | |
18 | pub struct AbstractOperand; | |
3b2f2976 XL |
19 | #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] |
20 | pub struct AbstractType; | |
532ac7d7 | 21 | pub type AbstractElem = ProjectionElem<AbstractOperand, AbstractType>; |
54a0048b SL |
22 | |
23 | pub trait Lift { | |
24 | type Abstract; | |
25 | fn lift(&self) -> Self::Abstract; | |
26 | } | |
27 | impl<'tcx> Lift for Operand<'tcx> { | |
28 | type Abstract = AbstractOperand; | |
e1599b0c XL |
29 | fn lift(&self) -> Self::Abstract { |
30 | AbstractOperand | |
31 | } | |
ea8adc8c XL |
32 | } |
33 | impl Lift for Local { | |
34 | type Abstract = AbstractOperand; | |
e1599b0c XL |
35 | fn lift(&self) -> Self::Abstract { |
36 | AbstractOperand | |
37 | } | |
54a0048b | 38 | } |
3b2f2976 XL |
39 | impl<'tcx> Lift for Ty<'tcx> { |
40 | type Abstract = AbstractType; | |
e1599b0c XL |
41 | fn lift(&self) -> Self::Abstract { |
42 | AbstractType | |
43 | } | |
3b2f2976 | 44 | } |
ff7c6d11 | 45 | impl<'tcx> Lift for PlaceElem<'tcx> { |
532ac7d7 | 46 | type Abstract = AbstractElem; |
54a0048b SL |
47 | fn lift(&self) -> Self::Abstract { |
48 | match *self { | |
e1599b0c | 49 | ProjectionElem::Deref => ProjectionElem::Deref, |
dfeec247 | 50 | ProjectionElem::Field(f, ty) => ProjectionElem::Field(f, ty.lift()), |
e1599b0c | 51 | ProjectionElem::Index(ref i) => ProjectionElem::Index(i.lift()), |
60c5eb7d XL |
52 | ProjectionElem::Subslice { from, to, from_end } => { |
53 | ProjectionElem::Subslice { from, to, from_end } | |
e1599b0c XL |
54 | } |
55 | ProjectionElem::ConstantIndex { offset, min_length, from_end } => { | |
56 | ProjectionElem::ConstantIndex { offset, min_length, from_end } | |
57 | } | |
dfeec247 | 58 | ProjectionElem::Downcast(a, u) => ProjectionElem::Downcast(a, u), |
54a0048b SL |
59 | } |
60 | } | |
61 | } |