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