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