]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_middle/src/ty/context.rs
New upstream version 1.64.0+dfsg1
[rustc.git] / compiler / rustc_middle / src / ty / context.rs
CommitLineData
e74abb32 1//! Type context book-keeping.
e1599b0c 2
48663c56 3use crate::arena::Arena;
3c0e092e 4use crate::dep_graph::{DepGraph, DepKind, DepKindStruct};
5869c6ff 5use crate::hir::place::Place as HirPlace;
9fa01778 6use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
064997fb 7use crate::lint::{struct_lint_level, LintLevelSource};
04454e1e 8use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
923072b8 9use crate::middle::resolve_lifetime;
9fa01778 10use crate::middle::stability;
923072b8 11use crate::mir::interpret::{self, Allocation, ConstAllocation};
5099ac24
FG
12use crate::mir::{
13 Body, BorrowCheckResult, Field, Local, Place, PlaceElem, ProjectionKind, Promoted,
14};
17df50a5 15use crate::thir::Thir;
9fa01778 16use crate::traits;
136023e0 17use crate::ty::query::{self, TyCtxtAt};
f9f354fc 18use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts};
f9f354fc 19use crate::ty::{
5e7ed085 20 self, AdtDef, AdtDefData, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
5099ac24
FG
21 ClosureSizeProfileData, Const, ConstS, ConstVid, DefIdTree, ExistentialPredicate, FloatTy,
22 FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List,
23 ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region,
24 RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
f9f354fc 25};
3dfed10e 26use rustc_ast as ast;
5e7ed085 27use rustc_data_structures::fingerprint::Fingerprint;
dfeec247 28use rustc_data_structures::fx::{FxHashMap, FxHashSet};
04454e1e 29use rustc_data_structures::intern::{Interned, WithStableHash};
c295e0f8 30use rustc_data_structures::memmap::Mmap;
60c5eb7d 31use rustc_data_structures::profiling::SelfProfilerRef;
dfeec247 32use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
17df50a5 33use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
fc512014 34use rustc_data_structures::steal::Steal;
064997fb 35use rustc_data_structures::sync::{self, Lock, Lrc, ReadGuard, RwLock, WorkerLocal};
5e7ed085 36use rustc_data_structures::vec_map::VecMap;
064997fb 37use rustc_errors::{DecorateLint, ErrorGuaranteed, LintDiagnosticBuilder, MultiSpan};
74b04a01
XL
38use rustc_hir as hir;
39use rustc_hir::def::{DefKind, Res};
5869c6ff 40use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
064997fb 41use rustc_hir::definitions::Definitions;
f035d41b 42use rustc_hir::intravisit::Visitor;
3dfed10e 43use rustc_hir::lang_items::LangItem;
fc512014 44use rustc_hir::{
136023e0
XL
45 Constness, ExprKind, HirId, ImplItemKind, ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet,
46 Node, TraitCandidate, TraitItemKind,
fc512014 47};
e74abb32 48use rustc_index::vec::{Idx, IndexVec};
dfeec247 49use rustc_macros::HashStable;
6a06907d 50use rustc_middle::mir::FakeReadCause;
5e7ed085 51use rustc_query_system::ich::StableHashingContext;
5869c6ff 52use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
923072b8
FG
53use rustc_session::config::{CrateType, OutputFilenames};
54use rustc_session::cstore::CrateStoreDyn;
dfeec247 55use rustc_session::lint::{Level, Lint};
136023e0 56use rustc_session::Limit;
74b04a01 57use rustc_session::Session;
136023e0 58use rustc_span::def_id::{DefPathHash, StableCrateId};
04454e1e 59use rustc_span::source_map::SourceMap;
6a06907d 60use rustc_span::symbol::{kw, sym, Ident, Symbol};
f035d41b 61use rustc_span::{Span, DUMMY_SP};
5e7ed085 62use rustc_target::abi::{Layout, LayoutS, TargetDataLayout, VariantIdx};
dfeec247 63use rustc_target::spec::abi;
923072b8
FG
64use rustc_type_ir::sty::TyKind::*;
65use rustc_type_ir::{InternAs, InternIteratorElement, Interner, TypeFlags};
74b04a01 66
ea8adc8c 67use std::any::Any;
e9174d1e 68use std::borrow::Borrow;
7cac9316 69use std::cmp::Ordering;
3b2f2976 70use std::collections::hash_map::{self, Entry};
8faf50e0 71use std::fmt;
dfeec247 72use std::hash::{Hash, Hasher};
c30ab7b3 73use std::iter;
dfeec247
XL
74use std::mem;
75use std::ops::{Bound, Deref};
ea8adc8c 76use std::sync::Arc;
e9174d1e 77
923072b8
FG
78use super::{ImplPolarity, RvalueScopes};
79
136023e0
XL
80pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync {
81 /// Creates a new `OnDiskCache` instance from the serialized data in `data`.
c295e0f8 82 fn new(sess: &'tcx Session, data: Mmap, start_pos: usize) -> Self
136023e0
XL
83 where
84 Self: Sized;
85
86 fn new_empty(source_map: &'tcx SourceMap) -> Self
87 where
88 Self: Sized;
89
c295e0f8 90 fn drop_serialized_data(&self, tcx: TyCtxt<'tcx>);
136023e0 91
923072b8
FG
92 fn serialize(&self, tcx: TyCtxt<'tcx>, encoder: FileEncoder) -> FileEncodeResult;
93}
94
95#[allow(rustc::usage_of_ty_tykind)]
96impl<'tcx> Interner for TyCtxt<'tcx> {
97 type AdtDef = ty::AdtDef<'tcx>;
98 type SubstsRef = ty::SubstsRef<'tcx>;
99 type DefId = DefId;
100 type Ty = Ty<'tcx>;
101 type Const = ty::Const<'tcx>;
102 type Region = Region<'tcx>;
103 type TypeAndMut = TypeAndMut<'tcx>;
104 type Mutability = hir::Mutability;
105 type Movability = hir::Movability;
106 type PolyFnSig = PolyFnSig<'tcx>;
107 type ListBinderExistentialPredicate = &'tcx List<Binder<'tcx, ExistentialPredicate<'tcx>>>;
108 type BinderListTy = Binder<'tcx, &'tcx List<Ty<'tcx>>>;
109 type ListTy = &'tcx List<Ty<'tcx>>;
110 type ProjectionTy = ty::ProjectionTy<'tcx>;
111 type ParamTy = ParamTy;
112 type BoundTy = ty::BoundTy;
113 type PlaceholderType = ty::PlaceholderType;
114 type InferTy = InferTy;
115 type DelaySpanBugEmitted = DelaySpanBugEmitted;
116 type PredicateKind = ty::PredicateKind<'tcx>;
117 type AllocId = crate::mir::interpret::AllocId;
118
119 type EarlyBoundRegion = ty::EarlyBoundRegion;
120 type BoundRegion = ty::BoundRegion;
121 type FreeRegion = ty::FreeRegion;
122 type RegionVid = ty::RegionVid;
123 type PlaceholderRegion = ty::PlaceholderRegion;
136023e0
XL
124}
125
1b1a35ee
XL
126/// A type that is not publicly constructable. This prevents people from making [`TyKind::Error`]s
127/// except through the error-reporting functions on a [`tcx`][TyCtxt].
3dfed10e
XL
128#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
129#[derive(TyEncodable, TyDecodable, HashStable)]
5e7ed085
FG
130pub struct DelaySpanBugEmitted {
131 pub reported: ErrorGuaranteed,
132 _priv: (),
133}
3dfed10e 134
5099ac24 135type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
83c7162d 136
a7813a04 137pub struct CtxtInterners<'tcx> {
e1599b0c 138 /// The arena that types, regions, etc. are allocated from.
dfeec247 139 arena: &'tcx WorkerLocal<Arena<'tcx>>,
a7813a04 140
c295e0f8
XL
141 // Specifically use a speedy hash algorithm for these hash sets, since
142 // they're accessed quite often.
04454e1e 143 type_: InternedSet<'tcx, WithStableHash<TyS<'tcx>>>,
532ac7d7 144 substs: InternedSet<'tcx, InternalSubsts<'tcx>>,
fc512014 145 canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
923072b8 146 region: InternedSet<'tcx, RegionKind<'tcx>>,
cdc7bbd5
XL
147 poly_existential_predicates:
148 InternedSet<'tcx, List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>>,
5099ac24 149 predicate: InternedSet<'tcx, PredicateS<'tcx>>,
b7449926 150 predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
532ac7d7 151 projs: InternedSet<'tcx, List<ProjectionKind>>,
e74abb32 152 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
5099ac24 153 const_: InternedSet<'tcx, ConstS<'tcx>>,
c295e0f8 154 const_allocation: InternedSet<'tcx, Allocation>,
cdc7bbd5 155 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
5e7ed085
FG
156 layout: InternedSet<'tcx, LayoutS<'tcx>>,
157 adt_def: InternedSet<'tcx, AdtDefData>,
a7813a04
XL
158}
159
dc9dc135 160impl<'tcx> CtxtInterners<'tcx> {
dfeec247 161 fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
a7813a04 162 CtxtInterners {
041b39d2 163 arena,
83c7162d 164 type_: Default::default(),
83c7162d
XL
165 substs: Default::default(),
166 region: Default::default(),
fc512014 167 poly_existential_predicates: Default::default(),
83c7162d 168 canonical_var_infos: Default::default(),
f035d41b 169 predicate: Default::default(),
83c7162d 170 predicates: Default::default(),
0bf4aa26 171 projs: Default::default(),
e74abb32 172 place_elems: Default::default(),
532ac7d7 173 const_: Default::default(),
c295e0f8 174 const_allocation: Default::default(),
cdc7bbd5 175 bound_variable_kinds: Default::default(),
c295e0f8 176 layout: Default::default(),
a2a8927a 177 adt_def: Default::default(),
a7813a04
XL
178 }
179 }
180
e1599b0c
XL
181 /// Interns a type.
182 #[allow(rustc::usage_of_ty_tykind)]
a1dfa0c6 183 #[inline(never)]
5e7ed085
FG
184 fn intern_ty(
185 &self,
186 kind: TyKind<'tcx>,
187 sess: &Session,
923072b8
FG
188 definitions: &rustc_hir::definitions::Definitions,
189 cstore: &CrateStoreDyn,
190 source_span: &IndexVec<LocalDefId, Span>,
5e7ed085 191 ) -> Ty<'tcx> {
5099ac24
FG
192 Ty(Interned::new_unchecked(
193 self.type_
194 .intern(kind, |kind| {
195 let flags = super::flags::FlagComputation::for_kind(&kind);
196
5e7ed085
FG
197 // It's impossible to hash inference regions (and will ICE), so we don't need to try to cache them.
198 // Without incremental, we rarely stable-hash types, so let's not do it proactively.
199 let stable_hash = if flags.flags.intersects(TypeFlags::HAS_RE_INFER)
200 || sess.opts.incremental.is_none()
201 {
202 Fingerprint::ZERO
203 } else {
204 let mut hasher = StableHasher::new();
205 let mut hcx = StableHashingContext::ignore_spans(
206 sess,
923072b8
FG
207 definitions,
208 cstore,
209 source_span,
5e7ed085
FG
210 );
211 kind.hash_stable(&mut hcx, &mut hasher);
212 hasher.finish()
213 };
214
5099ac24
FG
215 let ty_struct = TyS {
216 kind,
217 flags: flags.flags,
218 outer_exclusive_binder: flags.outer_exclusive_binder,
219 };
94b46f34 220
04454e1e
FG
221 InternedInSet(
222 self.arena.alloc(WithStableHash { internee: ty_struct, stable_hash }),
223 )
5099ac24
FG
224 })
225 .0,
226 ))
94b46f34 227 }
f035d41b
XL
228
229 #[inline(never)]
5099ac24
FG
230 fn intern_predicate(&self, kind: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
231 Predicate(Interned::new_unchecked(
232 self.predicate
233 .intern(kind, |kind| {
234 let flags = super::flags::FlagComputation::for_predicate(kind);
235
236 let predicate_struct = PredicateS {
237 kind,
238 flags: flags.flags,
239 outer_exclusive_binder: flags.outer_exclusive_binder,
240 };
f035d41b 241
5099ac24
FG
242 InternedInSet(self.arena.alloc(predicate_struct))
243 })
244 .0,
245 ))
f035d41b 246 }
a7813a04
XL
247}
248
e9174d1e 249pub struct CommonTypes<'tcx> {
a1dfa0c6 250 pub unit: Ty<'tcx>,
e9174d1e
SL
251 pub bool: Ty<'tcx>,
252 pub char: Ty<'tcx>,
253 pub isize: Ty<'tcx>,
254 pub i8: Ty<'tcx>,
255 pub i16: Ty<'tcx>,
256 pub i32: Ty<'tcx>,
257 pub i64: Ty<'tcx>,
32a655c1 258 pub i128: Ty<'tcx>,
e9174d1e
SL
259 pub usize: Ty<'tcx>,
260 pub u8: Ty<'tcx>,
261 pub u16: Ty<'tcx>,
262 pub u32: Ty<'tcx>,
263 pub u64: Ty<'tcx>,
32a655c1 264 pub u128: Ty<'tcx>,
e9174d1e
SL
265 pub f32: Ty<'tcx>,
266 pub f64: Ty<'tcx>,
f035d41b 267 pub str_: Ty<'tcx>,
5bcae85e 268 pub never: Ty<'tcx>,
e1599b0c 269 pub self_param: Ty<'tcx>,
cc61c64b 270
532ac7d7
XL
271 /// Dummy type used for the `Self` of a `TraitRef` created for converting
272 /// a trait object, and which gets removed in `ExistentialTraitRef`.
273 /// This type must not appear anywhere in other converted types.
274 pub trait_object_dummy_self: Ty<'tcx>,
48663c56 275}
532ac7d7 276
48663c56 277pub struct CommonLifetimes<'tcx> {
74b04a01
XL
278 /// `ReEmpty` in the root universe.
279 pub re_root_empty: Region<'tcx>,
280
281 /// `ReStatic`
7cac9316 282 pub re_static: Region<'tcx>,
74b04a01 283
5099ac24 284 /// Erased region, used outside of type inference.
7cac9316 285 pub re_erased: Region<'tcx>,
e9174d1e
SL
286}
287
48663c56 288pub struct CommonConsts<'tcx> {
5099ac24 289 pub unit: Const<'tcx>,
48663c56
XL
290}
291
dc9dc135 292pub struct LocalTableInContext<'a, V> {
f035d41b 293 hir_owner: LocalDefId,
dfeec247 294 data: &'a ItemLocalMap<V>,
3b2f2976
XL
295}
296
297/// Validate that the given HirId (respectively its `local_id` part) can be
3dfed10e 298/// safely used as a key in the maps of a TypeckResults. For that to be
3b2f2976 299/// the case, the HirId must have the same `owner` as all the other IDs in
ba9703b0 300/// this table (signified by `hir_owner`). Otherwise the HirId
3b2f2976
XL
301/// would be in a different frame of reference and using its `local_id`
302/// would result in lookup errors, or worse, in silently wrong data being
303/// stored/returned.
6a06907d 304#[inline]
3dfed10e 305fn validate_hir_id_for_typeck_results(hir_owner: LocalDefId, hir_id: hir::HirId) {
f035d41b 306 if hir_id.owner != hir_owner {
6a06907d 307 invalid_hir_id_for_typeck_results(hir_owner, hir_id);
3b2f2976
XL
308 }
309}
310
6a06907d
XL
311#[cold]
312#[inline(never)]
313fn invalid_hir_id_for_typeck_results(hir_owner: LocalDefId, hir_id: hir::HirId) {
314 ty::tls::with(|tcx| {
315 bug!(
316 "node {} with HirId::owner {:?} cannot be placed in TypeckResults with hir_owner {:?}",
317 tcx.hir().node_to_string(hir_id),
318 hir_id.owner,
319 hir_owner
320 )
321 });
322}
323
3b2f2976
XL
324impl<'a, V> LocalTableInContext<'a, V> {
325 pub fn contains_key(&self, id: hir::HirId) -> bool {
3dfed10e 326 validate_hir_id_for_typeck_results(self.hir_owner, id);
3b2f2976
XL
327 self.data.contains_key(&id.local_id)
328 }
329
330 pub fn get(&self, id: hir::HirId) -> Option<&V> {
3dfed10e 331 validate_hir_id_for_typeck_results(self.hir_owner, id);
3b2f2976
XL
332 self.data.get(&id.local_id)
333 }
334
0bf4aa26 335 pub fn iter(&self) -> hash_map::Iter<'_, hir::ItemLocalId, V> {
3b2f2976
XL
336 self.data.iter()
337 }
338}
339
340impl<'a, V> ::std::ops::Index<hir::HirId> for LocalTableInContext<'a, V> {
341 type Output = V;
342
343 fn index(&self, key: hir::HirId) -> &V {
344 self.get(key).expect("LocalTableInContext: key not found")
345 }
346}
347
dc9dc135 348pub struct LocalTableInContextMut<'a, V> {
f035d41b 349 hir_owner: LocalDefId,
dfeec247 350 data: &'a mut ItemLocalMap<V>,
3b2f2976
XL
351}
352
353impl<'a, V> LocalTableInContextMut<'a, V> {
354 pub fn get_mut(&mut self, id: hir::HirId) -> Option<&mut V> {
3dfed10e 355 validate_hir_id_for_typeck_results(self.hir_owner, id);
3b2f2976
XL
356 self.data.get_mut(&id.local_id)
357 }
358
0bf4aa26 359 pub fn entry(&mut self, id: hir::HirId) -> Entry<'_, hir::ItemLocalId, V> {
3dfed10e 360 validate_hir_id_for_typeck_results(self.hir_owner, id);
3b2f2976
XL
361 self.data.entry(id.local_id)
362 }
363
364 pub fn insert(&mut self, id: hir::HirId, val: V) -> Option<V> {
3dfed10e 365 validate_hir_id_for_typeck_results(self.hir_owner, id);
3b2f2976
XL
366 self.data.insert(id.local_id, val)
367 }
368
369 pub fn remove(&mut self, id: hir::HirId) -> Option<V> {
3dfed10e 370 validate_hir_id_for_typeck_results(self.hir_owner, id);
3b2f2976
XL
371 self.data.remove(&id.local_id)
372 }
373}
374
e1599b0c
XL
375/// Whenever a value may be live across a generator yield, the type of that value winds up in the
376/// `GeneratorInteriorTypeCause` struct. This struct adds additional information about such
377/// captured types that can be useful for diagnostics. In particular, it stores the span that
378/// caused a given type to be recorded, along with the scope that enclosed the value (which can
379/// be used to find the await that the value is live across).
380///
381/// For example:
382///
383/// ```ignore (pseudo-Rust)
384/// async move {
f9f354fc 385/// let x: T = expr;
e1599b0c
XL
386/// foo.await
387/// ...
388/// }
389/// ```
390///
f9f354fc
XL
391/// Here, we would store the type `T`, the span of the value `x`, the "scope-span" for
392/// the scope that contains `x`, the expr `T` evaluated from, and the span of `foo.await`.
3dfed10e 393#[derive(TyEncodable, TyDecodable, Clone, Debug, Eq, Hash, PartialEq, HashStable)]
064997fb 394#[derive(TypeFoldable, TypeVisitable)]
e1599b0c
XL
395pub struct GeneratorInteriorTypeCause<'tcx> {
396 /// Type of the captured binding.
397 pub ty: Ty<'tcx>,
398 /// Span of the binding that was captured.
399 pub span: Span,
400 /// Span of the scope of the captured binding.
401 pub scope_span: Option<Span>,
f9f354fc
XL
402 /// Span of `.await` or `yield` expression.
403 pub yield_span: Span,
dfeec247
XL
404 /// Expr which the type evaluated from.
405 pub expr: Option<hir::HirId>,
e1599b0c
XL
406}
407
04454e1e
FG
408// This type holds diagnostic information on generators and async functions across crate boundaries
409// and is used to provide better error messages
410#[derive(TyEncodable, TyDecodable, Clone, Debug, HashStable)]
411pub struct GeneratorDiagnosticData<'tcx> {
412 pub generator_interior_types: ty::Binder<'tcx, Vec<GeneratorInteriorTypeCause<'tcx>>>,
413 pub hir_owner: DefId,
414 pub nodes_types: ItemLocalMap<Ty<'tcx>>,
415 pub adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
416}
417
5e7ed085 418#[derive(TyEncodable, TyDecodable, Debug, HashStable)]
3dfed10e 419pub struct TypeckResults<'tcx> {
ba9703b0 420 /// The `HirId::owner` all `ItemLocalId`s in this table are relative to.
f035d41b 421 pub hir_owner: LocalDefId,
3b2f2976 422
7cac9316
XL
423 /// Resolved definitions for `<T>::X` associated paths and
424 /// method calls, including those of overloaded operators.
5e7ed085 425 type_dependent_defs: ItemLocalMap<Result<(DefKind, DefId), ErrorGuaranteed>>,
476ff2be 426
83c7162d
XL
427 /// Resolved field indices for field accesses in expressions (`S { field }`, `obj.field`)
428 /// or patterns (`S { field }`). The index is often useful by itself, but to learn more
429 /// about the field you also need definition of the variant to which the field
430 /// belongs, but it may not exist if it's a tuple field (`tuple.0`).
431 field_indices: ItemLocalMap<usize>,
432
9fa01778 433 /// Stores the types for various nodes in the AST. Note that this table
5099ac24 434 /// is not guaranteed to be populated outside inference. See
e9174d1e 435 /// typeck::check::fn_ctxt for details.
3b2f2976 436 node_types: ItemLocalMap<Ty<'tcx>>,
e9174d1e
SL
437
438 /// Stores the type parameters which were substituted to obtain the type
9fa01778 439 /// of this node. This only applies to nodes that refer to entities
e9174d1e
SL
440 /// parameterized by type parameters, such as generic fns, types, or
441 /// other items.
532ac7d7 442 node_substs: ItemLocalMap<SubstsRef<'tcx>>,
e9174d1e 443
0731742a
XL
444 /// This will either store the canonicalized types provided by the user
445 /// or the substitutions that the user explicitly gave (if any) attached
446 /// to `id`. These will not include any inferred values. The canonical form
447 /// is used to capture things like `_` or other unspecified values.
448 ///
449 /// For example, if the user wrote `foo.collect::<Vec<_>>()`, then the
450 /// canonical substitutions would include only `for<X> { Vec<X> }`.
451 ///
452 /// See also `AscribeUserType` statement in MIR.
9fa01778 453 user_provided_types: ItemLocalMap<CanonicalUserType<'tcx>>,
0bf4aa26
XL
454
455 /// Stores the canonicalized types provided by the user. See also
456 /// `AscribeUserType` statement in MIR.
457 pub user_provided_sigs: DefIdMap<CanonicalPolyFnSig<'tcx>>,
458
3b2f2976
XL
459 adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
460
ea8adc8c 461 /// Stores the actual binding mode for all instances of hir::BindingAnnotation.
3b2f2976 462 pat_binding_modes: ItemLocalMap<BindingMode>,
e9174d1e 463
ea8adc8c 464 /// Stores the types which were implicitly dereferenced in pattern binding modes
3dfed10e 465 /// for later usage in THIR lowering. For example,
ea8adc8c
XL
466 ///
467 /// ```
468 /// match &&Some(5i32) {
469 /// Some(n) => {},
470 /// _ => {},
471 /// }
472 /// ```
473 /// leads to a `vec![&&Option<i32>, &Option<i32>]`. Empty vectors are not stored.
474 ///
475 /// See:
29967ef6 476 /// <https://github.com/rust-lang/rfcs/blob/master/text/2005-match-ergonomics.md#definitions>
ea8adc8c
XL
477 pat_adjustments: ItemLocalMap<Vec<Ty<'tcx>>>,
478
ff7c6d11
XL
479 /// Records the reasons that we picked the kind of each closure;
480 /// not all closures are present in the map.
5869c6ff 481 closure_kind_origins: ItemLocalMap<(Span, HirPlace<'tcx>)>,
ea8adc8c 482
92a42be0
SL
483 /// For each fn, records the "liberated" types of its arguments
484 /// and return type. Liberated means that all bound regions
485 /// (including late-bound regions) are replaced with free
94b46f34 486 /// equivalents. This table is not used in codegen (since regions
92a42be0 487 /// are erased there) and hence is not serialized to metadata.
136023e0
XL
488 ///
489 /// This table also contains the "revealed" values for any `impl Trait`
490 /// that appear in the signature and whose values are being inferred
491 /// by this function.
492 ///
493 /// # Example
494 ///
495 /// ```rust
04454e1e 496 /// # use std::fmt::Debug;
136023e0
XL
497 /// fn foo(x: &u32) -> impl Debug { *x }
498 /// ```
499 ///
500 /// The function signature here would be:
501 ///
04454e1e 502 /// ```ignore (illustrative)
136023e0
XL
503 /// for<'a> fn(&'a u32) -> Foo
504 /// ```
505 ///
506 /// where `Foo` is an opaque type created for this function.
507 ///
508 ///
509 /// The *liberated* form of this would be
510 ///
04454e1e 511 /// ```ignore (illustrative)
136023e0
XL
512 /// fn(&'a u32) -> u32
513 /// ```
514 ///
515 /// Note that `'a` is not bound (it would be an `ReFree`) and
516 /// that the `Foo` opaque type is replaced by its hidden type.
3b2f2976 517 liberated_fn_sigs: ItemLocalMap<ty::FnSig<'tcx>>,
7453a54e
SL
518
519 /// For each FRU expression, record the normalized types of the fields
520 /// of the struct - this is needed because it is non-trivial to
521 /// normalize while preserving regions. This table is used only in
522 /// MIR construction and hence is not serialized to metadata.
3b2f2976 523 fru_field_types: ItemLocalMap<Vec<Ty<'tcx>>>,
32a655c1 524
532ac7d7
XL
525 /// For every coercion cast we add the HIR node ID of the cast
526 /// expression to this set.
527 coercion_casts: ItemLocalSet,
8bb4bdeb
XL
528
529 /// Set of trait imports actually used in the method resolution.
abe05a73 530 /// This is used for warning unused imports. During type
0531ce1d 531 /// checking, this `Lrc` should not be cloned: it must have a ref-count
abe05a73 532 /// of 1 so that we can insert things into the set mutably.
f035d41b 533 pub used_trait_imports: Lrc<FxHashSet<LocalDefId>>,
8bb4bdeb
XL
534
535 /// If any errors occurred while type-checking this body,
5e7ed085
FG
536 /// this field will be set to `Some(ErrorGuaranteed)`.
537 pub tainted_by_errors: Option<ErrorGuaranteed>,
94b46f34 538
5e7ed085
FG
539 /// All the opaque types that have hidden types set
540 /// by this function. For return-position-impl-trait we also store the
541 /// type here, so that mir-borrowck can figure out hidden types,
542 /// even if they are only set in dead code (which doesn't show up in MIR).
543 /// For type-alias-impl-trait, this map is only used to prevent query cycles,
544 /// so the hidden types are all `None`.
064997fb 545 pub concrete_opaque_types: VecMap<LocalDefId, Option<Ty<'tcx>>>,
0731742a 546
fc512014
XL
547 /// Tracks the minimum captures required for a closure;
548 /// see `MinCaptureInformationMap` for more details.
549 pub closure_min_captures: ty::MinCaptureInformationMap<'tcx>,
550
6a06907d
XL
551 /// Tracks the fake reads required for a closure and the reason for the fake read.
552 /// When performing pattern matching for closures, there are times we don't end up
553 /// reading places that are mentioned in a closure (because of _ patterns). However,
554 /// to ensure the places are initialized, we introduce fake reads.
555 /// Consider these two examples:
556 /// ``` (discriminant matching with only wildcard arm)
557 /// let x: u8;
558 /// let c = || match x { _ => () };
559 /// ```
560 /// In this example, we don't need to actually read/borrow `x` in `c`, and so we don't
561 /// want to capture it. However, we do still want an error here, because `x` should have
562 /// to be initialized at the point where c is created. Therefore, we add a "fake read"
563 /// instead.
564 /// ``` (destructured assignments)
565 /// let c = || {
566 /// let (t1, t2) = t;
567 /// }
568 /// ```
569 /// In the second example, we capture the disjoint fields of `t` (`t.0` & `t.1`), but
570 /// we never capture `t`. This becomes an issue when we build MIR as we require
571 /// information on `t` in order to create place `t.0` and `t.1`. We can solve this
572 /// issue by fake reading `t`.
064997fb 573 pub closure_fake_reads: FxHashMap<LocalDefId, Vec<(HirPlace<'tcx>, FakeReadCause, hir::HirId)>>,
6a06907d 574
923072b8
FG
575 /// Tracks the rvalue scoping rules which defines finer scoping for rvalue expressions
576 /// by applying extended parameter rules.
577 /// Details may be find in `rustc_typeck::check::rvalue_scopes`.
578 pub rvalue_scopes: RvalueScopes,
579
dfeec247 580 /// Stores the type, expression, span and optional scope span of all types
e1599b0c 581 /// that are live across the yield of this generator (if a generator).
cdc7bbd5 582 pub generator_interior_types: ty::Binder<'tcx, Vec<GeneratorInteriorTypeCause<'tcx>>>,
29967ef6
XL
583
584 /// We sometimes treat byte string literals (which are of type `&[u8; N]`)
585 /// as `&[u8]`, depending on the pattern in which they are used.
586 /// This hashset records all instances where we behave
587 /// like this to allow `const_to_pat` to reliably handle this situation.
588 pub treat_byte_string_as_slice: ItemLocalSet,
136023e0
XL
589
590 /// Contains the data for evaluating the effect of feature `capture_disjoint_fields`
591 /// on closure size.
064997fb 592 pub closure_size_eval: FxHashMap<LocalDefId, ClosureSizeProfileData<'tcx>>,
e9174d1e
SL
593}
594
3dfed10e
XL
595impl<'tcx> TypeckResults<'tcx> {
596 pub fn new(hir_owner: LocalDefId) -> TypeckResults<'tcx> {
597 TypeckResults {
ba9703b0 598 hir_owner,
a1dfa0c6
XL
599 type_dependent_defs: Default::default(),
600 field_indices: Default::default(),
0731742a 601 user_provided_types: Default::default(),
0bf4aa26 602 user_provided_sigs: Default::default(),
a1dfa0c6
XL
603 node_types: Default::default(),
604 node_substs: Default::default(),
a1dfa0c6
XL
605 adjustments: Default::default(),
606 pat_binding_modes: Default::default(),
607 pat_adjustments: Default::default(),
a1dfa0c6
XL
608 closure_kind_origins: Default::default(),
609 liberated_fn_sigs: Default::default(),
610 fru_field_types: Default::default(),
532ac7d7 611 coercion_casts: Default::default(),
a1dfa0c6 612 used_trait_imports: Lrc::new(Default::default()),
ba9703b0 613 tainted_by_errors: None,
416331ca 614 concrete_opaque_types: Default::default(),
fc512014 615 closure_min_captures: Default::default(),
6a06907d 616 closure_fake_reads: Default::default(),
923072b8 617 rvalue_scopes: Default::default(),
fc512014 618 generator_interior_types: ty::Binder::dummy(Default::default()),
29967ef6 619 treat_byte_string_as_slice: Default::default(),
136023e0 620 closure_size_eval: Default::default(),
e9174d1e
SL
621 }
622 }
c30ab7b3 623
476ff2be 624 /// Returns the final resolution of a `QPath` in an `Expr` or `Pat` node.
dfeec247 625 pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res {
476ff2be 626 match *qpath {
48663c56 627 hir::QPath::Resolved(_, ref path) => path.res,
3dfed10e 628 hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self
dfeec247 629 .type_dependent_def(id)
48663c56 630 .map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)),
476ff2be
SL
631 }
632 }
633
48663c56
XL
634 pub fn type_dependent_defs(
635 &self,
5e7ed085 636 ) -> LocalTableInContext<'_, Result<(DefKind, DefId), ErrorGuaranteed>> {
ba9703b0 637 LocalTableInContext { hir_owner: self.hir_owner, data: &self.type_dependent_defs }
3b2f2976
XL
638 }
639
48663c56 640 pub fn type_dependent_def(&self, id: HirId) -> Option<(DefKind, DefId)> {
3dfed10e 641 validate_hir_id_for_typeck_results(self.hir_owner, id);
48663c56 642 self.type_dependent_defs.get(&id.local_id).cloned().and_then(|r| r.ok())
532ac7d7
XL
643 }
644
645 pub fn type_dependent_def_id(&self, id: HirId) -> Option<DefId> {
48663c56 646 self.type_dependent_def(id).map(|(_, def_id)| def_id)
532ac7d7
XL
647 }
648
48663c56
XL
649 pub fn type_dependent_defs_mut(
650 &mut self,
5e7ed085 651 ) -> LocalTableInContextMut<'_, Result<(DefKind, DefId), ErrorGuaranteed>> {
ba9703b0 652 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.type_dependent_defs }
3b2f2976
XL
653 }
654
0bf4aa26 655 pub fn field_indices(&self) -> LocalTableInContext<'_, usize> {
ba9703b0 656 LocalTableInContext { hir_owner: self.hir_owner, data: &self.field_indices }
83c7162d
XL
657 }
658
0bf4aa26 659 pub fn field_indices_mut(&mut self) -> LocalTableInContextMut<'_, usize> {
ba9703b0 660 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.field_indices }
83c7162d
XL
661 }
662
dfeec247 663 pub fn user_provided_types(&self) -> LocalTableInContext<'_, CanonicalUserType<'tcx>> {
ba9703b0 664 LocalTableInContext { hir_owner: self.hir_owner, data: &self.user_provided_types }
0531ce1d
XL
665 }
666
0731742a 667 pub fn user_provided_types_mut(
dfeec247 668 &mut self,
9fa01778 669 ) -> LocalTableInContextMut<'_, CanonicalUserType<'tcx>> {
ba9703b0 670 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.user_provided_types }
0531ce1d
XL
671 }
672
0bf4aa26 673 pub fn node_types(&self) -> LocalTableInContext<'_, Ty<'tcx>> {
ba9703b0 674 LocalTableInContext { hir_owner: self.hir_owner, data: &self.node_types }
3b2f2976
XL
675 }
676
0bf4aa26 677 pub fn node_types_mut(&mut self) -> LocalTableInContextMut<'_, Ty<'tcx>> {
ba9703b0 678 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_types }
3b2f2976
XL
679 }
680
04454e1e
FG
681 pub fn get_generator_diagnostic_data(&self) -> GeneratorDiagnosticData<'tcx> {
682 let generator_interior_type = self.generator_interior_types.map_bound_ref(|vec| {
683 vec.iter()
684 .map(|item| {
685 GeneratorInteriorTypeCause {
686 ty: item.ty,
687 span: item.span,
688 scope_span: item.scope_span,
689 yield_span: item.yield_span,
690 expr: None, //FIXME: Passing expression over crate boundaries is impossible at the moment
691 }
692 })
693 .collect::<Vec<_>>()
694 });
695 GeneratorDiagnosticData {
696 generator_interior_types: generator_interior_type,
697 hir_owner: self.hir_owner.to_def_id(),
698 nodes_types: self.node_types.clone(),
699 adjustments: self.adjustments.clone(),
700 }
701 }
702
9fa01778 703 pub fn node_type(&self, id: hir::HirId) -> Ty<'tcx> {
dfeec247
XL
704 self.node_type_opt(id).unwrap_or_else(|| {
705 bug!("node_type: no type for node `{}`", tls::with(|tcx| tcx.hir().node_to_string(id)))
706 })
c30ab7b3
SL
707 }
708
9fa01778 709 pub fn node_type_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> {
3dfed10e 710 validate_hir_id_for_typeck_results(self.hir_owner, id);
3b2f2976
XL
711 self.node_types.get(&id.local_id).cloned()
712 }
713
532ac7d7 714 pub fn node_substs_mut(&mut self) -> LocalTableInContextMut<'_, SubstsRef<'tcx>> {
ba9703b0 715 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_substs }
3b2f2976
XL
716 }
717
532ac7d7 718 pub fn node_substs(&self, id: hir::HirId) -> SubstsRef<'tcx> {
3dfed10e 719 validate_hir_id_for_typeck_results(self.hir_owner, id);
532ac7d7 720 self.node_substs.get(&id.local_id).cloned().unwrap_or_else(|| InternalSubsts::empty())
c30ab7b3
SL
721 }
722
532ac7d7 723 pub fn node_substs_opt(&self, id: hir::HirId) -> Option<SubstsRef<'tcx>> {
3dfed10e 724 validate_hir_id_for_typeck_results(self.hir_owner, id);
3b2f2976 725 self.node_substs.get(&id.local_id).cloned()
c30ab7b3
SL
726 }
727
728 // Returns the type of a pattern as a monotype. Like @expr_ty, this function
729 // doesn't provide type parameter substitutions.
dfeec247 730 pub fn pat_ty(&self, pat: &hir::Pat<'_>) -> Ty<'tcx> {
9fa01778 731 self.node_type(pat.hir_id)
c30ab7b3
SL
732 }
733
c30ab7b3
SL
734 // Returns the type of an expression as a monotype.
735 //
736 // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in
737 // some cases, we insert `Adjustment` annotations such as auto-deref or
738 // auto-ref. The type returned by this function does not consider such
739 // adjustments. See `expr_ty_adjusted()` instead.
740 //
0731742a 741 // NB (2): This type doesn't provide type parameter substitutions; e.g., if you
c30ab7b3
SL
742 // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
743 // instead of "fn(ty) -> T with T = isize".
dfeec247 744 pub fn expr_ty(&self, expr: &hir::Expr<'_>) -> Ty<'tcx> {
9fa01778 745 self.node_type(expr.hir_id)
c30ab7b3
SL
746 }
747
dfeec247 748 pub fn expr_ty_opt(&self, expr: &hir::Expr<'_>) -> Option<Ty<'tcx>> {
9fa01778 749 self.node_type_opt(expr.hir_id)
3b2f2976
XL
750 }
751
0bf4aa26 752 pub fn adjustments(&self) -> LocalTableInContext<'_, Vec<ty::adjustment::Adjustment<'tcx>>> {
ba9703b0 753 LocalTableInContext { hir_owner: self.hir_owner, data: &self.adjustments }
3b2f2976
XL
754 }
755
dfeec247
XL
756 pub fn adjustments_mut(
757 &mut self,
758 ) -> LocalTableInContextMut<'_, Vec<ty::adjustment::Adjustment<'tcx>>> {
ba9703b0 759 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.adjustments }
c30ab7b3
SL
760 }
761
dfeec247 762 pub fn expr_adjustments(&self, expr: &hir::Expr<'_>) -> &[ty::adjustment::Adjustment<'tcx>] {
3dfed10e 763 validate_hir_id_for_typeck_results(self.hir_owner, expr.hir_id);
3b2f2976 764 self.adjustments.get(&expr.hir_id.local_id).map_or(&[], |a| &a[..])
7cac9316
XL
765 }
766
c30ab7b3
SL
767 /// Returns the type of `expr`, considering any `Adjustment`
768 /// entry recorded for that expression.
dfeec247
XL
769 pub fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Ty<'tcx> {
770 self.expr_adjustments(expr).last().map_or_else(|| self.expr_ty(expr), |adj| adj.target)
c30ab7b3
SL
771 }
772
dfeec247
XL
773 pub fn expr_ty_adjusted_opt(&self, expr: &hir::Expr<'_>) -> Option<Ty<'tcx>> {
774 self.expr_adjustments(expr).last().map(|adj| adj.target).or_else(|| self.expr_ty_opt(expr))
c30ab7b3
SL
775 }
776
dfeec247 777 pub fn is_method_call(&self, expr: &hir::Expr<'_>) -> bool {
7cac9316
XL
778 // Only paths and method calls/overloaded operators have
779 // entries in type_dependent_defs, ignore the former here.
e74abb32 780 if let hir::ExprKind::Path(_) = expr.kind {
7cac9316
XL
781 return false;
782 }
c30ab7b3 783
29967ef6 784 matches!(self.type_dependent_defs().get(expr.hir_id), Some(Ok((DefKind::AssocFn, _))))
c30ab7b3
SL
785 }
786
dfeec247
XL
787 pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> Option<BindingMode> {
788 self.pat_binding_modes().get(id).copied().or_else(|| {
789 s.delay_span_bug(sp, "missing binding mode");
790 None
791 })
792 }
793
0bf4aa26 794 pub fn pat_binding_modes(&self) -> LocalTableInContext<'_, BindingMode> {
ba9703b0 795 LocalTableInContext { hir_owner: self.hir_owner, data: &self.pat_binding_modes }
3b2f2976
XL
796 }
797
dfeec247 798 pub fn pat_binding_modes_mut(&mut self) -> LocalTableInContextMut<'_, BindingMode> {
ba9703b0 799 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_binding_modes }
3b2f2976
XL
800 }
801
0bf4aa26 802 pub fn pat_adjustments(&self) -> LocalTableInContext<'_, Vec<Ty<'tcx>>> {
ba9703b0 803 LocalTableInContext { hir_owner: self.hir_owner, data: &self.pat_adjustments }
ea8adc8c
XL
804 }
805
dfeec247 806 pub fn pat_adjustments_mut(&mut self) -> LocalTableInContextMut<'_, Vec<Ty<'tcx>>> {
ba9703b0 807 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
ea8adc8c
XL
808 }
809
fc512014
XL
810 /// For a given closure, returns the iterator of `ty::CapturedPlace`s that are captured
811 /// by the closure.
812 pub fn closure_min_captures_flattened(
813 &self,
064997fb 814 closure_def_id: LocalDefId,
fc512014
XL
815 ) -> impl Iterator<Item = &ty::CapturedPlace<'tcx>> {
816 self.closure_min_captures
817 .get(&closure_def_id)
818 .map(|closure_min_captures| closure_min_captures.values().flat_map(|v| v.iter()))
819 .into_iter()
820 .flatten()
821 }
822
5869c6ff 823 pub fn closure_kind_origins(&self) -> LocalTableInContext<'_, (Span, HirPlace<'tcx>)> {
ba9703b0 824 LocalTableInContext { hir_owner: self.hir_owner, data: &self.closure_kind_origins }
3b2f2976
XL
825 }
826
5869c6ff
XL
827 pub fn closure_kind_origins_mut(
828 &mut self,
829 ) -> LocalTableInContextMut<'_, (Span, HirPlace<'tcx>)> {
ba9703b0 830 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.closure_kind_origins }
3b2f2976
XL
831 }
832
0bf4aa26 833 pub fn liberated_fn_sigs(&self) -> LocalTableInContext<'_, ty::FnSig<'tcx>> {
ba9703b0 834 LocalTableInContext { hir_owner: self.hir_owner, data: &self.liberated_fn_sigs }
3b2f2976
XL
835 }
836
0bf4aa26 837 pub fn liberated_fn_sigs_mut(&mut self) -> LocalTableInContextMut<'_, ty::FnSig<'tcx>> {
ba9703b0 838 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.liberated_fn_sigs }
3b2f2976
XL
839 }
840
0bf4aa26 841 pub fn fru_field_types(&self) -> LocalTableInContext<'_, Vec<Ty<'tcx>>> {
ba9703b0 842 LocalTableInContext { hir_owner: self.hir_owner, data: &self.fru_field_types }
3b2f2976
XL
843 }
844
0bf4aa26 845 pub fn fru_field_types_mut(&mut self) -> LocalTableInContextMut<'_, Vec<Ty<'tcx>>> {
ba9703b0 846 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.fru_field_types }
3b2f2976
XL
847 }
848
532ac7d7 849 pub fn is_coercion_cast(&self, hir_id: hir::HirId) -> bool {
3dfed10e 850 validate_hir_id_for_typeck_results(self.hir_owner, hir_id);
532ac7d7 851 self.coercion_casts.contains(&hir_id.local_id)
3b2f2976
XL
852 }
853
532ac7d7
XL
854 pub fn set_coercion_cast(&mut self, id: ItemLocalId) {
855 self.coercion_casts.insert(id);
3b2f2976 856 }
532ac7d7
XL
857
858 pub fn coercion_casts(&self) -> &ItemLocalSet {
859 &self.coercion_casts
860 }
3b2f2976
XL
861}
862
e74abb32 863rustc_index::newtype_index! {
0731742a 864 pub struct UserTypeAnnotationIndex {
532ac7d7 865 derive [HashStable]
9fa01778 866 DEBUG_FORMAT = "UserType({})",
0731742a
XL
867 const START_INDEX = 0,
868 }
869}
870
871/// Mapping of type annotation indices to canonical user type annotations.
872pub type CanonicalUserTypeAnnotations<'tcx> =
9fa01778
XL
873 IndexVec<UserTypeAnnotationIndex, CanonicalUserTypeAnnotation<'tcx>>;
874
064997fb 875#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable, Lift)]
9fa01778
XL
876pub struct CanonicalUserTypeAnnotation<'tcx> {
877 pub user_ty: CanonicalUserType<'tcx>,
878 pub span: Span,
879 pub inferred_ty: Ty<'tcx>,
880}
881
0731742a 882/// Canonicalized user type annotation.
dc9dc135 883pub type CanonicalUserType<'tcx> = Canonical<'tcx, UserType<'tcx>>;
0731742a 884
a2a8927a 885impl<'tcx> CanonicalUserType<'tcx> {
0731742a 886 /// Returns `true` if this represents a substitution of the form `[?0, ?1, ?2]`,
9fa01778 887 /// i.e., each thing is mapped to a canonical variable with the same index.
0731742a
XL
888 pub fn is_identity(&self) -> bool {
889 match self.value {
9fa01778
XL
890 UserType::Ty(_) => false,
891 UserType::TypeOf(_, user_substs) => {
0731742a
XL
892 if user_substs.user_self_ty.is_some() {
893 return false;
894 }
895
cdc7bbd5 896 iter::zip(user_substs.substs, BoundVar::new(0)..).all(|(kind, cvar)| {
0731742a 897 match kind.unpack() {
1b1a35ee 898 GenericArgKind::Type(ty) => match ty.kind() {
0731742a
XL
899 ty::Bound(debruijn, b) => {
900 // We only allow a `ty::INNERMOST` index in substitutions.
1b1a35ee 901 assert_eq!(*debruijn, ty::INNERMOST);
0731742a
XL
902 cvar == b.var
903 }
904 _ => false,
905 },
906
5099ac24 907 GenericArgKind::Lifetime(r) => match *r {
0731742a
XL
908 ty::ReLateBound(debruijn, br) => {
909 // We only allow a `ty::INNERMOST` index in substitutions.
5099ac24 910 assert_eq!(debruijn, ty::INNERMOST);
cdc7bbd5 911 cvar == br.var
0731742a
XL
912 }
913 _ => false,
914 },
532ac7d7 915
923072b8 916 GenericArgKind::Const(ct) => match ct.kind() {
60c5eb7d 917 ty::ConstKind::Bound(debruijn, b) => {
532ac7d7
XL
918 // We only allow a `ty::INNERMOST` index in substitutions.
919 assert_eq!(debruijn, ty::INNERMOST);
920 cvar == b
921 }
922 _ => false,
923 },
0731742a
XL
924 }
925 })
dfeec247 926 }
0731742a
XL
927 }
928 }
929}
930
9fa01778 931/// A user-given type annotation attached to a constant. These arise
0731742a
XL
932/// from constants that are named via paths, like `Foo::<A>::new` and
933/// so forth.
3dfed10e 934#[derive(Copy, Clone, Debug, PartialEq, TyEncodable, TyDecodable)]
064997fb 935#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
9fa01778 936pub enum UserType<'tcx> {
0731742a
XL
937 Ty(Ty<'tcx>),
938
939 /// The canonical type is the result of `type_of(def_id)` with the
940 /// given substitutions applied.
941 TypeOf(DefId, UserSubsts<'tcx>),
942}
943
e9174d1e 944impl<'tcx> CommonTypes<'tcx> {
5e7ed085
FG
945 fn new(
946 interners: &CtxtInterners<'tcx>,
947 sess: &Session,
923072b8
FG
948 definitions: &rustc_hir::definitions::Definitions,
949 cstore: &CrateStoreDyn,
950 source_span: &IndexVec<LocalDefId, Span>,
5e7ed085 951 ) -> CommonTypes<'tcx> {
923072b8 952 let mk = |ty| interners.intern_ty(ty, sess, definitions, cstore, source_span);
a1dfa0c6 953
e9174d1e 954 CommonTypes {
a1dfa0c6 955 unit: mk(Tuple(List::empty())),
b7449926
XL
956 bool: mk(Bool),
957 char: mk(Char),
958 never: mk(Never),
5869c6ff
XL
959 isize: mk(Int(ty::IntTy::Isize)),
960 i8: mk(Int(ty::IntTy::I8)),
961 i16: mk(Int(ty::IntTy::I16)),
962 i32: mk(Int(ty::IntTy::I32)),
963 i64: mk(Int(ty::IntTy::I64)),
964 i128: mk(Int(ty::IntTy::I128)),
965 usize: mk(Uint(ty::UintTy::Usize)),
966 u8: mk(Uint(ty::UintTy::U8)),
967 u16: mk(Uint(ty::UintTy::U16)),
968 u32: mk(Uint(ty::UintTy::U32)),
969 u64: mk(Uint(ty::UintTy::U64)),
970 u128: mk(Uint(ty::UintTy::U128)),
971 f32: mk(Float(ty::FloatTy::F32)),
972 f64: mk(Float(ty::FloatTy::F64)),
f035d41b 973 str_: mk(Str),
dfeec247 974 self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
cc61c64b 975
532ac7d7 976 trait_object_dummy_self: mk(Infer(ty::FreshTy(0))),
48663c56
XL
977 }
978 }
979}
532ac7d7 980
48663c56
XL
981impl<'tcx> CommonLifetimes<'tcx> {
982 fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
5099ac24
FG
983 let mk = |r| {
984 Region(Interned::new_unchecked(
985 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
986 ))
987 };
48663c56
XL
988
989 CommonLifetimes {
5099ac24
FG
990 re_root_empty: mk(ty::ReEmpty(ty::UniverseIndex::ROOT)),
991 re_static: mk(ty::ReStatic),
992 re_erased: mk(ty::ReErased),
48663c56
XL
993 }
994 }
995}
996
997impl<'tcx> CommonConsts<'tcx> {
998 fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonConsts<'tcx> {
5099ac24
FG
999 let mk_const = |c| {
1000 Const(Interned::new_unchecked(
1001 interners.const_.intern(c, |c| InternedInSet(interners.arena.alloc(c))).0,
1002 ))
1003 };
48663c56
XL
1004
1005 CommonConsts {
5099ac24 1006 unit: mk_const(ty::ConstS {
923072b8 1007 kind: ty::ConstKind::Value(ty::ValTree::zst()),
ba9703b0 1008 ty: types.unit,
dc9dc135 1009 }),
e9174d1e
SL
1010 }
1011 }
1012}
1013
0bf4aa26
XL
1014// This struct contains information regarding the `ReFree(FreeRegion)` corresponding to a lifetime
1015// conflict.
1016#[derive(Debug)]
1017pub struct FreeRegionInfo {
f035d41b
XL
1018 // `LocalDefId` corresponding to FreeRegion
1019 pub def_id: LocalDefId,
0bf4aa26 1020 // the bound region corresponding to FreeRegion
fc512014 1021 pub boundregion: ty::BoundRegionKind,
0bf4aa26
XL
1022 // checks if bound region is in Impl Item
1023 pub is_impl_item: bool,
1024}
1025
ea8adc8c
XL
1026/// The central data structure of the compiler. It stores references
1027/// to the various **arenas** and also houses the results of the
ff7c6d11 1028/// various **compiler queries** that have been performed. See the
ba9703b0 1029/// [rustc dev guide] for more details.
ff7c6d11 1030///
ba9703b0 1031/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/ty.html
a7813a04 1032#[derive(Copy, Clone)]
e74abb32 1033#[rustc_diagnostic_item = "TyCtxt"]
5e7ed085 1034#[rustc_pass_by_value]
dc9dc135
XL
1035pub struct TyCtxt<'tcx> {
1036 gcx: &'tcx GlobalCtxt<'tcx>,
a7813a04 1037}
e9174d1e 1038
dc9dc135
XL
1039impl<'tcx> Deref for TyCtxt<'tcx> {
1040 type Target = &'tcx GlobalCtxt<'tcx>;
a1dfa0c6 1041 #[inline(always)]
a7813a04
XL
1042 fn deref(&self) -> &Self::Target {
1043 &self.gcx
1044 }
1045}
1046
1047pub struct GlobalCtxt<'tcx> {
60c5eb7d 1048 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
064997fb 1049 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
dc9dc135 1050
416331ca 1051 interners: CtxtInterners<'tcx>,
e9174d1e 1052
8bb4bdeb
XL
1053 pub sess: &'tcx Session,
1054
dfeec247
XL
1055 /// This only ever stores a `LintStore` but we don't want a dependency on that type here.
1056 ///
1057 /// FIXME(Centril): consider `dyn LintStoreMarker` once
1058 /// we can upcast to `Any` for some additional type safety.
1059 pub lint_store: Lrc<dyn Any + sync::Sync + sync::Send>,
e74abb32 1060
9cc50fc6
SL
1061 pub dep_graph: DepGraph,
1062
e74abb32 1063 pub prof: SelfProfilerRef,
dc9dc135 1064
e9174d1e
SL
1065 /// Common types, pre-interned for your convenience.
1066 pub types: CommonTypes<'tcx>,
1067
48663c56
XL
1068 /// Common lifetimes, pre-interned for your convenience.
1069 pub lifetimes: CommonLifetimes<'tcx>,
1070
1071 /// Common consts, pre-interned for your convenience.
1072 pub consts: CommonConsts<'tcx>,
1073
064997fb 1074 definitions: RwLock<Definitions>,
923072b8
FG
1075 cstore: Box<CrateStoreDyn>,
1076
136023e0
XL
1077 /// Output of the resolver.
1078 pub(crate) untracked_resolutions: ty::ResolverOutputs,
064997fb
FG
1079 untracked_resolver_for_lowering: Steal<ty::ResolverAstLowering>,
1080 /// The entire crate as AST. This field serves as the input for the hir_crate query,
1081 /// which lowers it from AST to HIR. It must not be read or used by anything else.
1082 pub untracked_crate: Steal<Lrc<ast::Crate>>,
7cac9316 1083
6a06907d
XL
1084 /// This provides access to the incremental compilation on-disk cache for query results.
1085 /// Do not access this directly. It is only meant to be used by
1086 /// `DepGraph::try_mark_green()` and the query infrastructure.
1087 /// This is `None` if we are not incremental compilation mode
136023e0 1088 pub on_disk_cache: Option<&'tcx dyn OnDiskCache<'tcx>>,
6a06907d
XL
1089
1090 pub queries: &'tcx dyn query::QueryEngine<'tcx>,
1091 pub query_caches: query::QueryCaches<'tcx>,
3c0e092e 1092 query_kinds: &'tcx [DepKindStruct],
c30ab7b3 1093
f035d41b
XL
1094 // Internal caches for metadata decoding. No need to track deps on this.
1095 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
1096 pub pred_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Predicate<'tcx>>>,
9cc50fc6 1097
e9174d1e
SL
1098 /// Caches the results of trait selection. This cache is used
1099 /// for things that do not have to do with the parameters in scope.
1100 pub selection_cache: traits::SelectionCache<'tcx>,
1101
92a42be0
SL
1102 /// Caches the results of trait evaluation. This cache is used
1103 /// for things that do not have to do with the parameters in scope.
1104 /// Merge this with `selection_cache`?
1105 pub evaluation_cache: traits::EvaluationCache<'tcx>,
1106
54a0048b
SL
1107 /// The definite name of the current crate after taking into account
1108 /// attributes, commandline parameters, etc.
17df50a5 1109 crate_name: Symbol,
54a0048b
SL
1110
1111 /// Data layout specification for the current target.
1112 pub data_layout: TargetDataLayout,
1113
ba9703b0 1114 /// Stores memory for globals (statics/consts).
f9f354fc 1115 pub(crate) alloc_map: Lock<interpret::AllocMap<'tcx>>,
ff7c6d11 1116
ea8adc8c 1117 output_filenames: Arc<OutputFilenames>,
e9174d1e 1118}
e9174d1e 1119
dc9dc135 1120impl<'tcx> TyCtxt<'tcx> {
04454e1e
FG
1121 /// Expects a body and returns its codegen attributes.
1122 ///
1123 /// Unlike `codegen_fn_attrs`, this returns `CodegenFnAttrs::EMPTY` for
1124 /// constants.
1125 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
1126 let def_kind = self.def_kind(def_id);
1127 if def_kind.has_codegen_attrs() {
1128 self.codegen_fn_attrs(def_id)
1129 } else if matches!(
1130 def_kind,
1131 DefKind::AnonConst | DefKind::AssocConst | DefKind::Const | DefKind::InlineConst
1132 ) {
1133 CodegenFnAttrs::EMPTY
1134 } else {
1135 bug!(
1136 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
1137 def_id,
1138 def_kind
1139 )
1140 }
1141 }
1142
3dfed10e
XL
1143 pub fn typeck_opt_const_arg(
1144 self,
1145 def: ty::WithOptConstParam<LocalDefId>,
1146 ) -> &'tcx TypeckResults<'tcx> {
1147 if let Some(param_did) = def.const_param_did {
1148 self.typeck_const_arg((def.did, param_did))
1149 } else {
1150 self.typeck(def.did)
1151 }
1152 }
1153
5099ac24
FG
1154 pub fn mir_borrowck_opt_const_arg(
1155 self,
1156 def: ty::WithOptConstParam<LocalDefId>,
1157 ) -> &'tcx BorrowCheckResult<'tcx> {
1158 if let Some(param_did) = def.const_param_did {
1159 self.mir_borrowck_const_arg((def.did, param_did))
1160 } else {
1161 self.mir_borrowck(def.did)
1162 }
1163 }
1164
17df50a5
XL
1165 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
1166 self.arena.alloc(Steal::new(thir))
1167 }
1168
3dfed10e
XL
1169 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
1170 self.arena.alloc(Steal::new(mir))
7cac9316
XL
1171 }
1172
dfeec247
XL
1173 pub fn alloc_steal_promoted(
1174 self,
f9f354fc 1175 promoted: IndexVec<Promoted, Body<'tcx>>,
3dfed10e
XL
1176 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
1177 self.arena.alloc(Steal::new(promoted))
e1599b0c
XL
1178 }
1179
dc9dc135
XL
1180 pub fn alloc_adt_def(
1181 self,
1182 did: DefId,
1183 kind: AdtKind,
1184 variants: IndexVec<VariantIdx, ty::VariantDef>,
1185 repr: ReprOptions,
5e7ed085
FG
1186 ) -> ty::AdtDef<'tcx> {
1187 self.intern_adt_def(ty::AdtDefData::new(self, did, kind, variants, repr))
e9174d1e
SL
1188 }
1189
e1599b0c 1190 /// Allocates a read-only byte or string literal for `mir::interpret`.
94b46f34 1191 pub fn allocate_bytes(self, bytes: &[u8]) -> interpret::AllocId {
e1599b0c 1192 // Create an allocation that just contains these bytes.
17df50a5 1193 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes);
ff7c6d11 1194 let alloc = self.intern_const_alloc(alloc);
f9f354fc 1195 self.create_memory_alloc(alloc)
ff7c6d11
XL
1196 }
1197
b7449926
XL
1198 /// Returns a range of the start/end indices specified with the
1199 /// `rustc_layout_scalar_valid_range` attribute.
c295e0f8 1200 // FIXME(eddyb) this is an awkward spot for this method, maybe move it?
b7449926 1201 pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
b7449926 1202 let get = |name| {
04454e1e 1203 let Some(attr) = self.get_attr(def_id, name) else {
5e7ed085 1204 return Bound::Unbounded;
b7449926 1205 };
f035d41b 1206 debug!("layout_scalar_valid_range: attr={:?}", attr);
6a06907d 1207 if let Some(
a2a8927a
XL
1208 &[
1209 ast::NestedMetaItem::Literal(ast::Lit {
1210 kind: ast::LitKind::Int(a, _), ..
1211 }),
1212 ],
6a06907d
XL
1213 ) = attr.meta_item_list().as_deref()
1214 {
1215 Bound::Included(a)
1216 } else {
1217 self.sess
1218 .delay_span_bug(attr.span, "invalid rustc_layout_scalar_valid_range attribute");
1219 Bound::Unbounded
b7449926 1220 }
b7449926 1221 };
dfeec247
XL
1222 (
1223 get(sym::rustc_layout_scalar_valid_range_start),
1224 get(sym::rustc_layout_scalar_valid_range_end),
1225 )
b7449926
XL
1226 }
1227
29967ef6 1228 pub fn lift<T: Lift<'tcx>>(self, value: T) -> Option<T::Lifted> {
e9174d1e
SL
1229 value.lift_to_tcx(self)
1230 }
1231
9fa01778 1232 /// Creates a type context and call the closure with a `TyCtxt` reference
e9174d1e
SL
1233 /// to the context. The closure enforces that the type context and any interned
1234 /// value (types, substs, etc.) can only be used while `ty::tls` has a valid
1235 /// reference to the context, to allow formatting values that need it.
532ac7d7
XL
1236 pub fn create_global_ctxt(
1237 s: &'tcx Session,
dfeec247 1238 lint_store: Lrc<dyn Any + sync::Send + sync::Sync>,
60c5eb7d 1239 arena: &'tcx WorkerLocal<Arena<'tcx>>,
064997fb
FG
1240 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1241 definitions: Definitions,
923072b8
FG
1242 cstore: Box<CrateStoreDyn>,
1243 untracked_resolutions: ty::ResolverOutputs,
064997fb
FG
1244 untracked_resolver_for_lowering: ty::ResolverAstLowering,
1245 krate: Lrc<ast::Crate>,
ba9703b0 1246 dep_graph: DepGraph,
136023e0 1247 on_disk_cache: Option<&'tcx dyn OnDiskCache<'tcx>>,
6a06907d 1248 queries: &'tcx dyn query::QueryEngine<'tcx>,
3c0e092e 1249 query_kinds: &'tcx [DepKindStruct],
532ac7d7 1250 crate_name: &str,
17df50a5 1251 output_filenames: OutputFilenames,
532ac7d7 1252 ) -> GlobalCtxt<'tcx> {
29967ef6 1253 let data_layout = TargetDataLayout::parse(&s.target).unwrap_or_else(|err| {
83c7162d
XL
1254 s.fatal(&err);
1255 });
dfeec247 1256 let interners = CtxtInterners::new(arena);
923072b8
FG
1257 let common_types = CommonTypes::new(
1258 &interners,
1259 s,
1260 &definitions,
1261 &*cstore,
1262 // This is only used to create a stable hashing context.
1263 &untracked_resolutions.source_span,
1264 );
48663c56
XL
1265 let common_lifetimes = CommonLifetimes::new(&interners);
1266 let common_consts = CommonConsts::new(&interners, &common_types);
7cac9316 1267
532ac7d7 1268 GlobalCtxt {
8bb4bdeb 1269 sess: s,
e74abb32 1270 lint_store,
60c5eb7d 1271 arena,
064997fb 1272 hir_arena,
416331ca 1273 interners,
0bf4aa26 1274 dep_graph,
064997fb 1275 definitions: RwLock::new(definitions),
923072b8 1276 cstore,
e74abb32 1277 prof: s.prof.clone(),
e9174d1e 1278 types: common_types,
48663c56
XL
1279 lifetimes: common_lifetimes,
1280 consts: common_consts,
064997fb
FG
1281 untracked_resolutions,
1282 untracked_resolver_for_lowering: Steal::new(untracked_resolver_for_lowering),
1283 untracked_crate: Steal::new(krate),
6a06907d
XL
1284 on_disk_cache,
1285 queries,
1286 query_caches: query::QueryCaches::default(),
3c0e092e 1287 query_kinds,
f035d41b
XL
1288 ty_rcache: Default::default(),
1289 pred_rcache: Default::default(),
0bf4aa26
XL
1290 selection_cache: Default::default(),
1291 evaluation_cache: Default::default(),
476ff2be 1292 crate_name: Symbol::intern(crate_name),
041b39d2 1293 data_layout,
94b46f34 1294 alloc_map: Lock::new(interpret::AllocMap::new()),
17df50a5 1295 output_filenames: Arc::new(output_filenames),
532ac7d7 1296 }
e9174d1e 1297 }
cc61c64b 1298
923072b8 1299 pub(crate) fn query_kind(self, k: DepKind) -> &'tcx DepKindStruct {
3c0e092e
XL
1300 &self.query_kinds[k as usize]
1301 }
1302
f035d41b
XL
1303 /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used.
1304 #[track_caller]
1305 pub fn ty_error(self) -> Ty<'tcx> {
1306 self.ty_error_with_message(DUMMY_SP, "TyKind::Error constructed but no error reported")
1307 }
1308
1309 /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg` to
1310 /// ensure it gets used.
1311 #[track_caller]
1312 pub fn ty_error_with_message<S: Into<MultiSpan>>(self, span: S, msg: &str) -> Ty<'tcx> {
5e7ed085
FG
1313 let reported = self.sess.delay_span_bug(span, msg);
1314 self.mk_ty(Error(DelaySpanBugEmitted { reported, _priv: () }))
f035d41b
XL
1315 }
1316
5099ac24 1317 /// Like [TyCtxt::ty_error] but for constants.
f035d41b 1318 #[track_caller]
5099ac24
FG
1319 pub fn const_error(self, ty: Ty<'tcx>) -> Const<'tcx> {
1320 self.const_error_with_message(
1321 ty,
1322 DUMMY_SP,
1323 "ty::ConstKind::Error constructed but no error reported",
1324 )
1325 }
1326
1327 /// Like [TyCtxt::ty_error_with_message] but for constants.
1328 #[track_caller]
1329 pub fn const_error_with_message<S: Into<MultiSpan>>(
1330 self,
1331 ty: Ty<'tcx>,
1332 span: S,
1333 msg: &str,
1334 ) -> Const<'tcx> {
5e7ed085
FG
1335 let reported = self.sess.delay_span_bug(span, msg);
1336 self.mk_const(ty::ConstS {
923072b8 1337 kind: ty::ConstKind::Error(DelaySpanBugEmitted { reported, _priv: () }),
5e7ed085
FG
1338 ty,
1339 })
f035d41b
XL
1340 }
1341
1b1a35ee 1342 pub fn consider_optimizing<T: Fn() -> String>(self, msg: T) -> bool {
a2a8927a
XL
1343 let cname = self.crate_name(LOCAL_CRATE);
1344 self.sess.consider_optimizing(cname.as_str(), msg)
b7449926
XL
1345 }
1346
e1599b0c 1347 /// Obtain all lang items of this crate and all dependencies (recursively)
ba9703b0 1348 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
17df50a5 1349 self.get_lang_items(())
ea8adc8c
XL
1350 }
1351
e1599b0c
XL
1352 /// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to
1353 /// compare against another `DefId`, since `is_diagnostic_item` is cheaper.
1354 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
c295e0f8
XL
1355 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1356 }
1357
1358 /// Obtain the diagnostic item's name
1359 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1360 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
e1599b0c
XL
1361 }
1362
1363 /// Check whether the diagnostic item with the given `name` has the given `DefId`.
1364 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
c295e0f8 1365 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
e1599b0c
XL
1366 }
1367
5e7ed085 1368 pub fn stability(self) -> &'tcx stability::Index {
17df50a5 1369 self.stability_index(())
ea8adc8c
XL
1370 }
1371
60c5eb7d 1372 pub fn features(self) -> &'tcx rustc_feature::Features {
17df50a5 1373 self.features_query(())
0531ce1d
XL
1374 }
1375
ba9703b0 1376 pub fn def_key(self, id: DefId) -> rustc_hir::definitions::DefKey {
136023e0
XL
1377 // Accessing the DefKey is ok, since it is part of DefPathHash.
1378 if let Some(id) = id.as_local() {
064997fb 1379 self.definitions_untracked().def_key(id)
136023e0 1380 } else {
923072b8 1381 self.cstore.def_key(id)
136023e0 1382 }
ea8adc8c
XL
1383 }
1384
9fa01778 1385 /// Converts a `DefId` into its fully expanded `DefPath` (every
e1599b0c 1386 /// `DefId` is really just an interned `DefPath`).
ea8adc8c
XL
1387 ///
1388 /// Note that if `id` is not local to this crate, the result will
1389 /// be a non-local `DefPath`.
ba9703b0 1390 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
136023e0 1391 // Accessing the DefPath is ok, since it is part of DefPathHash.
ba9703b0 1392 if let Some(id) = id.as_local() {
064997fb 1393 self.definitions_untracked().def_path(id)
ba9703b0 1394 } else {
923072b8 1395 self.cstore.def_path(id)
ba9703b0 1396 }
ea8adc8c
XL
1397 }
1398
1399 #[inline]
ba9703b0 1400 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
136023e0 1401 // Accessing the DefPathHash is ok, it is incr. comp. stable.
ba9703b0 1402 if let Some(def_id) = def_id.as_local() {
064997fb 1403 self.definitions_untracked().def_path_hash(def_id)
ea8adc8c 1404 } else {
923072b8 1405 self.cstore.def_path_hash(def_id)
ea8adc8c
XL
1406 }
1407 }
1408
17df50a5 1409 #[inline]
136023e0
XL
1410 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1411 if crate_num == LOCAL_CRATE {
1412 self.sess.local_stable_crate_id()
1413 } else {
923072b8 1414 self.cstore.stable_crate_id(crate_num)
136023e0 1415 }
17df50a5
XL
1416 }
1417
c295e0f8
XL
1418 /// Maps a StableCrateId to the corresponding CrateNum. This method assumes
1419 /// that the crate in question has already been loaded by the CrateStore.
1420 #[inline]
1421 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1422 if stable_crate_id == self.sess.local_stable_crate_id() {
1423 LOCAL_CRATE
1424 } else {
923072b8 1425 self.cstore.stable_crate_id_to_crate_num(stable_crate_id)
c295e0f8
XL
1426 }
1427 }
1428
3c0e092e
XL
1429 /// Converts a `DefPathHash` to its corresponding `DefId` in the current compilation
1430 /// session, if it still exists. This is used during incremental compilation to
1431 /// turn a deserialized `DefPathHash` into its current `DefId`.
5099ac24 1432 pub fn def_path_hash_to_def_id(self, hash: DefPathHash, err: &mut dyn FnMut() -> !) -> DefId {
3c0e092e
XL
1433 debug!("def_path_hash_to_def_id({:?})", hash);
1434
1435 let stable_crate_id = hash.stable_crate_id();
1436
1437 // If this is a DefPathHash from the local crate, we can look up the
1438 // DefId in the tcx's `Definitions`.
1439 if stable_crate_id == self.sess.local_stable_crate_id() {
064997fb 1440 self.definitions.read().local_def_path_hash_to_def_id(hash, err).to_def_id()
3c0e092e
XL
1441 } else {
1442 // If this is a DefPathHash from an upstream crate, let the CrateStore map
1443 // it to a DefId.
923072b8
FG
1444 let cnum = self.cstore.stable_crate_id_to_crate_num(stable_crate_id);
1445 self.cstore.def_path_hash_to_def_id(cnum, hash)
3c0e092e
XL
1446 }
1447 }
1448
ea8adc8c
XL
1449 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1450 // We are explicitly not going through queries here in order to get
136023e0 1451 // crate name and stable crate id since this code is called from debug!()
ea8adc8c
XL
1452 // statements within the query system and we'd run into endless
1453 // recursion otherwise.
136023e0
XL
1454 let (crate_name, stable_crate_id) = if def_id.is_local() {
1455 (self.crate_name, self.sess.local_stable_crate_id())
ea8adc8c 1456 } else {
923072b8 1457 let cstore = &self.cstore;
136023e0 1458 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
ea8adc8c
XL
1459 };
1460
dfeec247 1461 format!(
064997fb 1462 "{}[{:04x}]{}",
dfeec247 1463 crate_name,
136023e0 1464 // Don't print the whole stable crate id. That's just
dfeec247 1465 // annoying in debug output.
064997fb 1466 stable_crate_id.to_u64() >> 8 * 6,
1b1a35ee 1467 self.def_path(def_id).to_string_no_crate_verbose()
dfeec247 1468 )
ea8adc8c
XL
1469 }
1470
064997fb
FG
1471 /// Create a new definition within the incr. comp. engine.
1472 pub fn create_def(self, parent: LocalDefId, data: hir::definitions::DefPathData) -> LocalDefId {
1473 // This function modifies `self.definitions` using a side-effect.
1474 // We need to ensure that these side effects are re-run by the incr. comp. engine.
1475 // Depending on the forever-red node will tell the graph that the calling query
1476 // needs to be re-evaluated.
1477 use rustc_query_system::dep_graph::DepNodeIndex;
1478 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1479
1480 // The following call has the side effect of modifying the tables inside `definitions`.
1481 // These very tables are relied on by the incr. comp. engine to decode DepNodes and to
1482 // decode the on-disk cache.
1483 //
1484 // Any LocalDefId which is used within queries, either as key or result, either:
1485 // - has been created before the construction of the TyCtxt;
1486 // - has been created by this call to `create_def`.
1487 // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
1488 // comp. engine itself.
1489 //
1490 // This call also writes to the value of `source_span` and `expn_that_defined` queries.
1491 // This is fine because:
1492 // - those queries are `eval_always` so we won't miss their result changing;
1493 // - this write will have happened before these queries are called.
1494 self.definitions.write().create_def(parent, data)
1495 }
1496
1497 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> + 'tcx {
1498 // Create a dependency to the crate to be sure we re-execute this when the amount of
1499 // definitions change.
1500 self.ensure().hir_crate(());
1501 // Leak a read lock once we start iterating on definitions, to prevent adding new onces
1502 // while iterating. If some query needs to add definitions, it should be `ensure`d above.
1503 let definitions = self.definitions.leak();
1504 definitions.iter_local_def_id()
1505 }
1506
1507 pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
1508 // Create a dependency to the crate to be sure we reexcute this when the amount of
1509 // definitions change.
1510 self.ensure().hir_crate(());
1511 // Leak a read lock once we start iterating on definitions, to prevent adding new onces
1512 // while iterating. If some query needs to add definitions, it should be `ensure`d above.
1513 let definitions = self.definitions.leak();
1514 definitions.def_path_table()
1515 }
1516
1517 pub fn def_path_hash_to_def_index_map(
1518 self,
1519 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
1520 // Create a dependency to the crate to be sure we reexcute this when the amount of
1521 // definitions change.
1522 self.ensure().hir_crate(());
1523 // Leak a read lock once we start iterating on definitions, to prevent adding new onces
1524 // while iterating. If some query needs to add definitions, it should be `ensure`d above.
1525 let definitions = self.definitions.leak();
1526 definitions.def_path_hash_to_def_index_map()
1527 }
1528
136023e0
XL
1529 /// Note that this is *untracked* and should only be used within the query
1530 /// system if the result is otherwise tracked through queries
923072b8
FG
1531 pub fn cstore_untracked(self) -> &'tcx CrateStoreDyn {
1532 &*self.cstore
136023e0
XL
1533 }
1534
1535 /// Note that this is *untracked* and should only be used within the query
1536 /// system if the result is otherwise tracked through queries
064997fb
FG
1537 #[inline]
1538 pub fn definitions_untracked(self) -> ReadGuard<'tcx, Definitions> {
1539 self.definitions.read()
923072b8
FG
1540 }
1541
1542 /// Note that this is *untracked* and should only be used within the query
1543 /// system if the result is otherwise tracked through queries
1544 #[inline]
1545 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
1546 self.untracked_resolutions.source_span.get(def_id).copied().unwrap_or(DUMMY_SP)
ea8adc8c
XL
1547 }
1548
0731742a 1549 #[inline(always)]
064997fb
FG
1550 pub fn with_stable_hashing_context<R>(
1551 self,
1552 f: impl FnOnce(StableHashingContext<'_>) -> R,
1553 ) -> R {
1554 let definitions = self.definitions_untracked();
1555 let hcx = StableHashingContext::new(
136023e0 1556 self.sess,
064997fb 1557 &*definitions,
923072b8
FG
1558 &*self.cstore,
1559 &self.untracked_resolutions.source_span,
064997fb
FG
1560 );
1561 f(hcx)
f035d41b
XL
1562 }
1563
923072b8
FG
1564 pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
1565 self.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
0531ce1d
XL
1566 }
1567
f9f354fc
XL
1568 /// If `true`, we should use lazy normalization for constants, otherwise
1569 /// we still evaluate them eagerly.
1570 #[inline]
1571 pub fn lazy_normalization(self) -> bool {
3dfed10e 1572 let features = self.features();
94222f64
XL
1573 // Note: We only use lazy normalization for generic const expressions.
1574 features.generic_const_exprs
f9f354fc
XL
1575 }
1576
83c7162d
XL
1577 #[inline]
1578 pub fn local_crate_exports_generics(self) -> bool {
b7449926 1579 debug_assert!(self.sess.opts.share_generics());
83c7162d 1580
f9f354fc 1581 self.sess.crate_types().iter().any(|crate_type| {
83c7162d 1582 match crate_type {
dfeec247
XL
1583 CrateType::Executable
1584 | CrateType::Staticlib
1585 | CrateType::ProcMacro
1586 | CrateType::Cdylib => false,
e74abb32
XL
1587
1588 // FIXME rust-lang/rust#64319, rust-lang/rust#64872:
1589 // We want to block export of generics from dylibs,
1590 // but we must fix rust-lang/rust#65890 before we can
1591 // do that robustly.
dfeec247 1592 CrateType::Dylib => true,
e74abb32 1593
dfeec247 1594 CrateType::Rlib => true,
83c7162d
XL
1595 }
1596 })
0531ce1d 1597 }
0bf4aa26 1598
fc512014 1599 // Returns the `DefId` and the `BoundRegionKind` corresponding to the given region.
1b1a35ee 1600 pub fn is_suitable_region(self, region: Region<'tcx>) -> Option<FreeRegionInfo> {
0bf4aa26 1601 let (suitable_region_binding_scope, bound_region) = match *region {
f035d41b
XL
1602 ty::ReFree(ref free_region) => {
1603 (free_region.scope.expect_local(), free_region.bound_region)
dfeec247 1604 }
f035d41b 1605 ty::ReEarlyBound(ref ebr) => (
04454e1e 1606 self.local_parent(ebr.def_id.expect_local()),
fc512014 1607 ty::BoundRegionKind::BrNamed(ebr.def_id, ebr.name),
f035d41b 1608 ),
0bf4aa26
XL
1609 _ => return None, // not a free region
1610 };
1611
5099ac24 1612 let is_impl_item = match self.hir().find_by_def_id(suitable_region_binding_scope) {
ba9703b0 1613 Some(Node::Item(..) | Node::TraitItem(..)) => false,
0bf4aa26
XL
1614 Some(Node::ImplItem(..)) => {
1615 self.is_bound_region_in_impl_item(suitable_region_binding_scope)
1616 }
1617 _ => return None,
1618 };
1619
ba9703b0 1620 Some(FreeRegionInfo {
0bf4aa26
XL
1621 def_id: suitable_region_binding_scope,
1622 boundregion: bound_region,
60c5eb7d 1623 is_impl_item,
ba9703b0 1624 })
0bf4aa26
XL
1625 }
1626
f035d41b
XL
1627 /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type.
1628 pub fn return_type_impl_or_dyn_traits(
1b1a35ee 1629 self,
f035d41b
XL
1630 scope_def_id: LocalDefId,
1631 ) -> Vec<&'tcx hir::Ty<'tcx>> {
3dfed10e 1632 let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
5e7ed085
FG
1633 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir().fn_decl_by_hir_id(hir_id) else {
1634 return vec![];
f9f354fc
XL
1635 };
1636
f035d41b
XL
1637 let mut v = TraitObjectVisitor(vec![], self.hir());
1638 v.visit_ty(hir_output);
1639 v.0
f9f354fc
XL
1640 }
1641
1b1a35ee 1642 pub fn return_type_impl_trait(self, scope_def_id: LocalDefId) -> Option<(Ty<'tcx>, Span)> {
136023e0 1643 // `type_of()` will fail on these (#55796, #86483), so only allow `fn`s or closures.
5099ac24 1644 match self.hir().get_by_def_id(scope_def_id) {
136023e0
XL
1645 Node::Item(&hir::Item { kind: ItemKind::Fn(..), .. }) => {}
1646 Node::TraitItem(&hir::TraitItem { kind: TraitItemKind::Fn(..), .. }) => {}
1647 Node::ImplItem(&hir::ImplItem { kind: ImplItemKind::Fn(..), .. }) => {}
923072b8 1648 Node::Expr(&hir::Expr { kind: ExprKind::Closure { .. }, .. }) => {}
136023e0 1649 _ => return None,
13cf67c4
XL
1650 }
1651
0bf4aa26 1652 let ret_ty = self.type_of(scope_def_id);
1b1a35ee 1653 match ret_ty.kind() {
0bf4aa26 1654 ty::FnDef(_, _) => {
1b1a35ee 1655 let sig = ret_ty.fn_sig(self);
fc512014 1656 let output = self.erase_late_bound_regions(sig.output());
0bf4aa26 1657 if output.is_impl_trait() {
5099ac24 1658 let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
60c5eb7d
XL
1659 let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap();
1660 Some((output, fn_decl.output.span()))
0bf4aa26
XL
1661 } else {
1662 None
1663 }
1664 }
dfeec247 1665 _ => None,
0bf4aa26
XL
1666 }
1667 }
1668
e1599b0c 1669 // Checks if the bound region is in Impl Item.
1b1a35ee 1670 pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
064997fb 1671 let container_id = self.parent(suitable_region_binding_scope.to_def_id());
0bf4aa26
XL
1672 if self.impl_trait_ref(container_id).is_some() {
1673 // For now, we do not try to target impls of traits. This is
1674 // because this message is going to suggest that the user
1675 // change the fn signature, but they may not be free to do so,
1676 // since the signature must match the trait.
1677 //
1678 // FIXME(#42706) -- in some cases, we could do better here.
1679 return true;
1680 }
1681 false
1682 }
9fa01778 1683
e1599b0c 1684 /// Determines whether identifiers in the assembly have strict naming rules.
9fa01778 1685 /// Currently, only NVPTX* targets need it.
1b1a35ee 1686 pub fn has_strict_asm_symbol_naming(self) -> bool {
29967ef6 1687 self.sess.target.arch.contains("nvptx")
ea8adc8c 1688 }
60c5eb7d
XL
1689
1690 /// Returns `&'static core::panic::Location<'static>`.
1b1a35ee 1691 pub fn caller_location_ty(self) -> Ty<'tcx> {
60c5eb7d
XL
1692 self.mk_imm_ref(
1693 self.lifetimes.re_static,
04454e1e 1694 self.bound_type_of(self.require_lang_item(LangItem::PanicLocation, None))
1b1a35ee 1695 .subst(self, self.mk_substs([self.lifetimes.re_static.into()].iter())),
60c5eb7d
XL
1696 )
1697 }
74b04a01
XL
1698
1699 /// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`).
1b1a35ee 1700 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
f9f354fc
XL
1701 match self.def_kind(def_id) {
1702 DefKind::Generator => match self.generator_kind(def_id).unwrap() {
1703 rustc_hir::GeneratorKind::Async(..) => ("an", "async closure"),
1704 rustc_hir::GeneratorKind::Gen => ("a", "generator"),
1705 },
1706 def_kind => (def_kind.article(), def_kind.descr(def_id)),
1707 }
74b04a01 1708 }
136023e0
XL
1709
1710 pub fn type_length_limit(self) -> Limit {
1711 self.limits(()).type_length_limit
1712 }
1713
1714 pub fn recursion_limit(self) -> Limit {
1715 self.limits(()).recursion_limit
1716 }
1717
1718 pub fn move_size_limit(self) -> Limit {
1719 self.limits(()).move_size_limit
1720 }
1721
1722 pub fn const_eval_limit(self) -> Limit {
1723 self.limits(()).const_eval_limit
1724 }
a2a8927a
XL
1725
1726 pub fn all_traits(self) -> impl Iterator<Item = DefId> + 'tcx {
1727 iter::once(LOCAL_CRATE)
1728 .chain(self.crates(()).iter().copied())
1729 .flat_map(move |cnum| self.traits_in_crate(cnum).iter().copied())
1730 }
e9174d1e
SL
1731}
1732
dc9dc135
XL
1733/// A trait implemented for all `X<'a>` types that can be safely and
1734/// efficiently converted to `X<'tcx>` as long as they are part of the
1735/// provided `TyCtxt<'tcx>`.
1736/// This can be done, for example, for `Ty<'tcx>` or `SubstsRef<'tcx>`
e9174d1e 1737/// by looking them up in their respective interners.
a7813a04
XL
1738///
1739/// However, this is still not the best implementation as it does
1740/// need to compare the components, even for interned values.
dc9dc135 1741/// It would be more efficient if `TypedArena` provided a way to
a7813a04
XL
1742/// determine whether the address is in the allocated range.
1743///
e1599b0c 1744/// `None` is returned if the value or one of the components is not part
e9174d1e 1745/// of the provided context.
dc9dc135
XL
1746/// For `Ty`, `None` can be returned if either the type interner doesn't
1747/// contain the `TyKind` key or if the address of the interned
e9174d1e 1748/// pointer differs. The latter case is possible if a primitive type,
0731742a 1749/// e.g., `()` or `u8`, was interned in a different context.
8faf50e0
XL
1750pub trait Lift<'tcx>: fmt::Debug {
1751 type Lifted: fmt::Debug + 'tcx;
29967ef6 1752 fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted>;
e9174d1e
SL
1753}
1754
5e7ed085 1755macro_rules! nop_lift {
5099ac24
FG
1756 ($set:ident; $ty:ty => $lifted:ty) => {
1757 impl<'a, 'tcx> Lift<'tcx> for $ty {
1758 type Lifted = $lifted;
1759 fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
923072b8 1760 if tcx.interners.$set.contains_pointer_to(&InternedInSet(&*self.0.0)) {
5e7ed085
FG
1761 // SAFETY: `self` is interned and therefore valid
1762 // for the entire lifetime of the `TyCtxt`.
5099ac24
FG
1763 Some(unsafe { mem::transmute(self) })
1764 } else {
1765 None
1766 }
1767 }
1768 }
1769 };
1770}
1771
5e7ed085
FG
1772// Can't use the macros as we have reuse the `substs` here.
1773//
1774// See `intern_type_list` for more info.
1775impl<'a, 'tcx> Lift<'tcx> for &'a List<Ty<'a>> {
1776 type Lifted = &'tcx List<Ty<'tcx>>;
1777 fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1778 if self.is_empty() {
1779 return Some(List::empty());
dfeec247 1780 }
5e7ed085
FG
1781 if tcx.interners.substs.contains_pointer_to(&InternedInSet(self.as_substs())) {
1782 // SAFETY: `self` is interned and therefore valid
1783 // for the entire lifetime of the `TyCtxt`.
1784 Some(unsafe { mem::transmute::<&'a List<Ty<'a>>, &'tcx List<Ty<'tcx>>>(self) })
1785 } else {
1786 None
1787 }
1788 }
ea8adc8c
XL
1789}
1790
0731742a 1791macro_rules! nop_list_lift {
dfeec247 1792 ($set:ident; $ty:ty => $lifted:ty) => {
0731742a 1793 impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> {
dfeec247 1794 type Lifted = &'tcx List<$lifted>;
29967ef6 1795 fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
dfeec247
XL
1796 if self.is_empty() {
1797 return Some(List::empty());
1798 }
5099ac24 1799 if tcx.interners.$set.contains_pointer_to(&InternedInSet(self)) {
29967ef6 1800 Some(unsafe { mem::transmute(self) })
dfeec247
XL
1801 } else {
1802 None
0731742a 1803 }
dfeec247
XL
1804 }
1805 }
0731742a 1806 };
a7813a04
XL
1807}
1808
dfeec247
XL
1809nop_lift! {type_; Ty<'a> => Ty<'tcx>}
1810nop_lift! {region; Region<'a> => Region<'tcx>}
5099ac24 1811nop_lift! {const_; Const<'a> => Const<'tcx>}
5e7ed085 1812nop_lift! {const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx>}
5099ac24 1813nop_lift! {predicate; Predicate<'a> => Predicate<'tcx>}
476ff2be 1814
cdc7bbd5 1815nop_list_lift! {poly_existential_predicates; ty::Binder<'a, ExistentialPredicate<'a>> => ty::Binder<'tcx, ExistentialPredicate<'tcx>>}
dfeec247 1816nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>}
fc512014 1817nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>}
dfeec247 1818nop_list_lift! {projs; ProjectionKind => ProjectionKind}
cdc7bbd5 1819nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind}
7cac9316 1820
e1599b0c 1821// This is the impl for `&'a InternalSubsts<'a>`.
dfeec247 1822nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}
0531ce1d 1823
136023e0 1824CloneLiftImpls! { for<'tcx> { Constness, traits::WellFormedLoc, } }
fc512014 1825
e9174d1e 1826pub mod tls {
dfeec247 1827 use super::{ptr_eq, GlobalCtxt, TyCtxt};
e9174d1e 1828
5099ac24 1829 use crate::dep_graph::TaskDepsRef;
9fa01778 1830 use crate::ty::query;
74b04a01 1831 use rustc_data_structures::sync::{self, Lock};
0731742a 1832 use rustc_data_structures::thin_vec::ThinVec;
dfeec247
XL
1833 use rustc_errors::Diagnostic;
1834 use std::mem;
83c7162d 1835
9fa01778 1836 #[cfg(not(parallel_compiler))]
94b46f34
XL
1837 use std::cell::Cell;
1838
9fa01778
XL
1839 #[cfg(parallel_compiler)]
1840 use rustc_rayon_core as rayon_core;
94b46f34 1841
83c7162d 1842 /// This is the implicit state of rustc. It contains the current
e1599b0c
XL
1843 /// `TyCtxt` and query. It is updated when creating a local interner or
1844 /// executing a new query. Whenever there's a `TyCtxt` value available
1845 /// you should also have access to an `ImplicitCtxt` through the functions
83c7162d
XL
1846 /// in this module.
1847 #[derive(Clone)]
dc9dc135 1848 pub struct ImplicitCtxt<'a, 'tcx> {
3dfed10e 1849 /// The current `TyCtxt`.
dc9dc135 1850 pub tcx: TyCtxt<'tcx>,
83c7162d 1851
e1599b0c
XL
1852 /// The current query job, if any. This is updated by `JobOwner::start` in
1853 /// `ty::query::plumbing` when executing a query.
5099ac24 1854 pub query: Option<query::QueryJobId>,
83c7162d 1855
0731742a 1856 /// Where to store diagnostics for the current query job, if any.
e1599b0c 1857 /// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query.
0731742a
XL
1858 pub diagnostics: Option<&'a Lock<ThinVec<Diagnostic>>>,
1859
83c7162d
XL
1860 /// Used to prevent layout from recursing too deeply.
1861 pub layout_depth: usize,
1862
1863 /// The current dep graph task. This is used to add dependencies to queries
e1599b0c 1864 /// when executing them.
5099ac24 1865 pub task_deps: TaskDepsRef<'a>,
83c7162d
XL
1866 }
1867
3dfed10e
XL
1868 impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> {
1869 pub fn new(gcx: &'tcx GlobalCtxt<'tcx>) -> Self {
1870 let tcx = TyCtxt { gcx };
5099ac24
FG
1871 ImplicitCtxt {
1872 tcx,
1873 query: None,
1874 diagnostics: None,
1875 layout_depth: 0,
1876 task_deps: TaskDepsRef::Ignore,
1877 }
3dfed10e
XL
1878 }
1879 }
1880
e1599b0c 1881 /// Sets Rayon's thread-local variable, which is preserved for Rayon jobs
94b46f34 1882 /// to `value` during the call to `f`. It is restored to its previous value after.
e1599b0c 1883 /// This is used to set the pointer to the new `ImplicitCtxt`.
9fa01778 1884 #[cfg(parallel_compiler)]
0731742a 1885 #[inline]
94b46f34
XL
1886 fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
1887 rayon_core::tlv::with(value, f)
1888 }
1889
e1599b0c
XL
1890 /// Gets Rayon's thread-local variable, which is preserved for Rayon jobs.
1891 /// This is used to get the pointer to the current `ImplicitCtxt`.
9fa01778 1892 #[cfg(parallel_compiler)]
0731742a 1893 #[inline]
3dfed10e 1894 pub fn get_tlv() -> usize {
94b46f34
XL
1895 rayon_core::tlv::get()
1896 }
1897
9fa01778 1898 #[cfg(not(parallel_compiler))]
532ac7d7 1899 thread_local! {
e1599b0c 1900 /// A thread local variable that stores a pointer to the current `ImplicitCtxt`.
17df50a5 1901 static TLV: Cell<usize> = const { Cell::new(0) };
532ac7d7 1902 }
e9174d1e 1903
94b46f34
XL
1904 /// Sets TLV to `value` during the call to `f`.
1905 /// It is restored to its previous value after.
e1599b0c 1906 /// This is used to set the pointer to the new `ImplicitCtxt`.
9fa01778 1907 #[cfg(not(parallel_compiler))]
0731742a 1908 #[inline]
83c7162d
XL
1909 fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
1910 let old = get_tlv();
3dfed10e 1911 let _reset = rustc_data_structures::OnDrop(move || TLV.with(|tlv| tlv.set(old)));
83c7162d
XL
1912 TLV.with(|tlv| tlv.set(value));
1913 f()
1914 }
e9174d1e 1915
e1599b0c 1916 /// Gets the pointer to the current `ImplicitCtxt`.
9fa01778 1917 #[cfg(not(parallel_compiler))]
74b04a01 1918 #[inline]
83c7162d
XL
1919 fn get_tlv() -> usize {
1920 TLV.with(|tlv| tlv.get())
7453a54e 1921 }
e9174d1e 1922
e1599b0c 1923 /// Sets `context` as the new current `ImplicitCtxt` for the duration of the function `f`.
0731742a 1924 #[inline]
dc9dc135
XL
1925 pub fn enter_context<'a, 'tcx, F, R>(context: &ImplicitCtxt<'a, 'tcx>, f: F) -> R
1926 where
1927 F: FnOnce(&ImplicitCtxt<'a, 'tcx>) -> R,
a7813a04 1928 {
dfeec247 1929 set_tlv(context as *const _ as usize, || f(&context))
a7813a04
XL
1930 }
1931
e1599b0c 1932 /// Allows access to the current `ImplicitCtxt` in a closure if one is available.
0731742a 1933 #[inline]
83c7162d 1934 pub fn with_context_opt<F, R>(f: F) -> R
dc9dc135
XL
1935 where
1936 F: for<'a, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'tcx>>) -> R,
a7813a04 1937 {
83c7162d
XL
1938 let context = get_tlv();
1939 if context == 0 {
e9174d1e 1940 f(None)
83c7162d 1941 } else {
94222f64 1942 // We could get an `ImplicitCtxt` pointer from another thread.
e1599b0c 1943 // Ensure that `ImplicitCtxt` is `Sync`.
dc9dc135 1944 sync::assert_sync::<ImplicitCtxt<'_, '_>>();
94b46f34 1945
dc9dc135 1946 unsafe { f(Some(&*(context as *const ImplicitCtxt<'_, '_>))) }
e9174d1e
SL
1947 }
1948 }
83c7162d 1949
e1599b0c
XL
1950 /// Allows access to the current `ImplicitCtxt`.
1951 /// Panics if there is no `ImplicitCtxt` available.
0731742a 1952 #[inline]
83c7162d 1953 pub fn with_context<F, R>(f: F) -> R
dc9dc135
XL
1954 where
1955 F: for<'a, 'tcx> FnOnce(&ImplicitCtxt<'a, 'tcx>) -> R,
83c7162d
XL
1956 {
1957 with_context_opt(|opt_context| f(opt_context.expect("no ImplicitCtxt stored in tls")))
1958 }
1959
f035d41b
XL
1960 /// Allows access to the current `ImplicitCtxt` whose tcx field is the same as the tcx argument
1961 /// passed in. This means the closure is given an `ImplicitCtxt` with the same `'tcx` lifetime
1962 /// as the `TyCtxt` passed in.
1963 /// This will panic if you pass it a `TyCtxt` which is different from the current
1964 /// `ImplicitCtxt`'s `tcx` field.
0731742a 1965 #[inline]
dc9dc135
XL
1966 pub fn with_related_context<'tcx, F, R>(tcx: TyCtxt<'tcx>, f: F) -> R
1967 where
1968 F: FnOnce(&ImplicitCtxt<'_, 'tcx>) -> R,
83c7162d 1969 {
dfeec247
XL
1970 with_context(|context| unsafe {
1971 assert!(ptr_eq(context.tcx.gcx, tcx.gcx));
1972 let context: &ImplicitCtxt<'_, '_> = mem::transmute(context);
1973 f(context)
83c7162d
XL
1974 })
1975 }
1976
e1599b0c
XL
1977 /// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
1978 /// Panics if there is no `ImplicitCtxt` available.
0731742a 1979 #[inline]
83c7162d 1980 pub fn with<F, R>(f: F) -> R
dc9dc135
XL
1981 where
1982 F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> R,
83c7162d
XL
1983 {
1984 with_context(|context| f(context.tcx))
1985 }
1986
e1599b0c
XL
1987 /// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
1988 /// The closure is passed None if there is no `ImplicitCtxt` available.
0731742a 1989 #[inline]
83c7162d 1990 pub fn with_opt<F, R>(f: F) -> R
dc9dc135
XL
1991 where
1992 F: for<'tcx> FnOnce(Option<TyCtxt<'tcx>>) -> R,
83c7162d
XL
1993 {
1994 with_context_opt(|opt_context| f(opt_context.map(|context| context.tcx)))
1995 }
e9174d1e
SL
1996}
1997
1998macro_rules! sty_debug_print {
3dfed10e 1999 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
e1599b0c 2000 // Curious inner module to allow variant names to be used as
e9174d1e
SL
2001 // variable names.
2002 #[allow(non_snake_case)]
2003 mod inner {
9fa01778 2004 use crate::ty::{self, TyCtxt};
5099ac24 2005 use crate::ty::context::InternedInSet;
a7813a04 2006
e9174d1e
SL
2007 #[derive(Copy, Clone)]
2008 struct DebugStat {
2009 total: usize,
532ac7d7 2010 lt_infer: usize,
e9174d1e 2011 ty_infer: usize,
532ac7d7
XL
2012 ct_infer: usize,
2013 all_infer: usize,
e9174d1e
SL
2014 }
2015
3dfed10e 2016 pub fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
e9174d1e
SL
2017 let mut total = DebugStat {
2018 total: 0,
532ac7d7
XL
2019 lt_infer: 0,
2020 ty_infer: 0,
2021 ct_infer: 0,
2022 all_infer: 0,
e9174d1e
SL
2023 };
2024 $(let mut $variant = total;)*
2025
416331ca
XL
2026 let shards = tcx.interners.type_.lock_shards();
2027 let types = shards.iter().flat_map(|shard| shard.keys());
5099ac24
FG
2028 for &InternedInSet(t) in types {
2029 let variant = match t.kind {
b7449926
XL
2030 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
2031 ty::Float(..) | ty::Str | ty::Never => continue,
f035d41b 2032 ty::Error(_) => /* unimportant */ continue,
e9174d1e
SL
2033 $(ty::$variant(..) => &mut $variant,)*
2034 };
5099ac24
FG
2035 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
2036 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
2037 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
e9174d1e
SL
2038
2039 variant.total += 1;
2040 total.total += 1;
532ac7d7 2041 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
e9174d1e 2042 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
532ac7d7
XL
2043 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
2044 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
e9174d1e 2045 }
3dfed10e
XL
2046 writeln!(fmt, "Ty interner total ty lt ct all")?;
2047 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
532ac7d7
XL
2048 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2049 stringify!($variant),
2050 uses = $variant.total,
2051 usespc = $variant.total as f64 * 100.0 / total.total as f64,
2052 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
2053 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
2054 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
3dfed10e 2055 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
532ac7d7 2056 )*
3dfed10e 2057 writeln!(fmt, " total {uses:6} \
532ac7d7
XL
2058 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2059 uses = total.total,
2060 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
2061 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
2062 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
2063 all = total.all_infer as f64 * 100.0 / total.total as f64)
e9174d1e
SL
2064 }
2065 }
2066
3dfed10e 2067 inner::go($fmt, $ctxt)
e9174d1e
SL
2068 }}
2069}
2070
dc9dc135 2071impl<'tcx> TyCtxt<'tcx> {
3dfed10e
XL
2072 pub fn debug_stats(self) -> impl std::fmt::Debug + 'tcx {
2073 struct DebugStats<'tcx>(TyCtxt<'tcx>);
2074
a2a8927a 2075 impl<'tcx> std::fmt::Debug for DebugStats<'tcx> {
3dfed10e
XL
2076 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2077 sty_debug_print!(
2078 fmt,
2079 self.0,
2080 Adt,
2081 Array,
2082 Slice,
2083 RawPtr,
2084 Ref,
2085 FnDef,
2086 FnPtr,
2087 Placeholder,
2088 Generator,
2089 GeneratorWitness,
2090 Dynamic,
2091 Closure,
2092 Tuple,
2093 Bound,
2094 Param,
2095 Infer,
2096 Projection,
2097 Opaque,
2098 Foreign
2099 )?;
2100
2101 writeln!(fmt, "InternalSubsts interner: #{}", self.0.interners.substs.len())?;
2102 writeln!(fmt, "Region interner: #{}", self.0.interners.region.len())?;
c295e0f8
XL
2103 writeln!(
2104 fmt,
2105 "Const Allocation interner: #{}",
2106 self.0.interners.const_allocation.len()
2107 )?;
2108 writeln!(fmt, "Layout interner: #{}", self.0.interners.layout.len())?;
3dfed10e
XL
2109
2110 Ok(())
2111 }
2112 }
2113
2114 DebugStats(self)
e9174d1e
SL
2115 }
2116}
2117
5099ac24
FG
2118// This type holds a `T` in the interner. The `T` is stored in the arena and
2119// this type just holds a pointer to it, but it still effectively owns it. It
2120// impls `Borrow` so that it can be looked up using the original
2121// (non-arena-memory-owning) types.
2122struct InternedInSet<'tcx, T: ?Sized>(&'tcx T);
e9174d1e 2123
5099ac24 2124impl<'tcx, T: 'tcx + ?Sized> Clone for InternedInSet<'tcx, T> {
a1dfa0c6 2125 fn clone(&self) -> Self {
5099ac24 2126 InternedInSet(self.0)
a1dfa0c6
XL
2127 }
2128}
a1dfa0c6 2129
5099ac24
FG
2130impl<'tcx, T: 'tcx + ?Sized> Copy for InternedInSet<'tcx, T> {}
2131
2132impl<'tcx, T: 'tcx + ?Sized> IntoPointer for InternedInSet<'tcx, T> {
dfeec247
XL
2133 fn into_pointer(&self) -> *const () {
2134 self.0 as *const _ as *const ()
2135 }
2136}
e9174d1e 2137
e1599b0c 2138#[allow(rustc::usage_of_ty_tykind)]
04454e1e 2139impl<'tcx> Borrow<TyKind<'tcx>> for InternedInSet<'tcx, WithStableHash<TyS<'tcx>>> {
dc9dc135 2140 fn borrow<'a>(&'a self) -> &'a TyKind<'tcx> {
5099ac24 2141 &self.0.kind
e9174d1e
SL
2142 }
2143}
5099ac24 2144
04454e1e
FG
2145impl<'tcx> PartialEq for InternedInSet<'tcx, WithStableHash<TyS<'tcx>>> {
2146 fn eq(&self, other: &InternedInSet<'tcx, WithStableHash<TyS<'tcx>>>) -> bool {
5099ac24
FG
2147 // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
2148 // `x == y`.
f035d41b
XL
2149 self.0.kind == other.0.kind
2150 }
2151}
2152
04454e1e 2153impl<'tcx> Eq for InternedInSet<'tcx, WithStableHash<TyS<'tcx>>> {}
f035d41b 2154
04454e1e 2155impl<'tcx> Hash for InternedInSet<'tcx, WithStableHash<TyS<'tcx>>> {
f035d41b 2156 fn hash<H: Hasher>(&self, s: &mut H) {
5099ac24 2157 // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
f035d41b
XL
2158 self.0.kind.hash(s)
2159 }
2160}
2161
5099ac24 2162impl<'tcx> Borrow<Binder<'tcx, PredicateKind<'tcx>>> for InternedInSet<'tcx, PredicateS<'tcx>> {
cdc7bbd5 2163 fn borrow<'a>(&'a self) -> &'a Binder<'tcx, PredicateKind<'tcx>> {
f035d41b
XL
2164 &self.0.kind
2165 }
2166}
e9174d1e 2167
5099ac24
FG
2168impl<'tcx> PartialEq for InternedInSet<'tcx, PredicateS<'tcx>> {
2169 fn eq(&self, other: &InternedInSet<'tcx, PredicateS<'tcx>>) -> bool {
2170 // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
2171 // `x == y`.
2172 self.0.kind == other.0.kind
9e0c209e
SL
2173 }
2174}
2175
5099ac24 2176impl<'tcx> Eq for InternedInSet<'tcx, PredicateS<'tcx>> {}
9e0c209e 2177
5099ac24 2178impl<'tcx> Hash for InternedInSet<'tcx, PredicateS<'tcx>> {
9e0c209e 2179 fn hash<H: Hasher>(&self, s: &mut H) {
5099ac24
FG
2180 // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
2181 self.0.kind.hash(s)
9e0c209e
SL
2182 }
2183}
2184
5099ac24 2185impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
f9f354fc 2186 fn borrow<'a>(&'a self) -> &'a [T] {
e74abb32
XL
2187 &self.0[..]
2188 }
2189}
2190
5099ac24
FG
2191impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
2192 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
2193 // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
2194 // `x == y`.
2195 self.0[..] == other.0[..]
2196 }
2197}
2198
2199impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
2200
2201impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
2202 fn hash<H: Hasher>(&self, s: &mut H) {
2203 // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
2204 self.0[..].hash(s)
2205 }
2206}
2207
9e0c209e 2208macro_rules! direct_interners {
5099ac24
FG
2209 ($($name:ident: $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2210 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2211 fn borrow<'a>(&'a self) -> &'a $ty {
2212 &self.0
2213 }
2214 }
2215
2216 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
9e0c209e 2217 fn eq(&self, other: &Self) -> bool {
5099ac24
FG
2218 // The `Borrow` trait requires that `x.borrow() == y.borrow()`
2219 // equals `x == y`.
9e0c209e
SL
2220 self.0 == other.0
2221 }
2222 }
2223
5099ac24 2224 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
9e0c209e 2225
5099ac24 2226 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
9e0c209e 2227 fn hash<H: Hasher>(&self, s: &mut H) {
5099ac24
FG
2228 // The `Borrow` trait requires that `x.borrow().hash(s) ==
2229 // x.hash(s)`.
9e0c209e
SL
2230 self.0.hash(s)
2231 }
2232 }
2233
5099ac24
FG
2234 impl<'tcx> TyCtxt<'tcx> {
2235 pub fn $method(self, v: $ty) -> $ret_ty {
2236 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2237 InternedInSet(self.interners.arena.alloc(v))
2238 }).0))
2239 }
2240 })+
2241 }
2242}
2243
2244direct_interners! {
923072b8 2245 region: mk_region(RegionKind<'tcx>): Region -> Region<'tcx>,
5099ac24 2246 const_: mk_const(ConstS<'tcx>): Const -> Const<'tcx>,
5e7ed085
FG
2247 const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2248 layout: intern_layout(LayoutS<'tcx>): Layout -> Layout<'tcx>,
2249 adt_def: intern_adt_def(AdtDefData): AdtDef -> AdtDef<'tcx>,
f035d41b 2250}
e9174d1e 2251
c30ab7b3 2252macro_rules! slice_interners {
1b1a35ee 2253 ($($field:ident: $method:ident($ty:ty)),+ $(,)?) => (
29967ef6
XL
2254 impl<'tcx> TyCtxt<'tcx> {
2255 $(pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
e74abb32 2256 self.interners.$field.intern_ref(v, || {
5099ac24 2257 InternedInSet(List::from_arena(&*self.arena, v))
e74abb32 2258 }).0
29967ef6
XL
2259 })+
2260 }
532ac7d7 2261 );
c30ab7b3
SL
2262}
2263
2264slice_interners!(
e74abb32 2265 substs: _intern_substs(GenericArg<'tcx>),
fc512014
XL
2266 canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo<'tcx>),
2267 poly_existential_predicates:
cdc7bbd5 2268 _intern_poly_existential_predicates(ty::Binder<'tcx, ExistentialPredicate<'tcx>>),
532ac7d7 2269 predicates: _intern_predicates(Predicate<'tcx>),
e74abb32 2270 projs: _intern_projs(ProjectionKind),
f9f354fc 2271 place_elems: _intern_place_elems(PlaceElem<'tcx>),
cdc7bbd5 2272 bound_variable_kinds: _intern_bound_variable_kinds(ty::BoundVariableKind),
9e0c209e 2273);
e9174d1e 2274
dc9dc135 2275impl<'tcx> TyCtxt<'tcx> {
ff7c6d11
XL
2276 /// Given a `fn` type, returns an equivalent `unsafe fn` type;
2277 /// that is, a `fn` type that is equivalent in every way for being
2278 /// unsafe.
8bb4bdeb
XL
2279 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2280 assert_eq!(sig.unsafety(), hir::Unsafety::Normal);
dfeec247 2281 self.mk_fn_ptr(sig.map_bound(|sig| ty::FnSig { unsafety: hir::Unsafety::Unsafe, ..sig }))
e9174d1e
SL
2282 }
2283
6a06907d
XL
2284 /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name`
2285 /// returns true if the `trait_def_id` defines an associated item of name `assoc_name`.
2286 pub fn trait_may_define_assoc_type(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2287 self.super_traits_of(trait_def_id).any(|trait_did| {
2288 self.associated_items(trait_did)
2289 .find_by_name_and_kind(self, assoc_name, ty::AssocKind::Type, trait_did)
2290 .is_some()
2291 })
2292 }
2293
923072b8
FG
2294 /// Given a `ty`, return whether it's an `impl Future<...>`.
2295 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2296 let ty::Opaque(def_id, _) = ty.kind() else { return false };
2297 let future_trait = self.lang_items().future_trait().unwrap();
2298
2299 self.explicit_item_bounds(def_id).iter().any(|(predicate, _)| {
2300 let ty::PredicateKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2301 return false;
2302 };
2303 trait_predicate.trait_ref.def_id == future_trait
2304 && trait_predicate.polarity == ImplPolarity::Positive
2305 })
2306 }
2307
c295e0f8 2308 /// Computes the def-ids of the transitive supertraits of `trait_def_id`. This (intentionally)
6a06907d
XL
2309 /// does not compute the full elaborated super-predicates but just the set of def-ids. It is used
2310 /// to identify which traits may define a given associated type to help avoid cycle errors.
2311 /// Returns a `DefId` iterator.
2312 fn super_traits_of(self, trait_def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
2313 let mut set = FxHashSet::default();
2314 let mut stack = vec![trait_def_id];
2315
2316 set.insert(trait_def_id);
2317
2318 iter::from_fn(move || -> Option<DefId> {
2319 let trait_did = stack.pop()?;
2320 let generic_predicates = self.super_predicates_of(trait_did);
2321
2322 for (predicate, _) in generic_predicates.predicates {
94222f64 2323 if let ty::PredicateKind::Trait(data) = predicate.kind().skip_binder() {
6a06907d
XL
2324 if set.insert(data.def_id()) {
2325 stack.push(data.def_id());
2326 }
2327 }
2328 }
2329
2330 Some(trait_did)
2331 })
2332 }
2333
f9f354fc
XL
2334 /// Given a closure signature, returns an equivalent fn signature. Detuples
2335 /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then
2336 /// you would get a `fn(u32, i32)`.
2337 /// `unsafety` determines the unsafety of the fn signature. If you pass
532ac7d7
XL
2338 /// `hir::Unsafety::Unsafe` in the previous example, then you would get
2339 /// an `unsafe fn (u32, i32)`.
2340 /// It cannot convert a closure that requires unsafe.
f9f354fc
XL
2341 pub fn signature_unclosure(
2342 self,
2343 sig: PolyFnSig<'tcx>,
2344 unsafety: hir::Unsafety,
2345 ) -> PolyFnSig<'tcx> {
2346 sig.map_bound(|s| {
1b1a35ee 2347 let params_iter = match s.inputs()[0].kind() {
5e7ed085 2348 ty::Tuple(params) => params.into_iter(),
ff7c6d11
XL
2349 _ => bug!(),
2350 };
dfeec247 2351 self.mk_fn_sig(params_iter, s.output(), s.c_variadic, unsafety, abi::Abi::Rust)
f9f354fc 2352 })
ff7c6d11
XL
2353 }
2354
f035d41b
XL
2355 /// Same a `self.mk_region(kind)`, but avoids accessing the interners if
2356 /// `*r == kind`.
2357 #[inline]
923072b8 2358 pub fn reuse_or_mk_region(self, r: Region<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> {
f035d41b
XL
2359 if *r == kind { r } else { self.mk_region(kind) }
2360 }
2361
e1599b0c 2362 #[allow(rustc::usage_of_ty_tykind)]
a1dfa0c6 2363 #[inline]
3dfed10e 2364 pub fn mk_ty(self, st: TyKind<'tcx>) -> Ty<'tcx> {
923072b8
FG
2365 self.interners.intern_ty(
2366 st,
2367 self.sess,
064997fb 2368 &self.definitions.read(),
923072b8
FG
2369 &*self.cstore,
2370 // This is only used to create a stable hashing context.
2371 &self.untracked_resolutions.source_span,
2372 )
e9174d1e
SL
2373 }
2374
f9f354fc 2375 #[inline]
cdc7bbd5 2376 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
5099ac24 2377 self.interners.intern_predicate(binder)
f9f354fc
XL
2378 }
2379
3dfed10e
XL
2380 #[inline]
2381 pub fn reuse_or_mk_predicate(
2382 self,
2383 pred: Predicate<'tcx>,
cdc7bbd5 2384 binder: Binder<'tcx, PredicateKind<'tcx>>,
3dfed10e 2385 ) -> Predicate<'tcx> {
5869c6ff 2386 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
3dfed10e
XL
2387 }
2388
5869c6ff 2389 pub fn mk_mach_int(self, tm: IntTy) -> Ty<'tcx> {
e9174d1e 2390 match tm {
5869c6ff
XL
2391 IntTy::Isize => self.types.isize,
2392 IntTy::I8 => self.types.i8,
2393 IntTy::I16 => self.types.i16,
2394 IntTy::I32 => self.types.i32,
2395 IntTy::I64 => self.types.i64,
2396 IntTy::I128 => self.types.i128,
e9174d1e
SL
2397 }
2398 }
2399
5869c6ff 2400 pub fn mk_mach_uint(self, tm: UintTy) -> Ty<'tcx> {
e9174d1e 2401 match tm {
5869c6ff
XL
2402 UintTy::Usize => self.types.usize,
2403 UintTy::U8 => self.types.u8,
2404 UintTy::U16 => self.types.u16,
2405 UintTy::U32 => self.types.u32,
2406 UintTy::U64 => self.types.u64,
2407 UintTy::U128 => self.types.u128,
e9174d1e
SL
2408 }
2409 }
2410
5869c6ff 2411 pub fn mk_mach_float(self, tm: FloatTy) -> Ty<'tcx> {
e9174d1e 2412 match tm {
5869c6ff
XL
2413 FloatTy::F32 => self.types.f32,
2414 FloatTy::F64 => self.types.f64,
e9174d1e
SL
2415 }
2416 }
2417
a1dfa0c6 2418 #[inline]
a7813a04 2419 pub fn mk_static_str(self) -> Ty<'tcx> {
f035d41b 2420 self.mk_imm_ref(self.lifetimes.re_static, self.types.str_)
e9174d1e
SL
2421 }
2422
a1dfa0c6 2423 #[inline]
5e7ed085 2424 pub fn mk_adt(self, def: AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
e1599b0c 2425 // Take a copy of substs so that we own the vectors inside.
b7449926 2426 self.mk_ty(Adt(def, substs))
e9174d1e
SL
2427 }
2428
a1dfa0c6 2429 #[inline]
abe05a73 2430 pub fn mk_foreign(self, def_id: DefId) -> Ty<'tcx> {
b7449926 2431 self.mk_ty(Foreign(def_id))
abe05a73
XL
2432 }
2433
416331ca
XL
2434 fn mk_generic_adt(self, wrapper_def_id: DefId, ty_param: Ty<'tcx>) -> Ty<'tcx> {
2435 let adt_def = self.adt_def(wrapper_def_id);
dfeec247
XL
2436 let substs =
2437 InternalSubsts::for_item(self, wrapper_def_id, |param, substs| match param.kind {
cdc7bbd5 2438 GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => bug!(),
94b46f34
XL
2439 GenericParamDefKind::Type { has_default, .. } => {
2440 if param.index == 0 {
416331ca 2441 ty_param.into()
94b46f34
XL
2442 } else {
2443 assert!(has_default);
04454e1e 2444 self.bound_type_of(param.def_id).subst(self, substs).into()
94b46f34
XL
2445 }
2446 }
dfeec247 2447 });
b7449926 2448 self.mk_ty(Adt(adt_def, substs))
e9174d1e
SL
2449 }
2450
416331ca
XL
2451 #[inline]
2452 pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> {
3dfed10e 2453 let def_id = self.require_lang_item(LangItem::OwnedBox, None);
416331ca
XL
2454 self.mk_generic_adt(def_id, ty)
2455 }
2456
e1599b0c 2457 #[inline]
3dfed10e 2458 pub fn mk_lang_item(self, ty: Ty<'tcx>, item: LangItem) -> Option<Ty<'tcx>> {
e1599b0c
XL
2459 let def_id = self.lang_items().require(item).ok()?;
2460 Some(self.mk_generic_adt(def_id, ty))
2461 }
2462
ba9703b0
XL
2463 #[inline]
2464 pub fn mk_diagnostic_item(self, ty: Ty<'tcx>, name: Symbol) -> Option<Ty<'tcx>> {
2465 let def_id = self.get_diagnostic_item(name)?;
2466 Some(self.mk_generic_adt(def_id, ty))
2467 }
2468
416331ca
XL
2469 #[inline]
2470 pub fn mk_maybe_uninit(self, ty: Ty<'tcx>) -> Ty<'tcx> {
3dfed10e 2471 let def_id = self.require_lang_item(LangItem::MaybeUninit, None);
416331ca
XL
2472 self.mk_generic_adt(def_id, ty)
2473 }
2474
a1dfa0c6 2475 #[inline]
a7813a04 2476 pub fn mk_ptr(self, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
b7449926 2477 self.mk_ty(RawPtr(tm))
e9174d1e
SL
2478 }
2479
a1dfa0c6 2480 #[inline]
7cac9316 2481 pub fn mk_ref(self, r: Region<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
b7449926 2482 self.mk_ty(Ref(r, tm.ty, tm.mutbl))
e9174d1e
SL
2483 }
2484
a1dfa0c6 2485 #[inline]
7cac9316 2486 pub fn mk_mut_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
74b04a01 2487 self.mk_ref(r, TypeAndMut { ty, mutbl: hir::Mutability::Mut })
e9174d1e
SL
2488 }
2489
a1dfa0c6 2490 #[inline]
7cac9316 2491 pub fn mk_imm_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
74b04a01 2492 self.mk_ref(r, TypeAndMut { ty, mutbl: hir::Mutability::Not })
e9174d1e
SL
2493 }
2494
a1dfa0c6 2495 #[inline]
a7813a04 2496 pub fn mk_mut_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
74b04a01 2497 self.mk_ptr(TypeAndMut { ty, mutbl: hir::Mutability::Mut })
e9174d1e
SL
2498 }
2499
a1dfa0c6 2500 #[inline]
a7813a04 2501 pub fn mk_imm_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
74b04a01 2502 self.mk_ptr(TypeAndMut { ty, mutbl: hir::Mutability::Not })
e9174d1e
SL
2503 }
2504
a1dfa0c6 2505 #[inline]
ea8adc8c 2506 pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
e74abb32 2507 self.mk_ty(Array(ty, ty::Const::from_usize(self, n)))
e9174d1e
SL
2508 }
2509
a1dfa0c6 2510 #[inline]
a7813a04 2511 pub fn mk_slice(self, ty: Ty<'tcx>) -> Ty<'tcx> {
b7449926 2512 self.mk_ty(Slice(ty))
e9174d1e
SL
2513 }
2514
a1dfa0c6 2515 #[inline]
0531ce1d 2516 pub fn intern_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
5e7ed085 2517 self.mk_ty(Tuple(self.intern_type_list(&ts)))
c30ab7b3
SL
2518 }
2519
0531ce1d 2520 pub fn mk_tup<I: InternAs<[Ty<'tcx>], Ty<'tcx>>>(self, iter: I) -> I::Output {
5e7ed085 2521 iter.intern_with(|ts| self.mk_ty(Tuple(self.intern_type_list(&ts))))
e9174d1e
SL
2522 }
2523
a1dfa0c6 2524 #[inline]
b7449926 2525 pub fn mk_unit(self) -> Ty<'tcx> {
a1dfa0c6 2526 self.types.unit
e9174d1e
SL
2527 }
2528
a1dfa0c6 2529 #[inline]
5bcae85e 2530 pub fn mk_diverging_default(self) -> Ty<'tcx> {
dfeec247 2531 if self.features().never_type_fallback { self.types.never } else { self.types.unit }
5bcae85e
SL
2532 }
2533
a1dfa0c6 2534 #[inline]
dfeec247 2535 pub fn mk_fn_def(self, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
b7449926 2536 self.mk_ty(FnDef(def_id, substs))
54a0048b
SL
2537 }
2538
a1dfa0c6 2539 #[inline]
8bb4bdeb 2540 pub fn mk_fn_ptr(self, fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
b7449926 2541 self.mk_ty(FnPtr(fty))
e9174d1e
SL
2542 }
2543
a1dfa0c6 2544 #[inline]
476ff2be
SL
2545 pub fn mk_dynamic(
2546 self,
cdc7bbd5 2547 obj: &'tcx List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>,
dfeec247 2548 reg: ty::Region<'tcx>,
476ff2be 2549 ) -> Ty<'tcx> {
b7449926 2550 self.mk_ty(Dynamic(obj, reg))
e9174d1e
SL
2551 }
2552
a1dfa0c6 2553 #[inline]
dfeec247
XL
2554 pub fn mk_projection(self, item_def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
2555 self.mk_ty(Projection(ProjectionTy { item_def_id, substs }))
2556 }
e9174d1e 2557
a1dfa0c6 2558 #[inline]
dfeec247 2559 pub fn mk_closure(self, closure_id: DefId, closure_substs: SubstsRef<'tcx>) -> Ty<'tcx> {
b7449926 2560 self.mk_ty(Closure(closure_id, closure_substs))
e9174d1e
SL
2561 }
2562
a1dfa0c6 2563 #[inline]
dfeec247
XL
2564 pub fn mk_generator(
2565 self,
2566 id: DefId,
2567 generator_substs: SubstsRef<'tcx>,
2568 movability: hir::Movability,
2569 ) -> Ty<'tcx> {
b7449926 2570 self.mk_ty(Generator(id, generator_substs, movability))
ea8adc8c
XL
2571 }
2572
a1dfa0c6 2573 #[inline]
cdc7bbd5 2574 pub fn mk_generator_witness(self, types: ty::Binder<'tcx, &'tcx List<Ty<'tcx>>>) -> Ty<'tcx> {
b7449926 2575 self.mk_ty(GeneratorWitness(types))
2c00a5a8
XL
2576 }
2577
a1dfa0c6 2578 #[inline]
532ac7d7 2579 pub fn mk_ty_var(self, v: TyVid) -> Ty<'tcx> {
48663c56 2580 self.mk_ty_infer(TyVar(v))
e9174d1e
SL
2581 }
2582
532ac7d7 2583 #[inline]
5099ac24 2584 pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
923072b8 2585 self.mk_const(ty::ConstS { kind: ty::ConstKind::Infer(InferConst::Var(v)), ty })
532ac7d7
XL
2586 }
2587
a1dfa0c6 2588 #[inline]
a7813a04 2589 pub fn mk_int_var(self, v: IntVid) -> Ty<'tcx> {
48663c56 2590 self.mk_ty_infer(IntVar(v))
e9174d1e
SL
2591 }
2592
a1dfa0c6 2593 #[inline]
a7813a04 2594 pub fn mk_float_var(self, v: FloatVid) -> Ty<'tcx> {
48663c56 2595 self.mk_ty_infer(FloatVar(v))
e9174d1e
SL
2596 }
2597
a1dfa0c6 2598 #[inline]
48663c56 2599 pub fn mk_ty_infer(self, it: InferTy) -> Ty<'tcx> {
b7449926 2600 self.mk_ty(Infer(it))
e9174d1e
SL
2601 }
2602
a1dfa0c6 2603 #[inline]
5099ac24 2604 pub fn mk_const_infer(self, ic: InferConst<'tcx>, ty: Ty<'tcx>) -> ty::Const<'tcx> {
923072b8 2605 self.mk_const(ty::ConstS { kind: ty::ConstKind::Infer(ic), ty })
48663c56
XL
2606 }
2607
2608 #[inline]
e74abb32 2609 pub fn mk_ty_param(self, index: u32, name: Symbol) -> Ty<'tcx> {
74b04a01 2610 self.mk_ty(Param(ParamTy { index, name }))
e9174d1e
SL
2611 }
2612
532ac7d7 2613 #[inline]
5099ac24 2614 pub fn mk_const_param(self, index: u32, name: Symbol, ty: Ty<'tcx>) -> Const<'tcx> {
923072b8 2615 self.mk_const(ty::ConstS { kind: ty::ConstKind::Param(ParamConst { index, name }), ty })
532ac7d7
XL
2616 }
2617
e74abb32 2618 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
94b46f34
XL
2619 match param.kind {
2620 GenericParamDefKind::Lifetime => {
2621 self.mk_region(ty::ReEarlyBound(param.to_early_bound_region_data())).into()
2622 }
532ac7d7 2623 GenericParamDefKind::Type { .. } => self.mk_ty_param(param.index, param.name).into(),
cdc7bbd5 2624 GenericParamDefKind::Const { .. } => {
532ac7d7
XL
2625 self.mk_const_param(param.index, param.name, self.type_of(param.def_id)).into()
2626 }
94b46f34 2627 }
e9174d1e 2628 }
9cc50fc6 2629
a1dfa0c6 2630 #[inline]
532ac7d7 2631 pub fn mk_opaque(self, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
b7449926 2632 self.mk_ty(Opaque(def_id, substs))
5bcae85e
SL
2633 }
2634
e74abb32
XL
2635 pub fn mk_place_field(self, place: Place<'tcx>, f: Field, ty: Ty<'tcx>) -> Place<'tcx> {
2636 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2637 }
2638
2639 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2640 self.mk_place_elem(place, PlaceElem::Deref)
2641 }
2642
2643 pub fn mk_place_downcast(
2644 self,
2645 place: Place<'tcx>,
5e7ed085 2646 adt_def: AdtDef<'tcx>,
e74abb32
XL
2647 variant_index: VariantIdx,
2648 ) -> Place<'tcx> {
2649 self.mk_place_elem(
2650 place,
5e7ed085 2651 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
e74abb32
XL
2652 )
2653 }
2654
2655 pub fn mk_place_downcast_unnamed(
2656 self,
2657 place: Place<'tcx>,
2658 variant_index: VariantIdx,
2659 ) -> Place<'tcx> {
2660 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2661 }
2662
2663 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2664 self.mk_place_elem(place, PlaceElem::Index(index))
2665 }
2666
2667 /// This method copies `Place`'s projection, add an element and reintern it. Should not be used
2668 /// to build a full `Place` it's just a convenient way to grab a projection and modify it in
2669 /// flight.
2670 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2671 let mut projection = place.projection.to_vec();
2672 projection.push(elem);
2673
dfeec247 2674 Place { local: place.local, projection: self.intern_place_elems(&projection) }
e74abb32
XL
2675 }
2676
fc512014 2677 pub fn intern_poly_existential_predicates(
dfeec247 2678 self,
cdc7bbd5
XL
2679 eps: &[ty::Binder<'tcx, ExistentialPredicate<'tcx>>],
2680 ) -> &'tcx List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>> {
476ff2be 2681 assert!(!eps.is_empty());
fc512014
XL
2682 assert!(
2683 eps.array_windows()
2684 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2685 != Ordering::Greater)
2686 );
2687 self._intern_poly_existential_predicates(eps)
476ff2be
SL
2688 }
2689
dfeec247 2690 pub fn intern_predicates(self, preds: &[Predicate<'tcx>]) -> &'tcx List<Predicate<'tcx>> {
7cac9316
XL
2691 // FIXME consider asking the input slice to be sorted to avoid
2692 // re-interning permutations, in which case that would be asserted
2693 // here.
74b04a01 2694 if preds.is_empty() {
7cac9316 2695 // The macro-generated method below asserts we don't intern an empty slice.
b7449926 2696 List::empty()
7cac9316
XL
2697 } else {
2698 self._intern_predicates(preds)
2699 }
2700 }
2701
b7449926 2702 pub fn intern_type_list(self, ts: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> {
5e7ed085
FG
2703 if ts.is_empty() {
2704 List::empty()
2705 } else {
2706 // Actually intern type lists as lists of `GenericArg`s.
2707 //
2708 // Transmuting from `Ty<'tcx>` to `GenericArg<'tcx>` is sound
2709 // as explained in ty_slice_as_generic_arg`. With this,
2710 // we guarantee that even when transmuting between `List<Ty<'tcx>>`
2711 // and `List<GenericArg<'tcx>>`, the uniqueness requirement for
2712 // lists is upheld.
2713 let substs = self._intern_substs(ty::subst::ty_slice_as_generic_args(ts));
2714 substs.try_as_type_list().unwrap()
2715 }
c30ab7b3
SL
2716 }
2717
e74abb32 2718 pub fn intern_substs(self, ts: &[GenericArg<'tcx>]) -> &'tcx List<GenericArg<'tcx>> {
74b04a01 2719 if ts.is_empty() { List::empty() } else { self._intern_substs(ts) }
c30ab7b3
SL
2720 }
2721
532ac7d7 2722 pub fn intern_projs(self, ps: &[ProjectionKind]) -> &'tcx List<ProjectionKind> {
74b04a01 2723 if ps.is_empty() { List::empty() } else { self._intern_projs(ps) }
0bf4aa26
XL
2724 }
2725
e74abb32 2726 pub fn intern_place_elems(self, ts: &[PlaceElem<'tcx>]) -> &'tcx List<PlaceElem<'tcx>> {
74b04a01 2727 if ts.is_empty() { List::empty() } else { self._intern_place_elems(ts) }
e74abb32
XL
2728 }
2729
fc512014
XL
2730 pub fn intern_canonical_var_infos(
2731 self,
2732 ts: &[CanonicalVarInfo<'tcx>],
2733 ) -> CanonicalVarInfos<'tcx> {
74b04a01 2734 if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) }
0531ce1d
XL
2735 }
2736
cdc7bbd5
XL
2737 pub fn intern_bound_variable_kinds(
2738 self,
2739 ts: &[ty::BoundVariableKind],
2740 ) -> &'tcx List<ty::BoundVariableKind> {
2741 if ts.is_empty() { List::empty() } else { self._intern_bound_variable_kinds(ts) }
2742 }
2743
dfeec247
XL
2744 pub fn mk_fn_sig<I>(
2745 self,
2746 inputs: I,
2747 output: I::Item,
2748 c_variadic: bool,
2749 unsafety: hir::Unsafety,
2750 abi: abi::Abi,
2751 ) -> <I::Item as InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>>::Output
416331ca
XL
2752 where
2753 I: Iterator<Item: InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>>,
476ff2be
SL
2754 {
2755 inputs.chain(iter::once(output)).intern_with(|xs| ty::FnSig {
2756 inputs_and_output: self.intern_type_list(xs),
dfeec247
XL
2757 c_variadic,
2758 unsafety,
2759 abi,
476ff2be
SL
2760 })
2761 }
2762
fc512014
XL
2763 pub fn mk_poly_existential_predicates<
2764 I: InternAs<
cdc7bbd5
XL
2765 [ty::Binder<'tcx, ExistentialPredicate<'tcx>>],
2766 &'tcx List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>,
fc512014 2767 >,
dfeec247
XL
2768 >(
2769 self,
2770 iter: I,
2771 ) -> I::Output {
fc512014 2772 iter.intern_with(|xs| self.intern_poly_existential_predicates(xs))
476ff2be
SL
2773 }
2774
dfeec247
XL
2775 pub fn mk_predicates<I: InternAs<[Predicate<'tcx>], &'tcx List<Predicate<'tcx>>>>(
2776 self,
2777 iter: I,
2778 ) -> I::Output {
7cac9316
XL
2779 iter.intern_with(|xs| self.intern_predicates(xs))
2780 }
2781
dfeec247 2782 pub fn mk_type_list<I: InternAs<[Ty<'tcx>], &'tcx List<Ty<'tcx>>>>(self, iter: I) -> I::Output {
c30ab7b3
SL
2783 iter.intern_with(|xs| self.intern_type_list(xs))
2784 }
2785
dfeec247
XL
2786 pub fn mk_substs<I: InternAs<[GenericArg<'tcx>], &'tcx List<GenericArg<'tcx>>>>(
2787 self,
2788 iter: I,
2789 ) -> I::Output {
c30ab7b3
SL
2790 iter.intern_with(|xs| self.intern_substs(xs))
2791 }
2792
dfeec247
XL
2793 pub fn mk_place_elems<I: InternAs<[PlaceElem<'tcx>], &'tcx List<PlaceElem<'tcx>>>>(
2794 self,
2795 iter: I,
2796 ) -> I::Output {
e74abb32
XL
2797 iter.intern_with(|xs| self.intern_place_elems(xs))
2798 }
2799
dfeec247 2800 pub fn mk_substs_trait(self, self_ty: Ty<'tcx>, rest: &[GenericArg<'tcx>]) -> SubstsRef<'tcx> {
94b46f34 2801 self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned()))
c30ab7b3 2802 }
3b2f2976 2803
cdc7bbd5
XL
2804 pub fn mk_bound_variable_kinds<
2805 I: InternAs<[ty::BoundVariableKind], &'tcx List<ty::BoundVariableKind>>,
2806 >(
2807 self,
2808 iter: I,
2809 ) -> I::Output {
2810 iter.intern_with(|xs| self.intern_bound_variable_kinds(xs))
2811 }
2812
532ac7d7
XL
2813 /// Walks upwards from `id` to find a node which might change lint levels with attributes.
2814 /// It stops at `bound` and just returns it if reached.
dfeec247
XL
2815 pub fn maybe_lint_level_root_bounded(self, mut id: HirId, bound: HirId) -> HirId {
2816 let hir = self.hir();
532ac7d7
XL
2817 loop {
2818 if id == bound {
2819 return bound;
3b2f2976 2820 }
dfeec247 2821
5e7ed085 2822 if hir.attrs(id).iter().any(|attr| Level::from_attr(attr).is_some()) {
532ac7d7
XL
2823 return id;
2824 }
dfeec247 2825 let next = hir.get_parent_node(id);
532ac7d7
XL
2826 if next == id {
2827 bug!("lint traversal reached the root of the crate");
2828 }
2829 id = next;
2830 }
2831 }
2832
2833 pub fn lint_level_at_node(
2834 self,
2835 lint: &'static Lint,
dfeec247 2836 mut id: hir::HirId,
fc512014 2837 ) -> (Level, LintLevelSource) {
17df50a5 2838 let sets = self.lint_levels(());
532ac7d7
XL
2839 loop {
2840 if let Some(pair) = sets.level_and_source(lint, id, self.sess) {
dfeec247 2841 return pair;
532ac7d7 2842 }
dc9dc135 2843 let next = self.hir().get_parent_node(id);
532ac7d7
XL
2844 if next == id {
2845 bug!("lint traversal reached the root of the crate");
2846 }
2847 id = next;
2848 }
3b2f2976
XL
2849 }
2850
064997fb
FG
2851 /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`,
2852 /// typically generated by `#[derive(LintDiagnostic)]`).
2853 pub fn emit_spanned_lint(
2854 self,
2855 lint: &'static Lint,
2856 hir_id: HirId,
2857 span: impl Into<MultiSpan>,
2858 decorator: impl for<'a> DecorateLint<'a, ()>,
2859 ) {
2860 self.struct_span_lint_hir(lint, hir_id, span, |diag| decorator.decorate_lint(diag))
2861 }
2862
dfeec247
XL
2863 pub fn struct_span_lint_hir(
2864 self,
2865 lint: &'static Lint,
2866 hir_id: HirId,
2867 span: impl Into<MultiSpan>,
5e7ed085 2868 decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
74b04a01 2869 ) {
532ac7d7 2870 let (level, src) = self.lint_level_at_node(lint, hir_id);
74b04a01 2871 struct_lint_level(self.sess, lint, level, src, Some(span.into()), decorate);
3b2f2976
XL
2872 }
2873
064997fb
FG
2874 /// Emit a lint from a lint struct (some type that implements `DecorateLint`, typically
2875 /// generated by `#[derive(LintDiagnostic)]`).
2876 pub fn emit_lint(
2877 self,
2878 lint: &'static Lint,
2879 id: HirId,
2880 decorator: impl for<'a> DecorateLint<'a, ()>,
2881 ) {
2882 self.struct_lint_node(lint, id, |diag| decorator.decorate_lint(diag))
2883 }
2884
dfeec247
XL
2885 pub fn struct_lint_node(
2886 self,
2887 lint: &'static Lint,
2888 id: HirId,
5e7ed085 2889 decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
74b04a01 2890 ) {
3b2f2976 2891 let (level, src) = self.lint_level_at_node(lint, id);
74b04a01 2892 struct_lint_level(self.sess, lint, level, src, None, decorate);
3b2f2976 2893 }
ea8adc8c 2894
17df50a5
XL
2895 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
2896 let map = self.in_scope_traits_map(id.owner)?;
2897 let candidates = map.get(&id.local_id)?;
2898 Some(&*candidates)
ea8adc8c
XL
2899 }
2900
2901 pub fn named_region(self, id: HirId) -> Option<resolve_lifetime::Region> {
cdc7bbd5 2902 debug!(?id, "named_region");
dfeec247 2903 self.named_region_map(id.owner).and_then(|map| map.get(&id.local_id).cloned())
ea8adc8c
XL
2904 }
2905
923072b8
FG
2906 pub fn is_late_bound(self, id: HirId) -> bool {
2907 self.is_late_bound_map(id.owner).map_or(false, |set| {
2908 let def_id = self.hir().local_def_id(id);
2909 set.contains(&def_id)
2910 })
2911 }
2912
cdc7bbd5
XL
2913 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
2914 self.mk_bound_variable_kinds(
2915 self.late_bound_vars_map(id.owner)
2916 .and_then(|map| map.get(&id.local_id).cloned())
2917 .unwrap_or_else(|| {
2918 bug!("No bound vars found for {:?} ({:?})", self.hir().node_to_string(id), id)
2919 })
2920 .iter(),
2921 )
ea8adc8c 2922 }
17df50a5 2923
c295e0f8
XL
2924 /// Whether the `def_id` counts as const fn in the current crate, considering all active
2925 /// feature gates
2926 pub fn is_const_fn(self, def_id: DefId) -> bool {
2927 if self.is_const_fn_raw(def_id) {
2928 match self.lookup_const_stability(def_id) {
923072b8 2929 Some(stability) if stability.is_const_unstable() => {
c295e0f8
XL
2930 // has a `rustc_const_unstable` attribute, check whether the user enabled the
2931 // corresponding feature gate.
2932 self.features()
2933 .declared_lib_features
2934 .iter()
2935 .any(|&(sym, _)| sym == stability.feature)
2936 }
2937 // functions without const stability are either stable user written
2938 // const fn or the user is using feature gates and we thus don't
2939 // care what they do
2940 _ => true,
2941 }
2942 } else {
2943 false
2944 }
2945 }
923072b8
FG
2946
2947 /// Whether the trait impl is marked const. This does not consider stability or feature gates.
2948 pub fn is_const_trait_impl_raw(self, def_id: DefId) -> bool {
2949 let Some(local_def_id) = def_id.as_local() else { return false };
2950 let hir_id = self.local_def_id_to_hir_id(local_def_id);
2951 let node = self.hir().get(hir_id);
2952
2953 matches!(
2954 node,
2955 hir::Node::Item(hir::Item {
2956 kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }),
2957 ..
2958 })
2959 )
2960 }
e9174d1e 2961}
c30ab7b3 2962
a2a8927a 2963impl<'tcx> TyCtxtAt<'tcx> {
3dfed10e
XL
2964 /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used.
2965 #[track_caller]
2966 pub fn ty_error(self) -> Ty<'tcx> {
2967 self.tcx.ty_error_with_message(self.span, "TyKind::Error constructed but no error reported")
2968 }
2969
2970 /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg to
2971 /// ensure it gets used.
2972 #[track_caller]
2973 pub fn ty_error_with_message(self, msg: &str) -> Ty<'tcx> {
2974 self.tcx.ty_error_with_message(self.span, msg)
2975 }
2976}
2977
532ac7d7
XL
2978// We are comparing types with different invariant lifetimes, so `ptr::eq`
2979// won't work for us.
2980fn ptr_eq<T, U>(t: *const T, u: *const U) -> bool {
2981 t as *const () == u as *const ()
2982}
2983
f035d41b 2984pub fn provide(providers: &mut ty::query::Providers) {
136023e0 2985 providers.resolutions = |tcx, ()| &tcx.untracked_resolutions;
064997fb 2986 providers.resolver_for_lowering = |tcx, ()| &tcx.untracked_resolver_for_lowering;
5099ac24
FG
2987 providers.module_reexports =
2988 |tcx, id| tcx.resolutions(()).reexport_map.get(&id).map(|v| &v[..]);
ea8adc8c
XL
2989 providers.crate_name = |tcx, id| {
2990 assert_eq!(id, LOCAL_CRATE);
2991 tcx.crate_name
2992 };
923072b8
FG
2993 providers.maybe_unused_trait_imports =
2994 |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
136023e0
XL
2995 providers.maybe_unused_extern_crates =
2996 |tcx, ()| &tcx.resolutions(()).maybe_unused_extern_crates[..];
2997 providers.names_imported_by_glob_use = |tcx, id| {
2998 tcx.arena.alloc(tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default())
2999 };
ea8adc8c 3000
136023e0
XL
3001 providers.extern_mod_stmt_cnum =
3002 |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
5099ac24 3003 providers.output_filenames = |tcx, ()| &tcx.output_filenames;
17df50a5 3004 providers.features_query = |tcx, ()| tcx.sess.features_untracked();
0531ce1d 3005 providers.is_panic_runtime = |tcx, cnum| {
ea8adc8c 3006 assert_eq!(cnum, LOCAL_CRATE);
3dfed10e 3007 tcx.sess.contains_name(tcx.hir().krate_attrs(), sym::panic_runtime)
ea8adc8c 3008 };
0531ce1d
XL
3009 providers.is_compiler_builtins = |tcx, cnum| {
3010 assert_eq!(cnum, LOCAL_CRATE);
3dfed10e 3011 tcx.sess.contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins)
abe05a73 3012 };
60c5eb7d
XL
3013 providers.has_panic_handler = |tcx, cnum| {
3014 assert_eq!(cnum, LOCAL_CRATE);
3015 // We want to check if the panic handler was defined in this crate
3016 tcx.lang_items().panic_impl().map_or(false, |did| did.is_local())
3017 };
ea8adc8c 3018}