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
>],