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