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