]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/ty/context.rs
f98172e420162c4ae6aecc0b8fd247e3589757f2
[rust.git] / compiler / rustc_middle / src / ty / context.rs
1 //! Type context book-keeping.
2
3 #![allow(rustc::usage_of_ty_tykind)]
4
5 pub mod tls;
6
7 use crate::arena::Arena;
8 use crate::dep_graph::{DepGraph, DepKindStruct};
9 use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos};
10 use crate::lint::struct_lint_level;
11 use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
12 use crate::middle::resolve_lifetime;
13 use crate::middle::stability;
14 use crate::mir::interpret::{self, Allocation, ConstAllocation};
15 use crate::mir::{
16     Body, BorrowCheckResult, Field, Local, Place, PlaceElem, ProjectionKind, Promoted,
17 };
18 use crate::thir::Thir;
19 use crate::traits;
20 use crate::ty::query::{self, TyCtxtAt};
21 use crate::ty::{
22     self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, DefIdTree, FloatTy, FloatVar,
23     FloatVid, GenericParamDefKind, ImplPolarity, InferTy, IntTy, IntVar, IntVid, List, ParamConst,
24     ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, Region, RegionKind,
25     ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut, TypeckResults, UintTy,
26     Visibility,
27 };
28 use crate::ty::{GenericArg, InternalSubsts, SubstsRef};
29 use rustc_ast as ast;
30 use rustc_data_structures::fingerprint::Fingerprint;
31 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
32 use rustc_data_structures::intern::Interned;
33 use rustc_data_structures::memmap::Mmap;
34 use rustc_data_structures::profiling::SelfProfilerRef;
35 use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
36 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
37 use rustc_data_structures::steal::Steal;
38 use rustc_data_structures::sync::{self, Lock, Lrc, ReadGuard, WorkerLocal};
39 use rustc_errors::{
40     DecorateLint, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, MultiSpan,
41 };
42 use rustc_hir as hir;
43 use rustc_hir::def::DefKind;
44 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
45 use rustc_hir::definitions::Definitions;
46 use rustc_hir::intravisit::Visitor;
47 use rustc_hir::lang_items::LangItem;
48 use rustc_hir::{
49     Constness, ExprKind, HirId, ImplItemKind, ItemKind, Node, TraitCandidate, TraitItemKind,
50 };
51 use rustc_index::vec::IndexVec;
52 use rustc_macros::HashStable;
53 use rustc_query_system::dep_graph::DepNodeIndex;
54 use rustc_query_system::ich::StableHashingContext;
55 use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
56 use rustc_session::config::CrateType;
57 use rustc_session::cstore::{CrateStoreDyn, Untracked};
58 use rustc_session::lint::Lint;
59 use rustc_session::Limit;
60 use rustc_session::Session;
61 use rustc_span::def_id::{DefPathHash, StableCrateId};
62 use rustc_span::source_map::SourceMap;
63 use rustc_span::symbol::{kw, sym, Ident, Symbol};
64 use rustc_span::{Span, DUMMY_SP};
65 use rustc_target::abi::{Layout, LayoutS, TargetDataLayout, VariantIdx};
66 use rustc_target::spec::abi;
67 use rustc_type_ir::sty::TyKind::*;
68 use rustc_type_ir::WithCachedTypeInfo;
69 use rustc_type_ir::{DynKind, InternAs, InternIteratorElement, Interner, TypeFlags};
70
71 use std::any::Any;
72 use std::borrow::Borrow;
73 use std::cmp::Ordering;
74 use std::fmt;
75 use std::hash::{Hash, Hasher};
76 use std::iter;
77 use std::mem;
78 use std::ops::{Bound, Deref};
79
80 const TINY_CONST_EVAL_LIMIT: Limit = Limit(20);
81
82 pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync {
83     /// Creates a new `OnDiskCache` instance from the serialized data in `data`.
84     fn new(sess: &'tcx Session, data: Mmap, start_pos: usize) -> Self
85     where
86         Self: Sized;
87
88     fn new_empty(source_map: &'tcx SourceMap) -> Self
89     where
90         Self: Sized;
91
92     fn drop_serialized_data(&self, tcx: TyCtxt<'tcx>);
93
94     fn serialize(&self, tcx: TyCtxt<'tcx>, encoder: FileEncoder) -> FileEncodeResult;
95 }
96
97 #[allow(rustc::usage_of_ty_tykind)]
98 impl<'tcx> Interner for TyCtxt<'tcx> {
99     type AdtDef = ty::AdtDef<'tcx>;
100     type SubstsRef = ty::SubstsRef<'tcx>;
101     type DefId = DefId;
102     type Ty = Ty<'tcx>;
103     type Const = ty::Const<'tcx>;
104     type Region = Region<'tcx>;
105     type TypeAndMut = TypeAndMut<'tcx>;
106     type Mutability = hir::Mutability;
107     type Movability = hir::Movability;
108     type PolyFnSig = PolyFnSig<'tcx>;
109     type ListBinderExistentialPredicate = &'tcx List<PolyExistentialPredicate<'tcx>>;
110     type BinderListTy = Binder<'tcx, &'tcx List<Ty<'tcx>>>;
111     type ListTy = &'tcx List<Ty<'tcx>>;
112     type AliasTy = ty::AliasTy<'tcx>;
113     type ParamTy = ParamTy;
114     type BoundTy = ty::BoundTy;
115     type PlaceholderType = ty::PlaceholderType;
116     type InferTy = InferTy;
117     type ErrorGuaranteed = ErrorGuaranteed;
118     type PredicateKind = ty::PredicateKind<'tcx>;
119     type AllocId = crate::mir::interpret::AllocId;
120
121     type EarlyBoundRegion = ty::EarlyBoundRegion;
122     type BoundRegion = ty::BoundRegion;
123     type FreeRegion = ty::FreeRegion;
124     type RegionVid = ty::RegionVid;
125     type PlaceholderRegion = ty::PlaceholderRegion;
126 }
127
128 type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
129
130 pub struct CtxtInterners<'tcx> {
131     /// The arena that types, regions, etc. are allocated from.
132     arena: &'tcx WorkerLocal<Arena<'tcx>>,
133
134     // Specifically use a speedy hash algorithm for these hash sets, since
135     // they're accessed quite often.
136     type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
137     const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
138     substs: InternedSet<'tcx, InternalSubsts<'tcx>>,
139     canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
140     region: InternedSet<'tcx, RegionKind<'tcx>>,
141     poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
142     predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
143     predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
144     projs: InternedSet<'tcx, List<ProjectionKind>>,
145     place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
146     const_: InternedSet<'tcx, ConstData<'tcx>>,
147     const_allocation: InternedSet<'tcx, Allocation>,
148     bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
149     layout: InternedSet<'tcx, LayoutS<VariantIdx>>,
150     adt_def: InternedSet<'tcx, AdtDefData>,
151 }
152
153 impl<'tcx> CtxtInterners<'tcx> {
154     fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
155         CtxtInterners {
156             arena,
157             type_: Default::default(),
158             const_lists: Default::default(),
159             substs: Default::default(),
160             region: Default::default(),
161             poly_existential_predicates: Default::default(),
162             canonical_var_infos: Default::default(),
163             predicate: Default::default(),
164             predicates: Default::default(),
165             projs: Default::default(),
166             place_elems: Default::default(),
167             const_: Default::default(),
168             const_allocation: Default::default(),
169             bound_variable_kinds: Default::default(),
170             layout: Default::default(),
171             adt_def: Default::default(),
172         }
173     }
174
175     /// Interns a type.
176     #[allow(rustc::usage_of_ty_tykind)]
177     #[inline(never)]
178     fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> {
179         Ty(Interned::new_unchecked(
180             self.type_
181                 .intern(kind, |kind| {
182                     let flags = super::flags::FlagComputation::for_kind(&kind);
183                     let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
184
185                     InternedInSet(self.arena.alloc(WithCachedTypeInfo {
186                         internee: kind,
187                         stable_hash,
188                         flags: flags.flags,
189                         outer_exclusive_binder: flags.outer_exclusive_binder,
190                     }))
191                 })
192                 .0,
193         ))
194     }
195
196     fn stable_hash<'a, T: HashStable<StableHashingContext<'a>>>(
197         &self,
198         flags: &ty::flags::FlagComputation,
199         sess: &'a Session,
200         untracked: &'a Untracked,
201         val: &T,
202     ) -> Fingerprint {
203         // It's impossible to hash inference variables (and will ICE), so we don't need to try to cache them.
204         // Without incremental, we rarely stable-hash types, so let's not do it proactively.
205         if flags.flags.intersects(TypeFlags::NEEDS_INFER) || sess.opts.incremental.is_none() {
206             Fingerprint::ZERO
207         } else {
208             let mut hasher = StableHasher::new();
209             let mut hcx = StableHashingContext::new(sess, untracked);
210             val.hash_stable(&mut hcx, &mut hasher);
211             hasher.finish()
212         }
213     }
214
215     #[inline(never)]
216     fn intern_predicate(
217         &self,
218         kind: Binder<'tcx, PredicateKind<'tcx>>,
219         sess: &Session,
220         untracked: &Untracked,
221     ) -> Predicate<'tcx> {
222         Predicate(Interned::new_unchecked(
223             self.predicate
224                 .intern(kind, |kind| {
225                     let flags = super::flags::FlagComputation::for_predicate(kind);
226
227                     let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
228
229                     InternedInSet(self.arena.alloc(WithCachedTypeInfo {
230                         internee: kind,
231                         stable_hash,
232                         flags: flags.flags,
233                         outer_exclusive_binder: flags.outer_exclusive_binder,
234                     }))
235                 })
236                 .0,
237         ))
238     }
239 }
240
241 pub struct CommonTypes<'tcx> {
242     pub unit: Ty<'tcx>,
243     pub bool: Ty<'tcx>,
244     pub char: Ty<'tcx>,
245     pub isize: Ty<'tcx>,
246     pub i8: Ty<'tcx>,
247     pub i16: Ty<'tcx>,
248     pub i32: Ty<'tcx>,
249     pub i64: Ty<'tcx>,
250     pub i128: Ty<'tcx>,
251     pub usize: Ty<'tcx>,
252     pub u8: Ty<'tcx>,
253     pub u16: Ty<'tcx>,
254     pub u32: Ty<'tcx>,
255     pub u64: Ty<'tcx>,
256     pub u128: Ty<'tcx>,
257     pub f32: Ty<'tcx>,
258     pub f64: Ty<'tcx>,
259     pub str_: Ty<'tcx>,
260     pub never: Ty<'tcx>,
261     pub self_param: Ty<'tcx>,
262
263     /// Dummy type used for the `Self` of a `TraitRef` created for converting
264     /// a trait object, and which gets removed in `ExistentialTraitRef`.
265     /// This type must not appear anywhere in other converted types.
266     pub trait_object_dummy_self: Ty<'tcx>,
267 }
268
269 pub struct CommonLifetimes<'tcx> {
270     /// `ReStatic`
271     pub re_static: Region<'tcx>,
272
273     /// Erased region, used outside of type inference.
274     pub re_erased: Region<'tcx>,
275 }
276
277 pub struct CommonConsts<'tcx> {
278     pub unit: Const<'tcx>,
279 }
280
281 impl<'tcx> CommonTypes<'tcx> {
282     fn new(
283         interners: &CtxtInterners<'tcx>,
284         sess: &Session,
285         untracked: &Untracked,
286     ) -> CommonTypes<'tcx> {
287         let mk = |ty| interners.intern_ty(ty, sess, untracked);
288
289         CommonTypes {
290             unit: mk(Tuple(List::empty())),
291             bool: mk(Bool),
292             char: mk(Char),
293             never: mk(Never),
294             isize: mk(Int(ty::IntTy::Isize)),
295             i8: mk(Int(ty::IntTy::I8)),
296             i16: mk(Int(ty::IntTy::I16)),
297             i32: mk(Int(ty::IntTy::I32)),
298             i64: mk(Int(ty::IntTy::I64)),
299             i128: mk(Int(ty::IntTy::I128)),
300             usize: mk(Uint(ty::UintTy::Usize)),
301             u8: mk(Uint(ty::UintTy::U8)),
302             u16: mk(Uint(ty::UintTy::U16)),
303             u32: mk(Uint(ty::UintTy::U32)),
304             u64: mk(Uint(ty::UintTy::U64)),
305             u128: mk(Uint(ty::UintTy::U128)),
306             f32: mk(Float(ty::FloatTy::F32)),
307             f64: mk(Float(ty::FloatTy::F64)),
308             str_: mk(Str),
309             self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
310
311             trait_object_dummy_self: mk(Infer(ty::FreshTy(0))),
312         }
313     }
314 }
315
316 impl<'tcx> CommonLifetimes<'tcx> {
317     fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
318         let mk = |r| {
319             Region(Interned::new_unchecked(
320                 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
321             ))
322         };
323
324         CommonLifetimes { re_static: mk(ty::ReStatic), re_erased: mk(ty::ReErased) }
325     }
326 }
327
328 impl<'tcx> CommonConsts<'tcx> {
329     fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonConsts<'tcx> {
330         let mk_const = |c| {
331             Const(Interned::new_unchecked(
332                 interners.const_.intern(c, |c| InternedInSet(interners.arena.alloc(c))).0,
333             ))
334         };
335
336         CommonConsts {
337             unit: mk_const(ty::ConstData {
338                 kind: ty::ConstKind::Value(ty::ValTree::zst()),
339                 ty: types.unit,
340             }),
341         }
342     }
343 }
344
345 /// This struct contains information regarding the `ReFree(FreeRegion)` corresponding to a lifetime
346 /// conflict.
347 #[derive(Debug)]
348 pub struct FreeRegionInfo {
349     /// `LocalDefId` corresponding to FreeRegion
350     pub def_id: LocalDefId,
351     /// the bound region corresponding to FreeRegion
352     pub boundregion: ty::BoundRegionKind,
353     /// checks if bound region is in Impl Item
354     pub is_impl_item: bool,
355 }
356
357 /// This struct should only be created by `create_def`.
358 #[derive(Copy, Clone)]
359 pub struct TyCtxtFeed<'tcx, KEY: Copy> {
360     pub tcx: TyCtxt<'tcx>,
361     // Do not allow direct access, as downstream code must not mutate this field.
362     key: KEY,
363 }
364
365 impl<'tcx> TyCtxt<'tcx> {
366     pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
367         TyCtxtFeed { tcx: self, key: () }
368     }
369     pub fn feed_local_crate(self) -> TyCtxtFeed<'tcx, CrateNum> {
370         TyCtxtFeed { tcx: self, key: LOCAL_CRATE }
371     }
372 }
373
374 impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
375     #[inline(always)]
376     pub fn key(&self) -> KEY {
377         self.key
378     }
379 }
380
381 impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
382     #[inline(always)]
383     pub fn def_id(&self) -> LocalDefId {
384         self.key
385     }
386 }
387
388 /// The central data structure of the compiler. It stores references
389 /// to the various **arenas** and also houses the results of the
390 /// various **compiler queries** that have been performed. See the
391 /// [rustc dev guide] for more details.
392 ///
393 /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/ty.html
394 #[derive(Copy, Clone)]
395 #[rustc_diagnostic_item = "TyCtxt"]
396 #[rustc_pass_by_value]
397 pub struct TyCtxt<'tcx> {
398     gcx: &'tcx GlobalCtxt<'tcx>,
399 }
400
401 impl<'tcx> Deref for TyCtxt<'tcx> {
402     type Target = &'tcx GlobalCtxt<'tcx>;
403     #[inline(always)]
404     fn deref(&self) -> &Self::Target {
405         &self.gcx
406     }
407 }
408
409 pub struct GlobalCtxt<'tcx> {
410     pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
411     pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
412
413     interners: CtxtInterners<'tcx>,
414
415     pub sess: &'tcx Session,
416
417     /// This only ever stores a `LintStore` but we don't want a dependency on that type here.
418     ///
419     /// FIXME(Centril): consider `dyn LintStoreMarker` once
420     /// we can upcast to `Any` for some additional type safety.
421     pub lint_store: Lrc<dyn Any + sync::Sync + sync::Send>,
422
423     pub dep_graph: DepGraph,
424
425     pub prof: SelfProfilerRef,
426
427     /// Common types, pre-interned for your convenience.
428     pub types: CommonTypes<'tcx>,
429
430     /// Common lifetimes, pre-interned for your convenience.
431     pub lifetimes: CommonLifetimes<'tcx>,
432
433     /// Common consts, pre-interned for your convenience.
434     pub consts: CommonConsts<'tcx>,
435
436     untracked: Untracked,
437
438     /// This provides access to the incremental compilation on-disk cache for query results.
439     /// Do not access this directly. It is only meant to be used by
440     /// `DepGraph::try_mark_green()` and the query infrastructure.
441     /// This is `None` if we are not incremental compilation mode
442     pub on_disk_cache: Option<&'tcx dyn OnDiskCache<'tcx>>,
443
444     pub queries: &'tcx dyn query::QueryEngine<'tcx>,
445     pub query_caches: query::QueryCaches<'tcx>,
446     pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>],
447
448     // Internal caches for metadata decoding. No need to track deps on this.
449     pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
450     pub pred_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Predicate<'tcx>>>,
451
452     /// Caches the results of trait selection. This cache is used
453     /// for things that do not have to do with the parameters in scope.
454     pub selection_cache: traits::SelectionCache<'tcx>,
455
456     /// Caches the results of trait evaluation. This cache is used
457     /// for things that do not have to do with the parameters in scope.
458     /// Merge this with `selection_cache`?
459     pub evaluation_cache: traits::EvaluationCache<'tcx>,
460
461     /// Data layout specification for the current target.
462     pub data_layout: TargetDataLayout,
463
464     /// Stores memory for globals (statics/consts).
465     pub(crate) alloc_map: Lock<interpret::AllocMap<'tcx>>,
466 }
467
468 impl<'tcx> TyCtxt<'tcx> {
469     /// Expects a body and returns its codegen attributes.
470     ///
471     /// Unlike `codegen_fn_attrs`, this returns `CodegenFnAttrs::EMPTY` for
472     /// constants.
473     pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
474         let def_kind = self.def_kind(def_id);
475         if def_kind.has_codegen_attrs() {
476             self.codegen_fn_attrs(def_id)
477         } else if matches!(
478             def_kind,
479             DefKind::AnonConst | DefKind::AssocConst | DefKind::Const | DefKind::InlineConst
480         ) {
481             CodegenFnAttrs::EMPTY
482         } else {
483             bug!(
484                 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
485                 def_id,
486                 def_kind
487             )
488         }
489     }
490
491     pub fn typeck_opt_const_arg(
492         self,
493         def: ty::WithOptConstParam<LocalDefId>,
494     ) -> &'tcx TypeckResults<'tcx> {
495         if let Some(param_did) = def.const_param_did {
496             self.typeck_const_arg((def.did, param_did))
497         } else {
498             self.typeck(def.did)
499         }
500     }
501
502     pub fn mir_borrowck_opt_const_arg(
503         self,
504         def: ty::WithOptConstParam<LocalDefId>,
505     ) -> &'tcx BorrowCheckResult<'tcx> {
506         if let Some(param_did) = def.const_param_did {
507             self.mir_borrowck_const_arg((def.did, param_did))
508         } else {
509             self.mir_borrowck(def.did)
510         }
511     }
512
513     pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
514         self.arena.alloc(Steal::new(thir))
515     }
516
517     pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
518         self.arena.alloc(Steal::new(mir))
519     }
520
521     pub fn alloc_steal_promoted(
522         self,
523         promoted: IndexVec<Promoted, Body<'tcx>>,
524     ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
525         self.arena.alloc(Steal::new(promoted))
526     }
527
528     pub fn alloc_adt_def(
529         self,
530         did: DefId,
531         kind: AdtKind,
532         variants: IndexVec<VariantIdx, ty::VariantDef>,
533         repr: ReprOptions,
534     ) -> ty::AdtDef<'tcx> {
535         self.intern_adt_def(ty::AdtDefData::new(self, did, kind, variants, repr))
536     }
537
538     /// Allocates a read-only byte or string literal for `mir::interpret`.
539     pub fn allocate_bytes(self, bytes: &[u8]) -> interpret::AllocId {
540         // Create an allocation that just contains these bytes.
541         let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes);
542         let alloc = self.intern_const_alloc(alloc);
543         self.create_memory_alloc(alloc)
544     }
545
546     /// Returns a range of the start/end indices specified with the
547     /// `rustc_layout_scalar_valid_range` attribute.
548     // FIXME(eddyb) this is an awkward spot for this method, maybe move it?
549     pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
550         let get = |name| {
551             let Some(attr) = self.get_attr(def_id, name) else {
552                 return Bound::Unbounded;
553             };
554             debug!("layout_scalar_valid_range: attr={:?}", attr);
555             if let Some(
556                 &[
557                     ast::NestedMetaItem::Lit(ast::MetaItemLit {
558                         kind: ast::LitKind::Int(a, _),
559                         ..
560                     }),
561                 ],
562             ) = attr.meta_item_list().as_deref()
563             {
564                 Bound::Included(a)
565             } else {
566                 self.sess
567                     .delay_span_bug(attr.span, "invalid rustc_layout_scalar_valid_range attribute");
568                 Bound::Unbounded
569             }
570         };
571         (
572             get(sym::rustc_layout_scalar_valid_range_start),
573             get(sym::rustc_layout_scalar_valid_range_end),
574         )
575     }
576
577     pub fn lift<T: Lift<'tcx>>(self, value: T) -> Option<T::Lifted> {
578         value.lift_to_tcx(self)
579     }
580
581     /// Creates a type context and call the closure with a `TyCtxt` reference
582     /// to the context. The closure enforces that the type context and any interned
583     /// value (types, substs, etc.) can only be used while `ty::tls` has a valid
584     /// reference to the context, to allow formatting values that need it.
585     pub fn create_global_ctxt(
586         s: &'tcx Session,
587         lint_store: Lrc<dyn Any + sync::Send + sync::Sync>,
588         arena: &'tcx WorkerLocal<Arena<'tcx>>,
589         hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
590         untracked: Untracked,
591         dep_graph: DepGraph,
592         on_disk_cache: Option<&'tcx dyn OnDiskCache<'tcx>>,
593         queries: &'tcx dyn query::QueryEngine<'tcx>,
594         query_kinds: &'tcx [DepKindStruct<'tcx>],
595     ) -> GlobalCtxt<'tcx> {
596         let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
597             s.emit_fatal(err);
598         });
599         let interners = CtxtInterners::new(arena);
600         let common_types = CommonTypes::new(&interners, s, &untracked);
601         let common_lifetimes = CommonLifetimes::new(&interners);
602         let common_consts = CommonConsts::new(&interners, &common_types);
603
604         GlobalCtxt {
605             sess: s,
606             lint_store,
607             arena,
608             hir_arena,
609             interners,
610             dep_graph,
611             prof: s.prof.clone(),
612             types: common_types,
613             lifetimes: common_lifetimes,
614             consts: common_consts,
615             untracked,
616             on_disk_cache,
617             queries,
618             query_caches: query::QueryCaches::default(),
619             query_kinds,
620             ty_rcache: Default::default(),
621             pred_rcache: Default::default(),
622             selection_cache: Default::default(),
623             evaluation_cache: Default::default(),
624             data_layout,
625             alloc_map: Lock::new(interpret::AllocMap::new()),
626         }
627     }
628
629     /// Constructs a `TyKind::Error` type with current `ErrorGuaranteed`
630     #[track_caller]
631     pub fn ty_error_with_guaranteed(self, reported: ErrorGuaranteed) -> Ty<'tcx> {
632         self.mk_ty(Error(reported))
633     }
634
635     /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used.
636     #[track_caller]
637     pub fn ty_error(self) -> Ty<'tcx> {
638         self.ty_error_with_message(DUMMY_SP, "TyKind::Error constructed but no error reported")
639     }
640
641     /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg` to
642     /// ensure it gets used.
643     #[track_caller]
644     pub fn ty_error_with_message<S: Into<MultiSpan>>(self, span: S, msg: &str) -> Ty<'tcx> {
645         let reported = self.sess.delay_span_bug(span, msg);
646         self.mk_ty(Error(reported))
647     }
648
649     /// Like [TyCtxt::ty_error] but for constants, with current `ErrorGuaranteed`
650     #[track_caller]
651     pub fn const_error_with_guaranteed(
652         self,
653         ty: Ty<'tcx>,
654         reported: ErrorGuaranteed,
655     ) -> Const<'tcx> {
656         self.mk_const(ty::ConstKind::Error(reported), ty)
657     }
658
659     /// Like [TyCtxt::ty_error] but for constants.
660     #[track_caller]
661     pub fn const_error(self, ty: Ty<'tcx>) -> Const<'tcx> {
662         self.const_error_with_message(
663             ty,
664             DUMMY_SP,
665             "ty::ConstKind::Error constructed but no error reported",
666         )
667     }
668
669     /// Like [TyCtxt::ty_error_with_message] but for constants.
670     #[track_caller]
671     pub fn const_error_with_message<S: Into<MultiSpan>>(
672         self,
673         ty: Ty<'tcx>,
674         span: S,
675         msg: &str,
676     ) -> Const<'tcx> {
677         let reported = self.sess.delay_span_bug(span, msg);
678         self.mk_const(ty::ConstKind::Error(reported), ty)
679     }
680
681     pub fn consider_optimizing<T: Fn() -> String>(self, msg: T) -> bool {
682         let cname = self.crate_name(LOCAL_CRATE);
683         self.sess.consider_optimizing(cname.as_str(), msg)
684     }
685
686     /// Obtain all lang items of this crate and all dependencies (recursively)
687     pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
688         self.get_lang_items(())
689     }
690
691     /// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to
692     /// compare against another `DefId`, since `is_diagnostic_item` is cheaper.
693     pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
694         self.all_diagnostic_items(()).name_to_id.get(&name).copied()
695     }
696
697     /// Obtain the diagnostic item's name
698     pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
699         self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
700     }
701
702     /// Check whether the diagnostic item with the given `name` has the given `DefId`.
703     pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
704         self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
705     }
706
707     /// Returns `true` if the node pointed to by `def_id` is a generator for an async construct.
708     pub fn generator_is_async(self, def_id: DefId) -> bool {
709         matches!(self.generator_kind(def_id), Some(hir::GeneratorKind::Async(_)))
710     }
711
712     pub fn stability(self) -> &'tcx stability::Index {
713         self.stability_index(())
714     }
715
716     pub fn features(self) -> &'tcx rustc_feature::Features {
717         self.features_query(())
718     }
719
720     pub fn def_key(self, id: DefId) -> rustc_hir::definitions::DefKey {
721         // Accessing the DefKey is ok, since it is part of DefPathHash.
722         if let Some(id) = id.as_local() {
723             self.definitions_untracked().def_key(id)
724         } else {
725             self.untracked.cstore.def_key(id)
726         }
727     }
728
729     /// Converts a `DefId` into its fully expanded `DefPath` (every
730     /// `DefId` is really just an interned `DefPath`).
731     ///
732     /// Note that if `id` is not local to this crate, the result will
733     ///  be a non-local `DefPath`.
734     pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
735         // Accessing the DefPath is ok, since it is part of DefPathHash.
736         if let Some(id) = id.as_local() {
737             self.definitions_untracked().def_path(id)
738         } else {
739             self.untracked.cstore.def_path(id)
740         }
741     }
742
743     #[inline]
744     pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
745         // Accessing the DefPathHash is ok, it is incr. comp. stable.
746         if let Some(def_id) = def_id.as_local() {
747             self.definitions_untracked().def_path_hash(def_id)
748         } else {
749             self.untracked.cstore.def_path_hash(def_id)
750         }
751     }
752
753     #[inline]
754     pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
755         if crate_num == LOCAL_CRATE {
756             self.sess.local_stable_crate_id()
757         } else {
758             self.untracked.cstore.stable_crate_id(crate_num)
759         }
760     }
761
762     /// Maps a StableCrateId to the corresponding CrateNum. This method assumes
763     /// that the crate in question has already been loaded by the CrateStore.
764     #[inline]
765     pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
766         if stable_crate_id == self.sess.local_stable_crate_id() {
767             LOCAL_CRATE
768         } else {
769             self.untracked.cstore.stable_crate_id_to_crate_num(stable_crate_id)
770         }
771     }
772
773     /// Converts a `DefPathHash` to its corresponding `DefId` in the current compilation
774     /// session, if it still exists. This is used during incremental compilation to
775     /// turn a deserialized `DefPathHash` into its current `DefId`.
776     pub fn def_path_hash_to_def_id(self, hash: DefPathHash, err: &mut dyn FnMut() -> !) -> DefId {
777         debug!("def_path_hash_to_def_id({:?})", hash);
778
779         let stable_crate_id = hash.stable_crate_id();
780
781         // If this is a DefPathHash from the local crate, we can look up the
782         // DefId in the tcx's `Definitions`.
783         if stable_crate_id == self.sess.local_stable_crate_id() {
784             self.untracked.definitions.read().local_def_path_hash_to_def_id(hash, err).to_def_id()
785         } else {
786             // If this is a DefPathHash from an upstream crate, let the CrateStore map
787             // it to a DefId.
788             let cstore = &*self.untracked.cstore;
789             let cnum = cstore.stable_crate_id_to_crate_num(stable_crate_id);
790             cstore.def_path_hash_to_def_id(cnum, hash)
791         }
792     }
793
794     pub fn def_path_debug_str(self, def_id: DefId) -> String {
795         // We are explicitly not going through queries here in order to get
796         // crate name and stable crate id since this code is called from debug!()
797         // statements within the query system and we'd run into endless
798         // recursion otherwise.
799         let (crate_name, stable_crate_id) = if def_id.is_local() {
800             (self.crate_name(LOCAL_CRATE), self.sess.local_stable_crate_id())
801         } else {
802             let cstore = &*self.untracked.cstore;
803             (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
804         };
805
806         format!(
807             "{}[{:04x}]{}",
808             crate_name,
809             // Don't print the whole stable crate id. That's just
810             // annoying in debug output.
811             stable_crate_id.to_u64() >> 8 * 6,
812             self.def_path(def_id).to_string_no_crate_verbose()
813         )
814     }
815 }
816
817 impl<'tcx> TyCtxtAt<'tcx> {
818     /// Create a new definition within the incr. comp. engine.
819     pub fn create_def(
820         self,
821         parent: LocalDefId,
822         data: hir::definitions::DefPathData,
823     ) -> TyCtxtFeed<'tcx, LocalDefId> {
824         // This function modifies `self.definitions` using a side-effect.
825         // We need to ensure that these side effects are re-run by the incr. comp. engine.
826         // Depending on the forever-red node will tell the graph that the calling query
827         // needs to be re-evaluated.
828         self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
829
830         // The following call has the side effect of modifying the tables inside `definitions`.
831         // These very tables are relied on by the incr. comp. engine to decode DepNodes and to
832         // decode the on-disk cache.
833         //
834         // Any LocalDefId which is used within queries, either as key or result, either:
835         // - has been created before the construction of the TyCtxt;
836         // - has been created by this call to `create_def`.
837         // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
838         // comp. engine itself.
839         //
840         // This call also writes to the value of `source_span` and `expn_that_defined` queries.
841         // This is fine because:
842         // - those queries are `eval_always` so we won't miss their result changing;
843         // - this write will have happened before these queries are called.
844         let key = self.untracked.definitions.write().create_def(parent, data);
845
846         let feed = TyCtxtFeed { tcx: self.tcx, key };
847         feed.def_span(self.span);
848         feed
849     }
850 }
851
852 impl<'tcx> TyCtxt<'tcx> {
853     pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> + 'tcx {
854         // Create a dependency to the red node to be sure we re-execute this when the amount of
855         // definitions change.
856         self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
857
858         let definitions = &self.untracked.definitions;
859         std::iter::from_generator(|| {
860             let mut i = 0;
861
862             // Recompute the number of definitions each time, because our caller may be creating
863             // new ones.
864             while i < { definitions.read().num_definitions() } {
865                 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
866                 yield LocalDefId { local_def_index };
867                 i += 1;
868             }
869
870             // Leak a read lock once we finish iterating on definitions, to prevent adding new ones.
871             definitions.leak();
872         })
873     }
874
875     pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
876         // Create a dependency to the crate to be sure we re-execute this when the amount of
877         // definitions change.
878         self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
879
880         // Leak a read lock once we start iterating on definitions, to prevent adding new ones
881         // while iterating. If some query needs to add definitions, it should be `ensure`d above.
882         let definitions = self.untracked.definitions.leak();
883         definitions.def_path_table()
884     }
885
886     pub fn def_path_hash_to_def_index_map(
887         self,
888     ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
889         // Create a dependency to the crate to be sure we re-execute this when the amount of
890         // definitions change.
891         self.ensure().hir_crate(());
892         // Leak a read lock once we start iterating on definitions, to prevent adding new ones
893         // while iterating. If some query needs to add definitions, it should be `ensure`d above.
894         let definitions = self.untracked.definitions.leak();
895         definitions.def_path_hash_to_def_index_map()
896     }
897
898     /// Note that this is *untracked* and should only be used within the query
899     /// system if the result is otherwise tracked through queries
900     pub fn cstore_untracked(self) -> &'tcx CrateStoreDyn {
901         &*self.untracked.cstore
902     }
903
904     /// Note that this is *untracked* and should only be used within the query
905     /// system if the result is otherwise tracked through queries
906     #[inline]
907     pub fn definitions_untracked(self) -> ReadGuard<'tcx, Definitions> {
908         self.untracked.definitions.read()
909     }
910
911     /// Note that this is *untracked* and should only be used within the query
912     /// system if the result is otherwise tracked through queries
913     #[inline]
914     pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
915         self.untracked.source_span.get(def_id).copied().unwrap_or(DUMMY_SP)
916     }
917
918     #[inline(always)]
919     pub fn with_stable_hashing_context<R>(
920         self,
921         f: impl FnOnce(StableHashingContext<'_>) -> R,
922     ) -> R {
923         f(StableHashingContext::new(self.sess, &self.untracked))
924     }
925
926     pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
927         self.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
928     }
929
930     /// If `true`, we should use lazy normalization for constants, otherwise
931     /// we still evaluate them eagerly.
932     #[inline]
933     pub fn lazy_normalization(self) -> bool {
934         let features = self.features();
935         // Note: We only use lazy normalization for generic const expressions.
936         features.generic_const_exprs
937     }
938
939     #[inline]
940     pub fn local_crate_exports_generics(self) -> bool {
941         debug_assert!(self.sess.opts.share_generics());
942
943         self.sess.crate_types().iter().any(|crate_type| {
944             match crate_type {
945                 CrateType::Executable
946                 | CrateType::Staticlib
947                 | CrateType::ProcMacro
948                 | CrateType::Cdylib => false,
949
950                 // FIXME rust-lang/rust#64319, rust-lang/rust#64872:
951                 // We want to block export of generics from dylibs,
952                 // but we must fix rust-lang/rust#65890 before we can
953                 // do that robustly.
954                 CrateType::Dylib => true,
955
956                 CrateType::Rlib => true,
957             }
958         })
959     }
960
961     /// Returns the `DefId` and the `BoundRegionKind` corresponding to the given region.
962     pub fn is_suitable_region(self, region: Region<'tcx>) -> Option<FreeRegionInfo> {
963         let (suitable_region_binding_scope, bound_region) = match *region {
964             ty::ReFree(ref free_region) => {
965                 (free_region.scope.expect_local(), free_region.bound_region)
966             }
967             ty::ReEarlyBound(ref ebr) => (
968                 self.local_parent(ebr.def_id.expect_local()),
969                 ty::BoundRegionKind::BrNamed(ebr.def_id, ebr.name),
970             ),
971             _ => return None, // not a free region
972         };
973
974         let is_impl_item = match self.hir().find_by_def_id(suitable_region_binding_scope) {
975             Some(Node::Item(..) | Node::TraitItem(..)) => false,
976             Some(Node::ImplItem(..)) => {
977                 self.is_bound_region_in_impl_item(suitable_region_binding_scope)
978             }
979             _ => return None,
980         };
981
982         Some(FreeRegionInfo {
983             def_id: suitable_region_binding_scope,
984             boundregion: bound_region,
985             is_impl_item,
986         })
987     }
988
989     /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type.
990     pub fn return_type_impl_or_dyn_traits(
991         self,
992         scope_def_id: LocalDefId,
993     ) -> Vec<&'tcx hir::Ty<'tcx>> {
994         let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
995         let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir().fn_decl_by_hir_id(hir_id) else {
996             return vec![];
997         };
998
999         let mut v = TraitObjectVisitor(vec![], self.hir());
1000         v.visit_ty(hir_output);
1001         v.0
1002     }
1003
1004     /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type and associated alias span when type alias is used
1005     pub fn return_type_impl_or_dyn_traits_with_type_alias(
1006         self,
1007         scope_def_id: LocalDefId,
1008     ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span)> {
1009         let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
1010         let mut v = TraitObjectVisitor(vec![], self.hir());
1011         // when the return type is a type alias
1012         if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir().fn_decl_by_hir_id(hir_id)
1013             && let hir::TyKind::Path(hir::QPath::Resolved(
1014                 None,
1015                 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
1016             && let Some(local_id) = def_id.as_local()
1017             && let Some(alias_ty) = self.hir().get_by_def_id(local_id).alias_ty() // it is type alias
1018             && let Some(alias_generics) = self.hir().get_by_def_id(local_id).generics()
1019         {
1020             v.visit_ty(alias_ty);
1021             if !v.0.is_empty() {
1022                 return Some((v.0, alias_generics.span));
1023             }
1024         }
1025         return None;
1026     }
1027
1028     pub fn return_type_impl_trait(self, scope_def_id: LocalDefId) -> Option<(Ty<'tcx>, Span)> {
1029         // `type_of()` will fail on these (#55796, #86483), so only allow `fn`s or closures.
1030         match self.hir().get_by_def_id(scope_def_id) {
1031             Node::Item(&hir::Item { kind: ItemKind::Fn(..), .. }) => {}
1032             Node::TraitItem(&hir::TraitItem { kind: TraitItemKind::Fn(..), .. }) => {}
1033             Node::ImplItem(&hir::ImplItem { kind: ImplItemKind::Fn(..), .. }) => {}
1034             Node::Expr(&hir::Expr { kind: ExprKind::Closure { .. }, .. }) => {}
1035             _ => return None,
1036         }
1037
1038         let ret_ty = self.type_of(scope_def_id);
1039         match ret_ty.kind() {
1040             ty::FnDef(_, _) => {
1041                 let sig = ret_ty.fn_sig(self);
1042                 let output = self.erase_late_bound_regions(sig.output());
1043                 if output.is_impl_trait() {
1044                     let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
1045                     let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap();
1046                     Some((output, fn_decl.output.span()))
1047                 } else {
1048                     None
1049                 }
1050             }
1051             _ => None,
1052         }
1053     }
1054
1055     /// Checks if the bound region is in Impl Item.
1056     pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
1057         let container_id = self.parent(suitable_region_binding_scope.to_def_id());
1058         if self.impl_trait_ref(container_id).is_some() {
1059             // For now, we do not try to target impls of traits. This is
1060             // because this message is going to suggest that the user
1061             // change the fn signature, but they may not be free to do so,
1062             // since the signature must match the trait.
1063             //
1064             // FIXME(#42706) -- in some cases, we could do better here.
1065             return true;
1066         }
1067         false
1068     }
1069
1070     /// Determines whether identifiers in the assembly have strict naming rules.
1071     /// Currently, only NVPTX* targets need it.
1072     pub fn has_strict_asm_symbol_naming(self) -> bool {
1073         self.sess.target.arch.contains("nvptx")
1074     }
1075
1076     /// Returns `&'static core::panic::Location<'static>`.
1077     pub fn caller_location_ty(self) -> Ty<'tcx> {
1078         self.mk_imm_ref(
1079             self.lifetimes.re_static,
1080             self.bound_type_of(self.require_lang_item(LangItem::PanicLocation, None))
1081                 .subst(self, self.mk_substs([self.lifetimes.re_static.into()].iter())),
1082         )
1083     }
1084
1085     /// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`).
1086     pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
1087         match self.def_kind(def_id) {
1088             DefKind::Generator => match self.generator_kind(def_id).unwrap() {
1089                 rustc_hir::GeneratorKind::Async(..) => ("an", "async closure"),
1090                 rustc_hir::GeneratorKind::Gen => ("a", "generator"),
1091             },
1092             def_kind => (def_kind.article(), def_kind.descr(def_id)),
1093         }
1094     }
1095
1096     pub fn type_length_limit(self) -> Limit {
1097         self.limits(()).type_length_limit
1098     }
1099
1100     pub fn recursion_limit(self) -> Limit {
1101         self.limits(()).recursion_limit
1102     }
1103
1104     pub fn move_size_limit(self) -> Limit {
1105         self.limits(()).move_size_limit
1106     }
1107
1108     pub fn const_eval_limit(self) -> Limit {
1109         if self.sess.opts.unstable_opts.tiny_const_eval_limit {
1110             TINY_CONST_EVAL_LIMIT
1111         } else {
1112             self.limits(()).const_eval_limit
1113         }
1114     }
1115
1116     pub fn all_traits(self) -> impl Iterator<Item = DefId> + 'tcx {
1117         iter::once(LOCAL_CRATE)
1118             .chain(self.crates(()).iter().copied())
1119             .flat_map(move |cnum| self.traits_in_crate(cnum).iter().copied())
1120     }
1121
1122     #[inline]
1123     pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
1124         self.visibility(def_id).expect_local()
1125     }
1126 }
1127
1128 /// A trait implemented for all `X<'a>` types that can be safely and
1129 /// efficiently converted to `X<'tcx>` as long as they are part of the
1130 /// provided `TyCtxt<'tcx>`.
1131 /// This can be done, for example, for `Ty<'tcx>` or `SubstsRef<'tcx>`
1132 /// by looking them up in their respective interners.
1133 ///
1134 /// However, this is still not the best implementation as it does
1135 /// need to compare the components, even for interned values.
1136 /// It would be more efficient if `TypedArena` provided a way to
1137 /// determine whether the address is in the allocated range.
1138 ///
1139 /// `None` is returned if the value or one of the components is not part
1140 /// of the provided context.
1141 /// For `Ty`, `None` can be returned if either the type interner doesn't
1142 /// contain the `TyKind` key or if the address of the interned
1143 /// pointer differs. The latter case is possible if a primitive type,
1144 /// e.g., `()` or `u8`, was interned in a different context.
1145 pub trait Lift<'tcx>: fmt::Debug {
1146     type Lifted: fmt::Debug + 'tcx;
1147     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted>;
1148 }
1149
1150 macro_rules! nop_lift {
1151     ($set:ident; $ty:ty => $lifted:ty) => {
1152         impl<'a, 'tcx> Lift<'tcx> for $ty {
1153             type Lifted = $lifted;
1154             fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1155                 if tcx.interners.$set.contains_pointer_to(&InternedInSet(&*self.0.0)) {
1156                     // SAFETY: `self` is interned and therefore valid
1157                     // for the entire lifetime of the `TyCtxt`.
1158                     Some(unsafe { mem::transmute(self) })
1159                 } else {
1160                     None
1161                 }
1162             }
1163         }
1164     };
1165 }
1166
1167 // Can't use the macros as we have reuse the `substs` here.
1168 //
1169 // See `intern_type_list` for more info.
1170 impl<'a, 'tcx> Lift<'tcx> for &'a List<Ty<'a>> {
1171     type Lifted = &'tcx List<Ty<'tcx>>;
1172     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1173         if self.is_empty() {
1174             return Some(List::empty());
1175         }
1176         if tcx.interners.substs.contains_pointer_to(&InternedInSet(self.as_substs())) {
1177             // SAFETY: `self` is interned and therefore valid
1178             // for the entire lifetime of the `TyCtxt`.
1179             Some(unsafe { mem::transmute::<&'a List<Ty<'a>>, &'tcx List<Ty<'tcx>>>(self) })
1180         } else {
1181             None
1182         }
1183     }
1184 }
1185
1186 macro_rules! nop_list_lift {
1187     ($set:ident; $ty:ty => $lifted:ty) => {
1188         impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> {
1189             type Lifted = &'tcx List<$lifted>;
1190             fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1191                 if self.is_empty() {
1192                     return Some(List::empty());
1193                 }
1194                 if tcx.interners.$set.contains_pointer_to(&InternedInSet(self)) {
1195                     Some(unsafe { mem::transmute(self) })
1196                 } else {
1197                     None
1198                 }
1199             }
1200         }
1201     };
1202 }
1203
1204 nop_lift! {type_; Ty<'a> => Ty<'tcx>}
1205 nop_lift! {region; Region<'a> => Region<'tcx>}
1206 nop_lift! {const_; Const<'a> => Const<'tcx>}
1207 nop_lift! {const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx>}
1208 nop_lift! {predicate; Predicate<'a> => Predicate<'tcx>}
1209
1210 nop_list_lift! {poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>}
1211 nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>}
1212 nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>}
1213 nop_list_lift! {projs; ProjectionKind => ProjectionKind}
1214 nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind}
1215
1216 // This is the impl for `&'a InternalSubsts<'a>`.
1217 nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}
1218
1219 CloneLiftImpls! { for<'tcx> {
1220     Constness, traits::WellFormedLoc, ImplPolarity, crate::mir::ReturnConstraint,
1221 } }
1222
1223 macro_rules! sty_debug_print {
1224     ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
1225         // Curious inner module to allow variant names to be used as
1226         // variable names.
1227         #[allow(non_snake_case)]
1228         mod inner {
1229             use crate::ty::{self, TyCtxt};
1230             use crate::ty::context::InternedInSet;
1231
1232             #[derive(Copy, Clone)]
1233             struct DebugStat {
1234                 total: usize,
1235                 lt_infer: usize,
1236                 ty_infer: usize,
1237                 ct_infer: usize,
1238                 all_infer: usize,
1239             }
1240
1241             pub fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1242                 let mut total = DebugStat {
1243                     total: 0,
1244                     lt_infer: 0,
1245                     ty_infer: 0,
1246                     ct_infer: 0,
1247                     all_infer: 0,
1248                 };
1249                 $(let mut $variant = total;)*
1250
1251                 let shards = tcx.interners.type_.lock_shards();
1252                 let types = shards.iter().flat_map(|shard| shard.keys());
1253                 for &InternedInSet(t) in types {
1254                     let variant = match t.internee {
1255                         ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1256                             ty::Float(..) | ty::Str | ty::Never => continue,
1257                         ty::Error(_) => /* unimportant */ continue,
1258                         $(ty::$variant(..) => &mut $variant,)*
1259                     };
1260                     let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1261                     let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1262                     let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1263
1264                     variant.total += 1;
1265                     total.total += 1;
1266                     if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1267                     if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1268                     if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1269                     if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1270                 }
1271                 writeln!(fmt, "Ty interner             total           ty lt ct all")?;
1272                 $(writeln!(fmt, "    {:18}: {uses:6} {usespc:4.1}%, \
1273                             {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1274                     stringify!($variant),
1275                     uses = $variant.total,
1276                     usespc = $variant.total as f64 * 100.0 / total.total as f64,
1277                     ty = $variant.ty_infer as f64 * 100.0  / total.total as f64,
1278                     lt = $variant.lt_infer as f64 * 100.0  / total.total as f64,
1279                     ct = $variant.ct_infer as f64 * 100.0  / total.total as f64,
1280                     all = $variant.all_infer as f64 * 100.0  / total.total as f64)?;
1281                 )*
1282                 writeln!(fmt, "                  total {uses:6}        \
1283                           {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1284                     uses = total.total,
1285                     ty = total.ty_infer as f64 * 100.0  / total.total as f64,
1286                     lt = total.lt_infer as f64 * 100.0  / total.total as f64,
1287                     ct = total.ct_infer as f64 * 100.0  / total.total as f64,
1288                     all = total.all_infer as f64 * 100.0  / total.total as f64)
1289             }
1290         }
1291
1292         inner::go($fmt, $ctxt)
1293     }}
1294 }
1295
1296 impl<'tcx> TyCtxt<'tcx> {
1297     pub fn debug_stats(self) -> impl std::fmt::Debug + 'tcx {
1298         struct DebugStats<'tcx>(TyCtxt<'tcx>);
1299
1300         impl<'tcx> std::fmt::Debug for DebugStats<'tcx> {
1301             fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1302                 sty_debug_print!(
1303                     fmt,
1304                     self.0,
1305                     Adt,
1306                     Array,
1307                     Slice,
1308                     RawPtr,
1309                     Ref,
1310                     FnDef,
1311                     FnPtr,
1312                     Placeholder,
1313                     Generator,
1314                     GeneratorWitness,
1315                     GeneratorWitnessMIR,
1316                     Dynamic,
1317                     Closure,
1318                     Tuple,
1319                     Bound,
1320                     Param,
1321                     Infer,
1322                     Alias,
1323                     Foreign
1324                 )?;
1325
1326                 writeln!(fmt, "InternalSubsts interner: #{}", self.0.interners.substs.len())?;
1327                 writeln!(fmt, "Region interner: #{}", self.0.interners.region.len())?;
1328                 writeln!(
1329                     fmt,
1330                     "Const Allocation interner: #{}",
1331                     self.0.interners.const_allocation.len()
1332                 )?;
1333                 writeln!(fmt, "Layout interner: #{}", self.0.interners.layout.len())?;
1334
1335                 Ok(())
1336             }
1337         }
1338
1339         DebugStats(self)
1340     }
1341 }
1342
1343 // This type holds a `T` in the interner. The `T` is stored in the arena and
1344 // this type just holds a pointer to it, but it still effectively owns it. It
1345 // impls `Borrow` so that it can be looked up using the original
1346 // (non-arena-memory-owning) types.
1347 struct InternedInSet<'tcx, T: ?Sized>(&'tcx T);
1348
1349 impl<'tcx, T: 'tcx + ?Sized> Clone for InternedInSet<'tcx, T> {
1350     fn clone(&self) -> Self {
1351         InternedInSet(self.0)
1352     }
1353 }
1354
1355 impl<'tcx, T: 'tcx + ?Sized> Copy for InternedInSet<'tcx, T> {}
1356
1357 impl<'tcx, T: 'tcx + ?Sized> IntoPointer for InternedInSet<'tcx, T> {
1358     fn into_pointer(&self) -> *const () {
1359         self.0 as *const _ as *const ()
1360     }
1361 }
1362
1363 #[allow(rustc::usage_of_ty_tykind)]
1364 impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1365     fn borrow(&self) -> &T {
1366         &self.0.internee
1367     }
1368 }
1369
1370 impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1371     fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1372         // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1373         // `x == y`.
1374         self.0.internee == other.0.internee
1375     }
1376 }
1377
1378 impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1379
1380 impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1381     fn hash<H: Hasher>(&self, s: &mut H) {
1382         // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
1383         self.0.internee.hash(s)
1384     }
1385 }
1386
1387 impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1388     fn borrow(&self) -> &[T] {
1389         &self.0[..]
1390     }
1391 }
1392
1393 impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
1394     fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
1395         // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1396         // `x == y`.
1397         self.0[..] == other.0[..]
1398     }
1399 }
1400
1401 impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
1402
1403 impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
1404     fn hash<H: Hasher>(&self, s: &mut H) {
1405         // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
1406         self.0[..].hash(s)
1407     }
1408 }
1409
1410 macro_rules! direct_interners {
1411     ($($name:ident: $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
1412         $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
1413             fn borrow<'a>(&'a self) -> &'a $ty {
1414                 &self.0
1415             }
1416         }
1417
1418         impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
1419             fn eq(&self, other: &Self) -> bool {
1420                 // The `Borrow` trait requires that `x.borrow() == y.borrow()`
1421                 // equals `x == y`.
1422                 self.0 == other.0
1423             }
1424         }
1425
1426         impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
1427
1428         impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
1429             fn hash<H: Hasher>(&self, s: &mut H) {
1430                 // The `Borrow` trait requires that `x.borrow().hash(s) ==
1431                 // x.hash(s)`.
1432                 self.0.hash(s)
1433             }
1434         }
1435
1436         impl<'tcx> TyCtxt<'tcx> {
1437             pub fn $method(self, v: $ty) -> $ret_ty {
1438                 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
1439                     InternedInSet(self.interners.arena.alloc(v))
1440                 }).0))
1441             }
1442         })+
1443     }
1444 }
1445
1446 direct_interners! {
1447     region: mk_region(RegionKind<'tcx>): Region -> Region<'tcx>,
1448     const_: mk_const_internal(ConstData<'tcx>): Const -> Const<'tcx>,
1449     const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
1450     layout: intern_layout(LayoutS<VariantIdx>): Layout -> Layout<'tcx>,
1451     adt_def: intern_adt_def(AdtDefData): AdtDef -> AdtDef<'tcx>,
1452 }
1453
1454 macro_rules! slice_interners {
1455     ($($field:ident: $method:ident($ty:ty)),+ $(,)?) => (
1456         impl<'tcx> TyCtxt<'tcx> {
1457             $(pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
1458                 self.interners.$field.intern_ref(v, || {
1459                     InternedInSet(List::from_arena(&*self.arena, v))
1460                 }).0
1461             })+
1462         }
1463     );
1464 }
1465
1466 slice_interners!(
1467     const_lists: _intern_const_list(Const<'tcx>),
1468     substs: _intern_substs(GenericArg<'tcx>),
1469     canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo<'tcx>),
1470     poly_existential_predicates:
1471         _intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
1472     predicates: _intern_predicates(Predicate<'tcx>),
1473     projs: _intern_projs(ProjectionKind),
1474     place_elems: _intern_place_elems(PlaceElem<'tcx>),
1475     bound_variable_kinds: _intern_bound_variable_kinds(ty::BoundVariableKind),
1476 );
1477
1478 impl<'tcx> TyCtxt<'tcx> {
1479     /// Given a `fn` type, returns an equivalent `unsafe fn` type;
1480     /// that is, a `fn` type that is equivalent in every way for being
1481     /// unsafe.
1482     pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
1483         assert_eq!(sig.unsafety(), hir::Unsafety::Normal);
1484         self.mk_fn_ptr(sig.map_bound(|sig| ty::FnSig { unsafety: hir::Unsafety::Unsafe, ..sig }))
1485     }
1486
1487     /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name`
1488     /// returns true if the `trait_def_id` defines an associated item of name `assoc_name`.
1489     pub fn trait_may_define_assoc_type(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
1490         self.super_traits_of(trait_def_id).any(|trait_did| {
1491             self.associated_items(trait_did)
1492                 .find_by_name_and_kind(self, assoc_name, ty::AssocKind::Type, trait_did)
1493                 .is_some()
1494         })
1495     }
1496
1497     /// Given a `ty`, return whether it's an `impl Future<...>`.
1498     pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
1499         let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
1500         let future_trait = self.require_lang_item(LangItem::Future, None);
1501
1502         self.explicit_item_bounds(def_id).iter().any(|(predicate, _)| {
1503             let ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() else {
1504                 return false;
1505             };
1506             trait_predicate.trait_ref.def_id == future_trait
1507                 && trait_predicate.polarity == ImplPolarity::Positive
1508         })
1509     }
1510
1511     /// Computes the def-ids of the transitive supertraits of `trait_def_id`. This (intentionally)
1512     /// does not compute the full elaborated super-predicates but just the set of def-ids. It is used
1513     /// to identify which traits may define a given associated type to help avoid cycle errors.
1514     /// Returns a `DefId` iterator.
1515     fn super_traits_of(self, trait_def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
1516         let mut set = FxHashSet::default();
1517         let mut stack = vec![trait_def_id];
1518
1519         set.insert(trait_def_id);
1520
1521         iter::from_fn(move || -> Option<DefId> {
1522             let trait_did = stack.pop()?;
1523             let generic_predicates = self.super_predicates_of(trait_did);
1524
1525             for (predicate, _) in generic_predicates.predicates {
1526                 if let ty::PredicateKind::Clause(ty::Clause::Trait(data)) =
1527                     predicate.kind().skip_binder()
1528                 {
1529                     if set.insert(data.def_id()) {
1530                         stack.push(data.def_id());
1531                     }
1532                 }
1533             }
1534
1535             Some(trait_did)
1536         })
1537     }
1538
1539     /// Given a closure signature, returns an equivalent fn signature. Detuples
1540     /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then
1541     /// you would get a `fn(u32, i32)`.
1542     /// `unsafety` determines the unsafety of the fn signature. If you pass
1543     /// `hir::Unsafety::Unsafe` in the previous example, then you would get
1544     /// an `unsafe fn (u32, i32)`.
1545     /// It cannot convert a closure that requires unsafe.
1546     pub fn signature_unclosure(
1547         self,
1548         sig: PolyFnSig<'tcx>,
1549         unsafety: hir::Unsafety,
1550     ) -> PolyFnSig<'tcx> {
1551         sig.map_bound(|s| {
1552             let params_iter = match s.inputs()[0].kind() {
1553                 ty::Tuple(params) => params.into_iter(),
1554                 _ => bug!(),
1555             };
1556             self.mk_fn_sig(params_iter, s.output(), s.c_variadic, unsafety, abi::Abi::Rust)
1557         })
1558     }
1559
1560     /// Same a `self.mk_region(kind)`, but avoids accessing the interners if
1561     /// `*r == kind`.
1562     #[inline]
1563     pub fn reuse_or_mk_region(self, r: Region<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> {
1564         if *r == kind { r } else { self.mk_region(kind) }
1565     }
1566
1567     #[allow(rustc::usage_of_ty_tykind)]
1568     #[inline]
1569     pub fn mk_ty(self, st: TyKind<'tcx>) -> Ty<'tcx> {
1570         self.interners.intern_ty(
1571             st,
1572             self.sess,
1573             // This is only used to create a stable hashing context.
1574             &self.untracked,
1575         )
1576     }
1577
1578     #[inline]
1579     pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
1580         self.interners.intern_predicate(
1581             binder,
1582             self.sess,
1583             // This is only used to create a stable hashing context.
1584             &self.untracked,
1585         )
1586     }
1587
1588     #[inline]
1589     pub fn reuse_or_mk_predicate(
1590         self,
1591         pred: Predicate<'tcx>,
1592         binder: Binder<'tcx, PredicateKind<'tcx>>,
1593     ) -> Predicate<'tcx> {
1594         if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
1595     }
1596
1597     pub fn mk_mach_int(self, tm: IntTy) -> Ty<'tcx> {
1598         match tm {
1599             IntTy::Isize => self.types.isize,
1600             IntTy::I8 => self.types.i8,
1601             IntTy::I16 => self.types.i16,
1602             IntTy::I32 => self.types.i32,
1603             IntTy::I64 => self.types.i64,
1604             IntTy::I128 => self.types.i128,
1605         }
1606     }
1607
1608     pub fn mk_mach_uint(self, tm: UintTy) -> Ty<'tcx> {
1609         match tm {
1610             UintTy::Usize => self.types.usize,
1611             UintTy::U8 => self.types.u8,
1612             UintTy::U16 => self.types.u16,
1613             UintTy::U32 => self.types.u32,
1614             UintTy::U64 => self.types.u64,
1615             UintTy::U128 => self.types.u128,
1616         }
1617     }
1618
1619     pub fn mk_mach_float(self, tm: FloatTy) -> Ty<'tcx> {
1620         match tm {
1621             FloatTy::F32 => self.types.f32,
1622             FloatTy::F64 => self.types.f64,
1623         }
1624     }
1625
1626     #[inline]
1627     pub fn mk_static_str(self) -> Ty<'tcx> {
1628         self.mk_imm_ref(self.lifetimes.re_static, self.types.str_)
1629     }
1630
1631     #[inline]
1632     pub fn mk_adt(self, def: AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
1633         // Take a copy of substs so that we own the vectors inside.
1634         self.mk_ty(Adt(def, substs))
1635     }
1636
1637     #[inline]
1638     pub fn mk_foreign(self, def_id: DefId) -> Ty<'tcx> {
1639         self.mk_ty(Foreign(def_id))
1640     }
1641
1642     fn mk_generic_adt(self, wrapper_def_id: DefId, ty_param: Ty<'tcx>) -> Ty<'tcx> {
1643         let adt_def = self.adt_def(wrapper_def_id);
1644         let substs =
1645             InternalSubsts::for_item(self, wrapper_def_id, |param, substs| match param.kind {
1646                 GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => bug!(),
1647                 GenericParamDefKind::Type { has_default, .. } => {
1648                     if param.index == 0 {
1649                         ty_param.into()
1650                     } else {
1651                         assert!(has_default);
1652                         self.bound_type_of(param.def_id).subst(self, substs).into()
1653                     }
1654                 }
1655             });
1656         self.mk_ty(Adt(adt_def, substs))
1657     }
1658
1659     #[inline]
1660     pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> {
1661         let def_id = self.require_lang_item(LangItem::OwnedBox, None);
1662         self.mk_generic_adt(def_id, ty)
1663     }
1664
1665     #[inline]
1666     pub fn mk_lang_item(self, ty: Ty<'tcx>, item: LangItem) -> Option<Ty<'tcx>> {
1667         let def_id = self.lang_items().get(item)?;
1668         Some(self.mk_generic_adt(def_id, ty))
1669     }
1670
1671     #[inline]
1672     pub fn mk_diagnostic_item(self, ty: Ty<'tcx>, name: Symbol) -> Option<Ty<'tcx>> {
1673         let def_id = self.get_diagnostic_item(name)?;
1674         Some(self.mk_generic_adt(def_id, ty))
1675     }
1676
1677     #[inline]
1678     pub fn mk_maybe_uninit(self, ty: Ty<'tcx>) -> Ty<'tcx> {
1679         let def_id = self.require_lang_item(LangItem::MaybeUninit, None);
1680         self.mk_generic_adt(def_id, ty)
1681     }
1682
1683     #[inline]
1684     pub fn mk_ptr(self, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
1685         self.mk_ty(RawPtr(tm))
1686     }
1687
1688     #[inline]
1689     pub fn mk_ref(self, r: Region<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
1690         self.mk_ty(Ref(r, tm.ty, tm.mutbl))
1691     }
1692
1693     #[inline]
1694     pub fn mk_mut_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
1695         self.mk_ref(r, TypeAndMut { ty, mutbl: hir::Mutability::Mut })
1696     }
1697
1698     #[inline]
1699     pub fn mk_imm_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
1700         self.mk_ref(r, TypeAndMut { ty, mutbl: hir::Mutability::Not })
1701     }
1702
1703     #[inline]
1704     pub fn mk_mut_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
1705         self.mk_ptr(TypeAndMut { ty, mutbl: hir::Mutability::Mut })
1706     }
1707
1708     #[inline]
1709     pub fn mk_imm_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
1710         self.mk_ptr(TypeAndMut { ty, mutbl: hir::Mutability::Not })
1711     }
1712
1713     #[inline]
1714     pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
1715         self.mk_ty(Array(ty, ty::Const::from_usize(self, n)))
1716     }
1717
1718     #[inline]
1719     pub fn mk_slice(self, ty: Ty<'tcx>) -> Ty<'tcx> {
1720         self.mk_ty(Slice(ty))
1721     }
1722
1723     #[inline]
1724     pub fn intern_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
1725         self.mk_ty(Tuple(self.intern_type_list(&ts)))
1726     }
1727
1728     pub fn mk_tup<I: InternAs<Ty<'tcx>, Ty<'tcx>>>(self, iter: I) -> I::Output {
1729         iter.intern_with(|ts| self.mk_ty(Tuple(self.intern_type_list(&ts))))
1730     }
1731
1732     #[inline]
1733     pub fn mk_unit(self) -> Ty<'tcx> {
1734         self.types.unit
1735     }
1736
1737     #[inline]
1738     pub fn mk_diverging_default(self) -> Ty<'tcx> {
1739         if self.features().never_type_fallback { self.types.never } else { self.types.unit }
1740     }
1741
1742     #[inline]
1743     pub fn mk_fn_def(
1744         self,
1745         def_id: DefId,
1746         substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
1747     ) -> Ty<'tcx> {
1748         let substs = self.check_substs(def_id, substs);
1749         self.mk_ty(FnDef(def_id, substs))
1750     }
1751
1752     #[inline(always)]
1753     fn check_substs(
1754         self,
1755         _def_id: DefId,
1756         substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
1757     ) -> SubstsRef<'tcx> {
1758         let substs = substs.into_iter().map(Into::into);
1759         #[cfg(debug_assertions)]
1760         {
1761             let n = self.generics_of(_def_id).count();
1762             assert_eq!(
1763                 (n, Some(n)),
1764                 substs.size_hint(),
1765                 "wrong number of generic parameters for {_def_id:?}: {:?}",
1766                 substs.collect::<Vec<_>>(),
1767             );
1768         }
1769         self.mk_substs(substs)
1770     }
1771
1772     #[inline]
1773     pub fn mk_fn_ptr(self, fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
1774         self.mk_ty(FnPtr(fty))
1775     }
1776
1777     #[inline]
1778     pub fn mk_dynamic(
1779         self,
1780         obj: &'tcx List<PolyExistentialPredicate<'tcx>>,
1781         reg: ty::Region<'tcx>,
1782         repr: DynKind,
1783     ) -> Ty<'tcx> {
1784         self.mk_ty(Dynamic(obj, reg, repr))
1785     }
1786
1787     #[inline]
1788     pub fn mk_projection(
1789         self,
1790         item_def_id: DefId,
1791         substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
1792     ) -> Ty<'tcx> {
1793         self.mk_ty(Alias(ty::Projection, self.mk_alias_ty(item_def_id, substs)))
1794     }
1795
1796     #[inline]
1797     pub fn mk_closure(self, closure_id: DefId, closure_substs: SubstsRef<'tcx>) -> Ty<'tcx> {
1798         self.mk_ty(Closure(closure_id, closure_substs))
1799     }
1800
1801     #[inline]
1802     pub fn mk_generator(
1803         self,
1804         id: DefId,
1805         generator_substs: SubstsRef<'tcx>,
1806         movability: hir::Movability,
1807     ) -> Ty<'tcx> {
1808         self.mk_ty(Generator(id, generator_substs, movability))
1809     }
1810
1811     #[inline]
1812     pub fn mk_generator_witness(self, types: ty::Binder<'tcx, &'tcx List<Ty<'tcx>>>) -> Ty<'tcx> {
1813         self.mk_ty(GeneratorWitness(types))
1814     }
1815
1816     /// Creates a `&mut Context<'_>` [`Ty`] with erased lifetimes.
1817     pub fn mk_task_context(self) -> Ty<'tcx> {
1818         let context_did = self.require_lang_item(LangItem::Context, None);
1819         let context_adt_ref = self.adt_def(context_did);
1820         let context_substs = self.intern_substs(&[self.lifetimes.re_erased.into()]);
1821         let context_ty = self.mk_adt(context_adt_ref, context_substs);
1822         self.mk_mut_ref(self.lifetimes.re_erased, context_ty)
1823     }
1824
1825     #[inline]
1826     pub fn mk_generator_witness_mir(self, id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
1827         self.mk_ty(GeneratorWitnessMIR(id, substs))
1828     }
1829
1830     #[inline]
1831     pub fn mk_ty_var(self, v: TyVid) -> Ty<'tcx> {
1832         self.mk_ty_infer(TyVar(v))
1833     }
1834
1835     #[inline]
1836     pub fn mk_const(self, kind: impl Into<ty::ConstKind<'tcx>>, ty: Ty<'tcx>) -> Const<'tcx> {
1837         self.mk_const_internal(ty::ConstData { kind: kind.into(), ty })
1838     }
1839
1840     #[inline]
1841     pub fn mk_int_var(self, v: IntVid) -> Ty<'tcx> {
1842         self.mk_ty_infer(IntVar(v))
1843     }
1844
1845     #[inline]
1846     pub fn mk_float_var(self, v: FloatVid) -> Ty<'tcx> {
1847         self.mk_ty_infer(FloatVar(v))
1848     }
1849
1850     #[inline]
1851     pub fn mk_ty_infer(self, it: InferTy) -> Ty<'tcx> {
1852         self.mk_ty(Infer(it))
1853     }
1854
1855     #[inline]
1856     pub fn mk_ty_param(self, index: u32, name: Symbol) -> Ty<'tcx> {
1857         self.mk_ty(Param(ParamTy { index, name }))
1858     }
1859
1860     pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
1861         match param.kind {
1862             GenericParamDefKind::Lifetime => {
1863                 self.mk_region(ty::ReEarlyBound(param.to_early_bound_region_data())).into()
1864             }
1865             GenericParamDefKind::Type { .. } => self.mk_ty_param(param.index, param.name).into(),
1866             GenericParamDefKind::Const { .. } => self
1867                 .mk_const(
1868                     ParamConst { index: param.index, name: param.name },
1869                     self.type_of(param.def_id),
1870                 )
1871                 .into(),
1872         }
1873     }
1874
1875     #[inline]
1876     pub fn mk_opaque(self, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
1877         self.mk_ty(Alias(ty::Opaque, self.mk_alias_ty(def_id, substs)))
1878     }
1879
1880     pub fn mk_place_field(self, place: Place<'tcx>, f: Field, ty: Ty<'tcx>) -> Place<'tcx> {
1881         self.mk_place_elem(place, PlaceElem::Field(f, ty))
1882     }
1883
1884     pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
1885         self.mk_place_elem(place, PlaceElem::Deref)
1886     }
1887
1888     pub fn mk_place_downcast(
1889         self,
1890         place: Place<'tcx>,
1891         adt_def: AdtDef<'tcx>,
1892         variant_index: VariantIdx,
1893     ) -> Place<'tcx> {
1894         self.mk_place_elem(
1895             place,
1896             PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
1897         )
1898     }
1899
1900     pub fn mk_place_downcast_unnamed(
1901         self,
1902         place: Place<'tcx>,
1903         variant_index: VariantIdx,
1904     ) -> Place<'tcx> {
1905         self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
1906     }
1907
1908     pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
1909         self.mk_place_elem(place, PlaceElem::Index(index))
1910     }
1911
1912     /// This method copies `Place`'s projection, add an element and reintern it. Should not be used
1913     /// to build a full `Place` it's just a convenient way to grab a projection and modify it in
1914     /// flight.
1915     pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
1916         let mut projection = place.projection.to_vec();
1917         projection.push(elem);
1918
1919         Place { local: place.local, projection: self.intern_place_elems(&projection) }
1920     }
1921
1922     pub fn intern_poly_existential_predicates(
1923         self,
1924         eps: &[PolyExistentialPredicate<'tcx>],
1925     ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
1926         assert!(!eps.is_empty());
1927         assert!(
1928             eps.array_windows()
1929                 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
1930                     != Ordering::Greater)
1931         );
1932         self._intern_poly_existential_predicates(eps)
1933     }
1934
1935     pub fn intern_predicates(self, preds: &[Predicate<'tcx>]) -> &'tcx List<Predicate<'tcx>> {
1936         // FIXME consider asking the input slice to be sorted to avoid
1937         // re-interning permutations, in which case that would be asserted
1938         // here.
1939         if preds.is_empty() {
1940             // The macro-generated method below asserts we don't intern an empty slice.
1941             List::empty()
1942         } else {
1943             self._intern_predicates(preds)
1944         }
1945     }
1946
1947     pub fn mk_const_list<I: InternAs<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>>(
1948         self,
1949         iter: I,
1950     ) -> I::Output {
1951         iter.intern_with(|xs| self.intern_const_list(xs))
1952     }
1953
1954     pub fn intern_const_list(self, cs: &[ty::Const<'tcx>]) -> &'tcx List<ty::Const<'tcx>> {
1955         if cs.is_empty() { List::empty() } else { self._intern_const_list(cs) }
1956     }
1957
1958     pub fn intern_type_list(self, ts: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> {
1959         if ts.is_empty() {
1960             List::empty()
1961         } else {
1962             // Actually intern type lists as lists of `GenericArg`s.
1963             //
1964             // Transmuting from `Ty<'tcx>` to `GenericArg<'tcx>` is sound
1965             // as explained in ty_slice_as_generic_arg`. With this,
1966             // we guarantee that even when transmuting between `List<Ty<'tcx>>`
1967             // and `List<GenericArg<'tcx>>`, the uniqueness requirement for
1968             // lists is upheld.
1969             let substs = self._intern_substs(ty::subst::ty_slice_as_generic_args(ts));
1970             substs.try_as_type_list().unwrap()
1971         }
1972     }
1973
1974     pub fn intern_substs(self, ts: &[GenericArg<'tcx>]) -> &'tcx List<GenericArg<'tcx>> {
1975         if ts.is_empty() { List::empty() } else { self._intern_substs(ts) }
1976     }
1977
1978     pub fn intern_projs(self, ps: &[ProjectionKind]) -> &'tcx List<ProjectionKind> {
1979         if ps.is_empty() { List::empty() } else { self._intern_projs(ps) }
1980     }
1981
1982     pub fn intern_place_elems(self, ts: &[PlaceElem<'tcx>]) -> &'tcx List<PlaceElem<'tcx>> {
1983         if ts.is_empty() { List::empty() } else { self._intern_place_elems(ts) }
1984     }
1985
1986     pub fn intern_canonical_var_infos(
1987         self,
1988         ts: &[CanonicalVarInfo<'tcx>],
1989     ) -> CanonicalVarInfos<'tcx> {
1990         if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) }
1991     }
1992
1993     pub fn intern_bound_variable_kinds(
1994         self,
1995         ts: &[ty::BoundVariableKind],
1996     ) -> &'tcx List<ty::BoundVariableKind> {
1997         if ts.is_empty() { List::empty() } else { self._intern_bound_variable_kinds(ts) }
1998     }
1999
2000     pub fn mk_fn_sig<I>(
2001         self,
2002         inputs: I,
2003         output: I::Item,
2004         c_variadic: bool,
2005         unsafety: hir::Unsafety,
2006         abi: abi::Abi,
2007     ) -> <I::Item as InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>>::Output
2008     where
2009         I: Iterator<Item: InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>>,
2010     {
2011         inputs.chain(iter::once(output)).intern_with(|xs| ty::FnSig {
2012             inputs_and_output: self.intern_type_list(xs),
2013             c_variadic,
2014             unsafety,
2015             abi,
2016         })
2017     }
2018
2019     pub fn mk_poly_existential_predicates<
2020         I: InternAs<PolyExistentialPredicate<'tcx>, &'tcx List<PolyExistentialPredicate<'tcx>>>,
2021     >(
2022         self,
2023         iter: I,
2024     ) -> I::Output {
2025         iter.intern_with(|xs| self.intern_poly_existential_predicates(xs))
2026     }
2027
2028     pub fn mk_predicates<I: InternAs<Predicate<'tcx>, &'tcx List<Predicate<'tcx>>>>(
2029         self,
2030         iter: I,
2031     ) -> I::Output {
2032         iter.intern_with(|xs| self.intern_predicates(xs))
2033     }
2034
2035     pub fn mk_type_list<I: InternAs<Ty<'tcx>, &'tcx List<Ty<'tcx>>>>(self, iter: I) -> I::Output {
2036         iter.intern_with(|xs| self.intern_type_list(xs))
2037     }
2038
2039     pub fn mk_substs<I: InternAs<GenericArg<'tcx>, &'tcx List<GenericArg<'tcx>>>>(
2040         self,
2041         iter: I,
2042     ) -> I::Output {
2043         iter.intern_with(|xs| self.intern_substs(xs))
2044     }
2045
2046     pub fn mk_place_elems<I: InternAs<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>>(
2047         self,
2048         iter: I,
2049     ) -> I::Output {
2050         iter.intern_with(|xs| self.intern_place_elems(xs))
2051     }
2052
2053     pub fn mk_substs_trait(
2054         self,
2055         self_ty: Ty<'tcx>,
2056         rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2057     ) -> SubstsRef<'tcx> {
2058         self.mk_substs(iter::once(self_ty.into()).chain(rest))
2059     }
2060
2061     pub fn mk_trait_ref(
2062         self,
2063         trait_def_id: DefId,
2064         substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
2065     ) -> ty::TraitRef<'tcx> {
2066         let substs = self.check_substs(trait_def_id, substs);
2067         ty::TraitRef { def_id: trait_def_id, substs, _use_mk_trait_ref_instead: () }
2068     }
2069
2070     pub fn mk_alias_ty(
2071         self,
2072         def_id: DefId,
2073         substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
2074     ) -> ty::AliasTy<'tcx> {
2075         let substs = self.check_substs(def_id, substs);
2076         ty::AliasTy { def_id, substs, _use_mk_alias_ty_instead: () }
2077     }
2078
2079     pub fn mk_bound_variable_kinds<
2080         I: InternAs<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
2081     >(
2082         self,
2083         iter: I,
2084     ) -> I::Output {
2085         iter.intern_with(|xs| self.intern_bound_variable_kinds(xs))
2086     }
2087
2088     /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`,
2089     /// typically generated by `#[derive(LintDiagnostic)]`).
2090     pub fn emit_spanned_lint(
2091         self,
2092         lint: &'static Lint,
2093         hir_id: HirId,
2094         span: impl Into<MultiSpan>,
2095         decorator: impl for<'a> DecorateLint<'a, ()>,
2096     ) {
2097         let msg = decorator.msg();
2098         let (level, src) = self.lint_level_at_node(lint, hir_id);
2099         struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, |diag| {
2100             decorator.decorate_lint(diag)
2101         })
2102     }
2103
2104     /// Emit a lint at the appropriate level for a hir node, with an associated span.
2105     ///
2106     /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
2107     ///
2108     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
2109     #[rustc_lint_diagnostics]
2110     pub fn struct_span_lint_hir(
2111         self,
2112         lint: &'static Lint,
2113         hir_id: HirId,
2114         span: impl Into<MultiSpan>,
2115         msg: impl Into<DiagnosticMessage>,
2116         decorate: impl for<'a, 'b> FnOnce(
2117             &'b mut DiagnosticBuilder<'a, ()>,
2118         ) -> &'b mut DiagnosticBuilder<'a, ()>,
2119     ) {
2120         let (level, src) = self.lint_level_at_node(lint, hir_id);
2121         struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, decorate);
2122     }
2123
2124     /// Emit a lint from a lint struct (some type that implements `DecorateLint`, typically
2125     /// generated by `#[derive(LintDiagnostic)]`).
2126     pub fn emit_lint(
2127         self,
2128         lint: &'static Lint,
2129         id: HirId,
2130         decorator: impl for<'a> DecorateLint<'a, ()>,
2131     ) {
2132         self.struct_lint_node(lint, id, decorator.msg(), |diag| decorator.decorate_lint(diag))
2133     }
2134
2135     /// Emit a lint at the appropriate level for a hir node.
2136     ///
2137     /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
2138     ///
2139     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
2140     #[rustc_lint_diagnostics]
2141     pub fn struct_lint_node(
2142         self,
2143         lint: &'static Lint,
2144         id: HirId,
2145         msg: impl Into<DiagnosticMessage>,
2146         decorate: impl for<'a, 'b> FnOnce(
2147             &'b mut DiagnosticBuilder<'a, ()>,
2148         ) -> &'b mut DiagnosticBuilder<'a, ()>,
2149     ) {
2150         let (level, src) = self.lint_level_at_node(lint, id);
2151         struct_lint_level(self.sess, lint, level, src, None, msg, decorate);
2152     }
2153
2154     pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
2155         let map = self.in_scope_traits_map(id.owner)?;
2156         let candidates = map.get(&id.local_id)?;
2157         Some(&*candidates)
2158     }
2159
2160     pub fn named_region(self, id: HirId) -> Option<resolve_lifetime::Region> {
2161         debug!(?id, "named_region");
2162         self.named_region_map(id.owner).and_then(|map| map.get(&id.local_id).cloned())
2163     }
2164
2165     pub fn is_late_bound(self, id: HirId) -> bool {
2166         self.is_late_bound_map(id.owner).map_or(false, |set| set.contains(&id.local_id))
2167     }
2168
2169     pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
2170         self.mk_bound_variable_kinds(
2171             self.late_bound_vars_map(id.owner)
2172                 .and_then(|map| map.get(&id.local_id).cloned())
2173                 .unwrap_or_else(|| {
2174                     bug!("No bound vars found for {}", self.hir().node_to_string(id))
2175                 })
2176                 .iter(),
2177         )
2178     }
2179
2180     /// Whether the `def_id` counts as const fn in the current crate, considering all active
2181     /// feature gates
2182     pub fn is_const_fn(self, def_id: DefId) -> bool {
2183         if self.is_const_fn_raw(def_id) {
2184             match self.lookup_const_stability(def_id) {
2185                 Some(stability) if stability.is_const_unstable() => {
2186                     // has a `rustc_const_unstable` attribute, check whether the user enabled the
2187                     // corresponding feature gate.
2188                     self.features()
2189                         .declared_lib_features
2190                         .iter()
2191                         .any(|&(sym, _)| sym == stability.feature)
2192                 }
2193                 // functions without const stability are either stable user written
2194                 // const fn or the user is using feature gates and we thus don't
2195                 // care what they do
2196                 _ => true,
2197             }
2198         } else {
2199             false
2200         }
2201     }
2202
2203     /// Whether the trait impl is marked const. This does not consider stability or feature gates.
2204     pub fn is_const_trait_impl_raw(self, def_id: DefId) -> bool {
2205         let Some(local_def_id) = def_id.as_local() else { return false };
2206         let hir_id = self.local_def_id_to_hir_id(local_def_id);
2207         let node = self.hir().get(hir_id);
2208
2209         matches!(
2210             node,
2211             hir::Node::Item(hir::Item {
2212                 kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }),
2213                 ..
2214             })
2215         )
2216     }
2217 }
2218
2219 impl<'tcx> TyCtxtAt<'tcx> {
2220     /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used.
2221     #[track_caller]
2222     pub fn ty_error(self) -> Ty<'tcx> {
2223         self.tcx.ty_error_with_message(self.span, "TyKind::Error constructed but no error reported")
2224     }
2225
2226     /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg to
2227     /// ensure it gets used.
2228     #[track_caller]
2229     pub fn ty_error_with_message(self, msg: &str) -> Ty<'tcx> {
2230         self.tcx.ty_error_with_message(self.span, msg)
2231     }
2232
2233     pub fn mk_trait_ref(
2234         self,
2235         trait_lang_item: LangItem,
2236         substs: impl IntoIterator<Item = impl Into<ty::GenericArg<'tcx>>>,
2237     ) -> ty::TraitRef<'tcx> {
2238         let trait_def_id = self.require_lang_item(trait_lang_item, Some(self.span));
2239         self.tcx.mk_trait_ref(trait_def_id, substs)
2240     }
2241 }
2242
2243 /// Parameter attributes that can only be determined by examining the body of a function instead
2244 /// of just its signature.
2245 ///
2246 /// These can be useful for optimization purposes when a function is directly called. We compute
2247 /// them and store them into the crate metadata so that downstream crates can make use of them.
2248 ///
2249 /// Right now, we only have `read_only`, but `no_capture` and `no_alias` might be useful in the
2250 /// future.
2251 #[derive(Clone, Copy, PartialEq, Debug, Default, TyDecodable, TyEncodable, HashStable)]
2252 pub struct DeducedParamAttrs {
2253     /// The parameter is marked immutable in the function and contains no `UnsafeCell` (i.e. its
2254     /// type is freeze).
2255     pub read_only: bool,
2256 }
2257
2258 pub fn provide(providers: &mut ty::query::Providers) {
2259     providers.module_reexports =
2260         |tcx, id| tcx.resolutions(()).reexport_map.get(&id).map(|v| &v[..]);
2261     providers.maybe_unused_trait_imports =
2262         |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
2263     providers.maybe_unused_extern_crates =
2264         |tcx, ()| &tcx.resolutions(()).maybe_unused_extern_crates[..];
2265     providers.names_imported_by_glob_use = |tcx, id| {
2266         tcx.arena.alloc(tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default())
2267     };
2268
2269     providers.extern_mod_stmt_cnum =
2270         |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
2271     providers.is_panic_runtime = |tcx, cnum| {
2272         assert_eq!(cnum, LOCAL_CRATE);
2273         tcx.sess.contains_name(tcx.hir().krate_attrs(), sym::panic_runtime)
2274     };
2275     providers.is_compiler_builtins = |tcx, cnum| {
2276         assert_eq!(cnum, LOCAL_CRATE);
2277         tcx.sess.contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins)
2278     };
2279     providers.has_panic_handler = |tcx, cnum| {
2280         assert_eq!(cnum, LOCAL_CRATE);
2281         // We want to check if the panic handler was defined in this crate
2282         tcx.lang_items().panic_impl().map_or(false, |did| did.is_local())
2283     };
2284     providers.source_span =
2285         |tcx, def_id| tcx.untracked.source_span.get(def_id).copied().unwrap_or(DUMMY_SP);
2286 }