]>
Commit | Line | Data |
---|---|---|
487cf647 FG |
1 | #![deny(rustc::untranslatable_diagnostic)] |
2 | #![deny(rustc::diagnostic_outside_of_impl)] | |
f9f354fc XL |
3 | use rustc_middle::mir::visit::{ |
4 | MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext, | |
5 | }; | |
6 | ||
7 | #[derive(Eq, PartialEq, Clone)] | |
8 | pub enum DefUse { | |
9 | Def, | |
10 | Use, | |
11 | Drop, | |
12 | } | |
13 | ||
14 | pub fn categorize(context: PlaceContext) -> Option<DefUse> { | |
15 | match context { | |
16 | /////////////////////////////////////////////////////////////////////////// | |
17 | // DEFS | |
18 | ||
19 | PlaceContext::MutatingUse(MutatingUseContext::Store) | | |
20 | ||
f9f354fc XL |
21 | // We let Call define the result in both the success and |
22 | // unwind cases. This is not really correct, however it | |
23 | // does not seem to be observable due to the way that we | |
24 | // generate MIR. To do things properly, we would apply | |
25 | // the def in call only to the input from the success | |
26 | // path and not the unwind path. -nmatsakis | |
27 | PlaceContext::MutatingUse(MutatingUseContext::Call) | | |
a2a8927a | 28 | PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) | |
f9f354fc XL |
29 | PlaceContext::MutatingUse(MutatingUseContext::Yield) | |
30 | ||
31 | // Storage live and storage dead aren't proper defines, but we can ignore | |
32 | // values that come before them. | |
33 | PlaceContext::NonUse(NonUseContext::StorageLive) | | |
34 | PlaceContext::NonUse(NonUseContext::StorageDead) => Some(DefUse::Def), | |
35 | ||
36 | /////////////////////////////////////////////////////////////////////////// | |
37 | // REGULAR USES | |
38 | // | |
39 | // These are uses that occur *outside* of a drop. For the | |
40 | // purposes of NLL, these are special in that **all** the | |
41 | // lifetimes appearing in the variable must be live for each regular use. | |
42 | ||
43 | PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) | | |
44 | PlaceContext::MutatingUse(MutatingUseContext::Projection) | | |
45 | ||
46 | // Borrows only consider their local used at the point of the borrow. | |
47 | // This won't affect the results since we use this analysis for generators | |
48 | // and we only care about the result at suspension points. Borrows cannot | |
49 | // cross suspension points so this behavior is unproblematic. | |
50 | PlaceContext::MutatingUse(MutatingUseContext::Borrow) | | |
51 | PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) | | |
52 | PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) | | |
f9f354fc | 53 | |
49aad941 FG |
54 | // `PlaceMention` and `AscribeUserType` both evaluate the place, which must not |
55 | // contain dangling references. | |
56 | PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention) | | |
57 | PlaceContext::NonUse(NonUseContext::AscribeUserTy(_)) | | |
58 | ||
f9f354fc XL |
59 | PlaceContext::MutatingUse(MutatingUseContext::AddressOf) | |
60 | PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) | | |
61 | PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect) | | |
62 | PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) | | |
63 | PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) | | |
f9f354fc XL |
64 | PlaceContext::MutatingUse(MutatingUseContext::Retag) => |
65 | Some(DefUse::Use), | |
66 | ||
67 | /////////////////////////////////////////////////////////////////////////// | |
68 | // DROP USES | |
69 | // | |
70 | // These are uses that occur in a DROP (a MIR drop, not a | |
71 | // call to `std::mem::drop()`). For the purposes of NLL, | |
72 | // uses in drop are special because `#[may_dangle]` | |
73 | // attributes can affect whether lifetimes must be live. | |
74 | ||
75 | PlaceContext::MutatingUse(MutatingUseContext::Drop) => | |
76 | Some(DefUse::Drop), | |
77 | ||
1b1a35ee | 78 | // Debug info is neither def nor use. |
f9f354fc | 79 | PlaceContext::NonUse(NonUseContext::VarDebugInfo) => None, |
04454e1e FG |
80 | |
81 | PlaceContext::MutatingUse(MutatingUseContext::Deinit | MutatingUseContext::SetDiscriminant) => { | |
82 | bug!("These statements are not allowed in this MIR phase") | |
83 | } | |
f9f354fc XL |
84 | } |
85 | } |