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