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