]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/ty/context.rs
Rollup merge of #107022 - scottmcm:ordering-option-eq, r=m-ou-se
[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                     GeneratorWitnessMIR,
1310                     Dynamic,
1311                     Closure,
1312                     Tuple,
1313                     Bound,
1314                     Param,
1315                     Infer,
1316                     Alias,
1317                     Foreign
1318                 )?;
1319
1320                 writeln!(fmt, "InternalSubsts interner: #{}", self.0.interners.substs.len())?;
1321                 writeln!(fmt, "Region interner: #{}", self.0.interners.region.len())?;
1322                 writeln!(
1323                     fmt,
1324                     "Const Allocation interner: #{}",
1325                     self.0.interners.const_allocation.len()
1326                 )?;
1327                 writeln!(fmt, "Layout interner: #{}", self.0.interners.layout.len())?;
1328
1329                 Ok(())
1330             }
1331         }
1332
1333         DebugStats(self)
1334     }
1335 }
1336
1337 // This type holds a `T` in the interner. The `T` is stored in the arena and
1338 // this type just holds a pointer to it, but it still effectively owns it. It
1339 // impls `Borrow` so that it can be looked up using the original
1340 // (non-arena-memory-owning) types.
1341 struct InternedInSet<'tcx, T: ?Sized>(&'tcx T);
1342
1343 impl<'tcx, T: 'tcx + ?Sized> Clone for InternedInSet<'tcx, T> {
1344     fn clone(&self) -> Self {
1345         InternedInSet(self.0)
1346     }
1347 }
1348
1349 impl<'tcx, T: 'tcx + ?Sized> Copy for InternedInSet<'tcx, T> {}
1350
1351 impl<'tcx, T: 'tcx + ?Sized> IntoPointer for InternedInSet<'tcx, T> {
1352     fn into_pointer(&self) -> *const () {
1353         self.0 as *const _ as *const ()
1354     }
1355 }
1356
1357 #[allow(rustc::usage_of_ty_tykind)]
1358 impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1359     fn borrow(&self) -> &T {
1360         &self.0.internee
1361     }
1362 }
1363
1364 impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1365     fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1366         // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1367         // `x == y`.
1368         self.0.internee == other.0.internee
1369     }
1370 }
1371
1372 impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1373
1374 impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1375     fn hash<H: Hasher>(&self, s: &mut H) {
1376         // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
1377         self.0.internee.hash(s)
1378     }
1379 }
1380
1381 impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1382     fn borrow(&self) -> &[T] {
1383         &self.0[..]
1384     }
1385 }
1386
1387 impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
1388     fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
1389         // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1390         // `x == y`.
1391         self.0[..] == other.0[..]
1392     }
1393 }
1394
1395 impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
1396
1397 impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
1398     fn hash<H: Hasher>(&self, s: &mut H) {
1399         // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
1400         self.0[..].hash(s)
1401     }
1402 }
1403
1404 macro_rules! direct_interners {
1405     ($($name:ident: $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
1406         $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
1407             fn borrow<'a>(&'a self) -> &'a $ty {
1408                 &self.0
1409             }
1410         }
1411
1412         impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
1413             fn eq(&self, other: &Self) -> bool {
1414                 // The `Borrow` trait requires that `x.borrow() == y.borrow()`
1415                 // equals `x == y`.
1416                 self.0 == other.0
1417             }
1418         }
1419
1420         impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
1421
1422         impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
1423             fn hash<H: Hasher>(&self, s: &mut H) {
1424                 // The `Borrow` trait requires that `x.borrow().hash(s) ==
1425                 // x.hash(s)`.
1426                 self.0.hash(s)
1427             }
1428         }
1429
1430         impl<'tcx> TyCtxt<'tcx> {
1431             pub fn $method(self, v: $ty) -> $ret_ty {
1432                 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
1433                     InternedInSet(self.interners.arena.alloc(v))
1434                 }).0))
1435             }
1436         })+
1437     }
1438 }
1439
1440 direct_interners! {
1441     region: mk_region(RegionKind<'tcx>): Region -> Region<'tcx>,
1442     const_: mk_const_internal(ConstData<'tcx>): Const -> Const<'tcx>,
1443     const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
1444     layout: intern_layout(LayoutS<VariantIdx>): Layout -> Layout<'tcx>,
1445     adt_def: intern_adt_def(AdtDefData): AdtDef -> AdtDef<'tcx>,
1446 }
1447
1448 macro_rules! slice_interners {
1449     ($($field:ident: $method:ident($ty:ty)),+ $(,)?) => (
1450         impl<'tcx> TyCtxt<'tcx> {
1451             $(pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
1452                 self.interners.$field.intern_ref(v, || {
1453                     InternedInSet(List::from_arena(&*self.arena, v))
1454                 }).0
1455             })+
1456         }
1457     );
1458 }
1459
1460 slice_interners!(
1461     const_lists: _intern_const_list(Const<'tcx>),
1462     substs: _intern_substs(GenericArg<'tcx>),
1463     canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo<'tcx>),
1464     poly_existential_predicates:
1465         _intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
1466     predicates: _intern_predicates(Predicate<'tcx>),
1467     projs: _intern_projs(ProjectionKind),
1468     place_elems: _intern_place_elems(PlaceElem<'tcx>),
1469     bound_variable_kinds: _intern_bound_variable_kinds(ty::BoundVariableKind),
1470 );
1471
1472 impl<'tcx> TyCtxt<'tcx> {
1473     /// Given a `fn` type, returns an equivalent `unsafe fn` type;
1474     /// that is, a `fn` type that is equivalent in every way for being
1475     /// unsafe.
1476     pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
1477         assert_eq!(sig.unsafety(), hir::Unsafety::Normal);
1478         self.mk_fn_ptr(sig.map_bound(|sig| ty::FnSig { unsafety: hir::Unsafety::Unsafe, ..sig }))
1479     }
1480
1481     /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name`
1482     /// returns true if the `trait_def_id` defines an associated item of name `assoc_name`.
1483     pub fn trait_may_define_assoc_type(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
1484         self.super_traits_of(trait_def_id).any(|trait_did| {
1485             self.associated_items(trait_did)
1486                 .find_by_name_and_kind(self, assoc_name, ty::AssocKind::Type, trait_did)
1487                 .is_some()
1488         })
1489     }
1490
1491     /// Given a `ty`, return whether it's an `impl Future<...>`.
1492     pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
1493         let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
1494         let future_trait = self.require_lang_item(LangItem::Future, None);
1495
1496         self.explicit_item_bounds(def_id).iter().any(|(predicate, _)| {
1497             let ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() else {
1498                 return false;
1499             };
1500             trait_predicate.trait_ref.def_id == future_trait
1501                 && trait_predicate.polarity == ImplPolarity::Positive
1502         })
1503     }
1504
1505     /// Computes the def-ids of the transitive supertraits of `trait_def_id`. This (intentionally)
1506     /// does not compute the full elaborated super-predicates but just the set of def-ids. It is used
1507     /// to identify which traits may define a given associated type to help avoid cycle errors.
1508     /// Returns a `DefId` iterator.
1509     fn super_traits_of(self, trait_def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
1510         let mut set = FxHashSet::default();
1511         let mut stack = vec![trait_def_id];
1512
1513         set.insert(trait_def_id);
1514
1515         iter::from_fn(move || -> Option<DefId> {
1516             let trait_did = stack.pop()?;
1517             let generic_predicates = self.super_predicates_of(trait_did);
1518
1519             for (predicate, _) in generic_predicates.predicates {
1520                 if let ty::PredicateKind::Clause(ty::Clause::Trait(data)) =
1521                     predicate.kind().skip_binder()
1522                 {
1523                     if set.insert(data.def_id()) {
1524                         stack.push(data.def_id());
1525                     }
1526                 }
1527             }
1528
1529             Some(trait_did)
1530         })
1531     }
1532
1533     /// Given a closure signature, returns an equivalent fn signature. Detuples
1534     /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then
1535     /// you would get a `fn(u32, i32)`.
1536     /// `unsafety` determines the unsafety of the fn signature. If you pass
1537     /// `hir::Unsafety::Unsafe` in the previous example, then you would get
1538     /// an `unsafe fn (u32, i32)`.
1539     /// It cannot convert a closure that requires unsafe.
1540     pub fn signature_unclosure(
1541         self,
1542         sig: PolyFnSig<'tcx>,
1543         unsafety: hir::Unsafety,
1544     ) -> PolyFnSig<'tcx> {
1545         sig.map_bound(|s| {
1546             let params_iter = match s.inputs()[0].kind() {
1547                 ty::Tuple(params) => params.into_iter(),
1548                 _ => bug!(),
1549             };
1550             self.mk_fn_sig(params_iter, s.output(), s.c_variadic, unsafety, abi::Abi::Rust)
1551         })
1552     }
1553
1554     /// Same a `self.mk_region(kind)`, but avoids accessing the interners if
1555     /// `*r == kind`.
1556     #[inline]
1557     pub fn reuse_or_mk_region(self, r: Region<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> {
1558         if *r == kind { r } else { self.mk_region(kind) }
1559     }
1560
1561     #[allow(rustc::usage_of_ty_tykind)]
1562     #[inline]
1563     pub fn mk_ty(self, st: TyKind<'tcx>) -> Ty<'tcx> {
1564         self.interners.intern_ty(
1565             st,
1566             self.sess,
1567             // This is only used to create a stable hashing context.
1568             &self.untracked,
1569         )
1570     }
1571
1572     #[inline]
1573     pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
1574         self.interners.intern_predicate(
1575             binder,
1576             self.sess,
1577             // This is only used to create a stable hashing context.
1578             &self.untracked,
1579         )
1580     }
1581
1582     #[inline]
1583     pub fn reuse_or_mk_predicate(
1584         self,
1585         pred: Predicate<'tcx>,
1586         binder: Binder<'tcx, PredicateKind<'tcx>>,
1587     ) -> Predicate<'tcx> {
1588         if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
1589     }
1590
1591     pub fn mk_mach_int(self, tm: IntTy) -> Ty<'tcx> {
1592         match tm {
1593             IntTy::Isize => self.types.isize,
1594             IntTy::I8 => self.types.i8,
1595             IntTy::I16 => self.types.i16,
1596             IntTy::I32 => self.types.i32,
1597             IntTy::I64 => self.types.i64,
1598             IntTy::I128 => self.types.i128,
1599         }
1600     }
1601
1602     pub fn mk_mach_uint(self, tm: UintTy) -> Ty<'tcx> {
1603         match tm {
1604             UintTy::Usize => self.types.usize,
1605             UintTy::U8 => self.types.u8,
1606             UintTy::U16 => self.types.u16,
1607             UintTy::U32 => self.types.u32,
1608             UintTy::U64 => self.types.u64,
1609             UintTy::U128 => self.types.u128,
1610         }
1611     }
1612
1613     pub fn mk_mach_float(self, tm: FloatTy) -> Ty<'tcx> {
1614         match tm {
1615             FloatTy::F32 => self.types.f32,
1616             FloatTy::F64 => self.types.f64,
1617         }
1618     }
1619
1620     #[inline]
1621     pub fn mk_static_str(self) -> Ty<'tcx> {
1622         self.mk_imm_ref(self.lifetimes.re_static, self.types.str_)
1623     }
1624
1625     #[inline]
1626     pub fn mk_adt(self, def: AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
1627         // Take a copy of substs so that we own the vectors inside.
1628         self.mk_ty(Adt(def, substs))
1629     }
1630
1631     #[inline]
1632     pub fn mk_foreign(self, def_id: DefId) -> Ty<'tcx> {
1633         self.mk_ty(Foreign(def_id))
1634     }
1635
1636     fn mk_generic_adt(self, wrapper_def_id: DefId, ty_param: Ty<'tcx>) -> Ty<'tcx> {
1637         let adt_def = self.adt_def(wrapper_def_id);
1638         let substs =
1639             InternalSubsts::for_item(self, wrapper_def_id, |param, substs| match param.kind {
1640                 GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => bug!(),
1641                 GenericParamDefKind::Type { has_default, .. } => {
1642                     if param.index == 0 {
1643                         ty_param.into()
1644                     } else {
1645                         assert!(has_default);
1646                         self.bound_type_of(param.def_id).subst(self, substs).into()
1647                     }
1648                 }
1649             });
1650         self.mk_ty(Adt(adt_def, substs))
1651     }
1652
1653     #[inline]
1654     pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> {
1655         let def_id = self.require_lang_item(LangItem::OwnedBox, None);
1656         self.mk_generic_adt(def_id, ty)
1657     }
1658
1659     #[inline]
1660     pub fn mk_lang_item(self, ty: Ty<'tcx>, item: LangItem) -> Option<Ty<'tcx>> {
1661         let def_id = self.lang_items().get(item)?;
1662         Some(self.mk_generic_adt(def_id, ty))
1663     }
1664
1665     #[inline]
1666     pub fn mk_diagnostic_item(self, ty: Ty<'tcx>, name: Symbol) -> Option<Ty<'tcx>> {
1667         let def_id = self.get_diagnostic_item(name)?;
1668         Some(self.mk_generic_adt(def_id, ty))
1669     }
1670
1671     #[inline]
1672     pub fn mk_maybe_uninit(self, ty: Ty<'tcx>) -> Ty<'tcx> {
1673         let def_id = self.require_lang_item(LangItem::MaybeUninit, None);
1674         self.mk_generic_adt(def_id, ty)
1675     }
1676
1677     #[inline]
1678     pub fn mk_ptr(self, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
1679         self.mk_ty(RawPtr(tm))
1680     }
1681
1682     #[inline]
1683     pub fn mk_ref(self, r: Region<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
1684         self.mk_ty(Ref(r, tm.ty, tm.mutbl))
1685     }
1686
1687     #[inline]
1688     pub fn mk_mut_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
1689         self.mk_ref(r, TypeAndMut { ty, mutbl: hir::Mutability::Mut })
1690     }
1691
1692     #[inline]
1693     pub fn mk_imm_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
1694         self.mk_ref(r, TypeAndMut { ty, mutbl: hir::Mutability::Not })
1695     }
1696
1697     #[inline]
1698     pub fn mk_mut_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
1699         self.mk_ptr(TypeAndMut { ty, mutbl: hir::Mutability::Mut })
1700     }
1701
1702     #[inline]
1703     pub fn mk_imm_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
1704         self.mk_ptr(TypeAndMut { ty, mutbl: hir::Mutability::Not })
1705     }
1706
1707     #[inline]
1708     pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
1709         self.mk_ty(Array(ty, ty::Const::from_usize(self, n)))
1710     }
1711
1712     #[inline]
1713     pub fn mk_slice(self, ty: Ty<'tcx>) -> Ty<'tcx> {
1714         self.mk_ty(Slice(ty))
1715     }
1716
1717     #[inline]
1718     pub fn intern_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
1719         self.mk_ty(Tuple(self.intern_type_list(&ts)))
1720     }
1721
1722     pub fn mk_tup<I: InternAs<Ty<'tcx>, Ty<'tcx>>>(self, iter: I) -> I::Output {
1723         iter.intern_with(|ts| self.mk_ty(Tuple(self.intern_type_list(&ts))))
1724     }
1725
1726     #[inline]
1727     pub fn mk_unit(self) -> Ty<'tcx> {
1728         self.types.unit
1729     }
1730
1731     #[inline]
1732     pub fn mk_diverging_default(self) -> Ty<'tcx> {
1733         if self.features().never_type_fallback { self.types.never } else { self.types.unit }
1734     }
1735
1736     #[inline]
1737     pub fn mk_fn_def(
1738         self,
1739         def_id: DefId,
1740         substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
1741     ) -> Ty<'tcx> {
1742         let substs = self.check_substs(def_id, substs);
1743         self.mk_ty(FnDef(def_id, substs))
1744     }
1745
1746     #[inline(always)]
1747     fn check_substs(
1748         self,
1749         _def_id: DefId,
1750         substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
1751     ) -> SubstsRef<'tcx> {
1752         let substs = substs.into_iter().map(Into::into);
1753         #[cfg(debug_assertions)]
1754         {
1755             let n = self.generics_of(_def_id).count();
1756             assert_eq!(
1757                 (n, Some(n)),
1758                 substs.size_hint(),
1759                 "wrong number of generic parameters for {_def_id:?}: {:?}",
1760                 substs.collect::<Vec<_>>(),
1761             );
1762         }
1763         self.mk_substs(substs)
1764     }
1765
1766     #[inline]
1767     pub fn mk_fn_ptr(self, fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
1768         self.mk_ty(FnPtr(fty))
1769     }
1770
1771     #[inline]
1772     pub fn mk_dynamic(
1773         self,
1774         obj: &'tcx List<PolyExistentialPredicate<'tcx>>,
1775         reg: ty::Region<'tcx>,
1776         repr: DynKind,
1777     ) -> Ty<'tcx> {
1778         self.mk_ty(Dynamic(obj, reg, repr))
1779     }
1780
1781     #[inline]
1782     pub fn mk_projection(
1783         self,
1784         item_def_id: DefId,
1785         substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
1786     ) -> Ty<'tcx> {
1787         self.mk_ty(Alias(ty::Projection, self.mk_alias_ty(item_def_id, substs)))
1788     }
1789
1790     #[inline]
1791     pub fn mk_closure(self, closure_id: DefId, closure_substs: SubstsRef<'tcx>) -> Ty<'tcx> {
1792         self.mk_ty(Closure(closure_id, closure_substs))
1793     }
1794
1795     #[inline]
1796     pub fn mk_generator(
1797         self,
1798         id: DefId,
1799         generator_substs: SubstsRef<'tcx>,
1800         movability: hir::Movability,
1801     ) -> Ty<'tcx> {
1802         self.mk_ty(Generator(id, generator_substs, movability))
1803     }
1804
1805     #[inline]
1806     pub fn mk_generator_witness(self, types: ty::Binder<'tcx, &'tcx List<Ty<'tcx>>>) -> Ty<'tcx> {
1807         self.mk_ty(GeneratorWitness(types))
1808     }
1809
1810     /// Creates a `&mut Context<'_>` [`Ty`] with erased lifetimes.
1811     pub fn mk_task_context(self) -> Ty<'tcx> {
1812         let context_did = self.require_lang_item(LangItem::Context, None);
1813         let context_adt_ref = self.adt_def(context_did);
1814         let context_substs = self.intern_substs(&[self.lifetimes.re_erased.into()]);
1815         let context_ty = self.mk_adt(context_adt_ref, context_substs);
1816         self.mk_mut_ref(self.lifetimes.re_erased, context_ty)
1817     }
1818
1819     #[inline]
1820     pub fn mk_generator_witness_mir(self, id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
1821         self.mk_ty(GeneratorWitnessMIR(id, substs))
1822     }
1823
1824     #[inline]
1825     pub fn mk_ty_var(self, v: TyVid) -> Ty<'tcx> {
1826         self.mk_ty_infer(TyVar(v))
1827     }
1828
1829     #[inline]
1830     pub fn mk_const(self, kind: impl Into<ty::ConstKind<'tcx>>, ty: Ty<'tcx>) -> Const<'tcx> {
1831         self.mk_const_internal(ty::ConstData { kind: kind.into(), ty })
1832     }
1833
1834     #[inline]
1835     pub fn mk_int_var(self, v: IntVid) -> Ty<'tcx> {
1836         self.mk_ty_infer(IntVar(v))
1837     }
1838
1839     #[inline]
1840     pub fn mk_float_var(self, v: FloatVid) -> Ty<'tcx> {
1841         self.mk_ty_infer(FloatVar(v))
1842     }
1843
1844     #[inline]
1845     pub fn mk_ty_infer(self, it: InferTy) -> Ty<'tcx> {
1846         self.mk_ty(Infer(it))
1847     }
1848
1849     #[inline]
1850     pub fn mk_ty_param(self, index: u32, name: Symbol) -> Ty<'tcx> {
1851         self.mk_ty(Param(ParamTy { index, name }))
1852     }
1853
1854     pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
1855         match param.kind {
1856             GenericParamDefKind::Lifetime => {
1857                 self.mk_region(ty::ReEarlyBound(param.to_early_bound_region_data())).into()
1858             }
1859             GenericParamDefKind::Type { .. } => self.mk_ty_param(param.index, param.name).into(),
1860             GenericParamDefKind::Const { .. } => self
1861                 .mk_const(
1862                     ParamConst { index: param.index, name: param.name },
1863                     self.type_of(param.def_id),
1864                 )
1865                 .into(),
1866         }
1867     }
1868
1869     #[inline]
1870     pub fn mk_opaque(self, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
1871         self.mk_ty(Alias(ty::Opaque, self.mk_alias_ty(def_id, substs)))
1872     }
1873
1874     pub fn mk_place_field(self, place: Place<'tcx>, f: Field, ty: Ty<'tcx>) -> Place<'tcx> {
1875         self.mk_place_elem(place, PlaceElem::Field(f, ty))
1876     }
1877
1878     pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
1879         self.mk_place_elem(place, PlaceElem::Deref)
1880     }
1881
1882     pub fn mk_place_downcast(
1883         self,
1884         place: Place<'tcx>,
1885         adt_def: AdtDef<'tcx>,
1886         variant_index: VariantIdx,
1887     ) -> Place<'tcx> {
1888         self.mk_place_elem(
1889             place,
1890             PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
1891         )
1892     }
1893
1894     pub fn mk_place_downcast_unnamed(
1895         self,
1896         place: Place<'tcx>,
1897         variant_index: VariantIdx,
1898     ) -> Place<'tcx> {
1899         self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
1900     }
1901
1902     pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
1903         self.mk_place_elem(place, PlaceElem::Index(index))
1904     }
1905
1906     /// This method copies `Place`'s projection, add an element and reintern it. Should not be used
1907     /// to build a full `Place` it's just a convenient way to grab a projection and modify it in
1908     /// flight.
1909     pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
1910         let mut projection = place.projection.to_vec();
1911         projection.push(elem);
1912
1913         Place { local: place.local, projection: self.intern_place_elems(&projection) }
1914     }
1915
1916     pub fn intern_poly_existential_predicates(
1917         self,
1918         eps: &[PolyExistentialPredicate<'tcx>],
1919     ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
1920         assert!(!eps.is_empty());
1921         assert!(
1922             eps.array_windows()
1923                 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
1924                     != Ordering::Greater)
1925         );
1926         self._intern_poly_existential_predicates(eps)
1927     }
1928
1929     pub fn intern_predicates(self, preds: &[Predicate<'tcx>]) -> &'tcx List<Predicate<'tcx>> {
1930         // FIXME consider asking the input slice to be sorted to avoid
1931         // re-interning permutations, in which case that would be asserted
1932         // here.
1933         if preds.is_empty() {
1934             // The macro-generated method below asserts we don't intern an empty slice.
1935             List::empty()
1936         } else {
1937             self._intern_predicates(preds)
1938         }
1939     }
1940
1941     pub fn mk_const_list<I: InternAs<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>>(
1942         self,
1943         iter: I,
1944     ) -> I::Output {
1945         iter.intern_with(|xs| self.intern_const_list(xs))
1946     }
1947
1948     pub fn intern_const_list(self, cs: &[ty::Const<'tcx>]) -> &'tcx List<ty::Const<'tcx>> {
1949         if cs.is_empty() { List::empty() } else { self._intern_const_list(cs) }
1950     }
1951
1952     pub fn intern_type_list(self, ts: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> {
1953         if ts.is_empty() {
1954             List::empty()
1955         } else {
1956             // Actually intern type lists as lists of `GenericArg`s.
1957             //
1958             // Transmuting from `Ty<'tcx>` to `GenericArg<'tcx>` is sound
1959             // as explained in ty_slice_as_generic_arg`. With this,
1960             // we guarantee that even when transmuting between `List<Ty<'tcx>>`
1961             // and `List<GenericArg<'tcx>>`, the uniqueness requirement for
1962             // lists is upheld.
1963             let substs = self._intern_substs(ty::subst::ty_slice_as_generic_args(ts));
1964             substs.try_as_type_list().unwrap()
1965         }
1966     }
1967
1968     pub fn intern_substs(self, ts: &[GenericArg<'tcx>]) -> &'tcx List<GenericArg<'tcx>> {
1969         if ts.is_empty() { List::empty() } else { self._intern_substs(ts) }
1970     }
1971
1972     pub fn intern_projs(self, ps: &[ProjectionKind]) -> &'tcx List<ProjectionKind> {
1973         if ps.is_empty() { List::empty() } else { self._intern_projs(ps) }
1974     }
1975
1976     pub fn intern_place_elems(self, ts: &[PlaceElem<'tcx>]) -> &'tcx List<PlaceElem<'tcx>> {
1977         if ts.is_empty() { List::empty() } else { self._intern_place_elems(ts) }
1978     }
1979
1980     pub fn intern_canonical_var_infos(
1981         self,
1982         ts: &[CanonicalVarInfo<'tcx>],
1983     ) -> CanonicalVarInfos<'tcx> {
1984         if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) }
1985     }
1986
1987     pub fn intern_bound_variable_kinds(
1988         self,
1989         ts: &[ty::BoundVariableKind],
1990     ) -> &'tcx List<ty::BoundVariableKind> {
1991         if ts.is_empty() { List::empty() } else { self._intern_bound_variable_kinds(ts) }
1992     }
1993
1994     pub fn mk_fn_sig<I>(
1995         self,
1996         inputs: I,
1997         output: I::Item,
1998         c_variadic: bool,
1999         unsafety: hir::Unsafety,
2000         abi: abi::Abi,
2001     ) -> <I::Item as InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>>::Output
2002     where
2003         I: Iterator<Item: InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>>,
2004     {
2005         inputs.chain(iter::once(output)).intern_with(|xs| ty::FnSig {
2006             inputs_and_output: self.intern_type_list(xs),
2007             c_variadic,
2008             unsafety,
2009             abi,
2010         })
2011     }
2012
2013     pub fn mk_poly_existential_predicates<
2014         I: InternAs<PolyExistentialPredicate<'tcx>, &'tcx List<PolyExistentialPredicate<'tcx>>>,
2015     >(
2016         self,
2017         iter: I,
2018     ) -> I::Output {
2019         iter.intern_with(|xs| self.intern_poly_existential_predicates(xs))
2020     }
2021
2022     pub fn mk_predicates<I: InternAs<Predicate<'tcx>, &'tcx List<Predicate<'tcx>>>>(
2023         self,
2024         iter: I,
2025     ) -> I::Output {
2026         iter.intern_with(|xs| self.intern_predicates(xs))
2027     }
2028
2029     pub fn mk_type_list<I: InternAs<Ty<'tcx>, &'tcx List<Ty<'tcx>>>>(self, iter: I) -> I::Output {
2030         iter.intern_with(|xs| self.intern_type_list(xs))
2031     }
2032
2033     pub fn mk_substs<I: InternAs<GenericArg<'tcx>, &'tcx List<GenericArg<'tcx>>>>(
2034         self,
2035         iter: I,
2036     ) -> I::Output {
2037         iter.intern_with(|xs| self.intern_substs(xs))
2038     }
2039
2040     pub fn mk_place_elems<I: InternAs<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>>(
2041         self,
2042         iter: I,
2043     ) -> I::Output {
2044         iter.intern_with(|xs| self.intern_place_elems(xs))
2045     }
2046
2047     pub fn mk_substs_trait(
2048         self,
2049         self_ty: Ty<'tcx>,
2050         rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2051     ) -> SubstsRef<'tcx> {
2052         self.mk_substs(iter::once(self_ty.into()).chain(rest))
2053     }
2054
2055     pub fn mk_trait_ref(
2056         self,
2057         trait_def_id: DefId,
2058         substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
2059     ) -> ty::TraitRef<'tcx> {
2060         let substs = self.check_substs(trait_def_id, substs);
2061         ty::TraitRef { def_id: trait_def_id, substs, _use_mk_trait_ref_instead: () }
2062     }
2063
2064     pub fn mk_alias_ty(
2065         self,
2066         def_id: DefId,
2067         substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
2068     ) -> ty::AliasTy<'tcx> {
2069         let substs = self.check_substs(def_id, substs);
2070         ty::AliasTy { def_id, substs, _use_mk_alias_ty_instead: () }
2071     }
2072
2073     pub fn mk_bound_variable_kinds<
2074         I: InternAs<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
2075     >(
2076         self,
2077         iter: I,
2078     ) -> I::Output {
2079         iter.intern_with(|xs| self.intern_bound_variable_kinds(xs))
2080     }
2081
2082     /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`,
2083     /// typically generated by `#[derive(LintDiagnostic)]`).
2084     pub fn emit_spanned_lint(
2085         self,
2086         lint: &'static Lint,
2087         hir_id: HirId,
2088         span: impl Into<MultiSpan>,
2089         decorator: impl for<'a> DecorateLint<'a, ()>,
2090     ) {
2091         let msg = decorator.msg();
2092         let (level, src) = self.lint_level_at_node(lint, hir_id);
2093         struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, |diag| {
2094             decorator.decorate_lint(diag)
2095         })
2096     }
2097
2098     /// Emit a lint at the appropriate level for a hir node, with an associated span.
2099     ///
2100     /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
2101     ///
2102     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
2103     #[rustc_lint_diagnostics]
2104     pub fn struct_span_lint_hir(
2105         self,
2106         lint: &'static Lint,
2107         hir_id: HirId,
2108         span: impl Into<MultiSpan>,
2109         msg: impl Into<DiagnosticMessage>,
2110         decorate: impl for<'a, 'b> FnOnce(
2111             &'b mut DiagnosticBuilder<'a, ()>,
2112         ) -> &'b mut DiagnosticBuilder<'a, ()>,
2113     ) {
2114         let (level, src) = self.lint_level_at_node(lint, hir_id);
2115         struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, decorate);
2116     }
2117
2118     /// Emit a lint from a lint struct (some type that implements `DecorateLint`, typically
2119     /// generated by `#[derive(LintDiagnostic)]`).
2120     pub fn emit_lint(
2121         self,
2122         lint: &'static Lint,
2123         id: HirId,
2124         decorator: impl for<'a> DecorateLint<'a, ()>,
2125     ) {
2126         self.struct_lint_node(lint, id, decorator.msg(), |diag| decorator.decorate_lint(diag))
2127     }
2128
2129     /// Emit a lint at the appropriate level for a hir node.
2130     ///
2131     /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
2132     ///
2133     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
2134     #[rustc_lint_diagnostics]
2135     pub fn struct_lint_node(
2136         self,
2137         lint: &'static Lint,
2138         id: HirId,
2139         msg: impl Into<DiagnosticMessage>,
2140         decorate: impl for<'a, 'b> FnOnce(
2141             &'b mut DiagnosticBuilder<'a, ()>,
2142         ) -> &'b mut DiagnosticBuilder<'a, ()>,
2143     ) {
2144         let (level, src) = self.lint_level_at_node(lint, id);
2145         struct_lint_level(self.sess, lint, level, src, None, msg, decorate);
2146     }
2147
2148     pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
2149         let map = self.in_scope_traits_map(id.owner)?;
2150         let candidates = map.get(&id.local_id)?;
2151         Some(&*candidates)
2152     }
2153
2154     pub fn named_region(self, id: HirId) -> Option<resolve_lifetime::Region> {
2155         debug!(?id, "named_region");
2156         self.named_region_map(id.owner).and_then(|map| map.get(&id.local_id).cloned())
2157     }
2158
2159     pub fn is_late_bound(self, id: HirId) -> bool {
2160         self.is_late_bound_map(id.owner.def_id).map_or(false, |set| {
2161             let def_id = self.hir().local_def_id(id);
2162             set.contains(&def_id)
2163         })
2164     }
2165
2166     pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
2167         self.mk_bound_variable_kinds(
2168             self.late_bound_vars_map(id.owner)
2169                 .and_then(|map| map.get(&id.local_id).cloned())
2170                 .unwrap_or_else(|| {
2171                     bug!("No bound vars found for {:?} ({:?})", self.hir().node_to_string(id), id)
2172                 })
2173                 .iter(),
2174         )
2175     }
2176
2177     /// Whether the `def_id` counts as const fn in the current crate, considering all active
2178     /// feature gates
2179     pub fn is_const_fn(self, def_id: DefId) -> bool {
2180         if self.is_const_fn_raw(def_id) {
2181             match self.lookup_const_stability(def_id) {
2182                 Some(stability) if stability.is_const_unstable() => {
2183                     // has a `rustc_const_unstable` attribute, check whether the user enabled the
2184                     // corresponding feature gate.
2185                     self.features()
2186                         .declared_lib_features
2187                         .iter()
2188                         .any(|&(sym, _)| sym == stability.feature)
2189                 }
2190                 // functions without const stability are either stable user written
2191                 // const fn or the user is using feature gates and we thus don't
2192                 // care what they do
2193                 _ => true,
2194             }
2195         } else {
2196             false
2197         }
2198     }
2199
2200     /// Whether the trait impl is marked const. This does not consider stability or feature gates.
2201     pub fn is_const_trait_impl_raw(self, def_id: DefId) -> bool {
2202         let Some(local_def_id) = def_id.as_local() else { return false };
2203         let hir_id = self.local_def_id_to_hir_id(local_def_id);
2204         let node = self.hir().get(hir_id);
2205
2206         matches!(
2207             node,
2208             hir::Node::Item(hir::Item {
2209                 kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }),
2210                 ..
2211             })
2212         )
2213     }
2214 }
2215
2216 impl<'tcx> TyCtxtAt<'tcx> {
2217     /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used.
2218     #[track_caller]
2219     pub fn ty_error(self) -> Ty<'tcx> {
2220         self.tcx.ty_error_with_message(self.span, "TyKind::Error constructed but no error reported")
2221     }
2222
2223     /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg to
2224     /// ensure it gets used.
2225     #[track_caller]
2226     pub fn ty_error_with_message(self, msg: &str) -> Ty<'tcx> {
2227         self.tcx.ty_error_with_message(self.span, msg)
2228     }
2229
2230     pub fn mk_trait_ref(
2231         self,
2232         trait_lang_item: LangItem,
2233         substs: impl IntoIterator<Item = impl Into<ty::GenericArg<'tcx>>>,
2234     ) -> ty::TraitRef<'tcx> {
2235         let trait_def_id = self.require_lang_item(trait_lang_item, Some(self.span));
2236         self.tcx.mk_trait_ref(trait_def_id, substs)
2237     }
2238 }
2239
2240 /// Parameter attributes that can only be determined by examining the body of a function instead
2241 /// of just its signature.
2242 ///
2243 /// These can be useful for optimization purposes when a function is directly called. We compute
2244 /// them and store them into the crate metadata so that downstream crates can make use of them.
2245 ///
2246 /// Right now, we only have `read_only`, but `no_capture` and `no_alias` might be useful in the
2247 /// future.
2248 #[derive(Clone, Copy, PartialEq, Debug, Default, TyDecodable, TyEncodable, HashStable)]
2249 pub struct DeducedParamAttrs {
2250     /// The parameter is marked immutable in the function and contains no `UnsafeCell` (i.e. its
2251     /// type is freeze).
2252     pub read_only: bool,
2253 }
2254
2255 pub fn provide(providers: &mut ty::query::Providers) {
2256     providers.module_reexports =
2257         |tcx, id| tcx.resolutions(()).reexport_map.get(&id).map(|v| &v[..]);
2258     providers.maybe_unused_trait_imports =
2259         |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
2260     providers.maybe_unused_extern_crates =
2261         |tcx, ()| &tcx.resolutions(()).maybe_unused_extern_crates[..];
2262     providers.names_imported_by_glob_use = |tcx, id| {
2263         tcx.arena.alloc(tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default())
2264     };
2265
2266     providers.extern_mod_stmt_cnum =
2267         |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
2268     providers.is_panic_runtime = |tcx, cnum| {
2269         assert_eq!(cnum, LOCAL_CRATE);
2270         tcx.sess.contains_name(tcx.hir().krate_attrs(), sym::panic_runtime)
2271     };
2272     providers.is_compiler_builtins = |tcx, cnum| {
2273         assert_eq!(cnum, LOCAL_CRATE);
2274         tcx.sess.contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins)
2275     };
2276     providers.has_panic_handler = |tcx, cnum| {
2277         assert_eq!(cnum, LOCAL_CRATE);
2278         // We want to check if the panic handler was defined in this crate
2279         tcx.lang_items().panic_impl().map_or(false, |did| did.is_local())
2280     };
2281     providers.source_span =
2282         |tcx, def_id| tcx.untracked.source_span.get(def_id).copied().unwrap_or(DUMMY_SP);
2283 }