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