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