- Move(MoveReason), // reference to x where x has a type that moves
-}
-
-#[derive(Copy, Clone, PartialEq, Debug)]
-pub enum MoveReason {
- DirectRefMove,
- PatBindingMove,
- CaptureMove,
-}
-
-#[derive(Copy, Clone, PartialEq, Debug)]
-pub enum MatchMode {
- NonBindingMatch,
- BorrowingMatch,
- CopyingMatch,
- MovingMatch,
-}
-
-#[derive(Copy, Clone, PartialEq, Debug)]
-enum TrackMatchMode {
- Unknown,
- Definite(MatchMode),
- Conflicting,
-}
-
-impl TrackMatchMode {
- // Builds up the whole match mode for a pattern from its constituent
- // parts. The lattice looks like this:
- //
- // Conflicting
- // / \
- // / \
- // Borrowing Moving
- // \ /
- // \ /
- // Copying
- // |
- // NonBinding
- // |
- // Unknown
- //
- // examples:
- //
- // * `(_, some_int)` pattern is Copying, since
- // NonBinding + Copying => Copying
- //
- // * `(some_int, some_box)` pattern is Moving, since
- // Copying + Moving => Moving
- //
- // * `(ref x, some_box)` pattern is Conflicting, since
- // Borrowing + Moving => Conflicting
- //
- // Note that the `Unknown` and `Conflicting` states are
- // represented separately from the other more interesting
- // `Definite` states, which simplifies logic here somewhat.
- fn lub(&mut self, mode: MatchMode) {
- *self = match (*self, mode) {
- // Note that clause order below is very significant.
- (Unknown, new) => Definite(new),
- (Definite(old), new) if old == new => Definite(old),
-
- (Definite(old), NonBindingMatch) => Definite(old),
- (Definite(NonBindingMatch), new) => Definite(new),
-
- (Definite(old), CopyingMatch) => Definite(old),
- (Definite(CopyingMatch), new) => Definite(new),
-
- (Definite(_), _) => Conflicting,
- (Conflicting, _) => *self,
- };
- }
-
- fn match_mode(&self) -> MatchMode {
- match *self {
- Unknown => NonBindingMatch,
- Definite(mode) => mode,
- Conflicting => {
- // Conservatively return MovingMatch to let the
- // compiler continue to make progress.
- MovingMatch
- }
- }
- }