]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_middle/src/ty/context.rs
New upstream version 1.66.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;
2b03887a 4use crate::dep_graph::{DepGraph, DepKindStruct};
5869c6ff 5use crate::hir::place::Place as HirPlace;
9fa01778 6use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
2b03887a 7use crate::lint::struct_lint_level;
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::{
5e7ed085 19 self, AdtDef, AdtDefData, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
5099ac24
FG
20 ClosureSizeProfileData, Const, ConstS, ConstVid, DefIdTree, ExistentialPredicate, FloatTy,
21 FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List,
22 ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region,
23 RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
f2b60f7d 24 Visibility,
f9f354fc 25};
2b03887a 26use crate::ty::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef, UserSubsts};
3dfed10e 27use rustc_ast as ast;
5e7ed085 28use rustc_data_structures::fingerprint::Fingerprint;
dfeec247 29use rustc_data_structures::fx::{FxHashMap, FxHashSet};
04454e1e 30use rustc_data_structures::intern::{Interned, WithStableHash};
c295e0f8 31use rustc_data_structures::memmap::Mmap;
60c5eb7d 32use rustc_data_structures::profiling::SelfProfilerRef;
dfeec247 33use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
17df50a5 34use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
fc512014 35use rustc_data_structures::steal::Steal;
064997fb 36use rustc_data_structures::sync::{self, Lock, Lrc, ReadGuard, RwLock, WorkerLocal};
2b03887a 37use rustc_data_structures::unord::UnordSet;
5e7ed085 38use rustc_data_structures::vec_map::VecMap;
2b03887a
FG
39use rustc_errors::{
40 DecorateLint, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, MultiSpan,
41};
74b04a01
XL
42use rustc_hir as hir;
43use rustc_hir::def::{DefKind, Res};
5869c6ff 44use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
064997fb 45use rustc_hir::definitions::Definitions;
2b03887a 46use rustc_hir::hir_id::OwnerId;
f035d41b 47use rustc_hir::intravisit::Visitor;
3dfed10e 48use rustc_hir::lang_items::LangItem;
fc512014 49use rustc_hir::{
136023e0
XL
50 Constness, ExprKind, HirId, ImplItemKind, ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet,
51 Node, TraitCandidate, TraitItemKind,
fc512014 52};
e74abb32 53use rustc_index::vec::{Idx, IndexVec};
dfeec247 54use rustc_macros::HashStable;
6a06907d 55use rustc_middle::mir::FakeReadCause;
5e7ed085 56use rustc_query_system::ich::StableHashingContext;
5869c6ff 57use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
923072b8
FG
58use rustc_session::config::{CrateType, OutputFilenames};
59use rustc_session::cstore::CrateStoreDyn;
2b03887a 60use rustc_session::lint::Lint;
136023e0 61use rustc_session::Limit;
74b04a01 62use rustc_session::Session;
136023e0 63use rustc_span::def_id::{DefPathHash, StableCrateId};
04454e1e 64use rustc_span::source_map::SourceMap;
6a06907d 65use rustc_span::symbol::{kw, sym, Ident, Symbol};
f035d41b 66use rustc_span::{Span, DUMMY_SP};
5e7ed085 67use rustc_target::abi::{Layout, LayoutS, TargetDataLayout, VariantIdx};
dfeec247 68use rustc_target::spec::abi;
923072b8 69use rustc_type_ir::sty::TyKind::*;
f2b60f7d 70use rustc_type_ir::{DynKind, InternAs, InternIteratorElement, Interner, TypeFlags};
74b04a01 71
ea8adc8c 72use std::any::Any;
e9174d1e 73use std::borrow::Borrow;
7cac9316 74use std::cmp::Ordering;
3b2f2976 75use std::collections::hash_map::{self, Entry};
8faf50e0 76use std::fmt;
dfeec247 77use std::hash::{Hash, Hasher};
c30ab7b3 78use std::iter;
dfeec247
XL
79use std::mem;
80use std::ops::{Bound, Deref};
ea8adc8c 81use std::sync::Arc;
e9174d1e 82
2b03887a 83use super::{ImplPolarity, ResolverOutputs, RvalueScopes};
923072b8 84
136023e0
XL
85pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync {
86 /// Creates a new `OnDiskCache` instance from the serialized data in `data`.
c295e0f8 87 fn new(sess: &'tcx Session, data: Mmap, start_pos: usize) -> Self
136023e0
XL
88 where
89 Self: Sized;
90
91 fn new_empty(source_map: &'tcx SourceMap) -> Self
92 where
93 Self: Sized;
94
c295e0f8 95 fn drop_serialized_data(&self, tcx: TyCtxt<'tcx>);
136023e0 96
923072b8
FG
97 fn serialize(&self, tcx: TyCtxt<'tcx>, encoder: FileEncoder) -> FileEncodeResult;
98}
99
100#[allow(rustc::usage_of_ty_tykind)]
101impl<'tcx> Interner for TyCtxt<'tcx> {
102 type AdtDef = ty::AdtDef<'tcx>;
103 type SubstsRef = ty::SubstsRef<'tcx>;
104 type DefId = DefId;
105 type Ty = Ty<'tcx>;
106 type Const = ty::Const<'tcx>;
107 type Region = Region<'tcx>;
108 type TypeAndMut = TypeAndMut<'tcx>;
109 type Mutability = hir::Mutability;
110 type Movability = hir::Movability;
111 type PolyFnSig = PolyFnSig<'tcx>;
112 type ListBinderExistentialPredicate = &'tcx List<Binder<'tcx, ExistentialPredicate<'tcx>>>;
113 type BinderListTy = Binder<'tcx, &'tcx List<Ty<'tcx>>>;
114 type ListTy = &'tcx List<Ty<'tcx>>;
115 type ProjectionTy = ty::ProjectionTy<'tcx>;
116 type ParamTy = ParamTy;
117 type BoundTy = ty::BoundTy;
118 type PlaceholderType = ty::PlaceholderType;
119 type InferTy = InferTy;
120 type DelaySpanBugEmitted = DelaySpanBugEmitted;
121 type PredicateKind = ty::PredicateKind<'tcx>;
122 type AllocId = crate::mir::interpret::AllocId;
123
124 type EarlyBoundRegion = ty::EarlyBoundRegion;
125 type BoundRegion = ty::BoundRegion;
126 type FreeRegion = ty::FreeRegion;
127 type RegionVid = ty::RegionVid;
128 type PlaceholderRegion = ty::PlaceholderRegion;
136023e0
XL
129}
130
1b1a35ee
XL
131/// A type that is not publicly constructable. This prevents people from making [`TyKind::Error`]s
132/// except through the error-reporting functions on a [`tcx`][TyCtxt].
3dfed10e
XL
133#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
134#[derive(TyEncodable, TyDecodable, HashStable)]
5e7ed085
FG
135pub struct DelaySpanBugEmitted {
136 pub reported: ErrorGuaranteed,
137 _priv: (),
138}
3dfed10e 139
5099ac24 140type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
83c7162d 141
a7813a04 142pub struct CtxtInterners<'tcx> {
e1599b0c 143 /// The arena that types, regions, etc. are allocated from.
dfeec247 144 arena: &'tcx WorkerLocal<Arena<'tcx>>,
a7813a04 145
c295e0f8
XL
146 // Specifically use a speedy hash algorithm for these hash sets, since
147 // they're accessed quite often.
04454e1e 148 type_: InternedSet<'tcx, WithStableHash<TyS<'tcx>>>,
532ac7d7 149 substs: InternedSet<'tcx, InternalSubsts<'tcx>>,
fc512014 150 canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
923072b8 151 region: InternedSet<'tcx, RegionKind<'tcx>>,
cdc7bbd5
XL
152 poly_existential_predicates:
153 InternedSet<'tcx, List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>>,
5099ac24 154 predicate: InternedSet<'tcx, PredicateS<'tcx>>,
b7449926 155 predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
532ac7d7 156 projs: InternedSet<'tcx, List<ProjectionKind>>,
e74abb32 157 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
5099ac24 158 const_: InternedSet<'tcx, ConstS<'tcx>>,
c295e0f8 159 const_allocation: InternedSet<'tcx, Allocation>,
cdc7bbd5 160 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
5e7ed085
FG
161 layout: InternedSet<'tcx, LayoutS<'tcx>>,
162 adt_def: InternedSet<'tcx, AdtDefData>,
a7813a04
XL
163}
164
dc9dc135 165impl<'tcx> CtxtInterners<'tcx> {
dfeec247 166 fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
a7813a04 167 CtxtInterners {
041b39d2 168 arena,
83c7162d 169 type_: Default::default(),
83c7162d
XL
170 substs: Default::default(),
171 region: Default::default(),
fc512014 172 poly_existential_predicates: Default::default(),
83c7162d 173 canonical_var_infos: Default::default(),
f035d41b 174 predicate: Default::default(),
83c7162d 175 predicates: Default::default(),
0bf4aa26 176 projs: Default::default(),
e74abb32 177 place_elems: Default::default(),
532ac7d7 178 const_: Default::default(),
c295e0f8 179 const_allocation: Default::default(),
cdc7bbd5 180 bound_variable_kinds: Default::default(),
c295e0f8 181 layout: Default::default(),
a2a8927a 182 adt_def: Default::default(),
a7813a04
XL
183 }
184 }
185
e1599b0c
XL
186 /// Interns a type.
187 #[allow(rustc::usage_of_ty_tykind)]
a1dfa0c6 188 #[inline(never)]
5e7ed085
FG
189 fn intern_ty(
190 &self,
191 kind: TyKind<'tcx>,
192 sess: &Session,
923072b8
FG
193 definitions: &rustc_hir::definitions::Definitions,
194 cstore: &CrateStoreDyn,
195 source_span: &IndexVec<LocalDefId, Span>,
5e7ed085 196 ) -> Ty<'tcx> {
5099ac24
FG
197 Ty(Interned::new_unchecked(
198 self.type_
199 .intern(kind, |kind| {
200 let flags = super::flags::FlagComputation::for_kind(&kind);
201
2b03887a 202 // It's impossible to hash inference variables (and will ICE), so we don't need to try to cache them.
5e7ed085 203 // Without incremental, we rarely stable-hash types, so let's not do it proactively.
2b03887a 204 let stable_hash = if flags.flags.intersects(TypeFlags::NEEDS_INFER)
5e7ed085
FG
205 || sess.opts.incremental.is_none()
206 {
207 Fingerprint::ZERO
208 } else {
209 let mut hasher = StableHasher::new();
210 let mut hcx = StableHashingContext::ignore_spans(
211 sess,
923072b8
FG
212 definitions,
213 cstore,
214 source_span,
5e7ed085
FG
215 );
216 kind.hash_stable(&mut hcx, &mut hasher);
217 hasher.finish()
218 };
219
5099ac24
FG
220 let ty_struct = TyS {
221 kind,
222 flags: flags.flags,
223 outer_exclusive_binder: flags.outer_exclusive_binder,
224 };
94b46f34 225
04454e1e
FG
226 InternedInSet(
227 self.arena.alloc(WithStableHash { internee: ty_struct, stable_hash }),
228 )
5099ac24
FG
229 })
230 .0,
231 ))
94b46f34 232 }
f035d41b
XL
233
234 #[inline(never)]
5099ac24
FG
235 fn intern_predicate(&self, kind: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
236 Predicate(Interned::new_unchecked(
237 self.predicate
238 .intern(kind, |kind| {
239 let flags = super::flags::FlagComputation::for_predicate(kind);
240
241 let predicate_struct = PredicateS {
242 kind,
243 flags: flags.flags,
244 outer_exclusive_binder: flags.outer_exclusive_binder,
245 };
f035d41b 246
5099ac24
FG
247 InternedInSet(self.arena.alloc(predicate_struct))
248 })
249 .0,
250 ))
f035d41b 251 }
a7813a04
XL
252}
253
e9174d1e 254pub struct CommonTypes<'tcx> {
a1dfa0c6 255 pub unit: Ty<'tcx>,
e9174d1e
SL
256 pub bool: Ty<'tcx>,
257 pub char: Ty<'tcx>,
258 pub isize: Ty<'tcx>,
259 pub i8: Ty<'tcx>,
260 pub i16: Ty<'tcx>,
261 pub i32: Ty<'tcx>,
262 pub i64: Ty<'tcx>,
32a655c1 263 pub i128: Ty<'tcx>,
e9174d1e
SL
264 pub usize: Ty<'tcx>,
265 pub u8: Ty<'tcx>,
266 pub u16: Ty<'tcx>,
267 pub u32: Ty<'tcx>,
268 pub u64: Ty<'tcx>,
32a655c1 269 pub u128: Ty<'tcx>,
e9174d1e
SL
270 pub f32: Ty<'tcx>,
271 pub f64: Ty<'tcx>,
f035d41b 272 pub str_: Ty<'tcx>,
5bcae85e 273 pub never: Ty<'tcx>,
e1599b0c 274 pub self_param: Ty<'tcx>,
cc61c64b 275
532ac7d7
XL
276 /// Dummy type used for the `Self` of a `TraitRef` created for converting
277 /// a trait object, and which gets removed in `ExistentialTraitRef`.
278 /// This type must not appear anywhere in other converted types.
279 pub trait_object_dummy_self: Ty<'tcx>,
48663c56 280}
532ac7d7 281
48663c56 282pub struct CommonLifetimes<'tcx> {
74b04a01 283 /// `ReStatic`
7cac9316 284 pub re_static: Region<'tcx>,
74b04a01 285
5099ac24 286 /// Erased region, used outside of type inference.
7cac9316 287 pub re_erased: Region<'tcx>,
e9174d1e
SL
288}
289
48663c56 290pub struct CommonConsts<'tcx> {
5099ac24 291 pub unit: Const<'tcx>,
48663c56
XL
292}
293
dc9dc135 294pub struct LocalTableInContext<'a, V> {
2b03887a 295 hir_owner: OwnerId,
dfeec247 296 data: &'a ItemLocalMap<V>,
3b2f2976
XL
297}
298
299/// Validate that the given HirId (respectively its `local_id` part) can be
3dfed10e 300/// safely used as a key in the maps of a TypeckResults. For that to be
3b2f2976 301/// the case, the HirId must have the same `owner` as all the other IDs in
ba9703b0 302/// this table (signified by `hir_owner`). Otherwise the HirId
3b2f2976
XL
303/// would be in a different frame of reference and using its `local_id`
304/// would result in lookup errors, or worse, in silently wrong data being
305/// stored/returned.
6a06907d 306#[inline]
2b03887a 307fn validate_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: hir::HirId) {
f035d41b 308 if hir_id.owner != hir_owner {
6a06907d 309 invalid_hir_id_for_typeck_results(hir_owner, hir_id);
3b2f2976
XL
310 }
311}
312
6a06907d
XL
313#[cold]
314#[inline(never)]
2b03887a 315fn invalid_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: hir::HirId) {
6a06907d
XL
316 ty::tls::with(|tcx| {
317 bug!(
318 "node {} with HirId::owner {:?} cannot be placed in TypeckResults with hir_owner {:?}",
319 tcx.hir().node_to_string(hir_id),
320 hir_id.owner,
321 hir_owner
322 )
323 });
324}
325
3b2f2976
XL
326impl<'a, V> LocalTableInContext<'a, V> {
327 pub fn contains_key(&self, id: hir::HirId) -> bool {
3dfed10e 328 validate_hir_id_for_typeck_results(self.hir_owner, id);
3b2f2976
XL
329 self.data.contains_key(&id.local_id)
330 }
331
332 pub fn get(&self, id: hir::HirId) -> Option<&V> {
3dfed10e 333 validate_hir_id_for_typeck_results(self.hir_owner, id);
3b2f2976
XL
334 self.data.get(&id.local_id)
335 }
336
0bf4aa26 337 pub fn iter(&self) -> hash_map::Iter<'_, hir::ItemLocalId, V> {
3b2f2976
XL
338 self.data.iter()
339 }
340}
341
342impl<'a, V> ::std::ops::Index<hir::HirId> for LocalTableInContext<'a, V> {
343 type Output = V;
344
345 fn index(&self, key: hir::HirId) -> &V {
346 self.get(key).expect("LocalTableInContext: key not found")
347 }
348}
349
dc9dc135 350pub struct LocalTableInContextMut<'a, V> {
2b03887a 351 hir_owner: OwnerId,
dfeec247 352 data: &'a mut ItemLocalMap<V>,
3b2f2976
XL
353}
354
355impl<'a, V> LocalTableInContextMut<'a, V> {
356 pub fn get_mut(&mut self, id: hir::HirId) -> Option<&mut V> {
3dfed10e 357 validate_hir_id_for_typeck_results(self.hir_owner, id);
3b2f2976
XL
358 self.data.get_mut(&id.local_id)
359 }
360
0bf4aa26 361 pub fn entry(&mut self, id: hir::HirId) -> Entry<'_, hir::ItemLocalId, V> {
3dfed10e 362 validate_hir_id_for_typeck_results(self.hir_owner, id);
3b2f2976
XL
363 self.data.entry(id.local_id)
364 }
365
366 pub fn insert(&mut self, id: hir::HirId, val: V) -> Option<V> {
3dfed10e 367 validate_hir_id_for_typeck_results(self.hir_owner, id);
3b2f2976
XL
368 self.data.insert(id.local_id, val)
369 }
370
371 pub fn remove(&mut self, id: hir::HirId) -> Option<V> {
3dfed10e 372 validate_hir_id_for_typeck_results(self.hir_owner, id);
3b2f2976
XL
373 self.data.remove(&id.local_id)
374 }
375}
376
e1599b0c
XL
377/// Whenever a value may be live across a generator yield, the type of that value winds up in the
378/// `GeneratorInteriorTypeCause` struct. This struct adds additional information about such
379/// captured types that can be useful for diagnostics. In particular, it stores the span that
380/// caused a given type to be recorded, along with the scope that enclosed the value (which can
381/// be used to find the await that the value is live across).
382///
383/// For example:
384///
385/// ```ignore (pseudo-Rust)
386/// async move {
f9f354fc 387/// let x: T = expr;
e1599b0c
XL
388/// foo.await
389/// ...
390/// }
391/// ```
392///
f9f354fc
XL
393/// Here, we would store the type `T`, the span of the value `x`, the "scope-span" for
394/// the scope that contains `x`, the expr `T` evaluated from, and the span of `foo.await`.
3dfed10e 395#[derive(TyEncodable, TyDecodable, Clone, Debug, Eq, Hash, PartialEq, HashStable)]
064997fb 396#[derive(TypeFoldable, TypeVisitable)]
e1599b0c
XL
397pub struct GeneratorInteriorTypeCause<'tcx> {
398 /// Type of the captured binding.
399 pub ty: Ty<'tcx>,
400 /// Span of the binding that was captured.
401 pub span: Span,
402 /// Span of the scope of the captured binding.
403 pub scope_span: Option<Span>,
f9f354fc
XL
404 /// Span of `.await` or `yield` expression.
405 pub yield_span: Span,
dfeec247
XL
406 /// Expr which the type evaluated from.
407 pub expr: Option<hir::HirId>,
e1599b0c
XL
408}
409
04454e1e
FG
410// This type holds diagnostic information on generators and async functions across crate boundaries
411// and is used to provide better error messages
412#[derive(TyEncodable, TyDecodable, Clone, Debug, HashStable)]
413pub struct GeneratorDiagnosticData<'tcx> {
414 pub generator_interior_types: ty::Binder<'tcx, Vec<GeneratorInteriorTypeCause<'tcx>>>,
415 pub hir_owner: DefId,
416 pub nodes_types: ItemLocalMap<Ty<'tcx>>,
417 pub adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
418}
419
5e7ed085 420#[derive(TyEncodable, TyDecodable, Debug, HashStable)]
3dfed10e 421pub struct TypeckResults<'tcx> {
ba9703b0 422 /// The `HirId::owner` all `ItemLocalId`s in this table are relative to.
2b03887a 423 pub hir_owner: OwnerId,
3b2f2976 424
7cac9316
XL
425 /// Resolved definitions for `<T>::X` associated paths and
426 /// method calls, including those of overloaded operators.
5e7ed085 427 type_dependent_defs: ItemLocalMap<Result<(DefKind, DefId), ErrorGuaranteed>>,
476ff2be 428
83c7162d
XL
429 /// Resolved field indices for field accesses in expressions (`S { field }`, `obj.field`)
430 /// or patterns (`S { field }`). The index is often useful by itself, but to learn more
431 /// about the field you also need definition of the variant to which the field
432 /// belongs, but it may not exist if it's a tuple field (`tuple.0`).
433 field_indices: ItemLocalMap<usize>,
434
9fa01778 435 /// Stores the types for various nodes in the AST. Note that this table
5099ac24 436 /// is not guaranteed to be populated outside inference. See
e9174d1e 437 /// typeck::check::fn_ctxt for details.
3b2f2976 438 node_types: ItemLocalMap<Ty<'tcx>>,
e9174d1e
SL
439
440 /// Stores the type parameters which were substituted to obtain the type
9fa01778 441 /// of this node. This only applies to nodes that refer to entities
e9174d1e
SL
442 /// parameterized by type parameters, such as generic fns, types, or
443 /// other items.
532ac7d7 444 node_substs: ItemLocalMap<SubstsRef<'tcx>>,
e9174d1e 445
0731742a
XL
446 /// This will either store the canonicalized types provided by the user
447 /// or the substitutions that the user explicitly gave (if any) attached
448 /// to `id`. These will not include any inferred values. The canonical form
449 /// is used to capture things like `_` or other unspecified values.
450 ///
451 /// For example, if the user wrote `foo.collect::<Vec<_>>()`, then the
452 /// canonical substitutions would include only `for<X> { Vec<X> }`.
453 ///
454 /// See also `AscribeUserType` statement in MIR.
9fa01778 455 user_provided_types: ItemLocalMap<CanonicalUserType<'tcx>>,
0bf4aa26
XL
456
457 /// Stores the canonicalized types provided by the user. See also
458 /// `AscribeUserType` statement in MIR.
459 pub user_provided_sigs: DefIdMap<CanonicalPolyFnSig<'tcx>>,
460
3b2f2976
XL
461 adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
462
ea8adc8c 463 /// Stores the actual binding mode for all instances of hir::BindingAnnotation.
3b2f2976 464 pat_binding_modes: ItemLocalMap<BindingMode>,
e9174d1e 465
ea8adc8c 466 /// Stores the types which were implicitly dereferenced in pattern binding modes
3dfed10e 467 /// for later usage in THIR lowering. For example,
ea8adc8c
XL
468 ///
469 /// ```
470 /// match &&Some(5i32) {
471 /// Some(n) => {},
472 /// _ => {},
473 /// }
474 /// ```
475 /// leads to a `vec![&&Option<i32>, &Option<i32>]`. Empty vectors are not stored.
476 ///
477 /// See:
29967ef6 478 /// <https://github.com/rust-lang/rfcs/blob/master/text/2005-match-ergonomics.md#definitions>
ea8adc8c
XL
479 pat_adjustments: ItemLocalMap<Vec<Ty<'tcx>>>,
480
ff7c6d11
XL
481 /// Records the reasons that we picked the kind of each closure;
482 /// not all closures are present in the map.
5869c6ff 483 closure_kind_origins: ItemLocalMap<(Span, HirPlace<'tcx>)>,
ea8adc8c 484
92a42be0
SL
485 /// For each fn, records the "liberated" types of its arguments
486 /// and return type. Liberated means that all bound regions
487 /// (including late-bound regions) are replaced with free
94b46f34 488 /// equivalents. This table is not used in codegen (since regions
92a42be0 489 /// are erased there) and hence is not serialized to metadata.
136023e0
XL
490 ///
491 /// This table also contains the "revealed" values for any `impl Trait`
492 /// that appear in the signature and whose values are being inferred
493 /// by this function.
494 ///
495 /// # Example
496 ///
497 /// ```rust
04454e1e 498 /// # use std::fmt::Debug;
136023e0
XL
499 /// fn foo(x: &u32) -> impl Debug { *x }
500 /// ```
501 ///
502 /// The function signature here would be:
503 ///
04454e1e 504 /// ```ignore (illustrative)
136023e0
XL
505 /// for<'a> fn(&'a u32) -> Foo
506 /// ```
507 ///
508 /// where `Foo` is an opaque type created for this function.
509 ///
510 ///
511 /// The *liberated* form of this would be
512 ///
04454e1e 513 /// ```ignore (illustrative)
136023e0
XL
514 /// fn(&'a u32) -> u32
515 /// ```
516 ///
517 /// Note that `'a` is not bound (it would be an `ReFree`) and
518 /// that the `Foo` opaque type is replaced by its hidden type.
3b2f2976 519 liberated_fn_sigs: ItemLocalMap<ty::FnSig<'tcx>>,
7453a54e
SL
520
521 /// For each FRU expression, record the normalized types of the fields
522 /// of the struct - this is needed because it is non-trivial to
523 /// normalize while preserving regions. This table is used only in
524 /// MIR construction and hence is not serialized to metadata.
3b2f2976 525 fru_field_types: ItemLocalMap<Vec<Ty<'tcx>>>,
32a655c1 526
532ac7d7
XL
527 /// For every coercion cast we add the HIR node ID of the cast
528 /// expression to this set.
529 coercion_casts: ItemLocalSet,
8bb4bdeb
XL
530
531 /// Set of trait imports actually used in the method resolution.
abe05a73 532 /// This is used for warning unused imports. During type
0531ce1d 533 /// checking, this `Lrc` should not be cloned: it must have a ref-count
abe05a73 534 /// of 1 so that we can insert things into the set mutably.
2b03887a 535 pub used_trait_imports: Lrc<UnordSet<LocalDefId>>,
8bb4bdeb
XL
536
537 /// If any errors occurred while type-checking this body,
5e7ed085
FG
538 /// this field will be set to `Some(ErrorGuaranteed)`.
539 pub tainted_by_errors: Option<ErrorGuaranteed>,
94b46f34 540
5e7ed085 541 /// All the opaque types that have hidden types set
2b03887a
FG
542 /// by this function. We also store the
543 /// type here, so that mir-borrowck can use it as a hint for figuring out hidden types,
5e7ed085 544 /// even if they are only set in dead code (which doesn't show up in MIR).
2b03887a 545 pub concrete_opaque_types: VecMap<LocalDefId, ty::OpaqueHiddenType<'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.
2b03887a 577 /// Details may be find in `rustc_hir_analysis::check::rvalue_scopes`.
923072b8
FG
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 595impl<'tcx> TypeckResults<'tcx> {
2b03887a 596 pub fn new(hir_owner: OwnerId) -> TypeckResults<'tcx> {
3dfed10e 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 876pub struct CanonicalUserTypeAnnotation<'tcx> {
f2b60f7d 877 pub user_ty: Box<CanonicalUserType<'tcx>>,
9fa01778
XL
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 988
f2b60f7d 989 CommonLifetimes { re_static: mk(ty::ReStatic), re_erased: mk(ty::ReErased) }
48663c56
XL
990 }
991}
992
993impl<'tcx> CommonConsts<'tcx> {
994 fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonConsts<'tcx> {
5099ac24
FG
995 let mk_const = |c| {
996 Const(Interned::new_unchecked(
997 interners.const_.intern(c, |c| InternedInSet(interners.arena.alloc(c))).0,
998 ))
999 };
48663c56
XL
1000
1001 CommonConsts {
5099ac24 1002 unit: mk_const(ty::ConstS {
923072b8 1003 kind: ty::ConstKind::Value(ty::ValTree::zst()),
ba9703b0 1004 ty: types.unit,
dc9dc135 1005 }),
e9174d1e
SL
1006 }
1007 }
1008}
1009
0bf4aa26
XL
1010// This struct contains information regarding the `ReFree(FreeRegion)` corresponding to a lifetime
1011// conflict.
1012#[derive(Debug)]
1013pub struct FreeRegionInfo {
f035d41b
XL
1014 // `LocalDefId` corresponding to FreeRegion
1015 pub def_id: LocalDefId,
0bf4aa26 1016 // the bound region corresponding to FreeRegion
fc512014 1017 pub boundregion: ty::BoundRegionKind,
0bf4aa26
XL
1018 // checks if bound region is in Impl Item
1019 pub is_impl_item: bool,
1020}
1021
ea8adc8c
XL
1022/// The central data structure of the compiler. It stores references
1023/// to the various **arenas** and also houses the results of the
ff7c6d11 1024/// various **compiler queries** that have been performed. See the
ba9703b0 1025/// [rustc dev guide] for more details.
ff7c6d11 1026///
ba9703b0 1027/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/ty.html
a7813a04 1028#[derive(Copy, Clone)]
e74abb32 1029#[rustc_diagnostic_item = "TyCtxt"]
5e7ed085 1030#[rustc_pass_by_value]
dc9dc135
XL
1031pub struct TyCtxt<'tcx> {
1032 gcx: &'tcx GlobalCtxt<'tcx>,
a7813a04 1033}
e9174d1e 1034
dc9dc135
XL
1035impl<'tcx> Deref for TyCtxt<'tcx> {
1036 type Target = &'tcx GlobalCtxt<'tcx>;
a1dfa0c6 1037 #[inline(always)]
a7813a04
XL
1038 fn deref(&self) -> &Self::Target {
1039 &self.gcx
1040 }
1041}
1042
1043pub struct GlobalCtxt<'tcx> {
60c5eb7d 1044 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
064997fb 1045 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
dc9dc135 1046
416331ca 1047 interners: CtxtInterners<'tcx>,
e9174d1e 1048
8bb4bdeb
XL
1049 pub sess: &'tcx Session,
1050
dfeec247
XL
1051 /// This only ever stores a `LintStore` but we don't want a dependency on that type here.
1052 ///
1053 /// FIXME(Centril): consider `dyn LintStoreMarker` once
1054 /// we can upcast to `Any` for some additional type safety.
1055 pub lint_store: Lrc<dyn Any + sync::Sync + sync::Send>,
e74abb32 1056
9cc50fc6
SL
1057 pub dep_graph: DepGraph,
1058
e74abb32 1059 pub prof: SelfProfilerRef,
dc9dc135 1060
e9174d1e
SL
1061 /// Common types, pre-interned for your convenience.
1062 pub types: CommonTypes<'tcx>,
1063
48663c56
XL
1064 /// Common lifetimes, pre-interned for your convenience.
1065 pub lifetimes: CommonLifetimes<'tcx>,
1066
1067 /// Common consts, pre-interned for your convenience.
1068 pub consts: CommonConsts<'tcx>,
1069
064997fb 1070 definitions: RwLock<Definitions>,
923072b8 1071
136023e0 1072 /// Output of the resolver.
2b03887a 1073 pub(crate) untracked_resolutions: ty::ResolverGlobalCtxt,
064997fb
FG
1074 untracked_resolver_for_lowering: Steal<ty::ResolverAstLowering>,
1075 /// The entire crate as AST. This field serves as the input for the hir_crate query,
1076 /// which lowers it from AST to HIR. It must not be read or used by anything else.
1077 pub untracked_crate: Steal<Lrc<ast::Crate>>,
7cac9316 1078
6a06907d
XL
1079 /// This provides access to the incremental compilation on-disk cache for query results.
1080 /// Do not access this directly. It is only meant to be used by
1081 /// `DepGraph::try_mark_green()` and the query infrastructure.
1082 /// This is `None` if we are not incremental compilation mode
136023e0 1083 pub on_disk_cache: Option<&'tcx dyn OnDiskCache<'tcx>>,
6a06907d
XL
1084
1085 pub queries: &'tcx dyn query::QueryEngine<'tcx>,
1086 pub query_caches: query::QueryCaches<'tcx>,
2b03887a 1087 pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>],
c30ab7b3 1088
f035d41b
XL
1089 // Internal caches for metadata decoding. No need to track deps on this.
1090 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
1091 pub pred_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Predicate<'tcx>>>,
9cc50fc6 1092
e9174d1e
SL
1093 /// Caches the results of trait selection. This cache is used
1094 /// for things that do not have to do with the parameters in scope.
1095 pub selection_cache: traits::SelectionCache<'tcx>,
1096
92a42be0
SL
1097 /// Caches the results of trait evaluation. This cache is used
1098 /// for things that do not have to do with the parameters in scope.
1099 /// Merge this with `selection_cache`?
1100 pub evaluation_cache: traits::EvaluationCache<'tcx>,
1101
54a0048b
SL
1102 /// The definite name of the current crate after taking into account
1103 /// attributes, commandline parameters, etc.
17df50a5 1104 crate_name: Symbol,
54a0048b
SL
1105
1106 /// Data layout specification for the current target.
1107 pub data_layout: TargetDataLayout,
1108
ba9703b0 1109 /// Stores memory for globals (statics/consts).
f9f354fc 1110 pub(crate) alloc_map: Lock<interpret::AllocMap<'tcx>>,
ff7c6d11 1111
ea8adc8c 1112 output_filenames: Arc<OutputFilenames>,
e9174d1e 1113}
e9174d1e 1114
dc9dc135 1115impl<'tcx> TyCtxt<'tcx> {
04454e1e
FG
1116 /// Expects a body and returns its codegen attributes.
1117 ///
1118 /// Unlike `codegen_fn_attrs`, this returns `CodegenFnAttrs::EMPTY` for
1119 /// constants.
1120 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
1121 let def_kind = self.def_kind(def_id);
1122 if def_kind.has_codegen_attrs() {
1123 self.codegen_fn_attrs(def_id)
1124 } else if matches!(
1125 def_kind,
1126 DefKind::AnonConst | DefKind::AssocConst | DefKind::Const | DefKind::InlineConst
1127 ) {
1128 CodegenFnAttrs::EMPTY
1129 } else {
1130 bug!(
1131 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
1132 def_id,
1133 def_kind
1134 )
1135 }
1136 }
1137
3dfed10e
XL
1138 pub fn typeck_opt_const_arg(
1139 self,
1140 def: ty::WithOptConstParam<LocalDefId>,
1141 ) -> &'tcx TypeckResults<'tcx> {
1142 if let Some(param_did) = def.const_param_did {
1143 self.typeck_const_arg((def.did, param_did))
1144 } else {
1145 self.typeck(def.did)
1146 }
1147 }
1148
5099ac24
FG
1149 pub fn mir_borrowck_opt_const_arg(
1150 self,
1151 def: ty::WithOptConstParam<LocalDefId>,
1152 ) -> &'tcx BorrowCheckResult<'tcx> {
1153 if let Some(param_did) = def.const_param_did {
1154 self.mir_borrowck_const_arg((def.did, param_did))
1155 } else {
1156 self.mir_borrowck(def.did)
1157 }
1158 }
1159
17df50a5
XL
1160 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
1161 self.arena.alloc(Steal::new(thir))
1162 }
1163
3dfed10e
XL
1164 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
1165 self.arena.alloc(Steal::new(mir))
7cac9316
XL
1166 }
1167
dfeec247
XL
1168 pub fn alloc_steal_promoted(
1169 self,
f9f354fc 1170 promoted: IndexVec<Promoted, Body<'tcx>>,
3dfed10e
XL
1171 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
1172 self.arena.alloc(Steal::new(promoted))
e1599b0c
XL
1173 }
1174
dc9dc135
XL
1175 pub fn alloc_adt_def(
1176 self,
1177 did: DefId,
1178 kind: AdtKind,
1179 variants: IndexVec<VariantIdx, ty::VariantDef>,
1180 repr: ReprOptions,
5e7ed085
FG
1181 ) -> ty::AdtDef<'tcx> {
1182 self.intern_adt_def(ty::AdtDefData::new(self, did, kind, variants, repr))
e9174d1e
SL
1183 }
1184
e1599b0c 1185 /// Allocates a read-only byte or string literal for `mir::interpret`.
94b46f34 1186 pub fn allocate_bytes(self, bytes: &[u8]) -> interpret::AllocId {
e1599b0c 1187 // Create an allocation that just contains these bytes.
17df50a5 1188 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes);
ff7c6d11 1189 let alloc = self.intern_const_alloc(alloc);
f9f354fc 1190 self.create_memory_alloc(alloc)
ff7c6d11
XL
1191 }
1192
b7449926
XL
1193 /// Returns a range of the start/end indices specified with the
1194 /// `rustc_layout_scalar_valid_range` attribute.
c295e0f8 1195 // FIXME(eddyb) this is an awkward spot for this method, maybe move it?
b7449926 1196 pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
b7449926 1197 let get = |name| {
04454e1e 1198 let Some(attr) = self.get_attr(def_id, name) else {
5e7ed085 1199 return Bound::Unbounded;
b7449926 1200 };
f035d41b 1201 debug!("layout_scalar_valid_range: attr={:?}", attr);
6a06907d 1202 if let Some(
a2a8927a
XL
1203 &[
1204 ast::NestedMetaItem::Literal(ast::Lit {
1205 kind: ast::LitKind::Int(a, _), ..
1206 }),
1207 ],
6a06907d
XL
1208 ) = attr.meta_item_list().as_deref()
1209 {
1210 Bound::Included(a)
1211 } else {
1212 self.sess
1213 .delay_span_bug(attr.span, "invalid rustc_layout_scalar_valid_range attribute");
1214 Bound::Unbounded
b7449926 1215 }
b7449926 1216 };
dfeec247
XL
1217 (
1218 get(sym::rustc_layout_scalar_valid_range_start),
1219 get(sym::rustc_layout_scalar_valid_range_end),
1220 )
b7449926
XL
1221 }
1222
29967ef6 1223 pub fn lift<T: Lift<'tcx>>(self, value: T) -> Option<T::Lifted> {
e9174d1e
SL
1224 value.lift_to_tcx(self)
1225 }
1226
9fa01778 1227 /// Creates a type context and call the closure with a `TyCtxt` reference
e9174d1e
SL
1228 /// to the context. The closure enforces that the type context and any interned
1229 /// value (types, substs, etc.) can only be used while `ty::tls` has a valid
1230 /// reference to the context, to allow formatting values that need it.
532ac7d7
XL
1231 pub fn create_global_ctxt(
1232 s: &'tcx Session,
dfeec247 1233 lint_store: Lrc<dyn Any + sync::Send + sync::Sync>,
60c5eb7d 1234 arena: &'tcx WorkerLocal<Arena<'tcx>>,
064997fb 1235 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
2b03887a 1236 resolver_outputs: ResolverOutputs,
064997fb 1237 krate: Lrc<ast::Crate>,
ba9703b0 1238 dep_graph: DepGraph,
136023e0 1239 on_disk_cache: Option<&'tcx dyn OnDiskCache<'tcx>>,
6a06907d 1240 queries: &'tcx dyn query::QueryEngine<'tcx>,
f2b60f7d 1241 query_kinds: &'tcx [DepKindStruct<'tcx>],
532ac7d7 1242 crate_name: &str,
17df50a5 1243 output_filenames: OutputFilenames,
532ac7d7 1244 ) -> GlobalCtxt<'tcx> {
2b03887a
FG
1245 let ResolverOutputs {
1246 definitions,
1247 global_ctxt: untracked_resolutions,
1248 ast_lowering: untracked_resolver_for_lowering,
1249 } = resolver_outputs;
29967ef6 1250 let data_layout = TargetDataLayout::parse(&s.target).unwrap_or_else(|err| {
f2b60f7d 1251 s.emit_fatal(err);
83c7162d 1252 });
dfeec247 1253 let interners = CtxtInterners::new(arena);
923072b8
FG
1254 let common_types = CommonTypes::new(
1255 &interners,
1256 s,
1257 &definitions,
2b03887a 1258 &*untracked_resolutions.cstore,
923072b8
FG
1259 // This is only used to create a stable hashing context.
1260 &untracked_resolutions.source_span,
1261 );
48663c56
XL
1262 let common_lifetimes = CommonLifetimes::new(&interners);
1263 let common_consts = CommonConsts::new(&interners, &common_types);
7cac9316 1264
532ac7d7 1265 GlobalCtxt {
8bb4bdeb 1266 sess: s,
e74abb32 1267 lint_store,
60c5eb7d 1268 arena,
064997fb 1269 hir_arena,
416331ca 1270 interners,
0bf4aa26 1271 dep_graph,
064997fb 1272 definitions: RwLock::new(definitions),
e74abb32 1273 prof: s.prof.clone(),
e9174d1e 1274 types: common_types,
48663c56
XL
1275 lifetimes: common_lifetimes,
1276 consts: common_consts,
064997fb
FG
1277 untracked_resolutions,
1278 untracked_resolver_for_lowering: Steal::new(untracked_resolver_for_lowering),
1279 untracked_crate: Steal::new(krate),
6a06907d
XL
1280 on_disk_cache,
1281 queries,
1282 query_caches: query::QueryCaches::default(),
3c0e092e 1283 query_kinds,
f035d41b
XL
1284 ty_rcache: Default::default(),
1285 pred_rcache: Default::default(),
0bf4aa26
XL
1286 selection_cache: Default::default(),
1287 evaluation_cache: Default::default(),
476ff2be 1288 crate_name: Symbol::intern(crate_name),
041b39d2 1289 data_layout,
94b46f34 1290 alloc_map: Lock::new(interpret::AllocMap::new()),
17df50a5 1291 output_filenames: Arc::new(output_filenames),
532ac7d7 1292 }
e9174d1e 1293 }
cc61c64b 1294
f035d41b
XL
1295 /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used.
1296 #[track_caller]
1297 pub fn ty_error(self) -> Ty<'tcx> {
1298 self.ty_error_with_message(DUMMY_SP, "TyKind::Error constructed but no error reported")
1299 }
1300
1301 /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg` to
1302 /// ensure it gets used.
1303 #[track_caller]
1304 pub fn ty_error_with_message<S: Into<MultiSpan>>(self, span: S, msg: &str) -> Ty<'tcx> {
5e7ed085
FG
1305 let reported = self.sess.delay_span_bug(span, msg);
1306 self.mk_ty(Error(DelaySpanBugEmitted { reported, _priv: () }))
f035d41b
XL
1307 }
1308
5099ac24 1309 /// Like [TyCtxt::ty_error] but for constants.
f035d41b 1310 #[track_caller]
5099ac24
FG
1311 pub fn const_error(self, ty: Ty<'tcx>) -> Const<'tcx> {
1312 self.const_error_with_message(
1313 ty,
1314 DUMMY_SP,
1315 "ty::ConstKind::Error constructed but no error reported",
1316 )
1317 }
1318
1319 /// Like [TyCtxt::ty_error_with_message] but for constants.
1320 #[track_caller]
1321 pub fn const_error_with_message<S: Into<MultiSpan>>(
1322 self,
1323 ty: Ty<'tcx>,
1324 span: S,
1325 msg: &str,
1326 ) -> Const<'tcx> {
5e7ed085
FG
1327 let reported = self.sess.delay_span_bug(span, msg);
1328 self.mk_const(ty::ConstS {
923072b8 1329 kind: ty::ConstKind::Error(DelaySpanBugEmitted { reported, _priv: () }),
5e7ed085
FG
1330 ty,
1331 })
f035d41b
XL
1332 }
1333
1b1a35ee 1334 pub fn consider_optimizing<T: Fn() -> String>(self, msg: T) -> bool {
a2a8927a
XL
1335 let cname = self.crate_name(LOCAL_CRATE);
1336 self.sess.consider_optimizing(cname.as_str(), msg)
b7449926
XL
1337 }
1338
e1599b0c 1339 /// Obtain all lang items of this crate and all dependencies (recursively)
ba9703b0 1340 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
17df50a5 1341 self.get_lang_items(())
ea8adc8c
XL
1342 }
1343
e1599b0c
XL
1344 /// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to
1345 /// compare against another `DefId`, since `is_diagnostic_item` is cheaper.
1346 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
c295e0f8
XL
1347 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1348 }
1349
1350 /// Obtain the diagnostic item's name
1351 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1352 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
e1599b0c
XL
1353 }
1354
1355 /// Check whether the diagnostic item with the given `name` has the given `DefId`.
1356 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
c295e0f8 1357 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
e1599b0c
XL
1358 }
1359
5e7ed085 1360 pub fn stability(self) -> &'tcx stability::Index {
17df50a5 1361 self.stability_index(())
ea8adc8c
XL
1362 }
1363
60c5eb7d 1364 pub fn features(self) -> &'tcx rustc_feature::Features {
17df50a5 1365 self.features_query(())
0531ce1d
XL
1366 }
1367
ba9703b0 1368 pub fn def_key(self, id: DefId) -> rustc_hir::definitions::DefKey {
136023e0
XL
1369 // Accessing the DefKey is ok, since it is part of DefPathHash.
1370 if let Some(id) = id.as_local() {
064997fb 1371 self.definitions_untracked().def_key(id)
136023e0 1372 } else {
2b03887a 1373 self.untracked_resolutions.cstore.def_key(id)
136023e0 1374 }
ea8adc8c
XL
1375 }
1376
9fa01778 1377 /// Converts a `DefId` into its fully expanded `DefPath` (every
e1599b0c 1378 /// `DefId` is really just an interned `DefPath`).
ea8adc8c
XL
1379 ///
1380 /// Note that if `id` is not local to this crate, the result will
1381 /// be a non-local `DefPath`.
ba9703b0 1382 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
136023e0 1383 // Accessing the DefPath is ok, since it is part of DefPathHash.
ba9703b0 1384 if let Some(id) = id.as_local() {
064997fb 1385 self.definitions_untracked().def_path(id)
ba9703b0 1386 } else {
2b03887a 1387 self.untracked_resolutions.cstore.def_path(id)
ba9703b0 1388 }
ea8adc8c
XL
1389 }
1390
1391 #[inline]
ba9703b0 1392 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
136023e0 1393 // Accessing the DefPathHash is ok, it is incr. comp. stable.
ba9703b0 1394 if let Some(def_id) = def_id.as_local() {
064997fb 1395 self.definitions_untracked().def_path_hash(def_id)
ea8adc8c 1396 } else {
2b03887a 1397 self.untracked_resolutions.cstore.def_path_hash(def_id)
ea8adc8c
XL
1398 }
1399 }
1400
17df50a5 1401 #[inline]
136023e0
XL
1402 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1403 if crate_num == LOCAL_CRATE {
1404 self.sess.local_stable_crate_id()
1405 } else {
2b03887a 1406 self.untracked_resolutions.cstore.stable_crate_id(crate_num)
136023e0 1407 }
17df50a5
XL
1408 }
1409
c295e0f8
XL
1410 /// Maps a StableCrateId to the corresponding CrateNum. This method assumes
1411 /// that the crate in question has already been loaded by the CrateStore.
1412 #[inline]
1413 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1414 if stable_crate_id == self.sess.local_stable_crate_id() {
1415 LOCAL_CRATE
1416 } else {
2b03887a 1417 self.untracked_resolutions.cstore.stable_crate_id_to_crate_num(stable_crate_id)
c295e0f8
XL
1418 }
1419 }
1420
3c0e092e
XL
1421 /// Converts a `DefPathHash` to its corresponding `DefId` in the current compilation
1422 /// session, if it still exists. This is used during incremental compilation to
1423 /// turn a deserialized `DefPathHash` into its current `DefId`.
5099ac24 1424 pub fn def_path_hash_to_def_id(self, hash: DefPathHash, err: &mut dyn FnMut() -> !) -> DefId {
3c0e092e
XL
1425 debug!("def_path_hash_to_def_id({:?})", hash);
1426
1427 let stable_crate_id = hash.stable_crate_id();
1428
1429 // If this is a DefPathHash from the local crate, we can look up the
1430 // DefId in the tcx's `Definitions`.
1431 if stable_crate_id == self.sess.local_stable_crate_id() {
064997fb 1432 self.definitions.read().local_def_path_hash_to_def_id(hash, err).to_def_id()
3c0e092e
XL
1433 } else {
1434 // If this is a DefPathHash from an upstream crate, let the CrateStore map
1435 // it to a DefId.
2b03887a
FG
1436 let cstore = &*self.untracked_resolutions.cstore;
1437 let cnum = cstore.stable_crate_id_to_crate_num(stable_crate_id);
1438 cstore.def_path_hash_to_def_id(cnum, hash)
3c0e092e
XL
1439 }
1440 }
1441
ea8adc8c
XL
1442 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1443 // We are explicitly not going through queries here in order to get
136023e0 1444 // crate name and stable crate id since this code is called from debug!()
ea8adc8c
XL
1445 // statements within the query system and we'd run into endless
1446 // recursion otherwise.
136023e0
XL
1447 let (crate_name, stable_crate_id) = if def_id.is_local() {
1448 (self.crate_name, self.sess.local_stable_crate_id())
ea8adc8c 1449 } else {
2b03887a 1450 let cstore = &*self.untracked_resolutions.cstore;
136023e0 1451 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
ea8adc8c
XL
1452 };
1453
dfeec247 1454 format!(
064997fb 1455 "{}[{:04x}]{}",
dfeec247 1456 crate_name,
136023e0 1457 // Don't print the whole stable crate id. That's just
dfeec247 1458 // annoying in debug output.
064997fb 1459 stable_crate_id.to_u64() >> 8 * 6,
1b1a35ee 1460 self.def_path(def_id).to_string_no_crate_verbose()
dfeec247 1461 )
ea8adc8c
XL
1462 }
1463
064997fb
FG
1464 /// Create a new definition within the incr. comp. engine.
1465 pub fn create_def(self, parent: LocalDefId, data: hir::definitions::DefPathData) -> LocalDefId {
1466 // This function modifies `self.definitions` using a side-effect.
1467 // We need to ensure that these side effects are re-run by the incr. comp. engine.
1468 // Depending on the forever-red node will tell the graph that the calling query
1469 // needs to be re-evaluated.
1470 use rustc_query_system::dep_graph::DepNodeIndex;
1471 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1472
1473 // The following call has the side effect of modifying the tables inside `definitions`.
1474 // These very tables are relied on by the incr. comp. engine to decode DepNodes and to
1475 // decode the on-disk cache.
1476 //
1477 // Any LocalDefId which is used within queries, either as key or result, either:
1478 // - has been created before the construction of the TyCtxt;
1479 // - has been created by this call to `create_def`.
1480 // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
1481 // comp. engine itself.
1482 //
1483 // This call also writes to the value of `source_span` and `expn_that_defined` queries.
1484 // This is fine because:
1485 // - those queries are `eval_always` so we won't miss their result changing;
1486 // - this write will have happened before these queries are called.
1487 self.definitions.write().create_def(parent, data)
1488 }
1489
1490 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> + 'tcx {
1491 // Create a dependency to the crate to be sure we re-execute this when the amount of
1492 // definitions change.
1493 self.ensure().hir_crate(());
f2b60f7d 1494 // Leak a read lock once we start iterating on definitions, to prevent adding new ones
064997fb
FG
1495 // while iterating. If some query needs to add definitions, it should be `ensure`d above.
1496 let definitions = self.definitions.leak();
1497 definitions.iter_local_def_id()
1498 }
1499
1500 pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
f2b60f7d 1501 // Create a dependency to the crate to be sure we re-execute this when the amount of
064997fb
FG
1502 // definitions change.
1503 self.ensure().hir_crate(());
f2b60f7d 1504 // Leak a read lock once we start iterating on definitions, to prevent adding new ones
064997fb
FG
1505 // while iterating. If some query needs to add definitions, it should be `ensure`d above.
1506 let definitions = self.definitions.leak();
1507 definitions.def_path_table()
1508 }
1509
1510 pub fn def_path_hash_to_def_index_map(
1511 self,
1512 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
f2b60f7d 1513 // Create a dependency to the crate to be sure we re-execute this when the amount of
064997fb
FG
1514 // definitions change.
1515 self.ensure().hir_crate(());
f2b60f7d 1516 // Leak a read lock once we start iterating on definitions, to prevent adding new ones
064997fb
FG
1517 // while iterating. If some query needs to add definitions, it should be `ensure`d above.
1518 let definitions = self.definitions.leak();
1519 definitions.def_path_hash_to_def_index_map()
1520 }
1521
136023e0
XL
1522 /// Note that this is *untracked* and should only be used within the query
1523 /// system if the result is otherwise tracked through queries
923072b8 1524 pub fn cstore_untracked(self) -> &'tcx CrateStoreDyn {
2b03887a 1525 &*self.untracked_resolutions.cstore
136023e0
XL
1526 }
1527
1528 /// Note that this is *untracked* and should only be used within the query
1529 /// system if the result is otherwise tracked through queries
064997fb
FG
1530 #[inline]
1531 pub fn definitions_untracked(self) -> ReadGuard<'tcx, Definitions> {
1532 self.definitions.read()
923072b8
FG
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
1537 #[inline]
1538 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
1539 self.untracked_resolutions.source_span.get(def_id).copied().unwrap_or(DUMMY_SP)
ea8adc8c
XL
1540 }
1541
0731742a 1542 #[inline(always)]
064997fb
FG
1543 pub fn with_stable_hashing_context<R>(
1544 self,
1545 f: impl FnOnce(StableHashingContext<'_>) -> R,
1546 ) -> R {
1547 let definitions = self.definitions_untracked();
1548 let hcx = StableHashingContext::new(
136023e0 1549 self.sess,
064997fb 1550 &*definitions,
2b03887a 1551 &*self.untracked_resolutions.cstore,
923072b8 1552 &self.untracked_resolutions.source_span,
064997fb
FG
1553 );
1554 f(hcx)
f035d41b
XL
1555 }
1556
923072b8
FG
1557 pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
1558 self.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
0531ce1d
XL
1559 }
1560
f9f354fc
XL
1561 /// If `true`, we should use lazy normalization for constants, otherwise
1562 /// we still evaluate them eagerly.
1563 #[inline]
1564 pub fn lazy_normalization(self) -> bool {
3dfed10e 1565 let features = self.features();
94222f64
XL
1566 // Note: We only use lazy normalization for generic const expressions.
1567 features.generic_const_exprs
f9f354fc
XL
1568 }
1569
83c7162d
XL
1570 #[inline]
1571 pub fn local_crate_exports_generics(self) -> bool {
b7449926 1572 debug_assert!(self.sess.opts.share_generics());
83c7162d 1573
f9f354fc 1574 self.sess.crate_types().iter().any(|crate_type| {
83c7162d 1575 match crate_type {
dfeec247
XL
1576 CrateType::Executable
1577 | CrateType::Staticlib
1578 | CrateType::ProcMacro
1579 | CrateType::Cdylib => false,
e74abb32
XL
1580
1581 // FIXME rust-lang/rust#64319, rust-lang/rust#64872:
1582 // We want to block export of generics from dylibs,
1583 // but we must fix rust-lang/rust#65890 before we can
1584 // do that robustly.
dfeec247 1585 CrateType::Dylib => true,
e74abb32 1586
dfeec247 1587 CrateType::Rlib => true,
83c7162d
XL
1588 }
1589 })
0531ce1d 1590 }
0bf4aa26 1591
f2b60f7d 1592 /// Returns the `DefId` and the `BoundRegionKind` corresponding to the given region.
1b1a35ee 1593 pub fn is_suitable_region(self, region: Region<'tcx>) -> Option<FreeRegionInfo> {
0bf4aa26 1594 let (suitable_region_binding_scope, bound_region) = match *region {
f035d41b
XL
1595 ty::ReFree(ref free_region) => {
1596 (free_region.scope.expect_local(), free_region.bound_region)
dfeec247 1597 }
f035d41b 1598 ty::ReEarlyBound(ref ebr) => (
04454e1e 1599 self.local_parent(ebr.def_id.expect_local()),
fc512014 1600 ty::BoundRegionKind::BrNamed(ebr.def_id, ebr.name),
f035d41b 1601 ),
0bf4aa26
XL
1602 _ => return None, // not a free region
1603 };
1604
5099ac24 1605 let is_impl_item = match self.hir().find_by_def_id(suitable_region_binding_scope) {
ba9703b0 1606 Some(Node::Item(..) | Node::TraitItem(..)) => false,
0bf4aa26
XL
1607 Some(Node::ImplItem(..)) => {
1608 self.is_bound_region_in_impl_item(suitable_region_binding_scope)
1609 }
1610 _ => return None,
1611 };
1612
ba9703b0 1613 Some(FreeRegionInfo {
0bf4aa26
XL
1614 def_id: suitable_region_binding_scope,
1615 boundregion: bound_region,
60c5eb7d 1616 is_impl_item,
ba9703b0 1617 })
0bf4aa26
XL
1618 }
1619
f035d41b
XL
1620 /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type.
1621 pub fn return_type_impl_or_dyn_traits(
1b1a35ee 1622 self,
f035d41b
XL
1623 scope_def_id: LocalDefId,
1624 ) -> Vec<&'tcx hir::Ty<'tcx>> {
3dfed10e 1625 let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
5e7ed085
FG
1626 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir().fn_decl_by_hir_id(hir_id) else {
1627 return vec![];
f9f354fc
XL
1628 };
1629
f035d41b
XL
1630 let mut v = TraitObjectVisitor(vec![], self.hir());
1631 v.visit_ty(hir_output);
1632 v.0
f9f354fc
XL
1633 }
1634
1b1a35ee 1635 pub fn return_type_impl_trait(self, scope_def_id: LocalDefId) -> Option<(Ty<'tcx>, Span)> {
136023e0 1636 // `type_of()` will fail on these (#55796, #86483), so only allow `fn`s or closures.
5099ac24 1637 match self.hir().get_by_def_id(scope_def_id) {
136023e0
XL
1638 Node::Item(&hir::Item { kind: ItemKind::Fn(..), .. }) => {}
1639 Node::TraitItem(&hir::TraitItem { kind: TraitItemKind::Fn(..), .. }) => {}
1640 Node::ImplItem(&hir::ImplItem { kind: ImplItemKind::Fn(..), .. }) => {}
923072b8 1641 Node::Expr(&hir::Expr { kind: ExprKind::Closure { .. }, .. }) => {}
136023e0 1642 _ => return None,
13cf67c4
XL
1643 }
1644
0bf4aa26 1645 let ret_ty = self.type_of(scope_def_id);
1b1a35ee 1646 match ret_ty.kind() {
0bf4aa26 1647 ty::FnDef(_, _) => {
1b1a35ee 1648 let sig = ret_ty.fn_sig(self);
fc512014 1649 let output = self.erase_late_bound_regions(sig.output());
0bf4aa26 1650 if output.is_impl_trait() {
5099ac24 1651 let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
60c5eb7d
XL
1652 let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap();
1653 Some((output, fn_decl.output.span()))
0bf4aa26
XL
1654 } else {
1655 None
1656 }
1657 }
dfeec247 1658 _ => None,
0bf4aa26
XL
1659 }
1660 }
1661
e1599b0c 1662 // Checks if the bound region is in Impl Item.
1b1a35ee 1663 pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
064997fb 1664 let container_id = self.parent(suitable_region_binding_scope.to_def_id());
0bf4aa26
XL
1665 if self.impl_trait_ref(container_id).is_some() {
1666 // For now, we do not try to target impls of traits. This is
1667 // because this message is going to suggest that the user
1668 // change the fn signature, but they may not be free to do so,
1669 // since the signature must match the trait.
1670 //
1671 // FIXME(#42706) -- in some cases, we could do better here.
1672 return true;
1673 }
1674 false
1675 }
9fa01778 1676
e1599b0c 1677 /// Determines whether identifiers in the assembly have strict naming rules.
9fa01778 1678 /// Currently, only NVPTX* targets need it.
1b1a35ee 1679 pub fn has_strict_asm_symbol_naming(self) -> bool {
29967ef6 1680 self.sess.target.arch.contains("nvptx")
ea8adc8c 1681 }
60c5eb7d
XL
1682
1683 /// Returns `&'static core::panic::Location<'static>`.
1b1a35ee 1684 pub fn caller_location_ty(self) -> Ty<'tcx> {
60c5eb7d
XL
1685 self.mk_imm_ref(
1686 self.lifetimes.re_static,
04454e1e 1687 self.bound_type_of(self.require_lang_item(LangItem::PanicLocation, None))
1b1a35ee 1688 .subst(self, self.mk_substs([self.lifetimes.re_static.into()].iter())),
60c5eb7d
XL
1689 )
1690 }
74b04a01
XL
1691
1692 /// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`).
1b1a35ee 1693 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
f9f354fc
XL
1694 match self.def_kind(def_id) {
1695 DefKind::Generator => match self.generator_kind(def_id).unwrap() {
1696 rustc_hir::GeneratorKind::Async(..) => ("an", "async closure"),
1697 rustc_hir::GeneratorKind::Gen => ("a", "generator"),
1698 },
1699 def_kind => (def_kind.article(), def_kind.descr(def_id)),
1700 }
74b04a01 1701 }
136023e0
XL
1702
1703 pub fn type_length_limit(self) -> Limit {
1704 self.limits(()).type_length_limit
1705 }
1706
1707 pub fn recursion_limit(self) -> Limit {
1708 self.limits(()).recursion_limit
1709 }
1710
1711 pub fn move_size_limit(self) -> Limit {
1712 self.limits(()).move_size_limit
1713 }
1714
1715 pub fn const_eval_limit(self) -> Limit {
1716 self.limits(()).const_eval_limit
1717 }
a2a8927a
XL
1718
1719 pub fn all_traits(self) -> impl Iterator<Item = DefId> + 'tcx {
1720 iter::once(LOCAL_CRATE)
1721 .chain(self.crates(()).iter().copied())
1722 .flat_map(move |cnum| self.traits_in_crate(cnum).iter().copied())
1723 }
f2b60f7d
FG
1724
1725 #[inline]
1726 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
2b03887a 1727 self.visibility(def_id).expect_local()
f2b60f7d 1728 }
e9174d1e
SL
1729}
1730
dc9dc135
XL
1731/// A trait implemented for all `X<'a>` types that can be safely and
1732/// efficiently converted to `X<'tcx>` as long as they are part of the
1733/// provided `TyCtxt<'tcx>`.
1734/// This can be done, for example, for `Ty<'tcx>` or `SubstsRef<'tcx>`
e9174d1e 1735/// by looking them up in their respective interners.
a7813a04
XL
1736///
1737/// However, this is still not the best implementation as it does
1738/// need to compare the components, even for interned values.
dc9dc135 1739/// It would be more efficient if `TypedArena` provided a way to
a7813a04
XL
1740/// determine whether the address is in the allocated range.
1741///
e1599b0c 1742/// `None` is returned if the value or one of the components is not part
e9174d1e 1743/// of the provided context.
dc9dc135
XL
1744/// For `Ty`, `None` can be returned if either the type interner doesn't
1745/// contain the `TyKind` key or if the address of the interned
e9174d1e 1746/// pointer differs. The latter case is possible if a primitive type,
0731742a 1747/// e.g., `()` or `u8`, was interned in a different context.
8faf50e0
XL
1748pub trait Lift<'tcx>: fmt::Debug {
1749 type Lifted: fmt::Debug + 'tcx;
29967ef6 1750 fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted>;
e9174d1e
SL
1751}
1752
5e7ed085 1753macro_rules! nop_lift {
5099ac24
FG
1754 ($set:ident; $ty:ty => $lifted:ty) => {
1755 impl<'a, 'tcx> Lift<'tcx> for $ty {
1756 type Lifted = $lifted;
1757 fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
923072b8 1758 if tcx.interners.$set.contains_pointer_to(&InternedInSet(&*self.0.0)) {
5e7ed085
FG
1759 // SAFETY: `self` is interned and therefore valid
1760 // for the entire lifetime of the `TyCtxt`.
5099ac24
FG
1761 Some(unsafe { mem::transmute(self) })
1762 } else {
1763 None
1764 }
1765 }
1766 }
1767 };
1768}
1769
5e7ed085
FG
1770// Can't use the macros as we have reuse the `substs` here.
1771//
1772// See `intern_type_list` for more info.
1773impl<'a, 'tcx> Lift<'tcx> for &'a List<Ty<'a>> {
1774 type Lifted = &'tcx List<Ty<'tcx>>;
1775 fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1776 if self.is_empty() {
1777 return Some(List::empty());
dfeec247 1778 }
5e7ed085
FG
1779 if tcx.interners.substs.contains_pointer_to(&InternedInSet(self.as_substs())) {
1780 // SAFETY: `self` is interned and therefore valid
1781 // for the entire lifetime of the `TyCtxt`.
1782 Some(unsafe { mem::transmute::<&'a List<Ty<'a>>, &'tcx List<Ty<'tcx>>>(self) })
1783 } else {
1784 None
1785 }
1786 }
ea8adc8c
XL
1787}
1788
0731742a 1789macro_rules! nop_list_lift {
dfeec247 1790 ($set:ident; $ty:ty => $lifted:ty) => {
0731742a 1791 impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> {
dfeec247 1792 type Lifted = &'tcx List<$lifted>;
29967ef6 1793 fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
dfeec247
XL
1794 if self.is_empty() {
1795 return Some(List::empty());
1796 }
5099ac24 1797 if tcx.interners.$set.contains_pointer_to(&InternedInSet(self)) {
29967ef6 1798 Some(unsafe { mem::transmute(self) })
dfeec247
XL
1799 } else {
1800 None
0731742a 1801 }
dfeec247
XL
1802 }
1803 }
0731742a 1804 };
a7813a04
XL
1805}
1806
dfeec247
XL
1807nop_lift! {type_; Ty<'a> => Ty<'tcx>}
1808nop_lift! {region; Region<'a> => Region<'tcx>}
5099ac24 1809nop_lift! {const_; Const<'a> => Const<'tcx>}
5e7ed085 1810nop_lift! {const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx>}
5099ac24 1811nop_lift! {predicate; Predicate<'a> => Predicate<'tcx>}
476ff2be 1812
cdc7bbd5 1813nop_list_lift! {poly_existential_predicates; ty::Binder<'a, ExistentialPredicate<'a>> => ty::Binder<'tcx, ExistentialPredicate<'tcx>>}
dfeec247 1814nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>}
fc512014 1815nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>}
dfeec247 1816nop_list_lift! {projs; ProjectionKind => ProjectionKind}
cdc7bbd5 1817nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind}
7cac9316 1818
e1599b0c 1819// This is the impl for `&'a InternalSubsts<'a>`.
dfeec247 1820nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}
0531ce1d 1821
f2b60f7d
FG
1822CloneLiftImpls! { for<'tcx> {
1823 Constness, traits::WellFormedLoc, ImplPolarity, crate::mir::ReturnConstraint,
1824} }
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};
dfeec247
XL
1832 use rustc_errors::Diagnostic;
1833 use std::mem;
f2b60f7d 1834 use thin_vec::ThinVec;
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
f2b60f7d
FG
1860 /// Used to prevent queries from calling too deeply.
1861 pub query_depth: usize,
83c7162d
XL
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,
f2b60f7d 1875 query_depth: 0,
5099ac24
FG
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(),
2b03887a 2369 &*self.untracked_resolutions.cstore,
923072b8
FG
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>,
f2b60f7d 2549 repr: DynKind,
476ff2be 2550 ) -> Ty<'tcx> {
f2b60f7d 2551 self.mk_ty(Dynamic(obj, reg, repr))
e9174d1e
SL
2552 }
2553
a1dfa0c6 2554 #[inline]
dfeec247
XL
2555 pub fn mk_projection(self, item_def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
2556 self.mk_ty(Projection(ProjectionTy { item_def_id, substs }))
2557 }
e9174d1e 2558
a1dfa0c6 2559 #[inline]
dfeec247 2560 pub fn mk_closure(self, closure_id: DefId, closure_substs: SubstsRef<'tcx>) -> Ty<'tcx> {
b7449926 2561 self.mk_ty(Closure(closure_id, closure_substs))
e9174d1e
SL
2562 }
2563
a1dfa0c6 2564 #[inline]
dfeec247
XL
2565 pub fn mk_generator(
2566 self,
2567 id: DefId,
2568 generator_substs: SubstsRef<'tcx>,
2569 movability: hir::Movability,
2570 ) -> Ty<'tcx> {
b7449926 2571 self.mk_ty(Generator(id, generator_substs, movability))
ea8adc8c
XL
2572 }
2573
a1dfa0c6 2574 #[inline]
cdc7bbd5 2575 pub fn mk_generator_witness(self, types: ty::Binder<'tcx, &'tcx List<Ty<'tcx>>>) -> Ty<'tcx> {
b7449926 2576 self.mk_ty(GeneratorWitness(types))
2c00a5a8
XL
2577 }
2578
a1dfa0c6 2579 #[inline]
532ac7d7 2580 pub fn mk_ty_var(self, v: TyVid) -> Ty<'tcx> {
48663c56 2581 self.mk_ty_infer(TyVar(v))
e9174d1e
SL
2582 }
2583
532ac7d7 2584 #[inline]
5099ac24 2585 pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
923072b8 2586 self.mk_const(ty::ConstS { kind: ty::ConstKind::Infer(InferConst::Var(v)), ty })
532ac7d7
XL
2587 }
2588
a1dfa0c6 2589 #[inline]
a7813a04 2590 pub fn mk_int_var(self, v: IntVid) -> Ty<'tcx> {
48663c56 2591 self.mk_ty_infer(IntVar(v))
e9174d1e
SL
2592 }
2593
a1dfa0c6 2594 #[inline]
a7813a04 2595 pub fn mk_float_var(self, v: FloatVid) -> Ty<'tcx> {
48663c56 2596 self.mk_ty_infer(FloatVar(v))
e9174d1e
SL
2597 }
2598
a1dfa0c6 2599 #[inline]
48663c56 2600 pub fn mk_ty_infer(self, it: InferTy) -> Ty<'tcx> {
b7449926 2601 self.mk_ty(Infer(it))
e9174d1e
SL
2602 }
2603
a1dfa0c6 2604 #[inline]
5099ac24 2605 pub fn mk_const_infer(self, ic: InferConst<'tcx>, ty: Ty<'tcx>) -> ty::Const<'tcx> {
923072b8 2606 self.mk_const(ty::ConstS { kind: ty::ConstKind::Infer(ic), ty })
48663c56
XL
2607 }
2608
2609 #[inline]
e74abb32 2610 pub fn mk_ty_param(self, index: u32, name: Symbol) -> Ty<'tcx> {
74b04a01 2611 self.mk_ty(Param(ParamTy { index, name }))
e9174d1e
SL
2612 }
2613
532ac7d7 2614 #[inline]
5099ac24 2615 pub fn mk_const_param(self, index: u32, name: Symbol, ty: Ty<'tcx>) -> Const<'tcx> {
923072b8 2616 self.mk_const(ty::ConstS { kind: ty::ConstKind::Param(ParamConst { index, name }), ty })
532ac7d7
XL
2617 }
2618
e74abb32 2619 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
94b46f34
XL
2620 match param.kind {
2621 GenericParamDefKind::Lifetime => {
2622 self.mk_region(ty::ReEarlyBound(param.to_early_bound_region_data())).into()
2623 }
532ac7d7 2624 GenericParamDefKind::Type { .. } => self.mk_ty_param(param.index, param.name).into(),
cdc7bbd5 2625 GenericParamDefKind::Const { .. } => {
532ac7d7
XL
2626 self.mk_const_param(param.index, param.name, self.type_of(param.def_id)).into()
2627 }
94b46f34 2628 }
e9174d1e 2629 }
9cc50fc6 2630
a1dfa0c6 2631 #[inline]
532ac7d7 2632 pub fn mk_opaque(self, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
b7449926 2633 self.mk_ty(Opaque(def_id, substs))
5bcae85e
SL
2634 }
2635
e74abb32
XL
2636 pub fn mk_place_field(self, place: Place<'tcx>, f: Field, ty: Ty<'tcx>) -> Place<'tcx> {
2637 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2638 }
2639
2640 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2641 self.mk_place_elem(place, PlaceElem::Deref)
2642 }
2643
2644 pub fn mk_place_downcast(
2645 self,
2646 place: Place<'tcx>,
5e7ed085 2647 adt_def: AdtDef<'tcx>,
e74abb32
XL
2648 variant_index: VariantIdx,
2649 ) -> Place<'tcx> {
2650 self.mk_place_elem(
2651 place,
5e7ed085 2652 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
e74abb32
XL
2653 )
2654 }
2655
2656 pub fn mk_place_downcast_unnamed(
2657 self,
2658 place: Place<'tcx>,
2659 variant_index: VariantIdx,
2660 ) -> Place<'tcx> {
2661 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2662 }
2663
2664 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2665 self.mk_place_elem(place, PlaceElem::Index(index))
2666 }
2667
2668 /// This method copies `Place`'s projection, add an element and reintern it. Should not be used
2669 /// to build a full `Place` it's just a convenient way to grab a projection and modify it in
2670 /// flight.
2671 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2672 let mut projection = place.projection.to_vec();
2673 projection.push(elem);
2674
dfeec247 2675 Place { local: place.local, projection: self.intern_place_elems(&projection) }
e74abb32
XL
2676 }
2677
fc512014 2678 pub fn intern_poly_existential_predicates(
dfeec247 2679 self,
cdc7bbd5
XL
2680 eps: &[ty::Binder<'tcx, ExistentialPredicate<'tcx>>],
2681 ) -> &'tcx List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>> {
476ff2be 2682 assert!(!eps.is_empty());
fc512014
XL
2683 assert!(
2684 eps.array_windows()
2685 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2686 != Ordering::Greater)
2687 );
2688 self._intern_poly_existential_predicates(eps)
476ff2be
SL
2689 }
2690
dfeec247 2691 pub fn intern_predicates(self, preds: &[Predicate<'tcx>]) -> &'tcx List<Predicate<'tcx>> {
7cac9316
XL
2692 // FIXME consider asking the input slice to be sorted to avoid
2693 // re-interning permutations, in which case that would be asserted
2694 // here.
74b04a01 2695 if preds.is_empty() {
7cac9316 2696 // The macro-generated method below asserts we don't intern an empty slice.
b7449926 2697 List::empty()
7cac9316
XL
2698 } else {
2699 self._intern_predicates(preds)
2700 }
2701 }
2702
b7449926 2703 pub fn intern_type_list(self, ts: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> {
5e7ed085
FG
2704 if ts.is_empty() {
2705 List::empty()
2706 } else {
2707 // Actually intern type lists as lists of `GenericArg`s.
2708 //
2709 // Transmuting from `Ty<'tcx>` to `GenericArg<'tcx>` is sound
2710 // as explained in ty_slice_as_generic_arg`. With this,
2711 // we guarantee that even when transmuting between `List<Ty<'tcx>>`
2712 // and `List<GenericArg<'tcx>>`, the uniqueness requirement for
2713 // lists is upheld.
2714 let substs = self._intern_substs(ty::subst::ty_slice_as_generic_args(ts));
2715 substs.try_as_type_list().unwrap()
2716 }
c30ab7b3
SL
2717 }
2718
e74abb32 2719 pub fn intern_substs(self, ts: &[GenericArg<'tcx>]) -> &'tcx List<GenericArg<'tcx>> {
74b04a01 2720 if ts.is_empty() { List::empty() } else { self._intern_substs(ts) }
c30ab7b3
SL
2721 }
2722
532ac7d7 2723 pub fn intern_projs(self, ps: &[ProjectionKind]) -> &'tcx List<ProjectionKind> {
74b04a01 2724 if ps.is_empty() { List::empty() } else { self._intern_projs(ps) }
0bf4aa26
XL
2725 }
2726
e74abb32 2727 pub fn intern_place_elems(self, ts: &[PlaceElem<'tcx>]) -> &'tcx List<PlaceElem<'tcx>> {
74b04a01 2728 if ts.is_empty() { List::empty() } else { self._intern_place_elems(ts) }
e74abb32
XL
2729 }
2730
fc512014
XL
2731 pub fn intern_canonical_var_infos(
2732 self,
2733 ts: &[CanonicalVarInfo<'tcx>],
2734 ) -> CanonicalVarInfos<'tcx> {
74b04a01 2735 if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) }
0531ce1d
XL
2736 }
2737
cdc7bbd5
XL
2738 pub fn intern_bound_variable_kinds(
2739 self,
2740 ts: &[ty::BoundVariableKind],
2741 ) -> &'tcx List<ty::BoundVariableKind> {
2742 if ts.is_empty() { List::empty() } else { self._intern_bound_variable_kinds(ts) }
2743 }
2744
dfeec247
XL
2745 pub fn mk_fn_sig<I>(
2746 self,
2747 inputs: I,
2748 output: I::Item,
2749 c_variadic: bool,
2750 unsafety: hir::Unsafety,
2751 abi: abi::Abi,
2752 ) -> <I::Item as InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>>::Output
416331ca
XL
2753 where
2754 I: Iterator<Item: InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>>,
476ff2be
SL
2755 {
2756 inputs.chain(iter::once(output)).intern_with(|xs| ty::FnSig {
2757 inputs_and_output: self.intern_type_list(xs),
dfeec247
XL
2758 c_variadic,
2759 unsafety,
2760 abi,
476ff2be
SL
2761 })
2762 }
2763
fc512014
XL
2764 pub fn mk_poly_existential_predicates<
2765 I: InternAs<
cdc7bbd5
XL
2766 [ty::Binder<'tcx, ExistentialPredicate<'tcx>>],
2767 &'tcx List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>,
fc512014 2768 >,
dfeec247
XL
2769 >(
2770 self,
2771 iter: I,
2772 ) -> I::Output {
fc512014 2773 iter.intern_with(|xs| self.intern_poly_existential_predicates(xs))
476ff2be
SL
2774 }
2775
dfeec247
XL
2776 pub fn mk_predicates<I: InternAs<[Predicate<'tcx>], &'tcx List<Predicate<'tcx>>>>(
2777 self,
2778 iter: I,
2779 ) -> I::Output {
7cac9316
XL
2780 iter.intern_with(|xs| self.intern_predicates(xs))
2781 }
2782
dfeec247 2783 pub fn mk_type_list<I: InternAs<[Ty<'tcx>], &'tcx List<Ty<'tcx>>>>(self, iter: I) -> I::Output {
c30ab7b3
SL
2784 iter.intern_with(|xs| self.intern_type_list(xs))
2785 }
2786
dfeec247
XL
2787 pub fn mk_substs<I: InternAs<[GenericArg<'tcx>], &'tcx List<GenericArg<'tcx>>>>(
2788 self,
2789 iter: I,
2790 ) -> I::Output {
c30ab7b3
SL
2791 iter.intern_with(|xs| self.intern_substs(xs))
2792 }
2793
dfeec247
XL
2794 pub fn mk_place_elems<I: InternAs<[PlaceElem<'tcx>], &'tcx List<PlaceElem<'tcx>>>>(
2795 self,
2796 iter: I,
2797 ) -> I::Output {
e74abb32
XL
2798 iter.intern_with(|xs| self.intern_place_elems(xs))
2799 }
2800
dfeec247 2801 pub fn mk_substs_trait(self, self_ty: Ty<'tcx>, rest: &[GenericArg<'tcx>]) -> SubstsRef<'tcx> {
94b46f34 2802 self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned()))
c30ab7b3 2803 }
3b2f2976 2804
cdc7bbd5
XL
2805 pub fn mk_bound_variable_kinds<
2806 I: InternAs<[ty::BoundVariableKind], &'tcx List<ty::BoundVariableKind>>,
2807 >(
2808 self,
2809 iter: I,
2810 ) -> I::Output {
2811 iter.intern_with(|xs| self.intern_bound_variable_kinds(xs))
2812 }
2813
064997fb
FG
2814 /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`,
2815 /// typically generated by `#[derive(LintDiagnostic)]`).
2816 pub fn emit_spanned_lint(
2817 self,
2818 lint: &'static Lint,
2819 hir_id: HirId,
2820 span: impl Into<MultiSpan>,
2821 decorator: impl for<'a> DecorateLint<'a, ()>,
2822 ) {
2b03887a
FG
2823 self.struct_span_lint_hir(lint, hir_id, span, decorator.msg(), |diag| {
2824 decorator.decorate_lint(diag)
2825 })
064997fb
FG
2826 }
2827
2b03887a
FG
2828 /// Emit a lint at the appropriate level for a hir node, with an associated span.
2829 ///
2830 /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
2831 ///
2832 /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
dfeec247
XL
2833 pub fn struct_span_lint_hir(
2834 self,
2835 lint: &'static Lint,
2836 hir_id: HirId,
2837 span: impl Into<MultiSpan>,
2b03887a
FG
2838 msg: impl Into<DiagnosticMessage>,
2839 decorate: impl for<'a, 'b> FnOnce(
2840 &'b mut DiagnosticBuilder<'a, ()>,
2841 ) -> &'b mut DiagnosticBuilder<'a, ()>,
74b04a01 2842 ) {
532ac7d7 2843 let (level, src) = self.lint_level_at_node(lint, hir_id);
2b03887a 2844 struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, decorate);
3b2f2976
XL
2845 }
2846
064997fb
FG
2847 /// Emit a lint from a lint struct (some type that implements `DecorateLint`, typically
2848 /// generated by `#[derive(LintDiagnostic)]`).
2849 pub fn emit_lint(
2850 self,
2851 lint: &'static Lint,
2852 id: HirId,
2853 decorator: impl for<'a> DecorateLint<'a, ()>,
2854 ) {
2b03887a 2855 self.struct_lint_node(lint, id, decorator.msg(), |diag| decorator.decorate_lint(diag))
064997fb
FG
2856 }
2857
2b03887a
FG
2858 /// Emit a lint at the appropriate level for a hir node.
2859 ///
2860 /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
2861 ///
2862 /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
dfeec247
XL
2863 pub fn struct_lint_node(
2864 self,
2865 lint: &'static Lint,
2866 id: HirId,
2b03887a
FG
2867 msg: impl Into<DiagnosticMessage>,
2868 decorate: impl for<'a, 'b> FnOnce(
2869 &'b mut DiagnosticBuilder<'a, ()>,
2870 ) -> &'b mut DiagnosticBuilder<'a, ()>,
74b04a01 2871 ) {
3b2f2976 2872 let (level, src) = self.lint_level_at_node(lint, id);
2b03887a 2873 struct_lint_level(self.sess, lint, level, src, None, msg, decorate);
3b2f2976 2874 }
ea8adc8c 2875
17df50a5
XL
2876 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
2877 let map = self.in_scope_traits_map(id.owner)?;
2878 let candidates = map.get(&id.local_id)?;
2879 Some(&*candidates)
ea8adc8c
XL
2880 }
2881
2882 pub fn named_region(self, id: HirId) -> Option<resolve_lifetime::Region> {
cdc7bbd5 2883 debug!(?id, "named_region");
dfeec247 2884 self.named_region_map(id.owner).and_then(|map| map.get(&id.local_id).cloned())
ea8adc8c
XL
2885 }
2886
923072b8 2887 pub fn is_late_bound(self, id: HirId) -> bool {
2b03887a 2888 self.is_late_bound_map(id.owner.def_id).map_or(false, |set| {
923072b8
FG
2889 let def_id = self.hir().local_def_id(id);
2890 set.contains(&def_id)
2891 })
2892 }
2893
cdc7bbd5
XL
2894 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
2895 self.mk_bound_variable_kinds(
2896 self.late_bound_vars_map(id.owner)
2897 .and_then(|map| map.get(&id.local_id).cloned())
2898 .unwrap_or_else(|| {
2899 bug!("No bound vars found for {:?} ({:?})", self.hir().node_to_string(id), id)
2900 })
2901 .iter(),
2902 )
ea8adc8c 2903 }
17df50a5 2904
c295e0f8
XL
2905 /// Whether the `def_id` counts as const fn in the current crate, considering all active
2906 /// feature gates
2907 pub fn is_const_fn(self, def_id: DefId) -> bool {
2908 if self.is_const_fn_raw(def_id) {
2909 match self.lookup_const_stability(def_id) {
923072b8 2910 Some(stability) if stability.is_const_unstable() => {
c295e0f8
XL
2911 // has a `rustc_const_unstable` attribute, check whether the user enabled the
2912 // corresponding feature gate.
2913 self.features()
2914 .declared_lib_features
2915 .iter()
2916 .any(|&(sym, _)| sym == stability.feature)
2917 }
2918 // functions without const stability are either stable user written
2919 // const fn or the user is using feature gates and we thus don't
2920 // care what they do
2921 _ => true,
2922 }
2923 } else {
2924 false
2925 }
2926 }
923072b8
FG
2927
2928 /// Whether the trait impl is marked const. This does not consider stability or feature gates.
2929 pub fn is_const_trait_impl_raw(self, def_id: DefId) -> bool {
2930 let Some(local_def_id) = def_id.as_local() else { return false };
2931 let hir_id = self.local_def_id_to_hir_id(local_def_id);
2932 let node = self.hir().get(hir_id);
2933
2934 matches!(
2935 node,
2936 hir::Node::Item(hir::Item {
2937 kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }),
2938 ..
2939 })
2940 )
2941 }
e9174d1e 2942}
c30ab7b3 2943
a2a8927a 2944impl<'tcx> TyCtxtAt<'tcx> {
3dfed10e
XL
2945 /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used.
2946 #[track_caller]
2947 pub fn ty_error(self) -> Ty<'tcx> {
2948 self.tcx.ty_error_with_message(self.span, "TyKind::Error constructed but no error reported")
2949 }
2950
2951 /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg to
2952 /// ensure it gets used.
2953 #[track_caller]
2954 pub fn ty_error_with_message(self, msg: &str) -> Ty<'tcx> {
2955 self.tcx.ty_error_with_message(self.span, msg)
2956 }
2957}
2958
2b03887a
FG
2959/// Parameter attributes that can only be determined by examining the body of a function instead
2960/// of just its signature.
2961///
2962/// These can be useful for optimization purposes when a function is directly called. We compute
2963/// them and store them into the crate metadata so that downstream crates can make use of them.
2964///
2965/// Right now, we only have `read_only`, but `no_capture` and `no_alias` might be useful in the
2966/// future.
2967#[derive(Clone, Copy, PartialEq, Debug, Default, TyDecodable, TyEncodable, HashStable)]
2968pub struct DeducedParamAttrs {
2969 /// The parameter is marked immutable in the function and contains no `UnsafeCell` (i.e. its
2970 /// type is freeze).
2971 pub read_only: bool,
2972}
2973
532ac7d7
XL
2974// We are comparing types with different invariant lifetimes, so `ptr::eq`
2975// won't work for us.
2976fn ptr_eq<T, U>(t: *const T, u: *const U) -> bool {
2977 t as *const () == u as *const ()
2978}
2979
f035d41b 2980pub fn provide(providers: &mut ty::query::Providers) {
136023e0 2981 providers.resolutions = |tcx, ()| &tcx.untracked_resolutions;
064997fb 2982 providers.resolver_for_lowering = |tcx, ()| &tcx.untracked_resolver_for_lowering;
5099ac24
FG
2983 providers.module_reexports =
2984 |tcx, id| tcx.resolutions(()).reexport_map.get(&id).map(|v| &v[..]);
ea8adc8c
XL
2985 providers.crate_name = |tcx, id| {
2986 assert_eq!(id, LOCAL_CRATE);
2987 tcx.crate_name
2988 };
923072b8
FG
2989 providers.maybe_unused_trait_imports =
2990 |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
136023e0
XL
2991 providers.maybe_unused_extern_crates =
2992 |tcx, ()| &tcx.resolutions(()).maybe_unused_extern_crates[..];
2993 providers.names_imported_by_glob_use = |tcx, id| {
2994 tcx.arena.alloc(tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default())
2995 };
ea8adc8c 2996
136023e0
XL
2997 providers.extern_mod_stmt_cnum =
2998 |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
5099ac24 2999 providers.output_filenames = |tcx, ()| &tcx.output_filenames;
17df50a5 3000 providers.features_query = |tcx, ()| tcx.sess.features_untracked();
0531ce1d 3001 providers.is_panic_runtime = |tcx, cnum| {
ea8adc8c 3002 assert_eq!(cnum, LOCAL_CRATE);
3dfed10e 3003 tcx.sess.contains_name(tcx.hir().krate_attrs(), sym::panic_runtime)
ea8adc8c 3004 };
0531ce1d
XL
3005 providers.is_compiler_builtins = |tcx, cnum| {
3006 assert_eq!(cnum, LOCAL_CRATE);
3dfed10e 3007 tcx.sess.contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins)
abe05a73 3008 };
60c5eb7d
XL
3009 providers.has_panic_handler = |tcx, cnum| {
3010 assert_eq!(cnum, LOCAL_CRATE);
3011 // We want to check if the panic handler was defined in this crate
3012 tcx.lang_items().panic_impl().map_or(false, |did| did.is_local())
3013 };
ea8adc8c 3014}