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