1 //! Values computed by queries that use MIR.
3 use crate::ty::{self, Ty};
4 use rustc_data_structures::sync::Lrc;
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;
12 use super::{Field, SourceInfo};
14 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
15 pub enum UnsafetyViolationKind {
17 /// Permitted both in `const fn`s and regular `fn`s.
19 BorrowPacked(hir::HirId),
22 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
23 pub struct UnsafetyViolation {
24 pub source_info: SourceInfo,
25 pub description: Symbol,
27 pub kind: UnsafetyViolationKind,
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)]>,
39 rustc_index::newtype_index! {
40 pub struct GeneratorSavedLocal {
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>>,
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>>,
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
59 pub storage_conflicts: BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal>,
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]>,
68 /// The result of the `mir_const_qualif` query.
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
73 #[derive(Clone, Copy, Debug, Default, RustcEncodable, RustcDecodable, HashStable)]
74 pub struct ConstQualifs {
75 pub has_mut_interior: bool,
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.
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.
95 /// Example: If type check produces a closure with the closure substs:
99 /// i8, // the "closure kind"
100 /// for<'x> fn(&'a &'x u32) -> &'x u32, // the "closure signature"
101 /// &'a String, // some upvar
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:
109 /// ClosureSubsts = [
110 /// i8, // the "closure kind"
111 /// for<'x> fn(&'1 &'x u32) -> &'x u32, // the "closure signature"
112 /// &'2 String, // some upvar
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.
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
136 pub num_external_vids: usize,
138 /// Requirements between the various free regions defined in
140 pub outlives_requirements: Vec<ClosureOutlivesRequirement<'tcx>>,
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>,
150 // ... must outlive this one.
151 pub outlived_free_region: ty::RegionVid,
153 // If not, report an error here ...
154 pub blame_span: Span,
156 // ... due to this reason.
157 pub category: ConstraintCategory,
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.
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 {
175 /// A constraint that came from checking the body of a closure.
177 /// We try to get the category that the closure used when reporting this.
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
194 // Boring and applicable everywhere.
197 /// A constraint that doesn't correspond to anything the user sees.
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`.
209 /// The type here is guaranteed not to contain any free regions at
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),
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>],