]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/ty/context.rs
Feed the `features_query` instead of grabbing it from the session lazily
[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     pub fn return_type_impl_trait(self, scope_def_id: LocalDefId) -> Option<(Ty<'tcx>, Span)> {
1001         // `type_of()` will fail on these (#55796, #86483), so only allow `fn`s or closures.
1002         match self.hir().get_by_def_id(scope_def_id) {
1003             Node::Item(&hir::Item { kind: ItemKind::Fn(..), .. }) => {}
1004             Node::TraitItem(&hir::TraitItem { kind: TraitItemKind::Fn(..), .. }) => {}
1005             Node::ImplItem(&hir::ImplItem { kind: ImplItemKind::Fn(..), .. }) => {}
1006             Node::Expr(&hir::Expr { kind: ExprKind::Closure { .. }, .. }) => {}
1007             _ => return None,
1008         }
1009
1010         let ret_ty = self.type_of(scope_def_id);
1011         match ret_ty.kind() {
1012             ty::FnDef(_, _) => {
1013                 let sig = ret_ty.fn_sig(self);
1014                 let output = self.erase_late_bound_regions(sig.output());
1015                 if output.is_impl_trait() {
1016                     let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
1017                     let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap();
1018                     Some((output, fn_decl.output.span()))
1019                 } else {
1020                     None
1021                 }
1022             }
1023             _ => None,
1024         }
1025     }
1026
1027     /// Checks if the bound region is in Impl Item.
1028     pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
1029         let container_id = self.parent(suitable_region_binding_scope.to_def_id());
1030         if self.impl_trait_ref(container_id).is_some() {
1031             // For now, we do not try to target impls of traits. This is
1032             // because this message is going to suggest that the user
1033             // change the fn signature, but they may not be free to do so,
1034             // since the signature must match the trait.
1035             //
1036             // FIXME(#42706) -- in some cases, we could do better here.
1037             return true;
1038         }
1039         false
1040     }
1041
1042     /// Determines whether identifiers in the assembly have strict naming rules.
1043     /// Currently, only NVPTX* targets need it.
1044     pub fn has_strict_asm_symbol_naming(self) -> bool {
1045         self.sess.target.arch.contains("nvptx")
1046     }
1047
1048     /// Returns `&'static core::panic::Location<'static>`.
1049     pub fn caller_location_ty(self) -> Ty<'tcx> {
1050         self.mk_imm_ref(
1051             self.lifetimes.re_static,
1052             self.bound_type_of(self.require_lang_item(LangItem::PanicLocation, None))
1053                 .subst(self, self.mk_substs([self.lifetimes.re_static.into()].iter())),
1054         )
1055     }
1056
1057     /// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`).
1058     pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
1059         match self.def_kind(def_id) {
1060             DefKind::Generator => match self.generator_kind(def_id).unwrap() {
1061                 rustc_hir::GeneratorKind::Async(..) => ("an", "async closure"),
1062                 rustc_hir::GeneratorKind::Gen => ("a", "generator"),
1063             },
1064             def_kind => (def_kind.article(), def_kind.descr(def_id)),
1065         }
1066     }
1067
1068     pub fn type_length_limit(self) -> Limit {
1069         self.limits(()).type_length_limit
1070     }
1071
1072     pub fn recursion_limit(self) -> Limit {
1073         self.limits(()).recursion_limit
1074     }
1075
1076     pub fn move_size_limit(self) -> Limit {
1077         self.limits(()).move_size_limit
1078     }
1079
1080     pub fn const_eval_limit(self) -> Limit {
1081         self.limits(()).const_eval_limit
1082     }
1083
1084     pub fn all_traits(self) -> impl Iterator<Item = DefId> + 'tcx {
1085         iter::once(LOCAL_CRATE)
1086             .chain(self.crates(()).iter().copied())
1087             .flat_map(move |cnum| self.traits_in_crate(cnum).iter().copied())
1088     }
1089
1090     #[inline]
1091     pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
1092         self.visibility(def_id).expect_local()
1093     }
1094 }
1095
1096 /// A trait implemented for all `X<'a>` types that can be safely and
1097 /// efficiently converted to `X<'tcx>` as long as they are part of the
1098 /// provided `TyCtxt<'tcx>`.
1099 /// This can be done, for example, for `Ty<'tcx>` or `SubstsRef<'tcx>`
1100 /// by looking them up in their respective interners.
1101 ///
1102 /// However, this is still not the best implementation as it does
1103 /// need to compare the components, even for interned values.
1104 /// It would be more efficient if `TypedArena` provided a way to
1105 /// determine whether the address is in the allocated range.
1106 ///
1107 /// `None` is returned if the value or one of the components is not part
1108 /// of the provided context.
1109 /// For `Ty`, `None` can be returned if either the type interner doesn't
1110 /// contain the `TyKind` key or if the address of the interned
1111 /// pointer differs. The latter case is possible if a primitive type,
1112 /// e.g., `()` or `u8`, was interned in a different context.
1113 pub trait Lift<'tcx>: fmt::Debug {
1114     type Lifted: fmt::Debug + 'tcx;
1115     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted>;
1116 }
1117
1118 macro_rules! nop_lift {
1119     ($set:ident; $ty:ty => $lifted:ty) => {
1120         impl<'a, 'tcx> Lift<'tcx> for $ty {
1121             type Lifted = $lifted;
1122             fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1123                 if tcx.interners.$set.contains_pointer_to(&InternedInSet(&*self.0.0)) {
1124                     // SAFETY: `self` is interned and therefore valid
1125                     // for the entire lifetime of the `TyCtxt`.
1126                     Some(unsafe { mem::transmute(self) })
1127                 } else {
1128                     None
1129                 }
1130             }
1131         }
1132     };
1133 }
1134
1135 // Can't use the macros as we have reuse the `substs` here.
1136 //
1137 // See `intern_type_list` for more info.
1138 impl<'a, 'tcx> Lift<'tcx> for &'a List<Ty<'a>> {
1139     type Lifted = &'tcx List<Ty<'tcx>>;
1140     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1141         if self.is_empty() {
1142             return Some(List::empty());
1143         }
1144         if tcx.interners.substs.contains_pointer_to(&InternedInSet(self.as_substs())) {
1145             // SAFETY: `self` is interned and therefore valid
1146             // for the entire lifetime of the `TyCtxt`.
1147             Some(unsafe { mem::transmute::<&'a List<Ty<'a>>, &'tcx List<Ty<'tcx>>>(self) })
1148         } else {
1149             None
1150         }
1151     }
1152 }
1153
1154 macro_rules! nop_list_lift {
1155     ($set:ident; $ty:ty => $lifted:ty) => {
1156         impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> {
1157             type Lifted = &'tcx List<$lifted>;
1158             fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1159                 if self.is_empty() {
1160                     return Some(List::empty());
1161                 }
1162                 if tcx.interners.$set.contains_pointer_to(&InternedInSet(self)) {
1163                     Some(unsafe { mem::transmute(self) })
1164                 } else {
1165                     None
1166                 }
1167             }
1168         }
1169     };
1170 }
1171
1172 nop_lift! {type_; Ty<'a> => Ty<'tcx>}
1173 nop_lift! {region; Region<'a> => Region<'tcx>}
1174 nop_lift! {const_; Const<'a> => Const<'tcx>}
1175 nop_lift! {const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx>}
1176 nop_lift! {predicate; Predicate<'a> => Predicate<'tcx>}
1177
1178 nop_list_lift! {poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>}
1179 nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>}
1180 nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>}
1181 nop_list_lift! {projs; ProjectionKind => ProjectionKind}
1182 nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind}
1183
1184 // This is the impl for `&'a InternalSubsts<'a>`.
1185 nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}
1186
1187 CloneLiftImpls! { for<'tcx> {
1188     Constness, traits::WellFormedLoc, ImplPolarity, crate::mir::ReturnConstraint,
1189 } }
1190
1191 pub mod tls {
1192     use super::{ptr_eq, GlobalCtxt, TyCtxt};
1193
1194     use crate::dep_graph::TaskDepsRef;
1195     use crate::ty::query;
1196     use rustc_data_structures::sync::{self, Lock};
1197     use rustc_errors::Diagnostic;
1198     use std::mem;
1199     use thin_vec::ThinVec;
1200
1201     #[cfg(not(parallel_compiler))]
1202     use std::cell::Cell;
1203
1204     #[cfg(parallel_compiler)]
1205     use rustc_rayon_core as rayon_core;
1206
1207     /// This is the implicit state of rustc. It contains the current
1208     /// `TyCtxt` and query. It is updated when creating a local interner or
1209     /// executing a new query. Whenever there's a `TyCtxt` value available
1210     /// you should also have access to an `ImplicitCtxt` through the functions
1211     /// in this module.
1212     #[derive(Clone)]
1213     pub struct ImplicitCtxt<'a, 'tcx> {
1214         /// The current `TyCtxt`.
1215         pub tcx: TyCtxt<'tcx>,
1216
1217         /// The current query job, if any. This is updated by `JobOwner::start` in
1218         /// `ty::query::plumbing` when executing a query.
1219         pub query: Option<query::QueryJobId>,
1220
1221         /// Where to store diagnostics for the current query job, if any.
1222         /// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query.
1223         pub diagnostics: Option<&'a Lock<ThinVec<Diagnostic>>>,
1224
1225         /// Used to prevent queries from calling too deeply.
1226         pub query_depth: usize,
1227
1228         /// The current dep graph task. This is used to add dependencies to queries
1229         /// when executing them.
1230         pub task_deps: TaskDepsRef<'a>,
1231     }
1232
1233     impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> {
1234         pub fn new(gcx: &'tcx GlobalCtxt<'tcx>) -> Self {
1235             let tcx = TyCtxt { gcx };
1236             ImplicitCtxt {
1237                 tcx,
1238                 query: None,
1239                 diagnostics: None,
1240                 query_depth: 0,
1241                 task_deps: TaskDepsRef::Ignore,
1242             }
1243         }
1244     }
1245
1246     /// Sets Rayon's thread-local variable, which is preserved for Rayon jobs
1247     /// to `value` during the call to `f`. It is restored to its previous value after.
1248     /// This is used to set the pointer to the new `ImplicitCtxt`.
1249     #[cfg(parallel_compiler)]
1250     #[inline]
1251     fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
1252         rayon_core::tlv::with(value, f)
1253     }
1254
1255     /// Gets Rayon's thread-local variable, which is preserved for Rayon jobs.
1256     /// This is used to get the pointer to the current `ImplicitCtxt`.
1257     #[cfg(parallel_compiler)]
1258     #[inline]
1259     pub fn get_tlv() -> usize {
1260         rayon_core::tlv::get()
1261     }
1262
1263     #[cfg(not(parallel_compiler))]
1264     thread_local! {
1265         /// A thread local variable that stores a pointer to the current `ImplicitCtxt`.
1266         static TLV: Cell<usize> = const { Cell::new(0) };
1267     }
1268
1269     /// Sets TLV to `value` during the call to `f`.
1270     /// It is restored to its previous value after.
1271     /// This is used to set the pointer to the new `ImplicitCtxt`.
1272     #[cfg(not(parallel_compiler))]
1273     #[inline]
1274     fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
1275         let old = get_tlv();
1276         let _reset = rustc_data_structures::OnDrop(move || TLV.with(|tlv| tlv.set(old)));
1277         TLV.with(|tlv| tlv.set(value));
1278         f()
1279     }
1280
1281     /// Gets the pointer to the current `ImplicitCtxt`.
1282     #[cfg(not(parallel_compiler))]
1283     #[inline]
1284     fn get_tlv() -> usize {
1285         TLV.with(|tlv| tlv.get())
1286     }
1287
1288     /// Sets `context` as the new current `ImplicitCtxt` for the duration of the function `f`.
1289     #[inline]
1290     pub fn enter_context<'a, 'tcx, F, R>(context: &ImplicitCtxt<'a, 'tcx>, f: F) -> R
1291     where
1292         F: FnOnce(&ImplicitCtxt<'a, 'tcx>) -> R,
1293     {
1294         set_tlv(context as *const _ as usize, || f(&context))
1295     }
1296
1297     /// Allows access to the current `ImplicitCtxt` in a closure if one is available.
1298     #[inline]
1299     pub fn with_context_opt<F, R>(f: F) -> R
1300     where
1301         F: for<'a, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'tcx>>) -> R,
1302     {
1303         let context = get_tlv();
1304         if context == 0 {
1305             f(None)
1306         } else {
1307             // We could get an `ImplicitCtxt` pointer from another thread.
1308             // Ensure that `ImplicitCtxt` is `Sync`.
1309             sync::assert_sync::<ImplicitCtxt<'_, '_>>();
1310
1311             unsafe { f(Some(&*(context as *const ImplicitCtxt<'_, '_>))) }
1312         }
1313     }
1314
1315     /// Allows access to the current `ImplicitCtxt`.
1316     /// Panics if there is no `ImplicitCtxt` available.
1317     #[inline]
1318     pub fn with_context<F, R>(f: F) -> R
1319     where
1320         F: for<'a, 'tcx> FnOnce(&ImplicitCtxt<'a, 'tcx>) -> R,
1321     {
1322         with_context_opt(|opt_context| f(opt_context.expect("no ImplicitCtxt stored in tls")))
1323     }
1324
1325     /// Allows access to the current `ImplicitCtxt` whose tcx field is the same as the tcx argument
1326     /// passed in. This means the closure is given an `ImplicitCtxt` with the same `'tcx` lifetime
1327     /// as the `TyCtxt` passed in.
1328     /// This will panic if you pass it a `TyCtxt` which is different from the current
1329     /// `ImplicitCtxt`'s `tcx` field.
1330     #[inline]
1331     pub fn with_related_context<'tcx, F, R>(tcx: TyCtxt<'tcx>, f: F) -> R
1332     where
1333         F: FnOnce(&ImplicitCtxt<'_, 'tcx>) -> R,
1334     {
1335         with_context(|context| unsafe {
1336             assert!(ptr_eq(context.tcx.gcx, tcx.gcx));
1337             let context: &ImplicitCtxt<'_, '_> = mem::transmute(context);
1338             f(context)
1339         })
1340     }
1341
1342     /// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
1343     /// Panics if there is no `ImplicitCtxt` available.
1344     #[inline]
1345     pub fn with<F, R>(f: F) -> R
1346     where
1347         F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> R,
1348     {
1349         with_context(|context| f(context.tcx))
1350     }
1351
1352     /// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
1353     /// The closure is passed None if there is no `ImplicitCtxt` available.
1354     #[inline]
1355     pub fn with_opt<F, R>(f: F) -> R
1356     where
1357         F: for<'tcx> FnOnce(Option<TyCtxt<'tcx>>) -> R,
1358     {
1359         with_context_opt(|opt_context| f(opt_context.map(|context| context.tcx)))
1360     }
1361 }
1362
1363 macro_rules! sty_debug_print {
1364     ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
1365         // Curious inner module to allow variant names to be used as
1366         // variable names.
1367         #[allow(non_snake_case)]
1368         mod inner {
1369             use crate::ty::{self, TyCtxt};
1370             use crate::ty::context::InternedInSet;
1371
1372             #[derive(Copy, Clone)]
1373             struct DebugStat {
1374                 total: usize,
1375                 lt_infer: usize,
1376                 ty_infer: usize,
1377                 ct_infer: usize,
1378                 all_infer: usize,
1379             }
1380
1381             pub fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1382                 let mut total = DebugStat {
1383                     total: 0,
1384                     lt_infer: 0,
1385                     ty_infer: 0,
1386                     ct_infer: 0,
1387                     all_infer: 0,
1388                 };
1389                 $(let mut $variant = total;)*
1390
1391                 let shards = tcx.interners.type_.lock_shards();
1392                 let types = shards.iter().flat_map(|shard| shard.keys());
1393                 for &InternedInSet(t) in types {
1394                     let variant = match t.internee {
1395                         ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1396                             ty::Float(..) | ty::Str | ty::Never => continue,
1397                         ty::Error(_) => /* unimportant */ continue,
1398                         $(ty::$variant(..) => &mut $variant,)*
1399                     };
1400                     let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1401                     let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1402                     let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1403
1404                     variant.total += 1;
1405                     total.total += 1;
1406                     if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1407                     if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1408                     if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1409                     if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1410                 }
1411                 writeln!(fmt, "Ty interner             total           ty lt ct all")?;
1412                 $(writeln!(fmt, "    {:18}: {uses:6} {usespc:4.1}%, \
1413                             {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1414                     stringify!($variant),
1415                     uses = $variant.total,
1416                     usespc = $variant.total as f64 * 100.0 / total.total as f64,
1417                     ty = $variant.ty_infer as f64 * 100.0  / total.total as f64,
1418                     lt = $variant.lt_infer as f64 * 100.0  / total.total as f64,
1419                     ct = $variant.ct_infer as f64 * 100.0  / total.total as f64,
1420                     all = $variant.all_infer as f64 * 100.0  / total.total as f64)?;
1421                 )*
1422                 writeln!(fmt, "                  total {uses:6}        \
1423                           {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1424                     uses = total.total,
1425                     ty = total.ty_infer as f64 * 100.0  / total.total as f64,
1426                     lt = total.lt_infer as f64 * 100.0  / total.total as f64,
1427                     ct = total.ct_infer as f64 * 100.0  / total.total as f64,
1428                     all = total.all_infer as f64 * 100.0  / total.total as f64)
1429             }
1430         }
1431
1432         inner::go($fmt, $ctxt)
1433     }}
1434 }
1435
1436 impl<'tcx> TyCtxt<'tcx> {
1437     pub fn debug_stats(self) -> impl std::fmt::Debug + 'tcx {
1438         struct DebugStats<'tcx>(TyCtxt<'tcx>);
1439
1440         impl<'tcx> std::fmt::Debug for DebugStats<'tcx> {
1441             fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1442                 sty_debug_print!(
1443                     fmt,
1444                     self.0,
1445                     Adt,
1446                     Array,
1447                     Slice,
1448                     RawPtr,
1449                     Ref,
1450                     FnDef,
1451                     FnPtr,
1452                     Placeholder,
1453                     Generator,
1454                     GeneratorWitness,
1455                     Dynamic,
1456                     Closure,
1457                     Tuple,
1458                     Bound,
1459                     Param,
1460                     Infer,
1461                     Alias,
1462                     Foreign
1463                 )?;
1464
1465                 writeln!(fmt, "InternalSubsts interner: #{}", self.0.interners.substs.len())?;
1466                 writeln!(fmt, "Region interner: #{}", self.0.interners.region.len())?;
1467                 writeln!(
1468                     fmt,
1469                     "Const Allocation interner: #{}",
1470                     self.0.interners.const_allocation.len()
1471                 )?;
1472                 writeln!(fmt, "Layout interner: #{}", self.0.interners.layout.len())?;
1473
1474                 Ok(())
1475             }
1476         }
1477
1478         DebugStats(self)
1479     }
1480 }
1481
1482 // This type holds a `T` in the interner. The `T` is stored in the arena and
1483 // this type just holds a pointer to it, but it still effectively owns it. It
1484 // impls `Borrow` so that it can be looked up using the original
1485 // (non-arena-memory-owning) types.
1486 struct InternedInSet<'tcx, T: ?Sized>(&'tcx T);
1487
1488 impl<'tcx, T: 'tcx + ?Sized> Clone for InternedInSet<'tcx, T> {
1489     fn clone(&self) -> Self {
1490         InternedInSet(self.0)
1491     }
1492 }
1493
1494 impl<'tcx, T: 'tcx + ?Sized> Copy for InternedInSet<'tcx, T> {}
1495
1496 impl<'tcx, T: 'tcx + ?Sized> IntoPointer for InternedInSet<'tcx, T> {
1497     fn into_pointer(&self) -> *const () {
1498         self.0 as *const _ as *const ()
1499     }
1500 }
1501
1502 #[allow(rustc::usage_of_ty_tykind)]
1503 impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1504     fn borrow(&self) -> &T {
1505         &self.0.internee
1506     }
1507 }
1508
1509 impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1510     fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1511         // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1512         // `x == y`.
1513         self.0.internee == other.0.internee
1514     }
1515 }
1516
1517 impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1518
1519 impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1520     fn hash<H: Hasher>(&self, s: &mut H) {
1521         // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
1522         self.0.internee.hash(s)
1523     }
1524 }
1525
1526 impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1527     fn borrow(&self) -> &[T] {
1528         &self.0[..]
1529     }
1530 }
1531
1532 impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
1533     fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
1534         // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1535         // `x == y`.
1536         self.0[..] == other.0[..]
1537     }
1538 }
1539
1540 impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
1541
1542 impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
1543     fn hash<H: Hasher>(&self, s: &mut H) {
1544         // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
1545         self.0[..].hash(s)
1546     }
1547 }
1548
1549 macro_rules! direct_interners {
1550     ($($name:ident: $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
1551         $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
1552             fn borrow<'a>(&'a self) -> &'a $ty {
1553                 &self.0
1554             }
1555         }
1556
1557         impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
1558             fn eq(&self, other: &Self) -> bool {
1559                 // The `Borrow` trait requires that `x.borrow() == y.borrow()`
1560                 // equals `x == y`.
1561                 self.0 == other.0
1562             }
1563         }
1564
1565         impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
1566
1567         impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
1568             fn hash<H: Hasher>(&self, s: &mut H) {
1569                 // The `Borrow` trait requires that `x.borrow().hash(s) ==
1570                 // x.hash(s)`.
1571                 self.0.hash(s)
1572             }
1573         }
1574
1575         impl<'tcx> TyCtxt<'tcx> {
1576             pub fn $method(self, v: $ty) -> $ret_ty {
1577                 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
1578                     InternedInSet(self.interners.arena.alloc(v))
1579                 }).0))
1580             }
1581         })+
1582     }
1583 }
1584
1585 direct_interners! {
1586     region: mk_region(RegionKind<'tcx>): Region -> Region<'tcx>,
1587     const_: mk_const_internal(ConstData<'tcx>): Const -> Const<'tcx>,
1588     const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
1589     layout: intern_layout(LayoutS<VariantIdx>): Layout -> Layout<'tcx>,
1590     adt_def: intern_adt_def(AdtDefData): AdtDef -> AdtDef<'tcx>,
1591 }
1592
1593 macro_rules! slice_interners {
1594     ($($field:ident: $method:ident($ty:ty)),+ $(,)?) => (
1595         impl<'tcx> TyCtxt<'tcx> {
1596             $(pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
1597                 self.interners.$field.intern_ref(v, || {
1598                     InternedInSet(List::from_arena(&*self.arena, v))
1599                 }).0
1600             })+
1601         }
1602     );
1603 }
1604
1605 slice_interners!(
1606     const_lists: _intern_const_list(Const<'tcx>),
1607     substs: _intern_substs(GenericArg<'tcx>),
1608     canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo<'tcx>),
1609     poly_existential_predicates:
1610         _intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
1611     predicates: _intern_predicates(Predicate<'tcx>),
1612     projs: _intern_projs(ProjectionKind),
1613     place_elems: _intern_place_elems(PlaceElem<'tcx>),
1614     bound_variable_kinds: _intern_bound_variable_kinds(ty::BoundVariableKind),
1615 );
1616
1617 impl<'tcx> TyCtxt<'tcx> {
1618     /// Given a `fn` type, returns an equivalent `unsafe fn` type;
1619     /// that is, a `fn` type that is equivalent in every way for being
1620     /// unsafe.
1621     pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
1622         assert_eq!(sig.unsafety(), hir::Unsafety::Normal);
1623         self.mk_fn_ptr(sig.map_bound(|sig| ty::FnSig { unsafety: hir::Unsafety::Unsafe, ..sig }))
1624     }
1625
1626     /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name`
1627     /// returns true if the `trait_def_id` defines an associated item of name `assoc_name`.
1628     pub fn trait_may_define_assoc_type(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
1629         self.super_traits_of(trait_def_id).any(|trait_did| {
1630             self.associated_items(trait_did)
1631                 .find_by_name_and_kind(self, assoc_name, ty::AssocKind::Type, trait_did)
1632                 .is_some()
1633         })
1634     }
1635
1636     /// Given a `ty`, return whether it's an `impl Future<...>`.
1637     pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
1638         let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
1639         let future_trait = self.require_lang_item(LangItem::Future, None);
1640
1641         self.explicit_item_bounds(def_id).iter().any(|(predicate, _)| {
1642             let ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() else {
1643                 return false;
1644             };
1645             trait_predicate.trait_ref.def_id == future_trait
1646                 && trait_predicate.polarity == ImplPolarity::Positive
1647         })
1648     }
1649
1650     /// Computes the def-ids of the transitive supertraits of `trait_def_id`. This (intentionally)
1651     /// does not compute the full elaborated super-predicates but just the set of def-ids. It is used
1652     /// to identify which traits may define a given associated type to help avoid cycle errors.
1653     /// Returns a `DefId` iterator.
1654     fn super_traits_of(self, trait_def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
1655         let mut set = FxHashSet::default();
1656         let mut stack = vec![trait_def_id];
1657
1658         set.insert(trait_def_id);
1659
1660         iter::from_fn(move || -> Option<DefId> {
1661             let trait_did = stack.pop()?;
1662             let generic_predicates = self.super_predicates_of(trait_did);
1663
1664             for (predicate, _) in generic_predicates.predicates {
1665                 if let ty::PredicateKind::Clause(ty::Clause::Trait(data)) =
1666                     predicate.kind().skip_binder()
1667                 {
1668                     if set.insert(data.def_id()) {
1669                         stack.push(data.def_id());
1670                     }
1671                 }
1672             }
1673
1674             Some(trait_did)
1675         })
1676     }
1677
1678     /// Given a closure signature, returns an equivalent fn signature. Detuples
1679     /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then
1680     /// you would get a `fn(u32, i32)`.
1681     /// `unsafety` determines the unsafety of the fn signature. If you pass
1682     /// `hir::Unsafety::Unsafe` in the previous example, then you would get
1683     /// an `unsafe fn (u32, i32)`.
1684     /// It cannot convert a closure that requires unsafe.
1685     pub fn signature_unclosure(
1686         self,
1687         sig: PolyFnSig<'tcx>,
1688         unsafety: hir::Unsafety,
1689     ) -> PolyFnSig<'tcx> {
1690         sig.map_bound(|s| {
1691             let params_iter = match s.inputs()[0].kind() {
1692                 ty::Tuple(params) => params.into_iter(),
1693                 _ => bug!(),
1694             };
1695             self.mk_fn_sig(params_iter, s.output(), s.c_variadic, unsafety, abi::Abi::Rust)
1696         })
1697     }
1698
1699     /// Same a `self.mk_region(kind)`, but avoids accessing the interners if
1700     /// `*r == kind`.
1701     #[inline]
1702     pub fn reuse_or_mk_region(self, r: Region<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> {
1703         if *r == kind { r } else { self.mk_region(kind) }
1704     }
1705
1706     #[allow(rustc::usage_of_ty_tykind)]
1707     #[inline]
1708     pub fn mk_ty(self, st: TyKind<'tcx>) -> Ty<'tcx> {
1709         self.interners.intern_ty(
1710             st,
1711             self.sess,
1712             // This is only used to create a stable hashing context.
1713             &self.untracked,
1714         )
1715     }
1716
1717     #[inline]
1718     pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
1719         self.interners.intern_predicate(
1720             binder,
1721             self.sess,
1722             // This is only used to create a stable hashing context.
1723             &self.untracked,
1724         )
1725     }
1726
1727     #[inline]
1728     pub fn reuse_or_mk_predicate(
1729         self,
1730         pred: Predicate<'tcx>,
1731         binder: Binder<'tcx, PredicateKind<'tcx>>,
1732     ) -> Predicate<'tcx> {
1733         if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
1734     }
1735
1736     pub fn mk_mach_int(self, tm: IntTy) -> Ty<'tcx> {
1737         match tm {
1738             IntTy::Isize => self.types.isize,
1739             IntTy::I8 => self.types.i8,
1740             IntTy::I16 => self.types.i16,
1741             IntTy::I32 => self.types.i32,
1742             IntTy::I64 => self.types.i64,
1743             IntTy::I128 => self.types.i128,
1744         }
1745     }
1746
1747     pub fn mk_mach_uint(self, tm: UintTy) -> Ty<'tcx> {
1748         match tm {
1749             UintTy::Usize => self.types.usize,
1750             UintTy::U8 => self.types.u8,
1751             UintTy::U16 => self.types.u16,
1752             UintTy::U32 => self.types.u32,
1753             UintTy::U64 => self.types.u64,
1754             UintTy::U128 => self.types.u128,
1755         }
1756     }
1757
1758     pub fn mk_mach_float(self, tm: FloatTy) -> Ty<'tcx> {
1759         match tm {
1760             FloatTy::F32 => self.types.f32,
1761             FloatTy::F64 => self.types.f64,
1762         }
1763     }
1764
1765     #[inline]
1766     pub fn mk_static_str(self) -> Ty<'tcx> {
1767         self.mk_imm_ref(self.lifetimes.re_static, self.types.str_)
1768     }
1769
1770     #[inline]
1771     pub fn mk_adt(self, def: AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
1772         // Take a copy of substs so that we own the vectors inside.
1773         self.mk_ty(Adt(def, substs))
1774     }
1775
1776     #[inline]
1777     pub fn mk_foreign(self, def_id: DefId) -> Ty<'tcx> {
1778         self.mk_ty(Foreign(def_id))
1779     }
1780
1781     fn mk_generic_adt(self, wrapper_def_id: DefId, ty_param: Ty<'tcx>) -> Ty<'tcx> {
1782         let adt_def = self.adt_def(wrapper_def_id);
1783         let substs =
1784             InternalSubsts::for_item(self, wrapper_def_id, |param, substs| match param.kind {
1785                 GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => bug!(),
1786                 GenericParamDefKind::Type { has_default, .. } => {
1787                     if param.index == 0 {
1788                         ty_param.into()
1789                     } else {
1790                         assert!(has_default);
1791                         self.bound_type_of(param.def_id).subst(self, substs).into()
1792                     }
1793                 }
1794             });
1795         self.mk_ty(Adt(adt_def, substs))
1796     }
1797
1798     #[inline]
1799     pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> {
1800         let def_id = self.require_lang_item(LangItem::OwnedBox, None);
1801         self.mk_generic_adt(def_id, ty)
1802     }
1803
1804     #[inline]
1805     pub fn mk_lang_item(self, ty: Ty<'tcx>, item: LangItem) -> Option<Ty<'tcx>> {
1806         let def_id = self.lang_items().get(item)?;
1807         Some(self.mk_generic_adt(def_id, ty))
1808     }
1809
1810     #[inline]
1811     pub fn mk_diagnostic_item(self, ty: Ty<'tcx>, name: Symbol) -> Option<Ty<'tcx>> {
1812         let def_id = self.get_diagnostic_item(name)?;
1813         Some(self.mk_generic_adt(def_id, ty))
1814     }
1815
1816     #[inline]
1817     pub fn mk_maybe_uninit(self, ty: Ty<'tcx>) -> Ty<'tcx> {
1818         let def_id = self.require_lang_item(LangItem::MaybeUninit, None);
1819         self.mk_generic_adt(def_id, ty)
1820     }
1821
1822     #[inline]
1823     pub fn mk_ptr(self, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
1824         self.mk_ty(RawPtr(tm))
1825     }
1826
1827     #[inline]
1828     pub fn mk_ref(self, r: Region<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
1829         self.mk_ty(Ref(r, tm.ty, tm.mutbl))
1830     }
1831
1832     #[inline]
1833     pub fn mk_mut_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
1834         self.mk_ref(r, TypeAndMut { ty, mutbl: hir::Mutability::Mut })
1835     }
1836
1837     #[inline]
1838     pub fn mk_imm_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
1839         self.mk_ref(r, TypeAndMut { ty, mutbl: hir::Mutability::Not })
1840     }
1841
1842     #[inline]
1843     pub fn mk_mut_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
1844         self.mk_ptr(TypeAndMut { ty, mutbl: hir::Mutability::Mut })
1845     }
1846
1847     #[inline]
1848     pub fn mk_imm_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
1849         self.mk_ptr(TypeAndMut { ty, mutbl: hir::Mutability::Not })
1850     }
1851
1852     #[inline]
1853     pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
1854         self.mk_ty(Array(ty, ty::Const::from_usize(self, n)))
1855     }
1856
1857     #[inline]
1858     pub fn mk_slice(self, ty: Ty<'tcx>) -> Ty<'tcx> {
1859         self.mk_ty(Slice(ty))
1860     }
1861
1862     #[inline]
1863     pub fn intern_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
1864         self.mk_ty(Tuple(self.intern_type_list(&ts)))
1865     }
1866
1867     pub fn mk_tup<I: InternAs<Ty<'tcx>, Ty<'tcx>>>(self, iter: I) -> I::Output {
1868         iter.intern_with(|ts| self.mk_ty(Tuple(self.intern_type_list(&ts))))
1869     }
1870
1871     #[inline]
1872     pub fn mk_unit(self) -> Ty<'tcx> {
1873         self.types.unit
1874     }
1875
1876     #[inline]
1877     pub fn mk_diverging_default(self) -> Ty<'tcx> {
1878         if self.features().never_type_fallback { self.types.never } else { self.types.unit }
1879     }
1880
1881     #[inline]
1882     pub fn mk_fn_def(
1883         self,
1884         def_id: DefId,
1885         substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
1886     ) -> Ty<'tcx> {
1887         let substs = self.check_substs(def_id, substs);
1888         self.mk_ty(FnDef(def_id, substs))
1889     }
1890
1891     #[inline(always)]
1892     fn check_substs(
1893         self,
1894         _def_id: DefId,
1895         substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
1896     ) -> SubstsRef<'tcx> {
1897         let substs = substs.into_iter().map(Into::into);
1898         #[cfg(debug_assertions)]
1899         {
1900             let n = self.generics_of(_def_id).count();
1901             assert_eq!(
1902                 (n, Some(n)),
1903                 substs.size_hint(),
1904                 "wrong number of generic parameters for {_def_id:?}: {:?}",
1905                 substs.collect::<Vec<_>>(),
1906             );
1907         }
1908         self.mk_substs(substs)
1909     }
1910
1911     #[inline]
1912     pub fn mk_fn_ptr(self, fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
1913         self.mk_ty(FnPtr(fty))
1914     }
1915
1916     #[inline]
1917     pub fn mk_dynamic(
1918         self,
1919         obj: &'tcx List<PolyExistentialPredicate<'tcx>>,
1920         reg: ty::Region<'tcx>,
1921         repr: DynKind,
1922     ) -> Ty<'tcx> {
1923         self.mk_ty(Dynamic(obj, reg, repr))
1924     }
1925
1926     #[inline]
1927     pub fn mk_projection(
1928         self,
1929         item_def_id: DefId,
1930         substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
1931     ) -> Ty<'tcx> {
1932         self.mk_ty(Alias(ty::Projection, self.mk_alias_ty(item_def_id, substs)))
1933     }
1934
1935     #[inline]
1936     pub fn mk_closure(self, closure_id: DefId, closure_substs: SubstsRef<'tcx>) -> Ty<'tcx> {
1937         self.mk_ty(Closure(closure_id, closure_substs))
1938     }
1939
1940     #[inline]
1941     pub fn mk_generator(
1942         self,
1943         id: DefId,
1944         generator_substs: SubstsRef<'tcx>,
1945         movability: hir::Movability,
1946     ) -> Ty<'tcx> {
1947         self.mk_ty(Generator(id, generator_substs, movability))
1948     }
1949
1950     #[inline]
1951     pub fn mk_generator_witness(self, types: ty::Binder<'tcx, &'tcx List<Ty<'tcx>>>) -> Ty<'tcx> {
1952         self.mk_ty(GeneratorWitness(types))
1953     }
1954
1955     #[inline]
1956     pub fn mk_ty_var(self, v: TyVid) -> Ty<'tcx> {
1957         self.mk_ty_infer(TyVar(v))
1958     }
1959
1960     #[inline]
1961     pub fn mk_const(self, kind: impl Into<ty::ConstKind<'tcx>>, ty: Ty<'tcx>) -> Const<'tcx> {
1962         self.mk_const_internal(ty::ConstData { kind: kind.into(), ty })
1963     }
1964
1965     #[inline]
1966     pub fn mk_int_var(self, v: IntVid) -> Ty<'tcx> {
1967         self.mk_ty_infer(IntVar(v))
1968     }
1969
1970     #[inline]
1971     pub fn mk_float_var(self, v: FloatVid) -> Ty<'tcx> {
1972         self.mk_ty_infer(FloatVar(v))
1973     }
1974
1975     #[inline]
1976     pub fn mk_ty_infer(self, it: InferTy) -> Ty<'tcx> {
1977         self.mk_ty(Infer(it))
1978     }
1979
1980     #[inline]
1981     pub fn mk_ty_param(self, index: u32, name: Symbol) -> Ty<'tcx> {
1982         self.mk_ty(Param(ParamTy { index, name }))
1983     }
1984
1985     pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
1986         match param.kind {
1987             GenericParamDefKind::Lifetime => {
1988                 self.mk_region(ty::ReEarlyBound(param.to_early_bound_region_data())).into()
1989             }
1990             GenericParamDefKind::Type { .. } => self.mk_ty_param(param.index, param.name).into(),
1991             GenericParamDefKind::Const { .. } => self
1992                 .mk_const(
1993                     ParamConst { index: param.index, name: param.name },
1994                     self.type_of(param.def_id),
1995                 )
1996                 .into(),
1997         }
1998     }
1999
2000     #[inline]
2001     pub fn mk_opaque(self, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
2002         self.mk_ty(Alias(ty::Opaque, self.mk_alias_ty(def_id, substs)))
2003     }
2004
2005     pub fn mk_place_field(self, place: Place<'tcx>, f: Field, ty: Ty<'tcx>) -> Place<'tcx> {
2006         self.mk_place_elem(place, PlaceElem::Field(f, ty))
2007     }
2008
2009     pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2010         self.mk_place_elem(place, PlaceElem::Deref)
2011     }
2012
2013     pub fn mk_place_downcast(
2014         self,
2015         place: Place<'tcx>,
2016         adt_def: AdtDef<'tcx>,
2017         variant_index: VariantIdx,
2018     ) -> Place<'tcx> {
2019         self.mk_place_elem(
2020             place,
2021             PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2022         )
2023     }
2024
2025     pub fn mk_place_downcast_unnamed(
2026         self,
2027         place: Place<'tcx>,
2028         variant_index: VariantIdx,
2029     ) -> Place<'tcx> {
2030         self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2031     }
2032
2033     pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2034         self.mk_place_elem(place, PlaceElem::Index(index))
2035     }
2036
2037     /// This method copies `Place`'s projection, add an element and reintern it. Should not be used
2038     /// to build a full `Place` it's just a convenient way to grab a projection and modify it in
2039     /// flight.
2040     pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2041         let mut projection = place.projection.to_vec();
2042         projection.push(elem);
2043
2044         Place { local: place.local, projection: self.intern_place_elems(&projection) }
2045     }
2046
2047     pub fn intern_poly_existential_predicates(
2048         self,
2049         eps: &[PolyExistentialPredicate<'tcx>],
2050     ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2051         assert!(!eps.is_empty());
2052         assert!(
2053             eps.array_windows()
2054                 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2055                     != Ordering::Greater)
2056         );
2057         self._intern_poly_existential_predicates(eps)
2058     }
2059
2060     pub fn intern_predicates(self, preds: &[Predicate<'tcx>]) -> &'tcx List<Predicate<'tcx>> {
2061         // FIXME consider asking the input slice to be sorted to avoid
2062         // re-interning permutations, in which case that would be asserted
2063         // here.
2064         if preds.is_empty() {
2065             // The macro-generated method below asserts we don't intern an empty slice.
2066             List::empty()
2067         } else {
2068             self._intern_predicates(preds)
2069         }
2070     }
2071
2072     pub fn mk_const_list<I: InternAs<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>>(
2073         self,
2074         iter: I,
2075     ) -> I::Output {
2076         iter.intern_with(|xs| self.intern_const_list(xs))
2077     }
2078
2079     pub fn intern_const_list(self, cs: &[ty::Const<'tcx>]) -> &'tcx List<ty::Const<'tcx>> {
2080         if cs.is_empty() { List::empty() } else { self._intern_const_list(cs) }
2081     }
2082
2083     pub fn intern_type_list(self, ts: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> {
2084         if ts.is_empty() {
2085             List::empty()
2086         } else {
2087             // Actually intern type lists as lists of `GenericArg`s.
2088             //
2089             // Transmuting from `Ty<'tcx>` to `GenericArg<'tcx>` is sound
2090             // as explained in ty_slice_as_generic_arg`. With this,
2091             // we guarantee that even when transmuting between `List<Ty<'tcx>>`
2092             // and `List<GenericArg<'tcx>>`, the uniqueness requirement for
2093             // lists is upheld.
2094             let substs = self._intern_substs(ty::subst::ty_slice_as_generic_args(ts));
2095             substs.try_as_type_list().unwrap()
2096         }
2097     }
2098
2099     pub fn intern_substs(self, ts: &[GenericArg<'tcx>]) -> &'tcx List<GenericArg<'tcx>> {
2100         if ts.is_empty() { List::empty() } else { self._intern_substs(ts) }
2101     }
2102
2103     pub fn intern_projs(self, ps: &[ProjectionKind]) -> &'tcx List<ProjectionKind> {
2104         if ps.is_empty() { List::empty() } else { self._intern_projs(ps) }
2105     }
2106
2107     pub fn intern_place_elems(self, ts: &[PlaceElem<'tcx>]) -> &'tcx List<PlaceElem<'tcx>> {
2108         if ts.is_empty() { List::empty() } else { self._intern_place_elems(ts) }
2109     }
2110
2111     pub fn intern_canonical_var_infos(
2112         self,
2113         ts: &[CanonicalVarInfo<'tcx>],
2114     ) -> CanonicalVarInfos<'tcx> {
2115         if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) }
2116     }
2117
2118     pub fn intern_bound_variable_kinds(
2119         self,
2120         ts: &[ty::BoundVariableKind],
2121     ) -> &'tcx List<ty::BoundVariableKind> {
2122         if ts.is_empty() { List::empty() } else { self._intern_bound_variable_kinds(ts) }
2123     }
2124
2125     pub fn mk_fn_sig<I>(
2126         self,
2127         inputs: I,
2128         output: I::Item,
2129         c_variadic: bool,
2130         unsafety: hir::Unsafety,
2131         abi: abi::Abi,
2132     ) -> <I::Item as InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>>::Output
2133     where
2134         I: Iterator<Item: InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>>,
2135     {
2136         inputs.chain(iter::once(output)).intern_with(|xs| ty::FnSig {
2137             inputs_and_output: self.intern_type_list(xs),
2138             c_variadic,
2139             unsafety,
2140             abi,
2141         })
2142     }
2143
2144     pub fn mk_poly_existential_predicates<
2145         I: InternAs<PolyExistentialPredicate<'tcx>, &'tcx List<PolyExistentialPredicate<'tcx>>>,
2146     >(
2147         self,
2148         iter: I,
2149     ) -> I::Output {
2150         iter.intern_with(|xs| self.intern_poly_existential_predicates(xs))
2151     }
2152
2153     pub fn mk_predicates<I: InternAs<Predicate<'tcx>, &'tcx List<Predicate<'tcx>>>>(
2154         self,
2155         iter: I,
2156     ) -> I::Output {
2157         iter.intern_with(|xs| self.intern_predicates(xs))
2158     }
2159
2160     pub fn mk_type_list<I: InternAs<Ty<'tcx>, &'tcx List<Ty<'tcx>>>>(self, iter: I) -> I::Output {
2161         iter.intern_with(|xs| self.intern_type_list(xs))
2162     }
2163
2164     pub fn mk_substs<I: InternAs<GenericArg<'tcx>, &'tcx List<GenericArg<'tcx>>>>(
2165         self,
2166         iter: I,
2167     ) -> I::Output {
2168         iter.intern_with(|xs| self.intern_substs(xs))
2169     }
2170
2171     pub fn mk_place_elems<I: InternAs<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>>(
2172         self,
2173         iter: I,
2174     ) -> I::Output {
2175         iter.intern_with(|xs| self.intern_place_elems(xs))
2176     }
2177
2178     pub fn mk_substs_trait(
2179         self,
2180         self_ty: Ty<'tcx>,
2181         rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2182     ) -> SubstsRef<'tcx> {
2183         self.mk_substs(iter::once(self_ty.into()).chain(rest))
2184     }
2185
2186     pub fn mk_trait_ref(
2187         self,
2188         trait_def_id: DefId,
2189         substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
2190     ) -> ty::TraitRef<'tcx> {
2191         let substs = self.check_substs(trait_def_id, substs);
2192         ty::TraitRef { def_id: trait_def_id, substs, _use_mk_trait_ref_instead: () }
2193     }
2194
2195     pub fn mk_alias_ty(
2196         self,
2197         def_id: DefId,
2198         substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
2199     ) -> ty::AliasTy<'tcx> {
2200         let substs = self.check_substs(def_id, substs);
2201         ty::AliasTy { def_id, substs, _use_mk_alias_ty_instead: () }
2202     }
2203
2204     pub fn mk_bound_variable_kinds<
2205         I: InternAs<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
2206     >(
2207         self,
2208         iter: I,
2209     ) -> I::Output {
2210         iter.intern_with(|xs| self.intern_bound_variable_kinds(xs))
2211     }
2212
2213     /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`,
2214     /// typically generated by `#[derive(LintDiagnostic)]`).
2215     pub fn emit_spanned_lint(
2216         self,
2217         lint: &'static Lint,
2218         hir_id: HirId,
2219         span: impl Into<MultiSpan>,
2220         decorator: impl for<'a> DecorateLint<'a, ()>,
2221     ) {
2222         let msg = decorator.msg();
2223         let (level, src) = self.lint_level_at_node(lint, hir_id);
2224         struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, |diag| {
2225             decorator.decorate_lint(diag)
2226         })
2227     }
2228
2229     /// Emit a lint at the appropriate level for a hir node, with an associated span.
2230     ///
2231     /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
2232     ///
2233     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
2234     #[rustc_lint_diagnostics]
2235     pub fn struct_span_lint_hir(
2236         self,
2237         lint: &'static Lint,
2238         hir_id: HirId,
2239         span: impl Into<MultiSpan>,
2240         msg: impl Into<DiagnosticMessage>,
2241         decorate: impl for<'a, 'b> FnOnce(
2242             &'b mut DiagnosticBuilder<'a, ()>,
2243         ) -> &'b mut DiagnosticBuilder<'a, ()>,
2244     ) {
2245         let (level, src) = self.lint_level_at_node(lint, hir_id);
2246         struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, decorate);
2247     }
2248
2249     /// Emit a lint from a lint struct (some type that implements `DecorateLint`, typically
2250     /// generated by `#[derive(LintDiagnostic)]`).
2251     pub fn emit_lint(
2252         self,
2253         lint: &'static Lint,
2254         id: HirId,
2255         decorator: impl for<'a> DecorateLint<'a, ()>,
2256     ) {
2257         self.struct_lint_node(lint, id, decorator.msg(), |diag| decorator.decorate_lint(diag))
2258     }
2259
2260     /// Emit a lint at the appropriate level for a hir node.
2261     ///
2262     /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
2263     ///
2264     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
2265     #[rustc_lint_diagnostics]
2266     pub fn struct_lint_node(
2267         self,
2268         lint: &'static Lint,
2269         id: HirId,
2270         msg: impl Into<DiagnosticMessage>,
2271         decorate: impl for<'a, 'b> FnOnce(
2272             &'b mut DiagnosticBuilder<'a, ()>,
2273         ) -> &'b mut DiagnosticBuilder<'a, ()>,
2274     ) {
2275         let (level, src) = self.lint_level_at_node(lint, id);
2276         struct_lint_level(self.sess, lint, level, src, None, msg, decorate);
2277     }
2278
2279     pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
2280         let map = self.in_scope_traits_map(id.owner)?;
2281         let candidates = map.get(&id.local_id)?;
2282         Some(&*candidates)
2283     }
2284
2285     pub fn named_region(self, id: HirId) -> Option<resolve_lifetime::Region> {
2286         debug!(?id, "named_region");
2287         self.named_region_map(id.owner).and_then(|map| map.get(&id.local_id).cloned())
2288     }
2289
2290     pub fn is_late_bound(self, id: HirId) -> bool {
2291         self.is_late_bound_map(id.owner.def_id).map_or(false, |set| {
2292             let def_id = self.hir().local_def_id(id);
2293             set.contains(&def_id)
2294         })
2295     }
2296
2297     pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
2298         self.mk_bound_variable_kinds(
2299             self.late_bound_vars_map(id.owner)
2300                 .and_then(|map| map.get(&id.local_id).cloned())
2301                 .unwrap_or_else(|| {
2302                     bug!("No bound vars found for {:?} ({:?})", self.hir().node_to_string(id), id)
2303                 })
2304                 .iter(),
2305         )
2306     }
2307
2308     /// Whether the `def_id` counts as const fn in the current crate, considering all active
2309     /// feature gates
2310     pub fn is_const_fn(self, def_id: DefId) -> bool {
2311         if self.is_const_fn_raw(def_id) {
2312             match self.lookup_const_stability(def_id) {
2313                 Some(stability) if stability.is_const_unstable() => {
2314                     // has a `rustc_const_unstable` attribute, check whether the user enabled the
2315                     // corresponding feature gate.
2316                     self.features()
2317                         .declared_lib_features
2318                         .iter()
2319                         .any(|&(sym, _)| sym == stability.feature)
2320                 }
2321                 // functions without const stability are either stable user written
2322                 // const fn or the user is using feature gates and we thus don't
2323                 // care what they do
2324                 _ => true,
2325             }
2326         } else {
2327             false
2328         }
2329     }
2330
2331     /// Whether the trait impl is marked const. This does not consider stability or feature gates.
2332     pub fn is_const_trait_impl_raw(self, def_id: DefId) -> bool {
2333         let Some(local_def_id) = def_id.as_local() else { return false };
2334         let hir_id = self.local_def_id_to_hir_id(local_def_id);
2335         let node = self.hir().get(hir_id);
2336
2337         matches!(
2338             node,
2339             hir::Node::Item(hir::Item {
2340                 kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }),
2341                 ..
2342             })
2343         )
2344     }
2345 }
2346
2347 impl<'tcx> TyCtxtAt<'tcx> {
2348     /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used.
2349     #[track_caller]
2350     pub fn ty_error(self) -> Ty<'tcx> {
2351         self.tcx.ty_error_with_message(self.span, "TyKind::Error constructed but no error reported")
2352     }
2353
2354     /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg to
2355     /// ensure it gets used.
2356     #[track_caller]
2357     pub fn ty_error_with_message(self, msg: &str) -> Ty<'tcx> {
2358         self.tcx.ty_error_with_message(self.span, msg)
2359     }
2360
2361     pub fn mk_trait_ref(
2362         self,
2363         trait_lang_item: LangItem,
2364         substs: impl IntoIterator<Item = impl Into<ty::GenericArg<'tcx>>>,
2365     ) -> ty::TraitRef<'tcx> {
2366         let trait_def_id = self.require_lang_item(trait_lang_item, Some(self.span));
2367         self.tcx.mk_trait_ref(trait_def_id, substs)
2368     }
2369 }
2370
2371 /// Parameter attributes that can only be determined by examining the body of a function instead
2372 /// of just its signature.
2373 ///
2374 /// These can be useful for optimization purposes when a function is directly called. We compute
2375 /// them and store them into the crate metadata so that downstream crates can make use of them.
2376 ///
2377 /// Right now, we only have `read_only`, but `no_capture` and `no_alias` might be useful in the
2378 /// future.
2379 #[derive(Clone, Copy, PartialEq, Debug, Default, TyDecodable, TyEncodable, HashStable)]
2380 pub struct DeducedParamAttrs {
2381     /// The parameter is marked immutable in the function and contains no `UnsafeCell` (i.e. its
2382     /// type is freeze).
2383     pub read_only: bool,
2384 }
2385
2386 // We are comparing types with different invariant lifetimes, so `ptr::eq`
2387 // won't work for us.
2388 fn ptr_eq<T, U>(t: *const T, u: *const U) -> bool {
2389     t as *const () == u as *const ()
2390 }
2391
2392 pub fn provide(providers: &mut ty::query::Providers) {
2393     providers.module_reexports =
2394         |tcx, id| tcx.resolutions(()).reexport_map.get(&id).map(|v| &v[..]);
2395     providers.maybe_unused_trait_imports =
2396         |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
2397     providers.maybe_unused_extern_crates =
2398         |tcx, ()| &tcx.resolutions(()).maybe_unused_extern_crates[..];
2399     providers.names_imported_by_glob_use = |tcx, id| {
2400         tcx.arena.alloc(tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default())
2401     };
2402
2403     providers.extern_mod_stmt_cnum =
2404         |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
2405     providers.is_panic_runtime = |tcx, cnum| {
2406         assert_eq!(cnum, LOCAL_CRATE);
2407         tcx.sess.contains_name(tcx.hir().krate_attrs(), sym::panic_runtime)
2408     };
2409     providers.is_compiler_builtins = |tcx, cnum| {
2410         assert_eq!(cnum, LOCAL_CRATE);
2411         tcx.sess.contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins)
2412     };
2413     providers.has_panic_handler = |tcx, cnum| {
2414         assert_eq!(cnum, LOCAL_CRATE);
2415         // We want to check if the panic handler was defined in this crate
2416         tcx.lang_items().panic_impl().map_or(false, |did| did.is_local())
2417     };
2418     providers.source_span =
2419         |tcx, def_id| tcx.untracked.source_span.get(def_id).copied().unwrap_or(DUMMY_SP);
2420 }