rustc_middle/mir/
query.rs

1//! Values computed by queries that use MIR.
2
3use std::fmt::{self, Debug};
4
5use rustc_abi::{FieldIdx, VariantIdx};
6use rustc_data_structures::fx::FxIndexMap;
7use rustc_errors::ErrorGuaranteed;
8use rustc_hir::def_id::LocalDefId;
9use rustc_index::IndexVec;
10use rustc_index::bit_set::BitMatrix;
11use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
12use rustc_span::{Span, Symbol};
13
14use super::{ConstValue, SourceInfo};
15use crate::ty::{self, CoroutineArgsExt, OpaqueHiddenType, Ty};
16
17rustc_index::newtype_index! {
18    #[derive(HashStable)]
19    #[encodable]
20    #[debug_format = "_s{}"]
21    pub struct CoroutineSavedLocal {}
22}
23
24#[derive(Clone, Debug, PartialEq, Eq)]
25#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
26pub struct CoroutineSavedTy<'tcx> {
27    pub ty: Ty<'tcx>,
28    /// Source info corresponding to the local in the original MIR body.
29    pub source_info: SourceInfo,
30    /// Whether the local should be ignored for trait bound computations.
31    pub ignore_for_traits: bool,
32}
33
34/// The layout of coroutine state.
35#[derive(Clone, PartialEq, Eq)]
36#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
37pub struct CoroutineLayout<'tcx> {
38    /// The type of every local stored inside the coroutine.
39    pub field_tys: IndexVec<CoroutineSavedLocal, CoroutineSavedTy<'tcx>>,
40
41    /// The name for debuginfo.
42    pub field_names: IndexVec<CoroutineSavedLocal, Option<Symbol>>,
43
44    /// Which of the above fields are in each variant. Note that one field may
45    /// be stored in multiple variants.
46    pub variant_fields: IndexVec<VariantIdx, IndexVec<FieldIdx, CoroutineSavedLocal>>,
47
48    /// The source that led to each variant being created (usually, a yield or
49    /// await).
50    pub variant_source_info: IndexVec<VariantIdx, SourceInfo>,
51
52    /// Which saved locals are storage-live at the same time. Locals that do not
53    /// have conflicts with each other are allowed to overlap in the computed
54    /// layout.
55    #[type_foldable(identity)]
56    #[type_visitable(ignore)]
57    pub storage_conflicts: BitMatrix<CoroutineSavedLocal, CoroutineSavedLocal>,
58}
59
60impl Debug for CoroutineLayout<'_> {
61    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
62        fmt.debug_struct("CoroutineLayout")
63            .field_with("field_tys", |fmt| {
64                fmt.debug_map().entries(self.field_tys.iter_enumerated()).finish()
65            })
66            .field_with("variant_fields", |fmt| {
67                let mut map = fmt.debug_map();
68                for (idx, fields) in self.variant_fields.iter_enumerated() {
69                    map.key_with(|fmt| {
70                        let variant_name = ty::CoroutineArgs::variant_name(idx);
71                        if fmt.alternate() {
72                            write!(fmt, "{variant_name:9}({idx:?})")
73                        } else {
74                            write!(fmt, "{variant_name}")
75                        }
76                    });
77                    // Force variant fields to print in regular mode instead of alternate mode.
78                    map.value_with(|fmt| write!(fmt, "{fields:?}"));
79                }
80                map.finish()
81            })
82            .field("storage_conflicts", &self.storage_conflicts)
83            .finish()
84    }
85}
86
87/// All the opaque types that have had their hidden type fully computed.
88/// Unlike the value in `TypeckResults`, this has unerased regions.
89#[derive(Default, Debug, TyEncodable, TyDecodable, HashStable)]
90pub struct DefinitionSiteHiddenTypes<'tcx>(pub FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>);
91
92/// The result of the `mir_const_qualif` query.
93///
94/// Each field (except `tainted_by_errors`) corresponds to an implementer of the `Qualif` trait in
95/// `rustc_const_eval/src/transform/check_consts/qualifs.rs`. See that file for more information on each
96/// `Qualif`.
97#[derive(Clone, Copy, Debug, Default, TyEncodable, TyDecodable, HashStable)]
98pub struct ConstQualifs {
99    pub has_mut_interior: bool,
100    pub needs_drop: bool,
101    pub needs_non_const_drop: bool,
102    pub tainted_by_errors: Option<ErrorGuaranteed>,
103}
104/// Outlives-constraints can be categorized to determine whether and why they
105/// are interesting (for error reporting). Order of variants indicates sort
106/// order of the category, thereby influencing diagnostic output.
107///
108/// See also `rustc_const_eval::borrow_check::constraints`.
109#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
110#[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)]
111pub enum ConstraintCategory<'tcx> {
112    Return(ReturnConstraint),
113    Yield,
114    UseAsConst,
115    UseAsStatic,
116    TypeAnnotation(AnnotationSource),
117    Cast {
118        /// Whether this cast is a coercion that was automatically inserted by the compiler.
119        is_implicit_coercion: bool,
120        /// Whether this is an unsizing coercion and if yes, this contains the target type.
121        /// Region variables are erased to ReErased.
122        unsize_to: Option<Ty<'tcx>>,
123    },
124
125    /// Contains the function type if available.
126    CallArgument(Option<Ty<'tcx>>),
127    CopyBound,
128    SizedBound,
129    Assignment,
130    /// A constraint that came from a usage of a variable (e.g. in an ADT expression
131    /// like `Foo { field: my_val }`)
132    Usage,
133    OpaqueType,
134    ClosureUpvar(FieldIdx),
135
136    /// A constraint from a user-written predicate
137    /// with the provided span, written on the item
138    /// with the given `DefId`
139    Predicate(Span),
140
141    /// A "boring" constraint (caused by the given location) is one that
142    /// the user probably doesn't want to see described in diagnostics,
143    /// because it is kind of an artifact of the type system setup.
144    Boring,
145    // Boring and applicable everywhere.
146    BoringNoLocation,
147
148    /// A constraint that doesn't correspond to anything the user sees.
149    Internal,
150
151    /// An internal constraint added when a region outlives a placeholder
152    /// it cannot name and therefore has to outlive `'static`. The argument
153    /// is the unnameable placeholder and the constraint is always between
154    /// an SCC representative and `'static`.
155    OutlivesUnnameablePlaceholder(
156        #[type_foldable(identity)]
157        #[type_visitable(ignore)]
158        ty::RegionVid,
159    ),
160}
161
162#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
163#[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)]
164pub enum ReturnConstraint {
165    Normal,
166    ClosureUpvar(FieldIdx),
167}
168
169#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
170#[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)]
171pub enum AnnotationSource {
172    Ascription,
173    Declaration,
174    OpaqueCast,
175    GenericArg,
176}
177
178/// The constituent parts of a mir constant of kind ADT or array.
179#[derive(Copy, Clone, Debug, HashStable)]
180pub struct DestructuredConstant<'tcx> {
181    pub variant: Option<VariantIdx>,
182    pub fields: &'tcx [(ConstValue, Ty<'tcx>)],
183}