]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_middle/src/mir/query.rs
New upstream version 1.65.0+dfsg1
[rustc.git] / compiler / rustc_middle / src / mir / query.rs
CommitLineData
dfeec247
XL
1//! Values computed by queries that use MIR.
2
923072b8 3use crate::mir::{Body, ConstantKind, Promoted};
5e7ed085 4use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt};
f2b60f7d 5use rustc_data_structures::fx::FxHashSet;
17df50a5 6use rustc_data_structures::vec_map::VecMap;
5e7ed085 7use rustc_errors::ErrorGuaranteed;
dfeec247 8use rustc_hir as hir;
3dfed10e 9use rustc_hir::def_id::{DefId, LocalDefId};
dfeec247
XL
10use rustc_index::bit_set::BitMatrix;
11use rustc_index::vec::IndexVec;
3dfed10e 12use rustc_span::Span;
dfeec247
XL
13use rustc_target::abi::VariantIdx;
14use smallvec::SmallVec;
f035d41b
XL
15use std::cell::Cell;
16use std::fmt::{self, Debug};
dfeec247
XL
17
18use super::{Field, SourceInfo};
19
5869c6ff 20#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
dfeec247 21pub enum UnsafetyViolationKind {
cdc7bbd5 22 /// Unsafe operation outside `unsafe`.
dfeec247 23 General,
f9f354fc
XL
24 /// Unsafe operation in an `unsafe fn` but outside an `unsafe` block.
25 /// Has to be handled as a lint for backwards compatibility.
f9f354fc 26 UnsafeFn,
dfeec247
XL
27}
28
5869c6ff 29#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
3dfed10e
XL
30pub enum UnsafetyViolationDetails {
31 CallToUnsafeFunction,
32 UseOfInlineAssembly,
33 InitializingTypeWith,
34 CastOfPointerToInt,
3dfed10e
XL
35 UseOfMutableStatic,
36 UseOfExternStatic,
37 DerefOfRawPointer,
3dfed10e
XL
38 AccessToUnionField,
39 MutationOfLayoutConstrainedField,
40 BorrowOfLayoutConstrainedField,
41 CallToFunctionWith,
42}
43
44impl UnsafetyViolationDetails {
45 pub fn description_and_note(&self) -> (&'static str, &'static str) {
46 use UnsafetyViolationDetails::*;
47 match self {
48 CallToUnsafeFunction => (
49 "call to unsafe function",
50 "consult the function's documentation for information on how to avoid undefined \
51 behavior",
52 ),
53 UseOfInlineAssembly => (
54 "use of inline assembly",
55 "inline assembly is entirely unchecked and can cause undefined behavior",
56 ),
57 InitializingTypeWith => (
58 "initializing type with `rustc_layout_scalar_valid_range` attr",
59 "initializing a layout restricted type's field with a value outside the valid \
60 range is undefined behavior",
61 ),
62 CastOfPointerToInt => {
63 ("cast of pointer to int", "casting pointers to integers in constants")
64 }
3dfed10e
XL
65 UseOfMutableStatic => (
66 "use of mutable static",
67 "mutable statics can be mutated by multiple threads: aliasing violations or data \
68 races will cause undefined behavior",
69 ),
70 UseOfExternStatic => (
71 "use of extern static",
72 "extern statics are not controlled by the Rust type system: invalid data, \
73 aliasing violations or data races will cause undefined behavior",
74 ),
75 DerefOfRawPointer => (
76 "dereference of raw pointer",
17df50a5 77 "raw pointers may be null, dangling or unaligned; they can violate aliasing rules \
3dfed10e
XL
78 and cause data races: all of these are undefined behavior",
79 ),
3dfed10e
XL
80 AccessToUnionField => (
81 "access to union field",
82 "the field may not be properly initialized: using uninitialized data will cause \
83 undefined behavior",
84 ),
85 MutationOfLayoutConstrainedField => (
86 "mutation of layout constrained field",
87 "mutating layout constrained fields cannot statically be checked for valid values",
88 ),
89 BorrowOfLayoutConstrainedField => (
90 "borrow of layout constrained field with interior mutability",
91 "references to fields of layout constrained fields lose the constraints. Coupled \
92 with interior mutability, the field can be changed to invalid values",
93 ),
94 CallToFunctionWith => (
95 "call to function with `#[target_feature]`",
96 "can only be called if the required target features are available",
97 ),
98 }
99 }
100}
101
5869c6ff 102#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
dfeec247
XL
103pub struct UnsafetyViolation {
104 pub source_info: SourceInfo,
f9f354fc 105 pub lint_root: hir::HirId,
dfeec247 106 pub kind: UnsafetyViolationKind,
3dfed10e 107 pub details: UnsafetyViolationDetails,
dfeec247
XL
108}
109
5e7ed085
FG
110#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
111pub enum UnusedUnsafe {
112 /// `unsafe` block contains no unsafe operations
113 /// > ``unnecessary `unsafe` block``
114 Unused,
115 /// `unsafe` block nested under another (used) `unsafe` block
116 /// > ``… because it's nested under this `unsafe` block``
117 InUnsafeBlock(hir::HirId),
5e7ed085
FG
118}
119
120#[derive(TyEncodable, TyDecodable, HashStable, Debug)]
dfeec247
XL
121pub struct UnsafetyCheckResult {
122 /// Violations that are propagated *upwards* from this function.
5e7ed085
FG
123 pub violations: Vec<UnsafetyViolation>,
124
125 /// Used `unsafe` blocks in this function. This is used for the "unused_unsafe" lint.
f2b60f7d 126 pub used_unsafe_blocks: FxHashSet<hir::HirId>,
5e7ed085
FG
127
128 /// This is `Some` iff the item is not a closure.
129 pub unused_unsafes: Option<Vec<(hir::HirId, UnusedUnsafe)>>,
dfeec247
XL
130}
131
132rustc_index::newtype_index! {
133 pub struct GeneratorSavedLocal {
134 derive [HashStable]
135 DEBUG_FORMAT = "_{}",
136 }
137}
138
139/// The layout of generator state.
064997fb 140#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
dfeec247
XL
141pub struct GeneratorLayout<'tcx> {
142 /// The type of every local stored inside the generator.
143 pub field_tys: IndexVec<GeneratorSavedLocal, Ty<'tcx>>,
144
145 /// Which of the above fields are in each variant. Note that one field may
146 /// be stored in multiple variants.
147 pub variant_fields: IndexVec<VariantIdx, IndexVec<Field, GeneratorSavedLocal>>,
148
f035d41b
XL
149 /// The source that led to each variant being created (usually, a yield or
150 /// await).
151 pub variant_source_info: IndexVec<VariantIdx, SourceInfo>,
152
dfeec247
XL
153 /// Which saved locals are storage-live at the same time. Locals that do not
154 /// have conflicts with each other are allowed to overlap in the computed
155 /// layout.
156 pub storage_conflicts: BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal>,
157}
158
f035d41b
XL
159impl Debug for GeneratorLayout<'_> {
160 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
161 /// Prints an iterator of (key, value) tuples as a map.
162 struct MapPrinter<'a, K, V>(Cell<Option<Box<dyn Iterator<Item = (K, V)> + 'a>>>);
163 impl<'a, K, V> MapPrinter<'a, K, V> {
164 fn new(iter: impl Iterator<Item = (K, V)> + 'a) -> Self {
165 Self(Cell::new(Some(Box::new(iter))))
166 }
167 }
168 impl<'a, K: Debug, V: Debug> Debug for MapPrinter<'a, K, V> {
169 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
170 fmt.debug_map().entries(self.0.take().unwrap()).finish()
171 }
172 }
173
174 /// Prints the generator variant name.
175 struct GenVariantPrinter(VariantIdx);
176 impl From<VariantIdx> for GenVariantPrinter {
177 fn from(idx: VariantIdx) -> Self {
178 GenVariantPrinter(idx)
179 }
180 }
181 impl Debug for GenVariantPrinter {
182 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
183 let variant_name = ty::GeneratorSubsts::variant_name(self.0);
184 if fmt.alternate() {
185 write!(fmt, "{:9}({:?})", variant_name, self.0)
186 } else {
187 write!(fmt, "{}", variant_name)
188 }
189 }
190 }
191
192 /// Forces its contents to print in regular mode instead of alternate mode.
193 struct OneLinePrinter<T>(T);
194 impl<T: Debug> Debug for OneLinePrinter<T> {
195 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
196 write!(fmt, "{:?}", self.0)
197 }
198 }
199
200 fmt.debug_struct("GeneratorLayout")
201 .field("field_tys", &MapPrinter::new(self.field_tys.iter_enumerated()))
202 .field(
203 "variant_fields",
204 &MapPrinter::new(
205 self.variant_fields
206 .iter_enumerated()
207 .map(|(k, v)| (GenVariantPrinter(k), OneLinePrinter(v))),
208 ),
209 )
210 .field("storage_conflicts", &self.storage_conflicts)
211 .finish()
212 }
213}
214
3dfed10e 215#[derive(Debug, TyEncodable, TyDecodable, HashStable)]
dfeec247 216pub struct BorrowCheckResult<'tcx> {
74b04a01 217 /// All the opaque types that are restricted to concrete types
3dfed10e 218 /// by this function. Unlike the value in `TypeckResults`, this has
74b04a01 219 /// unerased regions.
064997fb 220 pub concrete_opaque_types: VecMap<LocalDefId, OpaqueHiddenType<'tcx>>,
dfeec247
XL
221 pub closure_requirements: Option<ClosureRegionRequirements<'tcx>>,
222 pub used_mut_upvars: SmallVec<[Field; 8]>,
5e7ed085 223 pub tainted_by_errors: Option<ErrorGuaranteed>,
dfeec247
XL
224}
225
226/// The result of the `mir_const_qualif` query.
227///
5e7ed085 228/// Each field (except `error_occurred`) corresponds to an implementer of the `Qualif` trait in
c295e0f8 229/// `rustc_const_eval/src/transform/check_consts/qualifs.rs`. See that file for more information on each
dfeec247 230/// `Qualif`.
3dfed10e 231#[derive(Clone, Copy, Debug, Default, TyEncodable, TyDecodable, HashStable)]
dfeec247
XL
232pub struct ConstQualifs {
233 pub has_mut_interior: bool,
234 pub needs_drop: bool,
3c0e092e 235 pub needs_non_const_drop: bool,
f9f354fc 236 pub custom_eq: bool,
5e7ed085 237 pub tainted_by_errors: Option<ErrorGuaranteed>,
dfeec247
XL
238}
239
240/// After we borrow check a closure, we are left with various
241/// requirements that we have inferred between the free regions that
242/// appear in the closure's signature or on its field types. These
243/// requirements are then verified and proved by the closure's
244/// creating function. This struct encodes those requirements.
245///
ba9703b0
XL
246/// The requirements are listed as being between various `RegionVid`. The 0th
247/// region refers to `'static`; subsequent region vids refer to the free
248/// regions that appear in the closure (or generator's) type, in order of
249/// appearance. (This numbering is actually defined by the `UniversalRegions`
250/// struct in the NLL region checker. See for example
251/// `UniversalRegions::closure_mapping`.) Note the free regions in the
252/// closure's signature and captures are erased.
dfeec247
XL
253///
254/// Example: If type check produces a closure with the closure substs:
255///
256/// ```text
257/// ClosureSubsts = [
ba9703b0
XL
258/// 'a, // From the parent.
259/// 'b,
260/// i8, // the "closure kind"
261/// for<'x> fn(&'<erased> &'x u32) -> &'x u32, // the "closure signature"
262/// &'<erased> String, // some upvar
dfeec247
XL
263/// ]
264/// ```
265///
ba9703b0 266/// We would "renumber" each free region to a unique vid, as follows:
dfeec247
XL
267///
268/// ```text
269/// ClosureSubsts = [
ba9703b0
XL
270/// '1, // From the parent.
271/// '2,
272/// i8, // the "closure kind"
273/// for<'x> fn(&'3 &'x u32) -> &'x u32, // the "closure signature"
274/// &'4 String, // some upvar
dfeec247
XL
275/// ]
276/// ```
277///
278/// Now the code might impose a requirement like `'1: '2`. When an
279/// instance of the closure is created, the corresponding free regions
280/// can be extracted from its type and constrained to have the given
281/// outlives relationship.
282///
ba9703b0
XL
283/// In some cases, we have to record outlives requirements between types and
284/// regions as well. In that case, if those types include any regions, those
285/// regions are recorded using their external names (`ReStatic`,
286/// `ReEarlyBound`, `ReFree`). We use these because in a query response we
287/// cannot use `ReVar` (which is what we use internally within the rest of the
288/// NLL code).
3dfed10e 289#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
dfeec247
XL
290pub struct ClosureRegionRequirements<'tcx> {
291 /// The number of external regions defined on the closure. In our
292 /// example above, it would be 3 -- one for `'static`, then `'1`
293 /// and `'2`. This is just used for a sanity check later on, to
294 /// make sure that the number of regions we see at the callsite
295 /// matches.
296 pub num_external_vids: usize,
297
298 /// Requirements between the various free regions defined in
299 /// indices.
300 pub outlives_requirements: Vec<ClosureOutlivesRequirement<'tcx>>,
301}
302
303/// Indicates an outlives-constraint between a type or between two
304/// free regions declared on the closure.
3dfed10e 305#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
dfeec247
XL
306pub struct ClosureOutlivesRequirement<'tcx> {
307 // This region or type ...
308 pub subject: ClosureOutlivesSubject<'tcx>,
309
310 // ... must outlive this one.
311 pub outlived_free_region: ty::RegionVid,
312
313 // If not, report an error here ...
314 pub blame_span: Span,
315
316 // ... due to this reason.
923072b8 317 pub category: ConstraintCategory<'tcx>,
dfeec247
XL
318}
319
c295e0f8 320// Make sure this enum doesn't unintentionally grow
923072b8
FG
321#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
322rustc_data_structures::static_assert_size!(ConstraintCategory<'_>, 16);
c295e0f8 323
dfeec247
XL
324/// Outlives-constraints can be categorized to determine whether and why they
325/// are interesting (for error reporting). Order of variants indicates sort
326/// order of the category, thereby influencing diagnostic output.
327///
c295e0f8 328/// See also `rustc_const_eval::borrow_check::constraints`.
dfeec247 329#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
f2b60f7d 330#[derive(TyEncodable, TyDecodable, HashStable, Lift, TypeVisitable, TypeFoldable)]
923072b8 331pub enum ConstraintCategory<'tcx> {
f035d41b 332 Return(ReturnConstraint),
dfeec247
XL
333 Yield,
334 UseAsConst,
335 UseAsStatic,
336 TypeAnnotation,
337 Cast,
338
339 /// A constraint that came from checking the body of a closure.
340 ///
341 /// We try to get the category that the closure used when reporting this.
342 ClosureBounds,
923072b8
FG
343
344 /// Contains the function type if available.
345 CallArgument(Option<Ty<'tcx>>),
dfeec247
XL
346 CopyBound,
347 SizedBound,
348 Assignment,
c295e0f8
XL
349 /// A constraint that came from a usage of a variable (e.g. in an ADT expression
350 /// like `Foo { field: my_val }`)
351 Usage,
dfeec247 352 OpaqueType,
5099ac24 353 ClosureUpvar(Field),
dfeec247 354
c295e0f8
XL
355 /// A constraint from a user-written predicate
356 /// with the provided span, written on the item
357 /// with the given `DefId`
358 Predicate(Span),
359
dfeec247
XL
360 /// A "boring" constraint (caused by the given location) is one that
361 /// the user probably doesn't want to see described in diagnostics,
362 /// because it is kind of an artifact of the type system setup.
dfeec247
XL
363 Boring,
364 // Boring and applicable everywhere.
365 BoringNoLocation,
366
367 /// A constraint that doesn't correspond to anything the user sees.
368 Internal,
369}
370
f035d41b 371#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
f2b60f7d 372#[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)]
f035d41b
XL
373pub enum ReturnConstraint {
374 Normal,
5099ac24 375 ClosureUpvar(Field),
f035d41b
XL
376}
377
dfeec247
XL
378/// The subject of a `ClosureOutlivesRequirement` -- that is, the thing
379/// that must outlive some region.
3dfed10e 380#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
dfeec247
XL
381pub enum ClosureOutlivesSubject<'tcx> {
382 /// Subject is a type, typically a type parameter, but could also
383 /// be a projection. Indicates a requirement like `T: 'a` being
384 /// passed to the caller, where the type here is `T`.
385 ///
386 /// The type here is guaranteed not to contain any free regions at
387 /// present.
388 Ty(Ty<'tcx>),
389
390 /// Subject is a free region from the closure. Indicates a requirement
391 /// like `'a: 'b` being passed to the caller; the region here is `'a`.
392 Region(ty::RegionVid),
393}
394
923072b8 395/// The constituent parts of a type level constant of kind ADT or array.
dfeec247
XL
396#[derive(Copy, Clone, Debug, HashStable)]
397pub struct DestructuredConst<'tcx> {
f035d41b 398 pub variant: Option<VariantIdx>,
5099ac24 399 pub fields: &'tcx [ty::Const<'tcx>],
dfeec247 400}
f035d41b 401
923072b8
FG
402/// The constituent parts of a mir constant of kind ADT or array.
403#[derive(Copy, Clone, Debug, HashStable)]
404pub struct DestructuredMirConstant<'tcx> {
405 pub variant: Option<VariantIdx>,
406 pub fields: &'tcx [ConstantKind<'tcx>],
407}
408
f035d41b 409/// Coverage information summarized from a MIR if instrumented for source code coverage (see
5099ac24 410/// compiler option `-Cinstrument-coverage`). This information is generated by the
f035d41b 411/// `InstrumentCoverage` MIR pass and can be retrieved via the `coverageinfo` query.
3dfed10e 412#[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable)]
f035d41b 413pub struct CoverageInfo {
f035d41b
XL
414 /// The total number of coverage region counters added to the MIR `Body`.
415 pub num_counters: u32,
3dfed10e
XL
416
417 /// The total number of coverage region counter expressions added to the MIR `Body`.
418 pub num_expressions: u32,
419}
420
29967ef6
XL
421/// Shims which make dealing with `WithOptConstParam` easier.
422///
423/// For more information on why this is needed, consider looking
424/// at the docs for `WithOptConstParam` itself.
3dfed10e 425impl<'tcx> TyCtxt<'tcx> {
29967ef6 426 #[inline]
3dfed10e
XL
427 pub fn mir_const_qualif_opt_const_arg(
428 self,
429 def: ty::WithOptConstParam<LocalDefId>,
430 ) -> ConstQualifs {
431 if let Some(param_did) = def.const_param_did {
432 self.mir_const_qualif_const_arg((def.did, param_did))
433 } else {
434 self.mir_const_qualif(def.did)
435 }
436 }
437
29967ef6
XL
438 #[inline]
439 pub fn promoted_mir_opt_const_arg(
3dfed10e
XL
440 self,
441 def: ty::WithOptConstParam<DefId>,
442 ) -> &'tcx IndexVec<Promoted, Body<'tcx>> {
443 if let Some((did, param_did)) = def.as_const_arg() {
444 self.promoted_mir_of_const_arg((did, param_did))
445 } else {
446 self.promoted_mir(def.did)
447 }
448 }
29967ef6 449
5869c6ff
XL
450 #[inline]
451 pub fn mir_for_ctfe_opt_const_arg(self, def: ty::WithOptConstParam<DefId>) -> &'tcx Body<'tcx> {
452 if let Some((did, param_did)) = def.as_const_arg() {
453 self.mir_for_ctfe_of_const_arg((did, param_did))
454 } else {
455 self.mir_for_ctfe(def.did)
456 }
457 }
f035d41b 458}