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