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