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