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