]> git.lizzy.rs Git - rust.git/blob - src/librustc/mir/query.rs
Rollup merge of #68278 - wesleywiser:doc_query_key_recording, r=michaelwoerister
[rust.git] / src / librustc / mir / query.rs
1 //! Values computed by queries that use MIR.
2
3 use crate::ty::{self, Ty};
4 use rustc_data_structures::sync::Lrc;
5 use rustc_hir as hir;
6 use rustc_index::bit_set::BitMatrix;
7 use rustc_index::vec::IndexVec;
8 use rustc_span::{Span, Symbol};
9 use rustc_target::abi::VariantIdx;
10 use smallvec::SmallVec;
11
12 use super::{Field, SourceInfo};
13
14 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
15 pub enum UnsafetyViolationKind {
16     General,
17     /// Permitted both in `const fn`s and regular `fn`s.
18     GeneralAndConstFn,
19     BorrowPacked(hir::HirId),
20 }
21
22 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
23 pub struct UnsafetyViolation {
24     pub source_info: SourceInfo,
25     pub description: Symbol,
26     pub details: Symbol,
27     pub kind: UnsafetyViolationKind,
28 }
29
30 #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
31 pub struct UnsafetyCheckResult {
32     /// Violations that are propagated *upwards* from this function.
33     pub violations: Lrc<[UnsafetyViolation]>,
34     /// `unsafe` blocks in this function, along with whether they are used. This is
35     /// used for the "unused_unsafe" lint.
36     pub unsafe_blocks: Lrc<[(hir::HirId, bool)]>,
37 }
38
39 rustc_index::newtype_index! {
40     pub struct GeneratorSavedLocal {
41         derive [HashStable]
42         DEBUG_FORMAT = "_{}",
43     }
44 }
45
46 /// The layout of generator state.
47 #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
48 pub struct GeneratorLayout<'tcx> {
49     /// The type of every local stored inside the generator.
50     pub field_tys: IndexVec<GeneratorSavedLocal, Ty<'tcx>>,
51
52     /// Which of the above fields are in each variant. Note that one field may
53     /// be stored in multiple variants.
54     pub variant_fields: IndexVec<VariantIdx, IndexVec<Field, GeneratorSavedLocal>>,
55
56     /// Which saved locals are storage-live at the same time. Locals that do not
57     /// have conflicts with each other are allowed to overlap in the computed
58     /// layout.
59     pub storage_conflicts: BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal>,
60 }
61
62 #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
63 pub struct BorrowCheckResult<'tcx> {
64     pub closure_requirements: Option<ClosureRegionRequirements<'tcx>>,
65     pub used_mut_upvars: SmallVec<[Field; 8]>,
66 }
67
68 /// The result of the `mir_const_qualif` query.
69 ///
70 /// Each field corresponds to an implementer of the `Qualif` trait in
71 /// `librustc_mir/transform/check_consts/qualifs.rs`. See that file for more information on each
72 /// `Qualif`.
73 #[derive(Clone, Copy, Debug, Default, RustcEncodable, RustcDecodable, HashStable)]
74 pub struct ConstQualifs {
75     pub has_mut_interior: bool,
76     pub needs_drop: bool,
77 }
78
79 /// After we borrow check a closure, we are left with various
80 /// requirements that we have inferred between the free regions that
81 /// appear in the closure's signature or on its field types. These
82 /// requirements are then verified and proved by the closure's
83 /// creating function. This struct encodes those requirements.
84 ///
85 /// The requirements are listed as being between various
86 /// `RegionVid`. The 0th region refers to `'static`; subsequent region
87 /// vids refer to the free regions that appear in the closure (or
88 /// generator's) type, in order of appearance. (This numbering is
89 /// actually defined by the `UniversalRegions` struct in the NLL
90 /// region checker. See for example
91 /// `UniversalRegions::closure_mapping`.) Note that we treat the free
92 /// regions in the closure's type "as if" they were erased, so their
93 /// precise identity is not important, only their position.
94 ///
95 /// Example: If type check produces a closure with the closure substs:
96 ///
97 /// ```text
98 /// ClosureSubsts = [
99 ///     i8,                                  // the "closure kind"
100 ///     for<'x> fn(&'a &'x u32) -> &'x u32,  // the "closure signature"
101 ///     &'a String,                          // some upvar
102 /// ]
103 /// ```
104 ///
105 /// here, there is one unique free region (`'a`) but it appears
106 /// twice. We would "renumber" each occurrence to a unique vid, as follows:
107 ///
108 /// ```text
109 /// ClosureSubsts = [
110 ///     i8,                                  // the "closure kind"
111 ///     for<'x> fn(&'1 &'x u32) -> &'x u32,  // the "closure signature"
112 ///     &'2 String,                          // some upvar
113 /// ]
114 /// ```
115 ///
116 /// Now the code might impose a requirement like `'1: '2`. When an
117 /// instance of the closure is created, the corresponding free regions
118 /// can be extracted from its type and constrained to have the given
119 /// outlives relationship.
120 ///
121 /// In some cases, we have to record outlives requirements between
122 /// types and regions as well. In that case, if those types include
123 /// any regions, those regions are recorded as `ReClosureBound`
124 /// instances assigned one of these same indices. Those regions will
125 /// be substituted away by the creator. We use `ReClosureBound` in
126 /// that case because the regions must be allocated in the global
127 /// `TyCtxt`, and hence we cannot use `ReVar` (which is what we use
128 /// internally within the rest of the NLL code).
129 #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
130 pub struct ClosureRegionRequirements<'tcx> {
131     /// The number of external regions defined on the closure. In our
132     /// example above, it would be 3 -- one for `'static`, then `'1`
133     /// and `'2`. This is just used for a sanity check later on, to
134     /// make sure that the number of regions we see at the callsite
135     /// matches.
136     pub num_external_vids: usize,
137
138     /// Requirements between the various free regions defined in
139     /// indices.
140     pub outlives_requirements: Vec<ClosureOutlivesRequirement<'tcx>>,
141 }
142
143 /// Indicates an outlives-constraint between a type or between two
144 /// free regions declared on the closure.
145 #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
146 pub struct ClosureOutlivesRequirement<'tcx> {
147     // This region or type ...
148     pub subject: ClosureOutlivesSubject<'tcx>,
149
150     // ... must outlive this one.
151     pub outlived_free_region: ty::RegionVid,
152
153     // If not, report an error here ...
154     pub blame_span: Span,
155
156     // ... due to this reason.
157     pub category: ConstraintCategory,
158 }
159
160 /// Outlives-constraints can be categorized to determine whether and why they
161 /// are interesting (for error reporting). Order of variants indicates sort
162 /// order of the category, thereby influencing diagnostic output.
163 ///
164 /// See also [rustc_mir::borrow_check::nll::constraints].
165 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
166 #[derive(RustcEncodable, RustcDecodable, HashStable)]
167 pub enum ConstraintCategory {
168     Return,
169     Yield,
170     UseAsConst,
171     UseAsStatic,
172     TypeAnnotation,
173     Cast,
174
175     /// A constraint that came from checking the body of a closure.
176     ///
177     /// We try to get the category that the closure used when reporting this.
178     ClosureBounds,
179     CallArgument,
180     CopyBound,
181     SizedBound,
182     Assignment,
183     OpaqueType,
184
185     /// A "boring" constraint (caused by the given location) is one that
186     /// the user probably doesn't want to see described in diagnostics,
187     /// because it is kind of an artifact of the type system setup.
188     /// Example: `x = Foo { field: y }` technically creates
189     /// intermediate regions representing the "type of `Foo { field: y
190     /// }`", and data flows from `y` into those variables, but they
191     /// are not very interesting. The assignment into `x` on the other
192     /// hand might be.
193     Boring,
194     // Boring and applicable everywhere.
195     BoringNoLocation,
196
197     /// A constraint that doesn't correspond to anything the user sees.
198     Internal,
199 }
200
201 /// The subject of a `ClosureOutlivesRequirement` -- that is, the thing
202 /// that must outlive some region.
203 #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
204 pub enum ClosureOutlivesSubject<'tcx> {
205     /// Subject is a type, typically a type parameter, but could also
206     /// be a projection. Indicates a requirement like `T: 'a` being
207     /// passed to the caller, where the type here is `T`.
208     ///
209     /// The type here is guaranteed not to contain any free regions at
210     /// present.
211     Ty(Ty<'tcx>),
212
213     /// Subject is a free region from the closure. Indicates a requirement
214     /// like `'a: 'b` being passed to the caller; the region here is `'a`.
215     Region(ty::RegionVid),
216 }
217
218 /// The constituent parts of an ADT or array.
219 #[derive(Copy, Clone, Debug, HashStable)]
220 pub struct DestructuredConst<'tcx> {
221     pub variant: VariantIdx,
222     pub fields: &'tcx [&'tcx ty::Const<'tcx>],
223 }