]> git.proxmox.com Git - rustc.git/blob - src/librustc/mir/query.rs
New upstream version 1.42.0+dfsg1
[rustc.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 }