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