]>
Commit | Line | Data |
---|---|---|
e9174d1e SL |
1 | // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
e9174d1e | 11 | pub use self::Variance::*; |
476ff2be | 12 | pub use self::AssociatedItemContainer::*; |
e9174d1e | 13 | pub use self::BorrowKind::*; |
e9174d1e | 14 | pub use self::IntVarValue::*; |
9cc50fc6 | 15 | pub use self::fold::TypeFoldable; |
e9174d1e | 16 | |
32a655c1 | 17 | use hir::{map as hir_map, FreevarMap, TraitMap}; |
476ff2be | 18 | use hir::def::{Def, CtorKind, ExportMap}; |
2c00a5a8 | 19 | use hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; |
abe05a73 | 20 | use hir::map::DefPathData; |
ff7c6d11 | 21 | use hir::svh::Svh; |
2c00a5a8 | 22 | use ich::Fingerprint; |
cc61c64b | 23 | use ich::StableHashingContext; |
0531ce1d | 24 | use infer::canonical::{Canonical, Canonicalize}; |
8bb4bdeb | 25 | use middle::const_val::ConstVal; |
e9174d1e | 26 | use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; |
cc61c64b | 27 | use middle::privacy::AccessLevels; |
8bb4bdeb | 28 | use middle::resolve_lifetime::ObjectLifetimeDefault; |
c30ab7b3 | 29 | use mir::Mir; |
0531ce1d | 30 | use mir::interpret::{GlobalId, Value, PrimVal}; |
ea8adc8c | 31 | use mir::GeneratorLayout; |
abe05a73 | 32 | use session::CrateDisambiguator; |
0531ce1d | 33 | use traits::{self, Reveal}; |
54a0048b | 34 | use ty; |
9e0c209e | 35 | use ty::subst::{Subst, Substs}; |
0531ce1d | 36 | use ty::util::{IntTypeExt, Discr}; |
54a0048b | 37 | use ty::walk::TypeWalker; |
0531ce1d XL |
38 | use util::captures::Captures; |
39 | use util::nodemap::{NodeSet, DefIdMap, FxHashMap}; | |
e9174d1e | 40 | |
9e0c209e | 41 | use serialize::{self, Encodable, Encoder}; |
2c00a5a8 | 42 | use std::cell::RefCell; |
cc61c64b | 43 | use std::cmp; |
7cac9316 | 44 | use std::fmt; |
e9174d1e | 45 | use std::hash::{Hash, Hasher}; |
9e0c209e | 46 | use std::ops::Deref; |
0531ce1d | 47 | use rustc_data_structures::sync::Lrc; |
e9174d1e SL |
48 | use std::slice; |
49 | use std::vec::IntoIter; | |
c30ab7b3 | 50 | use std::mem; |
7cac9316 | 51 | use syntax::ast::{self, DUMMY_NODE_ID, Name, Ident, NodeId}; |
9e0c209e | 52 | use syntax::attr; |
7cac9316 | 53 | use syntax::ext::hygiene::{Mark, SyntaxContext}; |
476ff2be | 54 | use syntax::symbol::{Symbol, InternedString}; |
3157f602 | 55 | use syntax_pos::{DUMMY_SP, Span}; |
8bb4bdeb | 56 | |
476ff2be | 57 | use rustc_data_structures::accumulate_vec::IntoIter as AccIntoIter; |
cc61c64b XL |
58 | use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult, |
59 | HashStable}; | |
54a0048b SL |
60 | |
61 | use hir; | |
e9174d1e | 62 | |
0531ce1d | 63 | pub use self::sty::{Binder, CanonicalVar, DebruijnIndex}; |
ea8adc8c | 64 | pub use self::sty::{FnSig, GenSig, PolyFnSig, PolyGenSig}; |
8bb4bdeb | 65 | pub use self::sty::{InferTy, ParamTy, ProjectionTy, ExistentialPredicate}; |
ea8adc8c | 66 | pub use self::sty::{ClosureSubsts, GeneratorInterior, TypeAndMut}; |
e9174d1e | 67 | pub use self::sty::{TraitRef, TypeVariants, PolyTraitRef}; |
9e0c209e | 68 | pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef}; |
ea8adc8c | 69 | pub use self::sty::{ExistentialProjection, PolyExistentialProjection, Const}; |
e9174d1e | 70 | pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region}; |
7cac9316 | 71 | pub use self::sty::RegionKind; |
e9174d1e SL |
72 | pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid}; |
73 | pub use self::sty::BoundRegion::*; | |
e9174d1e | 74 | pub use self::sty::InferTy::*; |
7cac9316 | 75 | pub use self::sty::RegionKind::*; |
e9174d1e SL |
76 | pub use self::sty::TypeVariants::*; |
77 | ||
3b2f2976 XL |
78 | pub use self::binding::BindingMode; |
79 | pub use self::binding::BindingMode::*; | |
80 | ||
ff7c6d11 | 81 | pub use self::context::{TyCtxt, GlobalArenas, AllArenas, tls, keep_local}; |
0531ce1d | 82 | pub use self::context::{Lift, TypeckTables, InterpretInterner}; |
e9174d1e | 83 | |
cc61c64b XL |
84 | pub use self::instance::{Instance, InstanceDef}; |
85 | ||
7cac9316 | 86 | pub use self::trait_def::TraitDef; |
9cc50fc6 | 87 | |
8bb4bdeb XL |
88 | pub use self::maps::queries; |
89 | ||
e9174d1e | 90 | pub mod adjustment; |
3b2f2976 | 91 | pub mod binding; |
e9174d1e | 92 | pub mod cast; |
abe05a73 XL |
93 | #[macro_use] |
94 | pub mod codec; | |
e9174d1e | 95 | pub mod error; |
abe05a73 | 96 | mod erase_regions; |
e9174d1e SL |
97 | pub mod fast_reject; |
98 | pub mod fold; | |
32a655c1 | 99 | pub mod inhabitedness; |
54a0048b SL |
100 | pub mod item_path; |
101 | pub mod layout; | |
e9174d1e | 102 | pub mod _match; |
9cc50fc6 | 103 | pub mod maps; |
e9174d1e SL |
104 | pub mod outlives; |
105 | pub mod relate; | |
7cac9316 | 106 | pub mod steal; |
54a0048b | 107 | pub mod subst; |
9cc50fc6 | 108 | pub mod trait_def; |
e9174d1e SL |
109 | pub mod walk; |
110 | pub mod wf; | |
111 | pub mod util; | |
112 | ||
e9174d1e SL |
113 | mod context; |
114 | mod flags; | |
cc61c64b | 115 | mod instance; |
e9174d1e SL |
116 | mod structural_impls; |
117 | mod sty; | |
118 | ||
e9174d1e SL |
119 | // Data types |
120 | ||
121 | /// The complete set of all analyses described in this module. This is | |
122 | /// produced by the driver and fed to trans and later passes. | |
cc61c64b XL |
123 | /// |
124 | /// NB: These contents are being migrated into queries using the | |
125 | /// *on-demand* infrastructure. | |
a7813a04 | 126 | #[derive(Clone)] |
8bb4bdeb | 127 | pub struct CrateAnalysis { |
0531ce1d | 128 | pub access_levels: Lrc<AccessLevels>, |
476ff2be | 129 | pub name: String, |
54a0048b | 130 | pub glob_map: Option<hir::GlobMap>, |
e9174d1e SL |
131 | } |
132 | ||
32a655c1 SL |
133 | #[derive(Clone)] |
134 | pub struct Resolutions { | |
135 | pub freevars: FreevarMap, | |
136 | pub trait_map: TraitMap, | |
137 | pub maybe_unused_trait_imports: NodeSet, | |
3b2f2976 | 138 | pub maybe_unused_extern_crates: Vec<(NodeId, Span)>, |
cc61c64b | 139 | pub export_map: ExportMap, |
e9174d1e SL |
140 | } |
141 | ||
142 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | |
476ff2be | 143 | pub enum AssociatedItemContainer { |
e9174d1e SL |
144 | TraitContainer(DefId), |
145 | ImplContainer(DefId), | |
146 | } | |
147 | ||
476ff2be | 148 | impl AssociatedItemContainer { |
abe05a73 XL |
149 | /// Asserts that this is the def-id of an associated item declared |
150 | /// in a trait, and returns the trait def-id. | |
151 | pub fn assert_trait(&self) -> DefId { | |
152 | match *self { | |
153 | TraitContainer(id) => id, | |
154 | _ => bug!("associated item has wrong container type: {:?}", self) | |
155 | } | |
156 | } | |
157 | ||
e9174d1e SL |
158 | pub fn id(&self) -> DefId { |
159 | match *self { | |
160 | TraitContainer(id) => id, | |
161 | ImplContainer(id) => id, | |
162 | } | |
163 | } | |
164 | } | |
165 | ||
54a0048b SL |
166 | /// The "header" of an impl is everything outside the body: a Self type, a trait |
167 | /// ref (in the case of a trait impl), and a set of predicates (from the | |
168 | /// bounds/where clauses). | |
169 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] | |
170 | pub struct ImplHeader<'tcx> { | |
171 | pub impl_def_id: DefId, | |
172 | pub self_ty: Ty<'tcx>, | |
173 | pub trait_ref: Option<TraitRef<'tcx>>, | |
174 | pub predicates: Vec<Predicate<'tcx>>, | |
175 | } | |
176 | ||
3b2f2976 | 177 | #[derive(Copy, Clone, Debug, PartialEq, Eq)] |
476ff2be SL |
178 | pub struct AssociatedItem { |
179 | pub def_id: DefId, | |
180 | pub name: Name, | |
181 | pub kind: AssociatedKind, | |
182 | pub vis: Visibility, | |
183 | pub defaultness: hir::Defaultness, | |
184 | pub container: AssociatedItemContainer, | |
e9174d1e | 185 | |
476ff2be SL |
186 | /// Whether this is a method with an explicit self |
187 | /// as its first argument, allowing method calls. | |
188 | pub method_has_self_argument: bool, | |
189 | } | |
e9174d1e | 190 | |
3b2f2976 | 191 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, RustcEncodable, RustcDecodable)] |
476ff2be SL |
192 | pub enum AssociatedKind { |
193 | Const, | |
194 | Method, | |
195 | Type | |
196 | } | |
e9174d1e | 197 | |
476ff2be SL |
198 | impl AssociatedItem { |
199 | pub fn def(&self) -> Def { | |
200 | match self.kind { | |
201 | AssociatedKind::Const => Def::AssociatedConst(self.def_id), | |
202 | AssociatedKind::Method => Def::Method(self.def_id), | |
203 | AssociatedKind::Type => Def::AssociatedTy(self.def_id), | |
e9174d1e SL |
204 | } |
205 | } | |
8bb4bdeb XL |
206 | |
207 | /// Tests whether the associated item admits a non-trivial implementation | |
208 | /// for ! | |
209 | pub fn relevant_for_never<'tcx>(&self) -> bool { | |
210 | match self.kind { | |
211 | AssociatedKind::Const => true, | |
212 | AssociatedKind::Type => true, | |
213 | // FIXME(canndrew): Be more thorough here, check if any argument is uninhabited. | |
214 | AssociatedKind::Method => !self.method_has_self_argument, | |
215 | } | |
216 | } | |
7cac9316 XL |
217 | |
218 | pub fn signature<'a, 'tcx>(&self, tcx: &TyCtxt<'a, 'tcx, 'tcx>) -> String { | |
219 | match self.kind { | |
220 | ty::AssociatedKind::Method => { | |
221 | // We skip the binder here because the binder would deanonymize all | |
222 | // late-bound regions, and we don't want method signatures to show up | |
223 | // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound | |
224 | // regions just fine, showing `fn(&MyType)`. | |
041b39d2 | 225 | format!("{}", tcx.fn_sig(self.def_id).skip_binder()) |
7cac9316 XL |
226 | } |
227 | ty::AssociatedKind::Type => format!("type {};", self.name.to_string()), | |
228 | ty::AssociatedKind::Const => { | |
229 | format!("const {}: {:?};", self.name.to_string(), tcx.type_of(self.def_id)) | |
230 | } | |
231 | } | |
232 | } | |
e9174d1e SL |
233 | } |
234 | ||
9e0c209e | 235 | #[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable)] |
54a0048b SL |
236 | pub enum Visibility { |
237 | /// Visible everywhere (including in other crates). | |
238 | Public, | |
239 | /// Visible only in the given crate-local module. | |
32a655c1 | 240 | Restricted(DefId), |
54a0048b | 241 | /// Not visible anywhere in the local crate. This is the visibility of private external items. |
32a655c1 | 242 | Invisible, |
54a0048b SL |
243 | } |
244 | ||
32a655c1 SL |
245 | pub trait DefIdTree: Copy { |
246 | fn parent(self, id: DefId) -> Option<DefId>; | |
a7813a04 | 247 | |
32a655c1 SL |
248 | fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool { |
249 | if descendant.krate != ancestor.krate { | |
250 | return false; | |
251 | } | |
252 | ||
253 | while descendant != ancestor { | |
254 | match self.parent(descendant) { | |
255 | Some(parent) => descendant = parent, | |
256 | None => return false, | |
a7813a04 | 257 | } |
a7813a04 XL |
258 | } |
259 | true | |
260 | } | |
261 | } | |
262 | ||
32a655c1 SL |
263 | impl<'a, 'gcx, 'tcx> DefIdTree for TyCtxt<'a, 'gcx, 'tcx> { |
264 | fn parent(self, id: DefId) -> Option<DefId> { | |
265 | self.def_key(id).parent.map(|index| DefId { index: index, ..id }) | |
266 | } | |
267 | } | |
268 | ||
54a0048b | 269 | impl Visibility { |
a7813a04 | 270 | pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: TyCtxt) -> Self { |
54a0048b SL |
271 | match *visibility { |
272 | hir::Public => Visibility::Public, | |
32a655c1 | 273 | hir::Visibility::Crate => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)), |
476ff2be | 274 | hir::Visibility::Restricted { ref path, .. } => match path.def { |
a7813a04 XL |
275 | // If there is no resolution, `resolve` will have already reported an error, so |
276 | // assume that the visibility is public to avoid reporting more privacy errors. | |
3157f602 | 277 | Def::Err => Visibility::Public, |
32a655c1 | 278 | def => Visibility::Restricted(def.def_id()), |
a7813a04 | 279 | }, |
32a655c1 | 280 | hir::Inherited => { |
7cac9316 | 281 | Visibility::Restricted(tcx.hir.get_module_parent(id)) |
32a655c1 | 282 | } |
54a0048b SL |
283 | } |
284 | } | |
285 | ||
286 | /// Returns true if an item with this visibility is accessible from the given block. | |
32a655c1 | 287 | pub fn is_accessible_from<T: DefIdTree>(self, module: DefId, tree: T) -> bool { |
54a0048b SL |
288 | let restriction = match self { |
289 | // Public items are visible everywhere. | |
290 | Visibility::Public => return true, | |
291 | // Private items from other crates are visible nowhere. | |
32a655c1 | 292 | Visibility::Invisible => return false, |
54a0048b | 293 | // Restricted items are visible in an arbitrary local module. |
32a655c1 | 294 | Visibility::Restricted(other) if other.krate != module.krate => return false, |
54a0048b SL |
295 | Visibility::Restricted(module) => module, |
296 | }; | |
297 | ||
32a655c1 | 298 | tree.is_descendant_of(module, restriction) |
54a0048b SL |
299 | } |
300 | ||
301 | /// Returns true if this visibility is at least as accessible as the given visibility | |
32a655c1 | 302 | pub fn is_at_least<T: DefIdTree>(self, vis: Visibility, tree: T) -> bool { |
54a0048b SL |
303 | let vis_restriction = match vis { |
304 | Visibility::Public => return self == Visibility::Public, | |
32a655c1 | 305 | Visibility::Invisible => return true, |
54a0048b SL |
306 | Visibility::Restricted(module) => module, |
307 | }; | |
308 | ||
a7813a04 | 309 | self.is_accessible_from(vis_restriction, tree) |
54a0048b | 310 | } |
ff7c6d11 XL |
311 | |
312 | // Returns true if this item is visible anywhere in the local crate. | |
313 | pub fn is_visible_locally(self) -> bool { | |
314 | match self { | |
315 | Visibility::Public => true, | |
316 | Visibility::Restricted(def_id) => def_id.is_local(), | |
317 | Visibility::Invisible => false, | |
318 | } | |
319 | } | |
54a0048b SL |
320 | } |
321 | ||
e9174d1e SL |
322 | #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Copy)] |
323 | pub enum Variance { | |
324 | Covariant, // T<A> <: T<B> iff A <: B -- e.g., function return type | |
325 | Invariant, // T<A> <: T<B> iff B == A -- e.g., type of mutable cell | |
326 | Contravariant, // T<A> <: T<B> iff B <: A -- e.g., function param type | |
327 | Bivariant, // T<A> <: T<B> -- e.g., unused type parameter | |
328 | } | |
329 | ||
7cac9316 XL |
330 | /// The crate variances map is computed during typeck and contains the |
331 | /// variance of every item in the local crate. You should not use it | |
332 | /// directly, because to do so will make your pass dependent on the | |
333 | /// HIR of every item in the local crate. Instead, use | |
334 | /// `tcx.variances_of()` to get the variance for a *particular* | |
335 | /// item. | |
336 | pub struct CrateVariancesMap { | |
7cac9316 XL |
337 | /// For each item with generics, maps to a vector of the variance |
338 | /// of its generics. If an item has no generics, it will have no | |
339 | /// entry. | |
0531ce1d | 340 | pub variances: FxHashMap<DefId, Lrc<Vec<ty::Variance>>>, |
7cac9316 XL |
341 | |
342 | /// An empty vector, useful for cloning. | |
0531ce1d | 343 | pub empty_variance: Lrc<Vec<ty::Variance>>, |
7cac9316 XL |
344 | } |
345 | ||
cc61c64b XL |
346 | impl Variance { |
347 | /// `a.xform(b)` combines the variance of a context with the | |
348 | /// variance of a type with the following meaning. If we are in a | |
349 | /// context with variance `a`, and we encounter a type argument in | |
350 | /// a position with variance `b`, then `a.xform(b)` is the new | |
351 | /// variance with which the argument appears. | |
352 | /// | |
353 | /// Example 1: | |
354 | /// | |
355 | /// *mut Vec<i32> | |
356 | /// | |
357 | /// Here, the "ambient" variance starts as covariant. `*mut T` is | |
358 | /// invariant with respect to `T`, so the variance in which the | |
359 | /// `Vec<i32>` appears is `Covariant.xform(Invariant)`, which | |
360 | /// yields `Invariant`. Now, the type `Vec<T>` is covariant with | |
361 | /// respect to its type argument `T`, and hence the variance of | |
362 | /// the `i32` here is `Invariant.xform(Covariant)`, which results | |
363 | /// (again) in `Invariant`. | |
364 | /// | |
365 | /// Example 2: | |
366 | /// | |
367 | /// fn(*const Vec<i32>, *mut Vec<i32) | |
368 | /// | |
369 | /// The ambient variance is covariant. A `fn` type is | |
370 | /// contravariant with respect to its parameters, so the variance | |
371 | /// within which both pointer types appear is | |
372 | /// `Covariant.xform(Contravariant)`, or `Contravariant`. `*const | |
373 | /// T` is covariant with respect to `T`, so the variance within | |
374 | /// which the first `Vec<i32>` appears is | |
375 | /// `Contravariant.xform(Covariant)` or `Contravariant`. The same | |
376 | /// is true for its `i32` argument. In the `*mut T` case, the | |
377 | /// variance of `Vec<i32>` is `Contravariant.xform(Invariant)`, | |
378 | /// and hence the outermost type is `Invariant` with respect to | |
379 | /// `Vec<i32>` (and its `i32` argument). | |
380 | /// | |
381 | /// Source: Figure 1 of "Taming the Wildcards: | |
382 | /// Combining Definition- and Use-Site Variance" published in PLDI'11. | |
383 | pub fn xform(self, v: ty::Variance) -> ty::Variance { | |
384 | match (self, v) { | |
385 | // Figure 1, column 1. | |
386 | (ty::Covariant, ty::Covariant) => ty::Covariant, | |
387 | (ty::Covariant, ty::Contravariant) => ty::Contravariant, | |
388 | (ty::Covariant, ty::Invariant) => ty::Invariant, | |
389 | (ty::Covariant, ty::Bivariant) => ty::Bivariant, | |
390 | ||
391 | // Figure 1, column 2. | |
392 | (ty::Contravariant, ty::Covariant) => ty::Contravariant, | |
393 | (ty::Contravariant, ty::Contravariant) => ty::Covariant, | |
394 | (ty::Contravariant, ty::Invariant) => ty::Invariant, | |
395 | (ty::Contravariant, ty::Bivariant) => ty::Bivariant, | |
396 | ||
397 | // Figure 1, column 3. | |
398 | (ty::Invariant, _) => ty::Invariant, | |
399 | ||
400 | // Figure 1, column 4. | |
401 | (ty::Bivariant, _) => ty::Bivariant, | |
402 | } | |
403 | } | |
404 | } | |
405 | ||
e9174d1e SL |
406 | // Contains information needed to resolve types and (in the future) look up |
407 | // the types of AST nodes. | |
408 | #[derive(Copy, Clone, PartialEq, Eq, Hash)] | |
409 | pub struct CReaderCacheKey { | |
410 | pub cnum: CrateNum, | |
411 | pub pos: usize, | |
e9174d1e SL |
412 | } |
413 | ||
e9174d1e SL |
414 | // Flags that we track on types. These flags are propagated upwards |
415 | // through the type during type construction, so that we can quickly | |
416 | // check whether the type has various kinds of types in it without | |
417 | // recursing over the type itself. | |
418 | bitflags! { | |
ea8adc8c XL |
419 | pub struct TypeFlags: u32 { |
420 | const HAS_PARAMS = 1 << 0; | |
421 | const HAS_SELF = 1 << 1; | |
422 | const HAS_TY_INFER = 1 << 2; | |
423 | const HAS_RE_INFER = 1 << 3; | |
424 | const HAS_RE_SKOL = 1 << 4; | |
ff7c6d11 XL |
425 | |
426 | /// Does this have any `ReEarlyBound` regions? Used to | |
427 | /// determine whether substitition is required, since those | |
428 | /// represent regions that are bound in a `ty::Generics` and | |
429 | /// hence may be substituted. | |
ea8adc8c | 430 | const HAS_RE_EARLY_BOUND = 1 << 5; |
ff7c6d11 XL |
431 | |
432 | /// Does this have any region that "appears free" in the type? | |
433 | /// Basically anything but `ReLateBound` and `ReErased`. | |
ea8adc8c | 434 | const HAS_FREE_REGIONS = 1 << 6; |
ff7c6d11 XL |
435 | |
436 | /// Is an error type reachable? | |
ea8adc8c XL |
437 | const HAS_TY_ERR = 1 << 7; |
438 | const HAS_PROJECTION = 1 << 8; | |
439 | ||
440 | // FIXME: Rename this to the actual property since it's used for generators too | |
441 | const HAS_TY_CLOSURE = 1 << 9; | |
e9174d1e SL |
442 | |
443 | // true if there are "names" of types and regions and so forth | |
444 | // that are local to a particular fn | |
ea8adc8c | 445 | const HAS_LOCAL_NAMES = 1 << 10; |
e9174d1e | 446 | |
a7813a04 XL |
447 | // Present if the type belongs in a local type context. |
448 | // Only set for TyInfer other than Fresh. | |
ea8adc8c | 449 | const KEEP_IN_LOCAL_TCX = 1 << 11; |
a7813a04 | 450 | |
1bb2cb6e SL |
451 | // Is there a projection that does not involve a bound region? |
452 | // Currently we can't normalize projections w/ bound regions. | |
ea8adc8c | 453 | const HAS_NORMALIZABLE_PROJECTION = 1 << 12; |
1bb2cb6e | 454 | |
0531ce1d XL |
455 | // Set if this includes a "canonical" type or region var -- |
456 | // ought to be true only for the results of canonicalization. | |
457 | const HAS_CANONICAL_VARS = 1 << 13; | |
458 | ||
e9174d1e SL |
459 | const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits | |
460 | TypeFlags::HAS_SELF.bits | | |
ea8adc8c | 461 | TypeFlags::HAS_RE_EARLY_BOUND.bits; |
e9174d1e SL |
462 | |
463 | // Flags representing the nominal content of a type, | |
464 | // computed by FlagsComputation. If you add a new nominal | |
465 | // flag, it should be added here too. | |
466 | const NOMINAL_FLAGS = TypeFlags::HAS_PARAMS.bits | | |
467 | TypeFlags::HAS_SELF.bits | | |
468 | TypeFlags::HAS_TY_INFER.bits | | |
469 | TypeFlags::HAS_RE_INFER.bits | | |
c30ab7b3 | 470 | TypeFlags::HAS_RE_SKOL.bits | |
e9174d1e SL |
471 | TypeFlags::HAS_RE_EARLY_BOUND.bits | |
472 | TypeFlags::HAS_FREE_REGIONS.bits | | |
473 | TypeFlags::HAS_TY_ERR.bits | | |
474 | TypeFlags::HAS_PROJECTION.bits | | |
475 | TypeFlags::HAS_TY_CLOSURE.bits | | |
a7813a04 | 476 | TypeFlags::HAS_LOCAL_NAMES.bits | |
0531ce1d XL |
477 | TypeFlags::KEEP_IN_LOCAL_TCX.bits | |
478 | TypeFlags::HAS_CANONICAL_VARS.bits; | |
e9174d1e SL |
479 | } |
480 | } | |
481 | ||
482 | pub struct TyS<'tcx> { | |
483 | pub sty: TypeVariants<'tcx>, | |
7cac9316 | 484 | pub flags: TypeFlags, |
e9174d1e SL |
485 | |
486 | // the maximal depth of any bound regions appearing in this type. | |
487 | region_depth: u32, | |
488 | } | |
489 | ||
490 | impl<'tcx> PartialEq for TyS<'tcx> { | |
491 | #[inline] | |
492 | fn eq(&self, other: &TyS<'tcx>) -> bool { | |
493 | // (self as *const _) == (other as *const _) | |
494 | (self as *const TyS<'tcx>) == (other as *const TyS<'tcx>) | |
495 | } | |
496 | } | |
497 | impl<'tcx> Eq for TyS<'tcx> {} | |
498 | ||
499 | impl<'tcx> Hash for TyS<'tcx> { | |
500 | fn hash<H: Hasher>(&self, s: &mut H) { | |
501 | (self as *const TyS).hash(s) | |
502 | } | |
503 | } | |
504 | ||
041b39d2 XL |
505 | impl<'tcx> TyS<'tcx> { |
506 | pub fn is_primitive_ty(&self) -> bool { | |
507 | match self.sty { | |
508 | TypeVariants::TyBool | | |
509 | TypeVariants::TyChar | | |
510 | TypeVariants::TyInt(_) | | |
511 | TypeVariants::TyUint(_) | | |
512 | TypeVariants::TyFloat(_) | | |
513 | TypeVariants::TyInfer(InferTy::IntVar(_)) | | |
514 | TypeVariants::TyInfer(InferTy::FloatVar(_)) | | |
515 | TypeVariants::TyInfer(InferTy::FreshIntTy(_)) | | |
516 | TypeVariants::TyInfer(InferTy::FreshFloatTy(_)) => true, | |
517 | TypeVariants::TyRef(_, x) => x.ty.is_primitive_ty(), | |
518 | _ => false, | |
519 | } | |
520 | } | |
521 | ||
522 | pub fn is_suggestable(&self) -> bool { | |
523 | match self.sty { | |
524 | TypeVariants::TyAnon(..) | | |
525 | TypeVariants::TyFnDef(..) | | |
526 | TypeVariants::TyFnPtr(..) | | |
527 | TypeVariants::TyDynamic(..) | | |
528 | TypeVariants::TyClosure(..) | | |
3b2f2976 | 529 | TypeVariants::TyInfer(..) | |
041b39d2 XL |
530 | TypeVariants::TyProjection(..) => false, |
531 | _ => true, | |
532 | } | |
533 | } | |
534 | } | |
535 | ||
0531ce1d | 536 | impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::TyS<'gcx> { |
cc61c64b | 537 | fn hash_stable<W: StableHasherResult>(&self, |
0531ce1d | 538 | hcx: &mut StableHashingContext<'a>, |
cc61c64b XL |
539 | hasher: &mut StableHasher<W>) { |
540 | let ty::TyS { | |
541 | ref sty, | |
542 | ||
543 | // The other fields just provide fast access to information that is | |
544 | // also contained in `sty`, so no need to hash them. | |
545 | flags: _, | |
546 | region_depth: _, | |
547 | } = *self; | |
548 | ||
549 | sty.hash_stable(hcx, hasher); | |
550 | } | |
551 | } | |
552 | ||
e9174d1e SL |
553 | pub type Ty<'tcx> = &'tcx TyS<'tcx>; |
554 | ||
9e0c209e SL |
555 | impl<'tcx> serialize::UseSpecializedEncodable for Ty<'tcx> {} |
556 | impl<'tcx> serialize::UseSpecializedDecodable for Ty<'tcx> {} | |
557 | ||
0531ce1d XL |
558 | pub type CanonicalTy<'gcx> = Canonical<'gcx, Ty<'gcx>>; |
559 | ||
560 | impl <'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for Ty<'tcx> { | |
561 | type Canonicalized = CanonicalTy<'gcx>; | |
562 | ||
563 | fn intern(_gcx: TyCtxt<'_, 'gcx, 'gcx>, | |
564 | value: Canonical<'gcx, Self::Lifted>) -> Self::Canonicalized { | |
565 | value | |
566 | } | |
567 | } | |
568 | ||
c30ab7b3 | 569 | /// A wrapper for slices with the additional invariant |
9e0c209e SL |
570 | /// that the slice is interned and no other slice with |
571 | /// the same contents can exist in the same context. | |
572 | /// This means we can use pointer + length for both | |
573 | /// equality comparisons and hashing. | |
574 | #[derive(Debug, RustcEncodable)] | |
575 | pub struct Slice<T>([T]); | |
576 | ||
577 | impl<T> PartialEq for Slice<T> { | |
578 | #[inline] | |
579 | fn eq(&self, other: &Slice<T>) -> bool { | |
580 | (&self.0 as *const [T]) == (&other.0 as *const [T]) | |
9cc50fc6 SL |
581 | } |
582 | } | |
9e0c209e | 583 | impl<T> Eq for Slice<T> {} |
9cc50fc6 | 584 | |
9e0c209e SL |
585 | impl<T> Hash for Slice<T> { |
586 | fn hash<H: Hasher>(&self, s: &mut H) { | |
587 | (self.as_ptr(), self.len()).hash(s) | |
588 | } | |
589 | } | |
590 | ||
591 | impl<T> Deref for Slice<T> { | |
592 | type Target = [T]; | |
593 | fn deref(&self) -> &[T] { | |
594 | &self.0 | |
595 | } | |
596 | } | |
597 | ||
598 | impl<'a, T> IntoIterator for &'a Slice<T> { | |
599 | type Item = &'a T; | |
600 | type IntoIter = <&'a [T] as IntoIterator>::IntoIter; | |
601 | fn into_iter(self) -> Self::IntoIter { | |
602 | self[..].iter() | |
9cc50fc6 SL |
603 | } |
604 | } | |
605 | ||
9e0c209e | 606 | impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Slice<Ty<'tcx>> {} |
9cc50fc6 | 607 | |
c30ab7b3 SL |
608 | impl<T> Slice<T> { |
609 | pub fn empty<'a>() -> &'a Slice<T> { | |
610 | unsafe { | |
611 | mem::transmute(slice::from_raw_parts(0x1 as *const T, 0)) | |
612 | } | |
613 | } | |
614 | } | |
615 | ||
e9174d1e SL |
616 | /// Upvars do not get their own node-id. Instead, we use the pair of |
617 | /// the original var id (that is, the root variable that is referenced | |
618 | /// by the upvar) and the id of the closure expression. | |
32a655c1 | 619 | #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] |
e9174d1e | 620 | pub struct UpvarId { |
ea8adc8c | 621 | pub var_id: hir::HirId, |
abe05a73 | 622 | pub closure_expr_id: LocalDefId, |
e9174d1e SL |
623 | } |
624 | ||
625 | #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)] | |
626 | pub enum BorrowKind { | |
627 | /// Data must be immutable and is aliasable. | |
628 | ImmBorrow, | |
629 | ||
630 | /// Data must be immutable but not aliasable. This kind of borrow | |
631 | /// cannot currently be expressed by the user and is used only in | |
32a655c1 | 632 | /// implicit closure bindings. It is needed when the closure |
e9174d1e SL |
633 | /// is borrowing or mutating a mutable referent, e.g.: |
634 | /// | |
635 | /// let x: &mut isize = ...; | |
636 | /// let y = || *x += 5; | |
637 | /// | |
638 | /// If we were to try to translate this closure into a more explicit | |
639 | /// form, we'd encounter an error with the code as written: | |
640 | /// | |
641 | /// struct Env { x: & &mut isize } | |
642 | /// let x: &mut isize = ...; | |
643 | /// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn | |
644 | /// fn fn_ptr(env: &mut Env) { **env.x += 5; } | |
645 | /// | |
646 | /// This is then illegal because you cannot mutate a `&mut` found | |
647 | /// in an aliasable location. To solve, you'd have to translate with | |
648 | /// an `&mut` borrow: | |
649 | /// | |
650 | /// struct Env { x: & &mut isize } | |
651 | /// let x: &mut isize = ...; | |
652 | /// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x | |
653 | /// fn fn_ptr(env: &mut Env) { **env.x += 5; } | |
654 | /// | |
655 | /// Now the assignment to `**env.x` is legal, but creating a | |
656 | /// mutable pointer to `x` is not because `x` is not mutable. We | |
657 | /// could fix this by declaring `x` as `let mut x`. This is ok in | |
658 | /// user code, if awkward, but extra weird for closures, since the | |
659 | /// borrow is hidden. | |
660 | /// | |
661 | /// So we introduce a "unique imm" borrow -- the referent is | |
662 | /// immutable, but not aliasable. This solves the problem. For | |
663 | /// simplicity, we don't give users the way to express this | |
664 | /// borrow, it's just used when translating closures. | |
665 | UniqueImmBorrow, | |
666 | ||
667 | /// Data is mutable and not aliasable. | |
668 | MutBorrow | |
669 | } | |
670 | ||
671 | /// Information describing the capture of an upvar. This is computed | |
672 | /// during `typeck`, specifically by `regionck`. | |
9e0c209e SL |
673 | #[derive(PartialEq, Clone, Debug, Copy, RustcEncodable, RustcDecodable)] |
674 | pub enum UpvarCapture<'tcx> { | |
e9174d1e SL |
675 | /// Upvar is captured by value. This is always true when the |
676 | /// closure is labeled `move`, but can also be true in other cases | |
677 | /// depending on inference. | |
678 | ByValue, | |
679 | ||
680 | /// Upvar is captured by reference. | |
9e0c209e | 681 | ByRef(UpvarBorrow<'tcx>), |
e9174d1e SL |
682 | } |
683 | ||
9e0c209e SL |
684 | #[derive(PartialEq, Clone, Copy, RustcEncodable, RustcDecodable)] |
685 | pub struct UpvarBorrow<'tcx> { | |
e9174d1e SL |
686 | /// The kind of borrow: by-ref upvars have access to shared |
687 | /// immutable borrows, which are not part of the normal language | |
688 | /// syntax. | |
689 | pub kind: BorrowKind, | |
690 | ||
691 | /// Region of the resulting reference. | |
7cac9316 | 692 | pub region: ty::Region<'tcx>, |
e9174d1e SL |
693 | } |
694 | ||
476ff2be | 695 | pub type UpvarCaptureMap<'tcx> = FxHashMap<UpvarId, UpvarCapture<'tcx>>; |
e9174d1e SL |
696 | |
697 | #[derive(Copy, Clone)] | |
698 | pub struct ClosureUpvar<'tcx> { | |
7453a54e | 699 | pub def: Def, |
e9174d1e SL |
700 | pub span: Span, |
701 | pub ty: Ty<'tcx>, | |
702 | } | |
703 | ||
0531ce1d | 704 | #[derive(Clone, Copy, PartialEq, Eq)] |
e9174d1e | 705 | pub enum IntVarValue { |
b039eaaf SL |
706 | IntType(ast::IntTy), |
707 | UintType(ast::UintTy), | |
e9174d1e SL |
708 | } |
709 | ||
0531ce1d XL |
710 | #[derive(Clone, Copy, PartialEq, Eq)] |
711 | pub struct FloatVarValue(pub ast::FloatTy); | |
712 | ||
8bb4bdeb XL |
713 | #[derive(Copy, Clone, RustcEncodable, RustcDecodable)] |
714 | pub struct TypeParameterDef { | |
0531ce1d | 715 | pub name: InternedString, |
e9174d1e | 716 | pub def_id: DefId, |
e9174d1e | 717 | pub index: u32, |
8bb4bdeb XL |
718 | pub has_default: bool, |
719 | pub object_lifetime_default: ObjectLifetimeDefault, | |
c30ab7b3 SL |
720 | |
721 | /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute | |
722 | /// on generic parameter `T`, asserts data behind the parameter | |
723 | /// `T` won't be accessed during the parent type's `Drop` impl. | |
724 | pub pure_wrt_drop: bool, | |
ea8adc8c XL |
725 | |
726 | pub synthetic: Option<hir::SyntheticTyParamKind>, | |
e9174d1e SL |
727 | } |
728 | ||
32a655c1 SL |
729 | #[derive(Copy, Clone, RustcEncodable, RustcDecodable)] |
730 | pub struct RegionParameterDef { | |
e9174d1e SL |
731 | pub name: Name, |
732 | pub def_id: DefId, | |
e9174d1e | 733 | pub index: u32, |
c30ab7b3 SL |
734 | |
735 | /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute | |
736 | /// on generic parameter `'a`, asserts data of lifetime `'a` | |
737 | /// won't be accessed during the parent type's `Drop` impl. | |
738 | pub pure_wrt_drop: bool, | |
e9174d1e SL |
739 | } |
740 | ||
32a655c1 | 741 | impl RegionParameterDef { |
9e0c209e SL |
742 | pub fn to_early_bound_region_data(&self) -> ty::EarlyBoundRegion { |
743 | ty::EarlyBoundRegion { | |
7cac9316 | 744 | def_id: self.def_id, |
e9174d1e SL |
745 | index: self.index, |
746 | name: self.name, | |
9e0c209e | 747 | } |
e9174d1e | 748 | } |
9e0c209e | 749 | |
7cac9316 XL |
750 | pub fn to_bound_region(&self) -> ty::BoundRegion { |
751 | self.to_early_bound_region_data().to_bound_region() | |
752 | } | |
753 | } | |
754 | ||
755 | impl ty::EarlyBoundRegion { | |
e9174d1e | 756 | pub fn to_bound_region(&self) -> ty::BoundRegion { |
8bb4bdeb | 757 | ty::BoundRegion::BrNamed(self.def_id, self.name) |
e9174d1e SL |
758 | } |
759 | } | |
760 | ||
761 | /// Information about the formal type/lifetime parameters associated | |
762 | /// with an item or method. Analogous to hir::Generics. | |
ea8adc8c XL |
763 | /// |
764 | /// Note that in the presence of a `Self` parameter, the ordering here | |
765 | /// is different from the ordering in a Substs. Substs are ordered as | |
766 | /// Self, *Regions, *Other Type Params, (...child generics) | |
767 | /// while this struct is ordered as | |
768 | /// regions = Regions | |
769 | /// types = [Self, *Other Type Params] | |
9e0c209e | 770 | #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] |
8bb4bdeb | 771 | pub struct Generics { |
9e0c209e SL |
772 | pub parent: Option<DefId>, |
773 | pub parent_regions: u32, | |
774 | pub parent_types: u32, | |
32a655c1 | 775 | pub regions: Vec<RegionParameterDef>, |
8bb4bdeb XL |
776 | pub types: Vec<TypeParameterDef>, |
777 | ||
2c00a5a8 XL |
778 | /// Reverse map to each `TypeParameterDef`'s `index` field |
779 | pub type_param_to_index: FxHashMap<DefId, u32>, | |
8bb4bdeb | 780 | |
9e0c209e | 781 | pub has_self: bool, |
3b2f2976 | 782 | pub has_late_bound_regions: Option<Span>, |
e9174d1e SL |
783 | } |
784 | ||
ea8adc8c | 785 | impl<'a, 'gcx, 'tcx> Generics { |
9e0c209e SL |
786 | pub fn parent_count(&self) -> usize { |
787 | self.parent_regions as usize + self.parent_types as usize | |
e9174d1e SL |
788 | } |
789 | ||
9e0c209e SL |
790 | pub fn own_count(&self) -> usize { |
791 | self.regions.len() + self.types.len() | |
e9174d1e SL |
792 | } |
793 | ||
9e0c209e SL |
794 | pub fn count(&self) -> usize { |
795 | self.parent_count() + self.own_count() | |
e9174d1e | 796 | } |
c30ab7b3 | 797 | |
ea8adc8c XL |
798 | pub fn region_param(&'tcx self, |
799 | param: &EarlyBoundRegion, | |
800 | tcx: TyCtxt<'a, 'gcx, 'tcx>) | |
801 | -> &'tcx RegionParameterDef | |
802 | { | |
803 | if let Some(index) = param.index.checked_sub(self.parent_count() as u32) { | |
804 | &self.regions[index as usize - self.has_self as usize] | |
805 | } else { | |
806 | tcx.generics_of(self.parent.expect("parent_count>0 but no parent?")) | |
807 | .region_param(param, tcx) | |
808 | } | |
809 | } | |
810 | ||
811 | /// Returns the `TypeParameterDef` associated with this `ParamTy`. | |
812 | pub fn type_param(&'tcx self, | |
813 | param: &ParamTy, | |
814 | tcx: TyCtxt<'a, 'gcx, 'tcx>) | |
815 | -> &TypeParameterDef { | |
816 | if let Some(idx) = param.idx.checked_sub(self.parent_count() as u32) { | |
817 | // non-Self type parameters are always offset by exactly | |
818 | // `self.regions.len()`. In the absence of a Self, this is obvious, | |
ff7c6d11 | 819 | // but even in the presence of a `Self` we just have to "compensate" |
ea8adc8c XL |
820 | // for the regions: |
821 | // | |
ff7c6d11 XL |
822 | // Without a `Self` (or in a nested generics that doesn't have |
823 | // a `Self` in itself, even through it parent does), for example | |
824 | // for `fn foo<'a, T1, T2>()`, the situation is: | |
825 | // Substs: | |
826 | // 0 1 2 | |
827 | // 'a T1 T2 | |
828 | // generics.types: | |
829 | // 0 1 | |
830 | // T1 T2 | |
831 | // | |
832 | // And with a `Self`, for example for `trait Foo<'a, 'b, T1, T2>`, the | |
ea8adc8c XL |
833 | // situation is: |
834 | // Substs: | |
835 | // 0 1 2 3 4 | |
836 | // Self 'a 'b T1 T2 | |
837 | // generics.types: | |
838 | // 0 1 2 | |
839 | // Self T1 T2 | |
ff7c6d11 XL |
840 | // |
841 | // And it can be seen that in both cases, to move from a substs | |
842 | // offset to a generics offset you just have to offset by the | |
843 | // number of regions. | |
ea8adc8c | 844 | let type_param_offset = self.regions.len(); |
ff7c6d11 XL |
845 | |
846 | let has_self = self.has_self && self.parent.is_none(); | |
847 | let is_separated_self = type_param_offset != 0 && idx == 0 && has_self; | |
848 | ||
ea8adc8c | 849 | if let Some(idx) = (idx as usize).checked_sub(type_param_offset) { |
ff7c6d11 | 850 | assert!(!is_separated_self, "found a Self after type_param_offset"); |
ea8adc8c XL |
851 | &self.types[idx] |
852 | } else { | |
ff7c6d11 | 853 | assert!(is_separated_self, "non-Self param before type_param_offset"); |
ea8adc8c XL |
854 | &self.types[0] |
855 | } | |
856 | } else { | |
857 | tcx.generics_of(self.parent.expect("parent_count>0 but no parent?")) | |
858 | .type_param(param, tcx) | |
859 | } | |
c30ab7b3 | 860 | } |
e9174d1e SL |
861 | } |
862 | ||
863 | /// Bounds on generics. | |
8bb4bdeb | 864 | #[derive(Clone, Default)] |
e9174d1e | 865 | pub struct GenericPredicates<'tcx> { |
9e0c209e SL |
866 | pub parent: Option<DefId>, |
867 | pub predicates: Vec<Predicate<'tcx>>, | |
e9174d1e SL |
868 | } |
869 | ||
9e0c209e SL |
870 | impl<'tcx> serialize::UseSpecializedEncodable for GenericPredicates<'tcx> {} |
871 | impl<'tcx> serialize::UseSpecializedDecodable for GenericPredicates<'tcx> {} | |
e9174d1e | 872 | |
9e0c209e | 873 | impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> { |
a7813a04 | 874 | pub fn instantiate(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>) |
e9174d1e | 875 | -> InstantiatedPredicates<'tcx> { |
9e0c209e SL |
876 | let mut instantiated = InstantiatedPredicates::empty(); |
877 | self.instantiate_into(tcx, &mut instantiated, substs); | |
878 | instantiated | |
879 | } | |
880 | pub fn instantiate_own(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>) | |
881 | -> InstantiatedPredicates<'tcx> { | |
e9174d1e | 882 | InstantiatedPredicates { |
9e0c209e | 883 | predicates: self.predicates.subst(tcx, substs) |
e9174d1e SL |
884 | } |
885 | } | |
886 | ||
9e0c209e SL |
887 | fn instantiate_into(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, |
888 | instantiated: &mut InstantiatedPredicates<'tcx>, | |
889 | substs: &Substs<'tcx>) { | |
890 | if let Some(def_id) = self.parent { | |
7cac9316 | 891 | tcx.predicates_of(def_id).instantiate_into(tcx, instantiated, substs); |
9e0c209e SL |
892 | } |
893 | instantiated.predicates.extend(self.predicates.iter().map(|p| p.subst(tcx, substs))) | |
894 | } | |
895 | ||
7cac9316 XL |
896 | pub fn instantiate_identity(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) |
897 | -> InstantiatedPredicates<'tcx> { | |
898 | let mut instantiated = InstantiatedPredicates::empty(); | |
899 | self.instantiate_identity_into(tcx, &mut instantiated); | |
900 | instantiated | |
901 | } | |
902 | ||
903 | fn instantiate_identity_into(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, | |
904 | instantiated: &mut InstantiatedPredicates<'tcx>) { | |
905 | if let Some(def_id) = self.parent { | |
906 | tcx.predicates_of(def_id).instantiate_identity_into(tcx, instantiated); | |
907 | } | |
908 | instantiated.predicates.extend(&self.predicates) | |
909 | } | |
910 | ||
a7813a04 | 911 | pub fn instantiate_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, |
e9174d1e SL |
912 | poly_trait_ref: &ty::PolyTraitRef<'tcx>) |
913 | -> InstantiatedPredicates<'tcx> | |
914 | { | |
9e0c209e | 915 | assert_eq!(self.parent, None); |
e9174d1e | 916 | InstantiatedPredicates { |
9e0c209e | 917 | predicates: self.predicates.iter().map(|pred| { |
a7813a04 | 918 | pred.subst_supertrait(tcx, poly_trait_ref) |
9e0c209e | 919 | }).collect() |
e9174d1e SL |
920 | } |
921 | } | |
922 | } | |
923 | ||
7cac9316 | 924 | #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] |
e9174d1e SL |
925 | pub enum Predicate<'tcx> { |
926 | /// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be | |
927 | /// the `Self` type of the trait reference and `A`, `B`, and `C` | |
9e0c209e | 928 | /// would be the type parameters. |
e9174d1e SL |
929 | Trait(PolyTraitPredicate<'tcx>), |
930 | ||
e9174d1e | 931 | /// where 'a : 'b |
9e0c209e | 932 | RegionOutlives(PolyRegionOutlivesPredicate<'tcx>), |
e9174d1e SL |
933 | |
934 | /// where T : 'a | |
935 | TypeOutlives(PolyTypeOutlivesPredicate<'tcx>), | |
936 | ||
937 | /// where <T as TraitRef>::Name == X, approximately. | |
938 | /// See `ProjectionPredicate` struct for details. | |
939 | Projection(PolyProjectionPredicate<'tcx>), | |
940 | ||
941 | /// no syntax: T WF | |
942 | WellFormed(Ty<'tcx>), | |
943 | ||
944 | /// trait must be object-safe | |
945 | ObjectSafe(DefId), | |
a7813a04 | 946 | |
9e0c209e SL |
947 | /// No direct syntax. May be thought of as `where T : FnFoo<...>` |
948 | /// for some substitutions `...` and T being a closure type. | |
949 | /// Satisfied (or refuted) once we know the closure's kind. | |
ff7c6d11 | 950 | ClosureKind(DefId, ClosureSubsts<'tcx>, ClosureKind), |
cc61c64b XL |
951 | |
952 | /// `T1 <: T2` | |
953 | Subtype(PolySubtypePredicate<'tcx>), | |
ea8adc8c XL |
954 | |
955 | /// Constant initializer must evaluate successfully. | |
956 | ConstEvaluatable(DefId, &'tcx Substs<'tcx>), | |
e9174d1e SL |
957 | } |
958 | ||
abe05a73 XL |
959 | impl<'tcx> AsRef<Predicate<'tcx>> for Predicate<'tcx> { |
960 | fn as_ref(&self) -> &Predicate<'tcx> { | |
961 | self | |
962 | } | |
963 | } | |
964 | ||
a7813a04 | 965 | impl<'a, 'gcx, 'tcx> Predicate<'tcx> { |
e9174d1e SL |
966 | /// Performs a substitution suitable for going from a |
967 | /// poly-trait-ref to supertraits that must hold if that | |
968 | /// poly-trait-ref holds. This is slightly different from a normal | |
969 | /// substitution in terms of what happens with bound regions. See | |
970 | /// lengthy comment below for details. | |
a7813a04 | 971 | pub fn subst_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, |
e9174d1e SL |
972 | trait_ref: &ty::PolyTraitRef<'tcx>) |
973 | -> ty::Predicate<'tcx> | |
974 | { | |
975 | // The interaction between HRTB and supertraits is not entirely | |
976 | // obvious. Let me walk you (and myself) through an example. | |
977 | // | |
978 | // Let's start with an easy case. Consider two traits: | |
979 | // | |
980 | // trait Foo<'a> : Bar<'a,'a> { } | |
981 | // trait Bar<'b,'c> { } | |
982 | // | |
983 | // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then | |
984 | // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we | |
985 | // knew that `Foo<'x>` (for any 'x) then we also know that | |
986 | // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from | |
987 | // normal substitution. | |
988 | // | |
989 | // In terms of why this is sound, the idea is that whenever there | |
990 | // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>` | |
991 | // holds. So if there is an impl of `T:Foo<'a>` that applies to | |
992 | // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all | |
993 | // `'a`. | |
994 | // | |
995 | // Another example to be careful of is this: | |
996 | // | |
997 | // trait Foo1<'a> : for<'b> Bar1<'a,'b> { } | |
998 | // trait Bar1<'b,'c> { } | |
999 | // | |
1000 | // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know? | |
1001 | // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The | |
1002 | // reason is similar to the previous example: any impl of | |
1003 | // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`. So | |
1004 | // basically we would want to collapse the bound lifetimes from | |
1005 | // the input (`trait_ref`) and the supertraits. | |
1006 | // | |
1007 | // To achieve this in practice is fairly straightforward. Let's | |
1008 | // consider the more complicated scenario: | |
1009 | // | |
1010 | // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x` | |
1011 | // has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`, | |
1012 | // where both `'x` and `'b` would have a DB index of 1. | |
1013 | // The substitution from the input trait-ref is therefore going to be | |
1014 | // `'a => 'x` (where `'x` has a DB index of 1). | |
1015 | // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an | |
1016 | // early-bound parameter and `'b' is a late-bound parameter with a | |
1017 | // DB index of 1. | |
1018 | // - If we replace `'a` with `'x` from the input, it too will have | |
1019 | // a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>` | |
1020 | // just as we wanted. | |
1021 | // | |
1022 | // There is only one catch. If we just apply the substitution `'a | |
1023 | // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will | |
1024 | // adjust the DB index because we substituting into a binder (it | |
1025 | // tries to be so smart...) resulting in `for<'x> for<'b> | |
1026 | // Bar1<'x,'b>` (we have no syntax for this, so use your | |
1027 | // imagination). Basically the 'x will have DB index of 2 and 'b | |
1028 | // will have DB index of 1. Not quite what we want. So we apply | |
1029 | // the substitution to the *contents* of the trait reference, | |
1030 | // rather than the trait reference itself (put another way, the | |
1031 | // substitution code expects equal binding levels in the values | |
1032 | // from the substitution and the value being substituted into, and | |
1033 | // this trick achieves that). | |
1034 | ||
1035 | let substs = &trait_ref.0.substs; | |
1036 | match *self { | |
1037 | Predicate::Trait(ty::Binder(ref data)) => | |
1038 | Predicate::Trait(ty::Binder(data.subst(tcx, substs))), | |
cc61c64b XL |
1039 | Predicate::Subtype(ty::Binder(ref data)) => |
1040 | Predicate::Subtype(ty::Binder(data.subst(tcx, substs))), | |
e9174d1e SL |
1041 | Predicate::RegionOutlives(ty::Binder(ref data)) => |
1042 | Predicate::RegionOutlives(ty::Binder(data.subst(tcx, substs))), | |
1043 | Predicate::TypeOutlives(ty::Binder(ref data)) => | |
1044 | Predicate::TypeOutlives(ty::Binder(data.subst(tcx, substs))), | |
1045 | Predicate::Projection(ty::Binder(ref data)) => | |
1046 | Predicate::Projection(ty::Binder(data.subst(tcx, substs))), | |
1047 | Predicate::WellFormed(data) => | |
1048 | Predicate::WellFormed(data.subst(tcx, substs)), | |
1049 | Predicate::ObjectSafe(trait_def_id) => | |
1050 | Predicate::ObjectSafe(trait_def_id), | |
ff7c6d11 XL |
1051 | Predicate::ClosureKind(closure_def_id, closure_substs, kind) => |
1052 | Predicate::ClosureKind(closure_def_id, closure_substs.subst(tcx, substs), kind), | |
ea8adc8c XL |
1053 | Predicate::ConstEvaluatable(def_id, const_substs) => |
1054 | Predicate::ConstEvaluatable(def_id, const_substs.subst(tcx, substs)), | |
e9174d1e SL |
1055 | } |
1056 | } | |
1057 | } | |
1058 | ||
7cac9316 | 1059 | #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] |
e9174d1e SL |
1060 | pub struct TraitPredicate<'tcx> { |
1061 | pub trait_ref: TraitRef<'tcx> | |
1062 | } | |
1063 | pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>; | |
1064 | ||
1065 | impl<'tcx> TraitPredicate<'tcx> { | |
1066 | pub fn def_id(&self) -> DefId { | |
1067 | self.trait_ref.def_id | |
1068 | } | |
1069 | ||
9e0c209e SL |
1070 | pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a { |
1071 | self.trait_ref.input_types() | |
e9174d1e SL |
1072 | } |
1073 | ||
1074 | pub fn self_ty(&self) -> Ty<'tcx> { | |
1075 | self.trait_ref.self_ty() | |
1076 | } | |
1077 | } | |
1078 | ||
1079 | impl<'tcx> PolyTraitPredicate<'tcx> { | |
1080 | pub fn def_id(&self) -> DefId { | |
7453a54e | 1081 | // ok to skip binder since trait def-id does not care about regions |
e9174d1e SL |
1082 | self.0.def_id() |
1083 | } | |
1084 | } | |
1085 | ||
7cac9316 | 1086 | #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] |
e9174d1e SL |
1087 | pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B` |
1088 | pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>; | |
0531ce1d XL |
1089 | pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<ty::Region<'tcx>, |
1090 | ty::Region<'tcx>>; | |
1091 | pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<Ty<'tcx>, | |
1092 | ty::Region<'tcx>>; | |
1093 | pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<RegionOutlivesPredicate<'tcx>>; | |
1094 | pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<TypeOutlivesPredicate<'tcx>>; | |
e9174d1e | 1095 | |
7cac9316 | 1096 | #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] |
cc61c64b XL |
1097 | pub struct SubtypePredicate<'tcx> { |
1098 | pub a_is_expected: bool, | |
1099 | pub a: Ty<'tcx>, | |
1100 | pub b: Ty<'tcx> | |
1101 | } | |
1102 | pub type PolySubtypePredicate<'tcx> = ty::Binder<SubtypePredicate<'tcx>>; | |
1103 | ||
e9174d1e SL |
1104 | /// This kind of predicate has no *direct* correspondent in the |
1105 | /// syntax, but it roughly corresponds to the syntactic forms: | |
1106 | /// | |
1107 | /// 1. `T : TraitRef<..., Item=Type>` | |
1108 | /// 2. `<T as TraitRef<...>>::Item == Type` (NYI) | |
1109 | /// | |
1110 | /// In particular, form #1 is "desugared" to the combination of a | |
1111 | /// normal trait predicate (`T : TraitRef<...>`) and one of these | |
1112 | /// predicates. Form #2 is a broader form in that it also permits | |
ff7c6d11 XL |
1113 | /// equality between arbitrary types. Processing an instance of |
1114 | /// Form #2 eventually yields one of these `ProjectionPredicate` | |
e9174d1e | 1115 | /// instances to normalize the LHS. |
0531ce1d | 1116 | #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] |
e9174d1e SL |
1117 | pub struct ProjectionPredicate<'tcx> { |
1118 | pub projection_ty: ProjectionTy<'tcx>, | |
1119 | pub ty: Ty<'tcx>, | |
1120 | } | |
1121 | ||
1122 | pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>; | |
1123 | ||
1124 | impl<'tcx> PolyProjectionPredicate<'tcx> { | |
041b39d2 XL |
1125 | pub fn to_poly_trait_ref(&self, tcx: TyCtxt) -> PolyTraitRef<'tcx> { |
1126 | // Note: unlike with TraitRef::to_poly_trait_ref(), | |
1127 | // self.0.trait_ref is permitted to have escaping regions. | |
1128 | // This is because here `self` has a `Binder` and so does our | |
1129 | // return value, so we are preserving the number of binding | |
1130 | // levels. | |
1131 | ty::Binder(self.0.projection_ty.trait_ref(tcx)) | |
e9174d1e | 1132 | } |
3b2f2976 XL |
1133 | |
1134 | pub fn ty(&self) -> Binder<Ty<'tcx>> { | |
1135 | Binder(self.skip_binder().ty) // preserves binding levels | |
1136 | } | |
e9174d1e SL |
1137 | } |
1138 | ||
1139 | pub trait ToPolyTraitRef<'tcx> { | |
1140 | fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>; | |
1141 | } | |
1142 | ||
1143 | impl<'tcx> ToPolyTraitRef<'tcx> for TraitRef<'tcx> { | |
1144 | fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> { | |
1145 | assert!(!self.has_escaping_regions()); | |
1146 | ty::Binder(self.clone()) | |
1147 | } | |
1148 | } | |
1149 | ||
1150 | impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> { | |
1151 | fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> { | |
7453a54e | 1152 | self.map_bound_ref(|trait_pred| trait_pred.trait_ref) |
e9174d1e SL |
1153 | } |
1154 | } | |
1155 | ||
e9174d1e SL |
1156 | pub trait ToPredicate<'tcx> { |
1157 | fn to_predicate(&self) -> Predicate<'tcx>; | |
1158 | } | |
1159 | ||
1160 | impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> { | |
1161 | fn to_predicate(&self) -> Predicate<'tcx> { | |
1162 | // we're about to add a binder, so let's check that we don't | |
1163 | // accidentally capture anything, or else that might be some | |
1164 | // weird debruijn accounting. | |
1165 | assert!(!self.has_escaping_regions()); | |
1166 | ||
1167 | ty::Predicate::Trait(ty::Binder(ty::TraitPredicate { | |
1168 | trait_ref: self.clone() | |
1169 | })) | |
1170 | } | |
1171 | } | |
1172 | ||
1173 | impl<'tcx> ToPredicate<'tcx> for PolyTraitRef<'tcx> { | |
1174 | fn to_predicate(&self) -> Predicate<'tcx> { | |
1175 | ty::Predicate::Trait(self.to_poly_trait_predicate()) | |
1176 | } | |
1177 | } | |
1178 | ||
9e0c209e | 1179 | impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> { |
e9174d1e SL |
1180 | fn to_predicate(&self) -> Predicate<'tcx> { |
1181 | Predicate::RegionOutlives(self.clone()) | |
1182 | } | |
1183 | } | |
1184 | ||
1185 | impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> { | |
1186 | fn to_predicate(&self) -> Predicate<'tcx> { | |
1187 | Predicate::TypeOutlives(self.clone()) | |
1188 | } | |
1189 | } | |
1190 | ||
1191 | impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> { | |
1192 | fn to_predicate(&self) -> Predicate<'tcx> { | |
1193 | Predicate::Projection(self.clone()) | |
1194 | } | |
1195 | } | |
1196 | ||
1197 | impl<'tcx> Predicate<'tcx> { | |
1198 | /// Iterates over the types in this predicate. Note that in all | |
1199 | /// cases this is skipping over a binder, so late-bound regions | |
1200 | /// with depth 0 are bound by the predicate. | |
1201 | pub fn walk_tys(&self) -> IntoIter<Ty<'tcx>> { | |
1202 | let vec: Vec<_> = match *self { | |
1203 | ty::Predicate::Trait(ref data) => { | |
9e0c209e | 1204 | data.skip_binder().input_types().collect() |
a7813a04 | 1205 | } |
cc61c64b XL |
1206 | ty::Predicate::Subtype(ty::Binder(SubtypePredicate { a, b, a_is_expected: _ })) => { |
1207 | vec![a, b] | |
1208 | } | |
e9174d1e SL |
1209 | ty::Predicate::TypeOutlives(ty::Binder(ref data)) => { |
1210 | vec![data.0] | |
1211 | } | |
1212 | ty::Predicate::RegionOutlives(..) => { | |
1213 | vec![] | |
1214 | } | |
1215 | ty::Predicate::Projection(ref data) => { | |
041b39d2 | 1216 | data.0.projection_ty.substs.types().chain(Some(data.0.ty)).collect() |
e9174d1e SL |
1217 | } |
1218 | ty::Predicate::WellFormed(data) => { | |
1219 | vec![data] | |
1220 | } | |
1221 | ty::Predicate::ObjectSafe(_trait_def_id) => { | |
1222 | vec![] | |
1223 | } | |
ff7c6d11 XL |
1224 | ty::Predicate::ClosureKind(_closure_def_id, closure_substs, _kind) => { |
1225 | closure_substs.substs.types().collect() | |
a7813a04 | 1226 | } |
ea8adc8c XL |
1227 | ty::Predicate::ConstEvaluatable(_, substs) => { |
1228 | substs.types().collect() | |
1229 | } | |
e9174d1e SL |
1230 | }; |
1231 | ||
1232 | // The only reason to collect into a vector here is that I was | |
1233 | // too lazy to make the full (somewhat complicated) iterator | |
1234 | // type that would be needed here. But I wanted this fn to | |
1235 | // return an iterator conceptually, rather than a `Vec`, so as | |
1236 | // to be closer to `Ty::walk`. | |
1237 | vec.into_iter() | |
1238 | } | |
1239 | ||
1240 | pub fn to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'tcx>> { | |
1241 | match *self { | |
1242 | Predicate::Trait(ref t) => { | |
1243 | Some(t.to_poly_trait_ref()) | |
1244 | } | |
1245 | Predicate::Projection(..) | | |
cc61c64b | 1246 | Predicate::Subtype(..) | |
e9174d1e SL |
1247 | Predicate::RegionOutlives(..) | |
1248 | Predicate::WellFormed(..) | | |
1249 | Predicate::ObjectSafe(..) | | |
a7813a04 | 1250 | Predicate::ClosureKind(..) | |
ea8adc8c XL |
1251 | Predicate::TypeOutlives(..) | |
1252 | Predicate::ConstEvaluatable(..) => { | |
e9174d1e SL |
1253 | None |
1254 | } | |
1255 | } | |
1256 | } | |
abe05a73 XL |
1257 | |
1258 | pub fn to_opt_type_outlives(&self) -> Option<PolyTypeOutlivesPredicate<'tcx>> { | |
1259 | match *self { | |
1260 | Predicate::TypeOutlives(data) => { | |
1261 | Some(data) | |
1262 | } | |
1263 | Predicate::Trait(..) | | |
1264 | Predicate::Projection(..) | | |
abe05a73 XL |
1265 | Predicate::Subtype(..) | |
1266 | Predicate::RegionOutlives(..) | | |
1267 | Predicate::WellFormed(..) | | |
1268 | Predicate::ObjectSafe(..) | | |
1269 | Predicate::ClosureKind(..) | | |
1270 | Predicate::ConstEvaluatable(..) => { | |
1271 | None | |
1272 | } | |
1273 | } | |
1274 | } | |
e9174d1e SL |
1275 | } |
1276 | ||
1277 | /// Represents the bounds declared on a particular set of type | |
1278 | /// parameters. Should eventually be generalized into a flag list of | |
1279 | /// where clauses. You can obtain a `InstantiatedPredicates` list from a | |
1280 | /// `GenericPredicates` by using the `instantiate` method. Note that this method | |
1281 | /// reflects an important semantic invariant of `InstantiatedPredicates`: while | |
1282 | /// the `GenericPredicates` are expressed in terms of the bound type | |
1283 | /// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance | |
1284 | /// represented a set of bounds for some particular instantiation, | |
1285 | /// meaning that the generic parameters have been substituted with | |
1286 | /// their values. | |
1287 | /// | |
1288 | /// Example: | |
1289 | /// | |
1290 | /// struct Foo<T,U:Bar<T>> { ... } | |
1291 | /// | |
1292 | /// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like | |
1293 | /// `[[], [U:Bar<T>]]`. Now if there were some particular reference | |
1294 | /// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[], | |
1295 | /// [usize:Bar<isize>]]`. | |
1296 | #[derive(Clone)] | |
1297 | pub struct InstantiatedPredicates<'tcx> { | |
9e0c209e | 1298 | pub predicates: Vec<Predicate<'tcx>>, |
e9174d1e SL |
1299 | } |
1300 | ||
1301 | impl<'tcx> InstantiatedPredicates<'tcx> { | |
1302 | pub fn empty() -> InstantiatedPredicates<'tcx> { | |
9e0c209e | 1303 | InstantiatedPredicates { predicates: vec![] } |
e9174d1e SL |
1304 | } |
1305 | ||
1306 | pub fn is_empty(&self) -> bool { | |
1307 | self.predicates.is_empty() | |
1308 | } | |
1309 | } | |
1310 | ||
0531ce1d XL |
1311 | /// "Universes" are used during type- and trait-checking in the |
1312 | /// presence of `for<..>` binders to control what sets of names are | |
1313 | /// visible. Universes are arranged into a tree: the root universe | |
1314 | /// contains names that are always visible. But when you enter into | |
1315 | /// some subuniverse, then it may add names that are only visible | |
1316 | /// within that subtree (but it can still name the names of its | |
1317 | /// ancestor universes). | |
1318 | /// | |
1319 | /// To make this more concrete, consider this program: | |
1320 | /// | |
1321 | /// ``` | |
1322 | /// struct Foo { } | |
1323 | /// fn bar<T>(x: T) { | |
1324 | /// let y: for<'a> fn(&'a u8, Foo) = ...; | |
1325 | /// } | |
1326 | /// ``` | |
1327 | /// | |
1328 | /// The struct name `Foo` is in the root universe U0. But the type | |
1329 | /// parameter `T`, introduced on `bar`, is in a subuniverse U1 -- | |
1330 | /// i.e., within `bar`, we can name both `T` and `Foo`, but outside of | |
1331 | /// `bar`, we cannot name `T`. Then, within the type of `y`, the | |
1332 | /// region `'a` is in a subuniverse U2 of U1, because we can name it | |
1333 | /// inside the fn type but not outside. | |
1334 | /// | |
1335 | /// Universes are related to **skolemization** -- which is a way of | |
1336 | /// doing type- and trait-checking around these "forall" binders (also | |
1337 | /// called **universal quantification**). The idea is that when, in | |
1338 | /// the body of `bar`, we refer to `T` as a type, we aren't referring | |
1339 | /// to any type in particular, but rather a kind of "fresh" type that | |
1340 | /// is distinct from all other types we have actually declared. This | |
1341 | /// is called a **skolemized** type, and we use universes to talk | |
1342 | /// about this. In other words, a type name in universe 0 always | |
1343 | /// corresponds to some "ground" type that the user declared, but a | |
1344 | /// type name in a non-zero universe is a skolemized type -- an | |
1345 | /// idealized representative of "types in general" that we use for | |
1346 | /// checking generic functions. | |
1347 | #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] | |
1348 | pub struct UniverseIndex(u32); | |
1349 | ||
1350 | impl UniverseIndex { | |
1351 | /// The root universe, where things that the user defined are | |
1352 | /// visible. | |
1353 | pub fn root() -> UniverseIndex { | |
1354 | UniverseIndex(0) | |
1355 | } | |
1356 | ||
1357 | /// A "subuniverse" corresponds to being inside a `forall` quantifier. | |
1358 | /// So, for example, suppose we have this type in universe `U`: | |
1359 | /// | |
1360 | /// ``` | |
1361 | /// for<'a> fn(&'a u32) | |
1362 | /// ``` | |
1363 | /// | |
1364 | /// Once we "enter" into this `for<'a>` quantifier, we are in a | |
1365 | /// subuniverse of `U` -- in this new universe, we can name the | |
1366 | /// region `'a`, but that region was not nameable from `U` because | |
1367 | /// it was not in scope there. | |
1368 | pub fn subuniverse(self) -> UniverseIndex { | |
1369 | UniverseIndex(self.0 + 1) | |
1370 | } | |
1371 | } | |
1372 | ||
7cac9316 XL |
1373 | /// When type checking, we use the `ParamEnv` to track |
1374 | /// details about the set of where-clauses that are in scope at this | |
1375 | /// particular point. | |
1376 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | |
1377 | pub struct ParamEnv<'tcx> { | |
e9174d1e SL |
1378 | /// Obligations that the caller must satisfy. This is basically |
1379 | /// the set of bounds on the in-scope type parameters, translated | |
1380 | /// into Obligations, and elaborated and normalized. | |
7cac9316 XL |
1381 | pub caller_bounds: &'tcx Slice<ty::Predicate<'tcx>>, |
1382 | ||
1383 | /// Typically, this is `Reveal::UserFacing`, but during trans we | |
1384 | /// want `Reveal::All` -- note that this is always paired with an | |
1385 | /// empty environment. To get that, use `ParamEnv::reveal()`. | |
1386 | pub reveal: traits::Reveal, | |
1387 | } | |
1388 | ||
1389 | impl<'tcx> ParamEnv<'tcx> { | |
0531ce1d XL |
1390 | /// Construct a trait environment suitable for contexts where |
1391 | /// there are no where clauses in scope. Hidden types (like `impl | |
1392 | /// Trait`) are left hidden, so this is suitable for ordinary | |
1393 | /// type-checking. | |
1394 | pub fn empty() -> Self { | |
1395 | Self::new(ty::Slice::empty(), Reveal::UserFacing) | |
1396 | } | |
1397 | ||
1398 | /// Construct a trait environment with no where clauses in scope | |
1399 | /// where the values of all `impl Trait` and other hidden types | |
1400 | /// are revealed. This is suitable for monomorphized, post-typeck | |
1401 | /// environments like trans or doing optimizations. | |
1402 | /// | |
1403 | /// NB. If you want to have predicates in scope, use `ParamEnv::new`, | |
1404 | /// or invoke `param_env.with_reveal_all()`. | |
1405 | pub fn reveal_all() -> Self { | |
1406 | Self::new(ty::Slice::empty(), Reveal::All) | |
1407 | } | |
1408 | ||
1409 | /// Construct a trait environment with the given set of predicates. | |
1410 | pub fn new(caller_bounds: &'tcx ty::Slice<ty::Predicate<'tcx>>, | |
1411 | reveal: Reveal) | |
1412 | -> Self { | |
1413 | ty::ParamEnv { caller_bounds, reveal } | |
1414 | } | |
1415 | ||
1416 | /// Returns a new parameter environment with the same clauses, but | |
1417 | /// which "reveals" the true results of projections in all cases | |
1418 | /// (even for associated types that are specializable). This is | |
1419 | /// the desired behavior during trans and certain other special | |
1420 | /// contexts; normally though we want to use `Reveal::UserFacing`, | |
1421 | /// which is the default. | |
1422 | pub fn with_reveal_all(self) -> Self { | |
1423 | ty::ParamEnv { reveal: Reveal::All, ..self } | |
1424 | } | |
1425 | ||
1426 | /// Returns this same environment but with no caller bounds. | |
1427 | pub fn without_caller_bounds(self) -> Self { | |
1428 | ty::ParamEnv { caller_bounds: ty::Slice::empty(), ..self } | |
1429 | } | |
1430 | ||
7cac9316 | 1431 | /// Creates a suitable environment in which to perform trait |
0531ce1d XL |
1432 | /// queries on the given value. When type-checking, this is simply |
1433 | /// the pair of the environment plus value. But when reveal is set to | |
1434 | /// All, then if `value` does not reference any type parameters, we will | |
1435 | /// pair it with the empty environment. This improves caching and is generally | |
1436 | /// invisible. | |
e9174d1e | 1437 | /// |
0531ce1d XL |
1438 | /// NB: We preserve the environment when type-checking because it |
1439 | /// is possible for the user to have wacky where-clauses like | |
7cac9316 | 1440 | /// `where Box<u32>: Copy`, which are clearly never |
0531ce1d XL |
1441 | /// satisfiable. We generally want to behave as if they were true, |
1442 | /// although the surrounding function is never reachable. | |
7cac9316 | 1443 | pub fn and<T: TypeFoldable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> { |
0531ce1d XL |
1444 | match self.reveal { |
1445 | Reveal::UserFacing => { | |
1446 | ParamEnvAnd { | |
1447 | param_env: self, | |
1448 | value, | |
1449 | } | |
e9174d1e | 1450 | } |
0531ce1d XL |
1451 | |
1452 | Reveal::All => { | |
1453 | if value.needs_infer() || value.has_param_types() || value.has_self_ty() { | |
1454 | ParamEnvAnd { | |
1455 | param_env: self, | |
1456 | value, | |
1457 | } | |
1458 | } else { | |
1459 | ParamEnvAnd { | |
1460 | param_env: self.without_caller_bounds(), | |
1461 | value, | |
1462 | } | |
1463 | } | |
e9174d1e SL |
1464 | } |
1465 | } | |
1466 | } | |
1467 | } | |
1468 | ||
7cac9316 XL |
1469 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] |
1470 | pub struct ParamEnvAnd<'tcx, T> { | |
1471 | pub param_env: ParamEnv<'tcx>, | |
1472 | pub value: T, | |
1473 | } | |
1474 | ||
1475 | impl<'tcx, T> ParamEnvAnd<'tcx, T> { | |
1476 | pub fn into_parts(self) -> (ParamEnv<'tcx>, T) { | |
1477 | (self.param_env, self.value) | |
1478 | } | |
1479 | } | |
1480 | ||
0531ce1d XL |
1481 | impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>> for ParamEnvAnd<'gcx, T> |
1482 | where T: HashStable<StableHashingContext<'a>> | |
ea8adc8c XL |
1483 | { |
1484 | fn hash_stable<W: StableHasherResult>(&self, | |
0531ce1d | 1485 | hcx: &mut StableHashingContext<'a>, |
ea8adc8c XL |
1486 | hasher: &mut StableHasher<W>) { |
1487 | let ParamEnvAnd { | |
1488 | ref param_env, | |
1489 | ref value | |
1490 | } = *self; | |
1491 | ||
1492 | param_env.hash_stable(hcx, hasher); | |
1493 | value.hash_stable(hcx, hasher); | |
1494 | } | |
1495 | } | |
1496 | ||
8bb4bdeb XL |
1497 | #[derive(Copy, Clone, Debug)] |
1498 | pub struct Destructor { | |
1499 | /// The def-id of the destructor method | |
1500 | pub did: DefId, | |
8bb4bdeb XL |
1501 | } |
1502 | ||
e9174d1e | 1503 | bitflags! { |
ea8adc8c XL |
1504 | pub struct AdtFlags: u32 { |
1505 | const NO_ADT_FLAGS = 0; | |
1506 | const IS_ENUM = 1 << 0; | |
1507 | const IS_PHANTOM_DATA = 1 << 1; | |
1508 | const IS_FUNDAMENTAL = 1 << 2; | |
1509 | const IS_UNION = 1 << 3; | |
1510 | const IS_BOX = 1 << 4; | |
abe05a73 XL |
1511 | /// Indicates whether this abstract data type will be expanded on in future (new |
1512 | /// fields/variants) and as such, whether downstream crates must match exhaustively on the | |
1513 | /// fields/variants of this data type. | |
1514 | /// | |
ff7c6d11 | 1515 | /// See RFC 2008 (<https://github.com/rust-lang/rfcs/pull/2008>). |
abe05a73 | 1516 | const IS_NON_EXHAUSTIVE = 1 << 5; |
e9174d1e SL |
1517 | } |
1518 | } | |
1519 | ||
32a655c1 | 1520 | #[derive(Debug)] |
476ff2be | 1521 | pub struct VariantDef { |
b039eaaf SL |
1522 | /// The variant's DefId. If this is a tuple-like struct, |
1523 | /// this is the DefId of the struct's ctor. | |
e9174d1e SL |
1524 | pub did: DefId, |
1525 | pub name: Name, // struct's name if this is a struct | |
8bb4bdeb | 1526 | pub discr: VariantDiscr, |
476ff2be | 1527 | pub fields: Vec<FieldDef>, |
c30ab7b3 | 1528 | pub ctor_kind: CtorKind, |
e9174d1e SL |
1529 | } |
1530 | ||
8bb4bdeb XL |
1531 | #[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)] |
1532 | pub enum VariantDiscr { | |
1533 | /// Explicit value for this variant, i.e. `X = 123`. | |
1534 | /// The `DefId` corresponds to the embedded constant. | |
1535 | Explicit(DefId), | |
1536 | ||
1537 | /// The previous variant's discriminant plus one. | |
1538 | /// For efficiency reasons, the distance from the | |
1539 | /// last `Explicit` discriminant is being stored, | |
1540 | /// or `0` for the first variant, if it has none. | |
1541 | Relative(usize), | |
1542 | } | |
1543 | ||
32a655c1 | 1544 | #[derive(Debug)] |
476ff2be | 1545 | pub struct FieldDef { |
e9174d1e | 1546 | pub did: DefId, |
e9174d1e | 1547 | pub name: Name, |
54a0048b | 1548 | pub vis: Visibility, |
e9174d1e SL |
1549 | } |
1550 | ||
1551 | /// The definition of an abstract data type - a struct or enum. | |
1552 | /// | |
1553 | /// These are all interned (by intern_adt_def) into the adt_defs | |
1554 | /// table. | |
476ff2be | 1555 | pub struct AdtDef { |
e9174d1e | 1556 | pub did: DefId, |
476ff2be | 1557 | pub variants: Vec<VariantDef>, |
8bb4bdeb XL |
1558 | flags: AdtFlags, |
1559 | pub repr: ReprOptions, | |
e9174d1e SL |
1560 | } |
1561 | ||
476ff2be SL |
1562 | impl PartialEq for AdtDef { |
1563 | // AdtDef are always interned and this is part of TyS equality | |
e9174d1e SL |
1564 | #[inline] |
1565 | fn eq(&self, other: &Self) -> bool { self as *const _ == other as *const _ } | |
1566 | } | |
1567 | ||
476ff2be | 1568 | impl Eq for AdtDef {} |
e9174d1e | 1569 | |
476ff2be | 1570 | impl Hash for AdtDef { |
e9174d1e SL |
1571 | #[inline] |
1572 | fn hash<H: Hasher>(&self, s: &mut H) { | |
476ff2be | 1573 | (self as *const AdtDef).hash(s) |
e9174d1e SL |
1574 | } |
1575 | } | |
1576 | ||
476ff2be | 1577 | impl<'tcx> serialize::UseSpecializedEncodable for &'tcx AdtDef { |
9e0c209e | 1578 | fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { |
9cc50fc6 SL |
1579 | self.did.encode(s) |
1580 | } | |
1581 | } | |
1582 | ||
476ff2be | 1583 | impl<'tcx> serialize::UseSpecializedDecodable for &'tcx AdtDef {} |
e9174d1e | 1584 | |
cc61c64b | 1585 | |
0531ce1d | 1586 | impl<'a> HashStable<StableHashingContext<'a>> for AdtDef { |
cc61c64b | 1587 | fn hash_stable<W: StableHasherResult>(&self, |
0531ce1d | 1588 | hcx: &mut StableHashingContext<'a>, |
cc61c64b | 1589 | hasher: &mut StableHasher<W>) { |
2c00a5a8 XL |
1590 | thread_local! { |
1591 | static CACHE: RefCell<FxHashMap<usize, Fingerprint>> = | |
1592 | RefCell::new(FxHashMap()); | |
1593 | } | |
1594 | ||
1595 | let hash: Fingerprint = CACHE.with(|cache| { | |
1596 | let addr = self as *const AdtDef as usize; | |
1597 | *cache.borrow_mut().entry(addr).or_insert_with(|| { | |
1598 | let ty::AdtDef { | |
1599 | did, | |
1600 | ref variants, | |
1601 | ref flags, | |
1602 | ref repr, | |
1603 | } = *self; | |
cc61c64b | 1604 | |
2c00a5a8 XL |
1605 | let mut hasher = StableHasher::new(); |
1606 | did.hash_stable(hcx, &mut hasher); | |
1607 | variants.hash_stable(hcx, &mut hasher); | |
1608 | flags.hash_stable(hcx, &mut hasher); | |
1609 | repr.hash_stable(hcx, &mut hasher); | |
1610 | ||
1611 | hasher.finish() | |
1612 | }) | |
1613 | }); | |
1614 | ||
1615 | hash.hash_stable(hcx, hasher); | |
cc61c64b XL |
1616 | } |
1617 | } | |
1618 | ||
0531ce1d | 1619 | #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] |
9e0c209e | 1620 | pub enum AdtKind { Struct, Union, Enum } |
e9174d1e | 1621 | |
cc61c64b XL |
1622 | bitflags! { |
1623 | #[derive(RustcEncodable, RustcDecodable, Default)] | |
ea8adc8c XL |
1624 | pub struct ReprFlags: u8 { |
1625 | const IS_C = 1 << 0; | |
1626 | const IS_PACKED = 1 << 1; | |
1627 | const IS_SIMD = 1 << 2; | |
2c00a5a8 | 1628 | const IS_TRANSPARENT = 1 << 3; |
cc61c64b | 1629 | // Internal only for now. If true, don't reorder fields. |
2c00a5a8 | 1630 | const IS_LINEAR = 1 << 4; |
cc61c64b XL |
1631 | |
1632 | // Any of these flags being set prevent field reordering optimisation. | |
1633 | const IS_UNOPTIMISABLE = ReprFlags::IS_C.bits | | |
1634 | ReprFlags::IS_PACKED.bits | | |
1635 | ReprFlags::IS_SIMD.bits | | |
ea8adc8c | 1636 | ReprFlags::IS_LINEAR.bits; |
cc61c64b XL |
1637 | } |
1638 | } | |
1639 | ||
1640 | impl_stable_hash_for!(struct ReprFlags { | |
1641 | bits | |
1642 | }); | |
1643 | ||
1644 | ||
1645 | ||
8bb4bdeb XL |
1646 | /// Represents the repr options provided by the user, |
1647 | #[derive(Copy, Clone, Eq, PartialEq, RustcEncodable, RustcDecodable, Default)] | |
1648 | pub struct ReprOptions { | |
8bb4bdeb | 1649 | pub int: Option<attr::IntType>, |
041b39d2 | 1650 | pub align: u32, |
cc61c64b | 1651 | pub flags: ReprFlags, |
8bb4bdeb XL |
1652 | } |
1653 | ||
cc61c64b XL |
1654 | impl_stable_hash_for!(struct ReprOptions { |
1655 | align, | |
1656 | int, | |
1657 | flags | |
1658 | }); | |
1659 | ||
8bb4bdeb XL |
1660 | impl ReprOptions { |
1661 | pub fn new(tcx: TyCtxt, did: DefId) -> ReprOptions { | |
cc61c64b XL |
1662 | let mut flags = ReprFlags::empty(); |
1663 | let mut size = None; | |
1664 | let mut max_align = 0; | |
8bb4bdeb XL |
1665 | for attr in tcx.get_attrs(did).iter() { |
1666 | for r in attr::find_repr_attrs(tcx.sess.diagnostic(), attr) { | |
cc61c64b | 1667 | flags.insert(match r { |
2c00a5a8 | 1668 | attr::ReprC => ReprFlags::IS_C, |
cc61c64b | 1669 | attr::ReprPacked => ReprFlags::IS_PACKED, |
2c00a5a8 | 1670 | attr::ReprTransparent => ReprFlags::IS_TRANSPARENT, |
cc61c64b XL |
1671 | attr::ReprSimd => ReprFlags::IS_SIMD, |
1672 | attr::ReprInt(i) => { | |
1673 | size = Some(i); | |
1674 | ReprFlags::empty() | |
1675 | }, | |
1676 | attr::ReprAlign(align) => { | |
1677 | max_align = cmp::max(align, max_align); | |
1678 | ReprFlags::empty() | |
1679 | }, | |
1680 | }); | |
8bb4bdeb XL |
1681 | } |
1682 | } | |
1683 | ||
cc61c64b XL |
1684 | // This is here instead of layout because the choice must make it into metadata. |
1685 | if !tcx.consider_optimizing(|| format!("Reorder fields of {:?}", tcx.item_path_str(did))) { | |
1686 | flags.insert(ReprFlags::IS_LINEAR); | |
1687 | } | |
1688 | ReprOptions { int: size, align: max_align, flags: flags } | |
8bb4bdeb XL |
1689 | } |
1690 | ||
cc61c64b XL |
1691 | #[inline] |
1692 | pub fn simd(&self) -> bool { self.flags.contains(ReprFlags::IS_SIMD) } | |
1693 | #[inline] | |
1694 | pub fn c(&self) -> bool { self.flags.contains(ReprFlags::IS_C) } | |
1695 | #[inline] | |
1696 | pub fn packed(&self) -> bool { self.flags.contains(ReprFlags::IS_PACKED) } | |
1697 | #[inline] | |
2c00a5a8 XL |
1698 | pub fn transparent(&self) -> bool { self.flags.contains(ReprFlags::IS_TRANSPARENT) } |
1699 | #[inline] | |
cc61c64b XL |
1700 | pub fn linear(&self) -> bool { self.flags.contains(ReprFlags::IS_LINEAR) } |
1701 | ||
8bb4bdeb | 1702 | pub fn discr_type(&self) -> attr::IntType { |
2c00a5a8 | 1703 | self.int.unwrap_or(attr::SignedInt(ast::IntTy::Isize)) |
8bb4bdeb XL |
1704 | } |
1705 | ||
1706 | /// Returns true if this `#[repr()]` should inhabit "smart enum | |
1707 | /// layout" optimizations, such as representing `Foo<&T>` as a | |
1708 | /// single pointer. | |
1709 | pub fn inhibit_enum_layout_opt(&self) -> bool { | |
cc61c64b | 1710 | self.c() || self.int.is_some() |
8bb4bdeb XL |
1711 | } |
1712 | } | |
1713 | ||
476ff2be | 1714 | impl<'a, 'gcx, 'tcx> AdtDef { |
8bb4bdeb | 1715 | fn new(tcx: TyCtxt, |
e9174d1e SL |
1716 | did: DefId, |
1717 | kind: AdtKind, | |
8bb4bdeb XL |
1718 | variants: Vec<VariantDef>, |
1719 | repr: ReprOptions) -> Self { | |
e9174d1e SL |
1720 | let mut flags = AdtFlags::NO_ADT_FLAGS; |
1721 | let attrs = tcx.get_attrs(did); | |
1722 | if attr::contains_name(&attrs, "fundamental") { | |
1723 | flags = flags | AdtFlags::IS_FUNDAMENTAL; | |
1724 | } | |
ea8adc8c | 1725 | if Some(did) == tcx.lang_items().phantom_data() { |
e9174d1e SL |
1726 | flags = flags | AdtFlags::IS_PHANTOM_DATA; |
1727 | } | |
ea8adc8c | 1728 | if Some(did) == tcx.lang_items().owned_box() { |
32a655c1 SL |
1729 | flags = flags | AdtFlags::IS_BOX; |
1730 | } | |
abe05a73 XL |
1731 | if tcx.has_attr(did, "non_exhaustive") { |
1732 | flags = flags | AdtFlags::IS_NON_EXHAUSTIVE; | |
1733 | } | |
9e0c209e SL |
1734 | match kind { |
1735 | AdtKind::Enum => flags = flags | AdtFlags::IS_ENUM, | |
1736 | AdtKind::Union => flags = flags | AdtFlags::IS_UNION, | |
1737 | AdtKind::Struct => {} | |
e9174d1e | 1738 | } |
476ff2be | 1739 | AdtDef { |
041b39d2 XL |
1740 | did, |
1741 | variants, | |
1742 | flags, | |
1743 | repr, | |
e9174d1e SL |
1744 | } |
1745 | } | |
1746 | ||
9e0c209e SL |
1747 | #[inline] |
1748 | pub fn is_struct(&self) -> bool { | |
1749 | !self.is_union() && !self.is_enum() | |
1750 | } | |
1751 | ||
1752 | #[inline] | |
1753 | pub fn is_union(&self) -> bool { | |
8bb4bdeb | 1754 | self.flags.intersects(AdtFlags::IS_UNION) |
9e0c209e SL |
1755 | } |
1756 | ||
1757 | #[inline] | |
1758 | pub fn is_enum(&self) -> bool { | |
8bb4bdeb | 1759 | self.flags.intersects(AdtFlags::IS_ENUM) |
9e0c209e SL |
1760 | } |
1761 | ||
abe05a73 XL |
1762 | #[inline] |
1763 | pub fn is_non_exhaustive(&self) -> bool { | |
1764 | self.flags.intersects(AdtFlags::IS_NON_EXHAUSTIVE) | |
1765 | } | |
1766 | ||
e9174d1e SL |
1767 | /// Returns the kind of the ADT - Struct or Enum. |
1768 | #[inline] | |
1769 | pub fn adt_kind(&self) -> AdtKind { | |
9e0c209e | 1770 | if self.is_enum() { |
e9174d1e | 1771 | AdtKind::Enum |
9e0c209e SL |
1772 | } else if self.is_union() { |
1773 | AdtKind::Union | |
e9174d1e SL |
1774 | } else { |
1775 | AdtKind::Struct | |
1776 | } | |
1777 | } | |
1778 | ||
9e0c209e SL |
1779 | pub fn descr(&self) -> &'static str { |
1780 | match self.adt_kind() { | |
1781 | AdtKind::Struct => "struct", | |
1782 | AdtKind::Union => "union", | |
1783 | AdtKind::Enum => "enum", | |
1784 | } | |
1785 | } | |
1786 | ||
1787 | pub fn variant_descr(&self) -> &'static str { | |
1788 | match self.adt_kind() { | |
1789 | AdtKind::Struct => "struct", | |
1790 | AdtKind::Union => "union", | |
1791 | AdtKind::Enum => "variant", | |
1792 | } | |
1793 | } | |
1794 | ||
e9174d1e SL |
1795 | /// Returns whether this type is #[fundamental] for the purposes |
1796 | /// of coherence checking. | |
1797 | #[inline] | |
1798 | pub fn is_fundamental(&self) -> bool { | |
8bb4bdeb | 1799 | self.flags.intersects(AdtFlags::IS_FUNDAMENTAL) |
e9174d1e SL |
1800 | } |
1801 | ||
1802 | /// Returns true if this is PhantomData<T>. | |
1803 | #[inline] | |
1804 | pub fn is_phantom_data(&self) -> bool { | |
8bb4bdeb | 1805 | self.flags.intersects(AdtFlags::IS_PHANTOM_DATA) |
e9174d1e SL |
1806 | } |
1807 | ||
32a655c1 SL |
1808 | /// Returns true if this is Box<T>. |
1809 | #[inline] | |
1810 | pub fn is_box(&self) -> bool { | |
8bb4bdeb | 1811 | self.flags.intersects(AdtFlags::IS_BOX) |
32a655c1 SL |
1812 | } |
1813 | ||
e9174d1e | 1814 | /// Returns whether this type has a destructor. |
8bb4bdeb XL |
1815 | pub fn has_dtor(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool { |
1816 | self.destructor(tcx).is_some() | |
e9174d1e SL |
1817 | } |
1818 | ||
2c00a5a8 XL |
1819 | /// Asserts this is a struct or union and returns its unique variant. |
1820 | pub fn non_enum_variant(&self) -> &VariantDef { | |
1821 | assert!(self.is_struct() || self.is_union()); | |
e9174d1e SL |
1822 | &self.variants[0] |
1823 | } | |
1824 | ||
e9174d1e | 1825 | #[inline] |
a7813a04 | 1826 | pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> GenericPredicates<'gcx> { |
7cac9316 | 1827 | tcx.predicates_of(self.did) |
e9174d1e SL |
1828 | } |
1829 | ||
1830 | /// Returns an iterator over all fields contained | |
1831 | /// by this ADT. | |
1832 | #[inline] | |
476ff2be SL |
1833 | pub fn all_fields<'s>(&'s self) -> impl Iterator<Item = &'s FieldDef> { |
1834 | self.variants.iter().flat_map(|v| v.fields.iter()) | |
e9174d1e SL |
1835 | } |
1836 | ||
e9174d1e SL |
1837 | pub fn is_payloadfree(&self) -> bool { |
1838 | !self.variants.is_empty() && | |
1839 | self.variants.iter().all(|v| v.fields.is_empty()) | |
1840 | } | |
1841 | ||
476ff2be | 1842 | pub fn variant_with_id(&self, vid: DefId) -> &VariantDef { |
e9174d1e SL |
1843 | self.variants |
1844 | .iter() | |
1845 | .find(|v| v.did == vid) | |
1846 | .expect("variant_with_id: unknown variant") | |
1847 | } | |
1848 | ||
1849 | pub fn variant_index_with_id(&self, vid: DefId) -> usize { | |
1850 | self.variants | |
1851 | .iter() | |
1852 | .position(|v| v.did == vid) | |
1853 | .expect("variant_index_with_id: unknown variant") | |
1854 | } | |
1855 | ||
476ff2be | 1856 | pub fn variant_of_def(&self, def: Def) -> &VariantDef { |
e9174d1e | 1857 | match def { |
c30ab7b3 SL |
1858 | Def::Variant(vid) | Def::VariantCtor(vid, ..) => self.variant_with_id(vid), |
1859 | Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) | | |
2c00a5a8 | 1860 | Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => self.non_enum_variant(), |
54a0048b | 1861 | _ => bug!("unexpected def {:?} in variant_of_def", def) |
e9174d1e SL |
1862 | } |
1863 | } | |
1864 | ||
cc61c64b | 1865 | #[inline] |
0531ce1d XL |
1866 | pub fn eval_explicit_discr( |
1867 | &self, | |
1868 | tcx: TyCtxt<'a, 'gcx, 'tcx>, | |
1869 | expr_did: DefId, | |
1870 | ) -> Option<Discr<'tcx>> { | |
1871 | let param_env = ParamEnv::empty(); | |
1872 | let repr_type = self.repr.discr_type(); | |
1873 | let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did); | |
1874 | let instance = ty::Instance::new(expr_did, substs); | |
1875 | let cid = GlobalId { | |
1876 | instance, | |
1877 | promoted: None | |
1878 | }; | |
1879 | match tcx.const_eval(param_env.and(cid)) { | |
1880 | Ok(&ty::Const { | |
1881 | val: ConstVal::Value(Value::ByVal(PrimVal::Bytes(b))), | |
1882 | ty, | |
1883 | }) => { | |
1884 | trace!("discriminants: {} ({:?})", b, repr_type); | |
1885 | Some(Discr { | |
1886 | val: b, | |
1887 | ty, | |
1888 | }) | |
1889 | }, | |
1890 | Ok(&ty::Const { | |
1891 | val: ConstVal::Value(other), | |
1892 | .. | |
1893 | }) => { | |
1894 | info!("invalid enum discriminant: {:#?}", other); | |
1895 | ::middle::const_val::struct_error( | |
1896 | tcx, | |
1897 | tcx.def_span(expr_did), | |
1898 | "constant evaluation of enum discriminant resulted in non-integer", | |
1899 | ).emit(); | |
1900 | None | |
1901 | } | |
1902 | Err(err) => { | |
1903 | err.report(tcx, tcx.def_span(expr_did), "enum discriminant"); | |
1904 | if !expr_did.is_local() { | |
1905 | span_bug!(tcx.def_span(expr_did), | |
1906 | "variant discriminant evaluation succeeded \ | |
1907 | in its crate but failed locally"); | |
1908 | } | |
1909 | None | |
1910 | } | |
1911 | _ => span_bug!(tcx.def_span(expr_did), "const eval "), | |
1912 | } | |
1913 | } | |
1914 | ||
1915 | #[inline] | |
1916 | pub fn discriminants( | |
1917 | &'a self, | |
1918 | tcx: TyCtxt<'a, 'gcx, 'tcx>, | |
1919 | ) -> impl Iterator<Item=Discr<'tcx>> + Captures<'gcx> + 'a { | |
8bb4bdeb XL |
1920 | let repr_type = self.repr.discr_type(); |
1921 | let initial = repr_type.initial_discriminant(tcx.global_tcx()); | |
0531ce1d | 1922 | let mut prev_discr = None::<Discr<'tcx>>; |
8bb4bdeb | 1923 | self.variants.iter().map(move |v| { |
0531ce1d | 1924 | let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx)); |
8bb4bdeb | 1925 | if let VariantDiscr::Explicit(expr_did) = v.discr { |
0531ce1d XL |
1926 | if let Some(new_discr) = self.eval_explicit_discr(tcx, expr_did) { |
1927 | discr = new_discr; | |
8bb4bdeb XL |
1928 | } |
1929 | } | |
1930 | prev_discr = Some(discr); | |
1931 | ||
1932 | discr | |
1933 | }) | |
e9174d1e SL |
1934 | } |
1935 | ||
cc61c64b XL |
1936 | /// Compute the discriminant value used by a specific variant. |
1937 | /// Unlike `discriminants`, this is (amortized) constant-time, | |
1938 | /// only doing at most one query for evaluating an explicit | |
1939 | /// discriminant (the last one before the requested variant), | |
1940 | /// assuming there are no constant-evaluation errors there. | |
1941 | pub fn discriminant_for_variant(&self, | |
1942 | tcx: TyCtxt<'a, 'gcx, 'tcx>, | |
1943 | variant_index: usize) | |
0531ce1d XL |
1944 | -> Discr<'tcx> { |
1945 | let (val, offset) = self.discriminant_def_for_variant(variant_index); | |
1946 | let explicit_value = val | |
1947 | .and_then(|expr_did| self.eval_explicit_discr(tcx, expr_did)) | |
1948 | .unwrap_or_else(|| self.repr.discr_type().initial_discriminant(tcx.global_tcx())); | |
1949 | explicit_value.checked_add(tcx, offset as u128).0 | |
1950 | } | |
1951 | ||
1952 | /// Yields a DefId for the discriminant and an offset to add to it | |
1953 | /// Alternatively, if there is no explicit discriminant, returns the | |
1954 | /// inferred discriminant directly | |
1955 | pub fn discriminant_def_for_variant( | |
1956 | &self, | |
1957 | variant_index: usize, | |
1958 | ) -> (Option<DefId>, usize) { | |
cc61c64b | 1959 | let mut explicit_index = variant_index; |
0531ce1d | 1960 | let expr_did; |
cc61c64b XL |
1961 | loop { |
1962 | match self.variants[explicit_index].discr { | |
0531ce1d XL |
1963 | ty::VariantDiscr::Relative(0) => { |
1964 | expr_did = None; | |
1965 | break; | |
1966 | }, | |
cc61c64b XL |
1967 | ty::VariantDiscr::Relative(distance) => { |
1968 | explicit_index -= distance; | |
1969 | } | |
0531ce1d XL |
1970 | ty::VariantDiscr::Explicit(did) => { |
1971 | expr_did = Some(did); | |
1972 | break; | |
cc61c64b XL |
1973 | } |
1974 | } | |
1975 | } | |
0531ce1d | 1976 | (expr_did, variant_index - explicit_index) |
cc61c64b XL |
1977 | } |
1978 | ||
8bb4bdeb | 1979 | pub fn destructor(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Destructor> { |
7cac9316 | 1980 | tcx.adt_destructor(self.did) |
e9174d1e SL |
1981 | } |
1982 | ||
cc61c64b | 1983 | /// Returns a list of types such that `Self: Sized` if and only |
a7813a04 XL |
1984 | /// if that type is Sized, or `TyErr` if this type is recursive. |
1985 | /// | |
a7813a04 XL |
1986 | /// Oddly enough, checking that the sized-constraint is Sized is |
1987 | /// actually more expressive than checking all members: | |
1988 | /// the Sized trait is inductive, so an associated type that references | |
1989 | /// Self would prevent its containing ADT from being Sized. | |
1990 | /// | |
1991 | /// Due to normalization being eager, this applies even if | |
1992 | /// the associated type is behind a pointer, e.g. issue #31299. | |
cc61c64b XL |
1993 | pub fn sized_constraint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx [Ty<'tcx>] { |
1994 | match queries::adt_sized_constraint::try_get(tcx, DUMMY_SP, self.did) { | |
1995 | Ok(tys) => tys, | |
3b2f2976 | 1996 | Err(mut bug) => { |
cc61c64b XL |
1997 | debug!("adt_sized_constraint: {:?} is recursive", self); |
1998 | // This should be reported as an error by `check_representable`. | |
1999 | // | |
2000 | // Consider the type as Sized in the meanwhile to avoid | |
3b2f2976 XL |
2001 | // further errors. Delay our `bug` diagnostic here to get |
2002 | // emitted later as well in case we accidentally otherwise don't | |
2003 | // emit an error. | |
2004 | bug.delay_as_bug(); | |
cc61c64b | 2005 | tcx.intern_type_list(&[tcx.types.err]) |
a7813a04 XL |
2006 | } |
2007 | } | |
2008 | } | |
2009 | ||
476ff2be SL |
2010 | fn sized_constraint_for_ty(&self, |
2011 | tcx: TyCtxt<'a, 'tcx, 'tcx>, | |
476ff2be SL |
2012 | ty: Ty<'tcx>) |
2013 | -> Vec<Ty<'tcx>> { | |
a7813a04 XL |
2014 | let result = match ty.sty { |
2015 | TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | | |
32a655c1 | 2016 | TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) | |
ea8adc8c | 2017 | TyArray(..) | TyClosure(..) | TyGenerator(..) | TyNever => { |
a7813a04 XL |
2018 | vec![] |
2019 | } | |
2020 | ||
2c00a5a8 XL |
2021 | TyStr | |
2022 | TyDynamic(..) | | |
2023 | TySlice(_) | | |
2024 | TyForeign(..) | | |
2025 | TyError | | |
2026 | TyGeneratorWitness(..) => { | |
a7813a04 XL |
2027 | // these are never sized - return the target type |
2028 | vec![ty] | |
2029 | } | |
2030 | ||
0531ce1d | 2031 | TyTuple(ref tys) => { |
9e0c209e SL |
2032 | match tys.last() { |
2033 | None => vec![], | |
cc61c64b | 2034 | Some(ty) => self.sized_constraint_for_ty(tcx, ty) |
9e0c209e | 2035 | } |
a7813a04 XL |
2036 | } |
2037 | ||
9e0c209e | 2038 | TyAdt(adt, substs) => { |
a7813a04 | 2039 | // recursive case |
cc61c64b | 2040 | let adt_tys = adt.sized_constraint(tcx); |
a7813a04 | 2041 | debug!("sized_constraint_for_ty({:?}) intermediate = {:?}", |
cc61c64b XL |
2042 | ty, adt_tys); |
2043 | adt_tys.iter() | |
2044 | .map(|ty| ty.subst(tcx, substs)) | |
2045 | .flat_map(|ty| self.sized_constraint_for_ty(tcx, ty)) | |
2046 | .collect() | |
a7813a04 XL |
2047 | } |
2048 | ||
5bcae85e | 2049 | TyProjection(..) | TyAnon(..) => { |
a7813a04 XL |
2050 | // must calculate explicitly. |
2051 | // FIXME: consider special-casing always-Sized projections | |
2052 | vec![ty] | |
2053 | } | |
2054 | ||
2055 | TyParam(..) => { | |
2056 | // perf hack: if there is a `T: Sized` bound, then | |
2057 | // we know that `T` is Sized and do not need to check | |
2058 | // it on the impl. | |
2059 | ||
ea8adc8c | 2060 | let sized_trait = match tcx.lang_items().sized_trait() { |
a7813a04 XL |
2061 | Some(x) => x, |
2062 | _ => return vec![ty] | |
2063 | }; | |
2064 | let sized_predicate = Binder(TraitRef { | |
2065 | def_id: sized_trait, | |
c30ab7b3 | 2066 | substs: tcx.mk_substs_trait(ty, &[]) |
a7813a04 | 2067 | }).to_predicate(); |
7cac9316 | 2068 | let predicates = tcx.predicates_of(self.did).predicates; |
a7813a04 XL |
2069 | if predicates.into_iter().any(|p| p == sized_predicate) { |
2070 | vec![] | |
2071 | } else { | |
2072 | vec![ty] | |
2073 | } | |
2074 | } | |
2075 | ||
2076 | TyInfer(..) => { | |
2077 | bug!("unexpected type `{:?}` in sized_constraint_for_ty", | |
2078 | ty) | |
2079 | } | |
2080 | }; | |
2081 | debug!("sized_constraint_for_ty({:?}) = {:?}", ty, result); | |
2082 | result | |
2083 | } | |
2084 | } | |
2085 | ||
476ff2be | 2086 | impl<'a, 'gcx, 'tcx> VariantDef { |
e9174d1e | 2087 | #[inline] |
7cac9316 XL |
2088 | pub fn find_field_named(&self, name: ast::Name) -> Option<&FieldDef> { |
2089 | self.index_of_field_named(name).map(|index| &self.fields[index]) | |
e9174d1e SL |
2090 | } |
2091 | ||
7cac9316 XL |
2092 | pub fn index_of_field_named(&self, name: ast::Name) -> Option<usize> { |
2093 | if let Some(index) = self.fields.iter().position(|f| f.name == name) { | |
2094 | return Some(index); | |
2095 | } | |
2096 | let mut ident = name.to_ident(); | |
2097 | while ident.ctxt != SyntaxContext::empty() { | |
2098 | ident.ctxt.remove_mark(); | |
2099 | if let Some(field) = self.fields.iter().position(|f| f.name.to_ident() == ident) { | |
2100 | return Some(field); | |
2101 | } | |
2102 | } | |
2103 | None | |
92a42be0 SL |
2104 | } |
2105 | ||
e9174d1e | 2106 | #[inline] |
476ff2be | 2107 | pub fn field_named(&self, name: ast::Name) -> &FieldDef { |
e9174d1e SL |
2108 | self.find_field_named(name).unwrap() |
2109 | } | |
476ff2be | 2110 | } |
e9174d1e | 2111 | |
476ff2be | 2112 | impl<'a, 'gcx, 'tcx> FieldDef { |
a7813a04 | 2113 | pub fn ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, subst: &Substs<'tcx>) -> Ty<'tcx> { |
7cac9316 | 2114 | tcx.type_of(self.did).subst(tcx, subst) |
e9174d1e | 2115 | } |
e9174d1e SL |
2116 | } |
2117 | ||
ff7c6d11 XL |
2118 | /// Represents the various closure traits in the Rust language. This |
2119 | /// will determine the type of the environment (`self`, in the | |
2120 | /// desuaring) argument that the closure expects. | |
2121 | /// | |
2122 | /// You can get the environment type of a closure using | |
2123 | /// `tcx.closure_env_ty()`. | |
a7813a04 | 2124 | #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] |
e9174d1e SL |
2125 | pub enum ClosureKind { |
2126 | // Warning: Ordering is significant here! The ordering is chosen | |
2127 | // because the trait Fn is a subtrait of FnMut and so in turn, and | |
2128 | // hence we order it so that Fn < FnMut < FnOnce. | |
54a0048b SL |
2129 | Fn, |
2130 | FnMut, | |
2131 | FnOnce, | |
e9174d1e SL |
2132 | } |
2133 | ||
a7813a04 | 2134 | impl<'a, 'tcx> ClosureKind { |
ff7c6d11 XL |
2135 | // This is the initial value used when doing upvar inference. |
2136 | pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn; | |
2137 | ||
a7813a04 | 2138 | pub fn trait_did(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> DefId { |
476ff2be SL |
2139 | match *self { |
2140 | ClosureKind::Fn => tcx.require_lang_item(FnTraitLangItem), | |
54a0048b | 2141 | ClosureKind::FnMut => { |
476ff2be | 2142 | tcx.require_lang_item(FnMutTraitLangItem) |
e9174d1e | 2143 | } |
54a0048b | 2144 | ClosureKind::FnOnce => { |
476ff2be | 2145 | tcx.require_lang_item(FnOnceTraitLangItem) |
e9174d1e | 2146 | } |
e9174d1e SL |
2147 | } |
2148 | } | |
2149 | ||
2150 | /// True if this a type that impls this closure kind | |
2151 | /// must also implement `other`. | |
2152 | pub fn extends(self, other: ty::ClosureKind) -> bool { | |
2153 | match (self, other) { | |
54a0048b SL |
2154 | (ClosureKind::Fn, ClosureKind::Fn) => true, |
2155 | (ClosureKind::Fn, ClosureKind::FnMut) => true, | |
2156 | (ClosureKind::Fn, ClosureKind::FnOnce) => true, | |
2157 | (ClosureKind::FnMut, ClosureKind::FnMut) => true, | |
2158 | (ClosureKind::FnMut, ClosureKind::FnOnce) => true, | |
2159 | (ClosureKind::FnOnce, ClosureKind::FnOnce) => true, | |
e9174d1e SL |
2160 | _ => false, |
2161 | } | |
2162 | } | |
ff7c6d11 XL |
2163 | |
2164 | /// Returns the representative scalar type for this closure kind. | |
2165 | /// See `TyS::to_opt_closure_kind` for more details. | |
2166 | pub fn to_ty(self, tcx: TyCtxt<'_, '_, 'tcx>) -> Ty<'tcx> { | |
2167 | match self { | |
2168 | ty::ClosureKind::Fn => tcx.types.i8, | |
2169 | ty::ClosureKind::FnMut => tcx.types.i16, | |
2170 | ty::ClosureKind::FnOnce => tcx.types.i32, | |
2171 | } | |
2172 | } | |
e9174d1e SL |
2173 | } |
2174 | ||
2175 | impl<'tcx> TyS<'tcx> { | |
2176 | /// Iterator that walks `self` and any types reachable from | |
2177 | /// `self`, in depth-first order. Note that just walks the types | |
2178 | /// that appear in `self`, it does not descend into the fields of | |
2179 | /// structs or variants. For example: | |
2180 | /// | |
2181 | /// ```notrust | |
2182 | /// isize => { isize } | |
2183 | /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize } | |
2184 | /// [isize] => { [isize], isize } | |
2185 | /// ``` | |
2186 | pub fn walk(&'tcx self) -> TypeWalker<'tcx> { | |
2187 | TypeWalker::new(self) | |
2188 | } | |
2189 | ||
2190 | /// Iterator that walks the immediate children of `self`. Hence | |
2191 | /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]` | |
2192 | /// (but not `i32`, like `walk`). | |
476ff2be | 2193 | pub fn walk_shallow(&'tcx self) -> AccIntoIter<walk::TypeWalkerArray<'tcx>> { |
e9174d1e SL |
2194 | walk::walk_shallow(self) |
2195 | } | |
2196 | ||
2197 | /// Walks `ty` and any types appearing within `ty`, invoking the | |
2198 | /// callback `f` on each type. If the callback returns false, then the | |
2199 | /// children of the current type are ignored. | |
2200 | /// | |
2201 | /// Note: prefer `ty.walk()` where possible. | |
2202 | pub fn maybe_walk<F>(&'tcx self, mut f: F) | |
2203 | where F : FnMut(Ty<'tcx>) -> bool | |
2204 | { | |
2205 | let mut walker = self.walk(); | |
2206 | while let Some(ty) = walker.next() { | |
2207 | if !f(ty) { | |
2208 | walker.skip_current_subtree(); | |
2209 | } | |
2210 | } | |
2211 | } | |
2212 | } | |
2213 | ||
e9174d1e SL |
2214 | impl BorrowKind { |
2215 | pub fn from_mutbl(m: hir::Mutability) -> BorrowKind { | |
2216 | match m { | |
2217 | hir::MutMutable => MutBorrow, | |
2218 | hir::MutImmutable => ImmBorrow, | |
2219 | } | |
2220 | } | |
2221 | ||
2222 | /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow | |
2223 | /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a | |
2224 | /// mutability that is stronger than necessary so that it at least *would permit* the borrow in | |
2225 | /// question. | |
2226 | pub fn to_mutbl_lossy(self) -> hir::Mutability { | |
2227 | match self { | |
2228 | MutBorrow => hir::MutMutable, | |
2229 | ImmBorrow => hir::MutImmutable, | |
2230 | ||
2231 | // We have no type corresponding to a unique imm borrow, so | |
2232 | // use `&mut`. It gives all the capabilities of an `&uniq` | |
2233 | // and hence is a safe "over approximation". | |
2234 | UniqueImmBorrow => hir::MutMutable, | |
2235 | } | |
2236 | } | |
2237 | ||
2238 | pub fn to_user_str(&self) -> &'static str { | |
2239 | match *self { | |
2240 | MutBorrow => "mutable", | |
2241 | ImmBorrow => "immutable", | |
2242 | UniqueImmBorrow => "uniquely immutable", | |
2243 | } | |
2244 | } | |
2245 | } | |
2246 | ||
cc61c64b XL |
2247 | #[derive(Debug, Clone)] |
2248 | pub enum Attributes<'gcx> { | |
0531ce1d | 2249 | Owned(Lrc<[ast::Attribute]>), |
cc61c64b XL |
2250 | Borrowed(&'gcx [ast::Attribute]) |
2251 | } | |
2252 | ||
2253 | impl<'gcx> ::std::ops::Deref for Attributes<'gcx> { | |
2254 | type Target = [ast::Attribute]; | |
2255 | ||
2256 | fn deref(&self) -> &[ast::Attribute] { | |
2257 | match self { | |
2258 | &Attributes::Owned(ref data) => &data, | |
2259 | &Attributes::Borrowed(data) => data | |
2260 | } | |
2261 | } | |
2262 | } | |
2263 | ||
a7813a04 | 2264 | impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { |
32a655c1 | 2265 | pub fn body_tables(self, body: hir::BodyId) -> &'gcx TypeckTables<'gcx> { |
7cac9316 | 2266 | self.typeck_tables_of(self.hir.body_owner_def_id(body)) |
32a655c1 SL |
2267 | } |
2268 | ||
7cac9316 XL |
2269 | /// Returns an iterator of the def-ids for all body-owners in this |
2270 | /// crate. If you would prefer to iterate over the bodies | |
2271 | /// themselves, you can do `self.hir.krate().body_ids.iter()`. | |
0531ce1d XL |
2272 | pub fn body_owners( |
2273 | self, | |
2274 | ) -> impl Iterator<Item = DefId> + Captures<'tcx> + Captures<'gcx> + 'a { | |
7cac9316 XL |
2275 | self.hir.krate() |
2276 | .body_ids | |
2277 | .iter() | |
2278 | .map(move |&body_id| self.hir.body_owner_def_id(body_id)) | |
7453a54e SL |
2279 | } |
2280 | ||
a7813a04 | 2281 | pub fn expr_span(self, id: NodeId) -> Span { |
32a655c1 SL |
2282 | match self.hir.find(id) { |
2283 | Some(hir_map::NodeExpr(e)) => { | |
e9174d1e SL |
2284 | e.span |
2285 | } | |
2286 | Some(f) => { | |
54a0048b | 2287 | bug!("Node id {} is not an expr: {:?}", id, f); |
e9174d1e SL |
2288 | } |
2289 | None => { | |
54a0048b | 2290 | bug!("Node id {} is not present in the node map", id); |
e9174d1e SL |
2291 | } |
2292 | } | |
2293 | } | |
2294 | ||
476ff2be SL |
2295 | pub fn provided_trait_methods(self, id: DefId) -> Vec<AssociatedItem> { |
2296 | self.associated_items(id) | |
2297 | .filter(|item| item.kind == AssociatedKind::Method && item.defaultness.has_value()) | |
2298 | .collect() | |
e9174d1e SL |
2299 | } |
2300 | ||
8bb4bdeb XL |
2301 | pub fn trait_relevant_for_never(self, did: DefId) -> bool { |
2302 | self.associated_items(did).any(|item| { | |
2303 | item.relevant_for_never() | |
e9174d1e SL |
2304 | }) |
2305 | } | |
2306 | ||
7cac9316 XL |
2307 | pub fn opt_associated_item(self, def_id: DefId) -> Option<AssociatedItem> { |
2308 | let is_associated_item = if let Some(node_id) = self.hir.as_local_node_id(def_id) { | |
2309 | match self.hir.get(node_id) { | |
2310 | hir_map::NodeTraitItem(_) | hir_map::NodeImplItem(_) => true, | |
2311 | _ => false, | |
2312 | } | |
2313 | } else { | |
2314 | match self.describe_def(def_id).expect("no def for def-id") { | |
2315 | Def::AssociatedConst(_) | Def::Method(_) | Def::AssociatedTy(_) => true, | |
2316 | _ => false, | |
2317 | } | |
2318 | }; | |
8bb4bdeb | 2319 | |
7cac9316 XL |
2320 | if is_associated_item { |
2321 | Some(self.associated_item(def_id)) | |
2322 | } else { | |
2323 | None | |
2324 | } | |
e9174d1e SL |
2325 | } |
2326 | ||
476ff2be SL |
2327 | fn associated_item_from_trait_item_ref(self, |
2328 | parent_def_id: DefId, | |
7cac9316 | 2329 | parent_vis: &hir::Visibility, |
32a655c1 | 2330 | trait_item_ref: &hir::TraitItemRef) |
476ff2be | 2331 | -> AssociatedItem { |
32a655c1 SL |
2332 | let def_id = self.hir.local_def_id(trait_item_ref.id.node_id); |
2333 | let (kind, has_self) = match trait_item_ref.kind { | |
2334 | hir::AssociatedItemKind::Const => (ty::AssociatedKind::Const, false), | |
2335 | hir::AssociatedItemKind::Method { has_self } => { | |
2336 | (ty::AssociatedKind::Method, has_self) | |
476ff2be | 2337 | } |
32a655c1 | 2338 | hir::AssociatedItemKind::Type => (ty::AssociatedKind::Type, false), |
476ff2be SL |
2339 | }; |
2340 | ||
2341 | AssociatedItem { | |
32a655c1 | 2342 | name: trait_item_ref.name, |
041b39d2 | 2343 | kind, |
7cac9316 XL |
2344 | // Visibility of trait items is inherited from their traits. |
2345 | vis: Visibility::from_hir(parent_vis, trait_item_ref.id.node_id, self), | |
32a655c1 | 2346 | defaultness: trait_item_ref.defaultness, |
041b39d2 | 2347 | def_id, |
476ff2be SL |
2348 | container: TraitContainer(parent_def_id), |
2349 | method_has_self_argument: has_self | |
2350 | } | |
2351 | } | |
2352 | ||
2353 | fn associated_item_from_impl_item_ref(self, | |
2354 | parent_def_id: DefId, | |
476ff2be SL |
2355 | impl_item_ref: &hir::ImplItemRef) |
2356 | -> AssociatedItem { | |
32a655c1 | 2357 | let def_id = self.hir.local_def_id(impl_item_ref.id.node_id); |
476ff2be SL |
2358 | let (kind, has_self) = match impl_item_ref.kind { |
2359 | hir::AssociatedItemKind::Const => (ty::AssociatedKind::Const, false), | |
2360 | hir::AssociatedItemKind::Method { has_self } => { | |
2361 | (ty::AssociatedKind::Method, has_self) | |
2362 | } | |
2363 | hir::AssociatedItemKind::Type => (ty::AssociatedKind::Type, false), | |
2364 | }; | |
2365 | ||
476ff2be SL |
2366 | ty::AssociatedItem { |
2367 | name: impl_item_ref.name, | |
041b39d2 | 2368 | kind, |
7cac9316 XL |
2369 | // Visibility of trait impl items doesn't matter. |
2370 | vis: ty::Visibility::from_hir(&impl_item_ref.vis, impl_item_ref.id.node_id, self), | |
476ff2be | 2371 | defaultness: impl_item_ref.defaultness, |
041b39d2 | 2372 | def_id, |
476ff2be SL |
2373 | container: ImplContainer(parent_def_id), |
2374 | method_has_self_argument: has_self | |
2375 | } | |
2376 | } | |
2377 | ||
0531ce1d XL |
2378 | pub fn associated_items( |
2379 | self, | |
2380 | def_id: DefId, | |
2381 | ) -> impl Iterator<Item = ty::AssociatedItem> + 'a { | |
476ff2be | 2382 | let def_ids = self.associated_item_def_ids(def_id); |
0531ce1d XL |
2383 | Box::new((0..def_ids.len()).map(move |i| self.associated_item(def_ids[i]))) |
2384 | as Box<dyn Iterator<Item = ty::AssociatedItem> + 'a> | |
e9174d1e SL |
2385 | } |
2386 | ||
cc61c64b XL |
2387 | /// Returns true if the impls are the same polarity and are implementing |
2388 | /// a trait which contains no items | |
2389 | pub fn impls_are_allowed_to_overlap(self, def_id1: DefId, def_id2: DefId) -> bool { | |
0531ce1d | 2390 | if !self.features().overlapping_marker_traits { |
cc61c64b XL |
2391 | return false; |
2392 | } | |
2393 | let trait1_is_empty = self.impl_trait_ref(def_id1) | |
2394 | .map_or(false, |trait_ref| { | |
2395 | self.associated_item_def_ids(trait_ref.def_id).is_empty() | |
2396 | }); | |
2397 | let trait2_is_empty = self.impl_trait_ref(def_id2) | |
2398 | .map_or(false, |trait_ref| { | |
2399 | self.associated_item_def_ids(trait_ref.def_id).is_empty() | |
2400 | }); | |
7cac9316 | 2401 | self.impl_polarity(def_id1) == self.impl_polarity(def_id2) |
cc61c64b XL |
2402 | && trait1_is_empty |
2403 | && trait2_is_empty | |
2404 | } | |
2405 | ||
5bcae85e SL |
2406 | // Returns `ty::VariantDef` if `def` refers to a struct, |
2407 | // or variant or their constructors, panics otherwise. | |
476ff2be | 2408 | pub fn expect_variant_def(self, def: Def) -> &'tcx VariantDef { |
5bcae85e | 2409 | match def { |
c30ab7b3 | 2410 | Def::Variant(did) | Def::VariantCtor(did, ..) => { |
9e0c209e | 2411 | let enum_did = self.parent_def_id(did).unwrap(); |
7cac9316 | 2412 | self.adt_def(enum_did).variant_with_id(did) |
5bcae85e | 2413 | } |
9e0c209e | 2414 | Def::Struct(did) | Def::Union(did) => { |
2c00a5a8 | 2415 | self.adt_def(did).non_enum_variant() |
5bcae85e | 2416 | } |
c30ab7b3 SL |
2417 | Def::StructCtor(ctor_did, ..) => { |
2418 | let did = self.parent_def_id(ctor_did).expect("struct ctor has no parent"); | |
2c00a5a8 | 2419 | self.adt_def(did).non_enum_variant() |
c30ab7b3 | 2420 | } |
5bcae85e SL |
2421 | _ => bug!("expect_variant_def used with unexpected def {:?}", def) |
2422 | } | |
2423 | } | |
2424 | ||
abe05a73 XL |
2425 | /// Given a `VariantDef`, returns the def-id of the `AdtDef` of which it is a part. |
2426 | pub fn adt_def_id_of_variant(self, variant_def: &'tcx VariantDef) -> DefId { | |
2427 | let def_key = self.def_key(variant_def.did); | |
2428 | match def_key.disambiguated_data.data { | |
2429 | // for enum variants and tuple structs, the def-id of the ADT itself | |
2430 | // is the *parent* of the variant | |
2431 | DefPathData::EnumVariant(..) | DefPathData::StructCtor => | |
2432 | DefId { krate: variant_def.did.krate, index: def_key.parent.unwrap() }, | |
2433 | ||
2434 | // otherwise, for structs and unions, they share a def-id | |
2435 | _ => variant_def.did, | |
2436 | } | |
2437 | } | |
2438 | ||
ea8adc8c | 2439 | pub fn item_name(self, id: DefId) -> InternedString { |
ff7c6d11 | 2440 | if id.index == CRATE_DEF_INDEX { |
ea8adc8c | 2441 | self.original_crate_name(id.krate).as_str() |
e9174d1e | 2442 | } else { |
ea8adc8c | 2443 | let def_key = self.def_key(id); |
9e0c209e | 2444 | // The name of a StructCtor is that of its struct parent. |
32a655c1 | 2445 | if let hir_map::DefPathData::StructCtor = def_key.disambiguated_data.data { |
9e0c209e SL |
2446 | self.item_name(DefId { |
2447 | krate: id.krate, | |
2448 | index: def_key.parent.unwrap() | |
2449 | }) | |
2450 | } else { | |
2451 | def_key.disambiguated_data.data.get_opt_name().unwrap_or_else(|| { | |
2452 | bug!("item_name: no name for {:?}", self.def_path(id)); | |
2453 | }) | |
2454 | } | |
e9174d1e SL |
2455 | } |
2456 | } | |
2457 | ||
cc61c64b XL |
2458 | /// Return the possibly-auto-generated MIR of a (DefId, Subst) pair. |
2459 | pub fn instance_mir(self, instance: ty::InstanceDef<'gcx>) | |
7cac9316 | 2460 | -> &'gcx Mir<'gcx> |
cc61c64b XL |
2461 | { |
2462 | match instance { | |
7cac9316 XL |
2463 | ty::InstanceDef::Item(did) => { |
2464 | self.optimized_mir(did) | |
2465 | } | |
2466 | ty::InstanceDef::Intrinsic(..) | | |
2467 | ty::InstanceDef::FnPtrShim(..) | | |
2468 | ty::InstanceDef::Virtual(..) | | |
2469 | ty::InstanceDef::ClosureOnceShim { .. } | | |
3b2f2976 XL |
2470 | ty::InstanceDef::DropGlue(..) | |
2471 | ty::InstanceDef::CloneShim(..) => { | |
7cac9316 XL |
2472 | self.mir_shims(instance) |
2473 | } | |
cc61c64b XL |
2474 | } |
2475 | } | |
2476 | ||
8bb4bdeb XL |
2477 | /// Given the DefId of an item, returns its MIR, borrowed immutably. |
2478 | /// Returns None if there is no MIR for the DefId | |
7cac9316 XL |
2479 | pub fn maybe_optimized_mir(self, did: DefId) -> Option<&'gcx Mir<'gcx>> { |
2480 | if self.is_mir_available(did) { | |
2481 | Some(self.optimized_mir(did)) | |
2482 | } else { | |
2483 | None | |
8bb4bdeb | 2484 | } |
c30ab7b3 SL |
2485 | } |
2486 | ||
e9174d1e | 2487 | /// Get the attributes of a definition. |
cc61c64b | 2488 | pub fn get_attrs(self, did: DefId) -> Attributes<'gcx> { |
32a655c1 | 2489 | if let Some(id) = self.hir.as_local_node_id(did) { |
cc61c64b | 2490 | Attributes::Borrowed(self.hir.attrs(id)) |
e9174d1e | 2491 | } else { |
7cac9316 | 2492 | Attributes::Owned(self.item_attrs(did)) |
e9174d1e SL |
2493 | } |
2494 | } | |
2495 | ||
2496 | /// Determine whether an item is annotated with an attribute | |
a7813a04 | 2497 | pub fn has_attr(self, did: DefId, attr: &str) -> bool { |
ff7c6d11 | 2498 | attr::contains_name(&self.get_attrs(did), attr) |
e9174d1e SL |
2499 | } |
2500 | ||
abe05a73 | 2501 | /// Returns true if this is an `auto trait`. |
abe05a73 XL |
2502 | pub fn trait_is_auto(self, trait_def_id: DefId) -> bool { |
2503 | self.trait_def(trait_def_id).has_auto_impl | |
b039eaaf SL |
2504 | } |
2505 | ||
ea8adc8c XL |
2506 | pub fn generator_layout(self, def_id: DefId) -> &'tcx GeneratorLayout<'tcx> { |
2507 | self.optimized_mir(def_id).generator_layout.as_ref().unwrap() | |
2508 | } | |
2509 | ||
e9174d1e SL |
2510 | /// Given the def_id of an impl, return the def_id of the trait it implements. |
2511 | /// If it implements no trait, return `None`. | |
a7813a04 | 2512 | pub fn trait_id_of_impl(self, def_id: DefId) -> Option<DefId> { |
e9174d1e SL |
2513 | self.impl_trait_ref(def_id).map(|tr| tr.def_id) |
2514 | } | |
2515 | ||
2516 | /// If the given def ID describes a method belonging to an impl, return the | |
2517 | /// ID of the impl that the method belongs to. Otherwise, return `None`. | |
a7813a04 | 2518 | pub fn impl_of_method(self, def_id: DefId) -> Option<DefId> { |
8bb4bdeb | 2519 | let item = if def_id.krate != LOCAL_CRATE { |
7cac9316 | 2520 | if let Some(Def::Method(_)) = self.describe_def(def_id) { |
8bb4bdeb XL |
2521 | Some(self.associated_item(def_id)) |
2522 | } else { | |
2523 | None | |
2524 | } | |
2525 | } else { | |
7cac9316 | 2526 | self.opt_associated_item(def_id) |
8bb4bdeb XL |
2527 | }; |
2528 | ||
2529 | match item { | |
e9174d1e | 2530 | Some(trait_item) => { |
476ff2be | 2531 | match trait_item.container { |
e9174d1e SL |
2532 | TraitContainer(_) => None, |
2533 | ImplContainer(def_id) => Some(def_id), | |
2534 | } | |
2535 | } | |
2536 | None => None | |
2537 | } | |
2538 | } | |
2539 | ||
54a0048b SL |
2540 | /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err` |
2541 | /// with the name of the crate containing the impl. | |
476ff2be | 2542 | pub fn span_of_impl(self, impl_did: DefId) -> Result<Span, Symbol> { |
54a0048b | 2543 | if impl_did.is_local() { |
32a655c1 SL |
2544 | let node_id = self.hir.as_local_node_id(impl_did).unwrap(); |
2545 | Ok(self.hir.span(node_id)) | |
54a0048b | 2546 | } else { |
ea8adc8c | 2547 | Err(self.crate_name(impl_did.krate)) |
54a0048b SL |
2548 | } |
2549 | } | |
7cac9316 | 2550 | |
ea8adc8c XL |
2551 | // Hygienically compare a use-site name (`use_name`) for a field or an associated item with its |
2552 | // supposed definition name (`def_name`). The method also needs `DefId` of the supposed | |
2553 | // definition's parent/scope to perform comparison. | |
2554 | pub fn hygienic_eq(self, use_name: Name, def_name: Name, def_parent_def_id: DefId) -> bool { | |
2555 | self.adjust(use_name, def_parent_def_id, DUMMY_NODE_ID).0 == def_name.to_ident() | |
2556 | } | |
2557 | ||
7cac9316 XL |
2558 | pub fn adjust(self, name: Name, scope: DefId, block: NodeId) -> (Ident, DefId) { |
2559 | self.adjust_ident(name.to_ident(), scope, block) | |
2560 | } | |
2561 | ||
2562 | pub fn adjust_ident(self, mut ident: Ident, scope: DefId, block: NodeId) -> (Ident, DefId) { | |
2563 | let expansion = match scope.krate { | |
2564 | LOCAL_CRATE => self.hir.definitions().expansion(scope.index), | |
2565 | _ => Mark::root(), | |
2566 | }; | |
2567 | let scope = match ident.ctxt.adjust(expansion) { | |
2568 | Some(macro_def) => self.hir.definitions().macro_def_scope(macro_def), | |
ea8adc8c | 2569 | None if block == DUMMY_NODE_ID => DefId::local(CRATE_DEF_INDEX), // Dummy DefId |
7cac9316 XL |
2570 | None => self.hir.get_module_parent(block), |
2571 | }; | |
2572 | (ident, scope) | |
2573 | } | |
e9174d1e SL |
2574 | } |
2575 | ||
a7813a04 XL |
2576 | impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { |
2577 | pub fn with_freevars<T, F>(self, fid: NodeId, f: F) -> T where | |
54a0048b | 2578 | F: FnOnce(&[hir::Freevar]) -> T, |
e9174d1e | 2579 | { |
ea8adc8c XL |
2580 | let def_id = self.hir.local_def_id(fid); |
2581 | match self.freevars(def_id) { | |
e9174d1e | 2582 | None => f(&[]), |
ea8adc8c | 2583 | Some(d) => f(&d), |
e9174d1e SL |
2584 | } |
2585 | } | |
e9174d1e | 2586 | } |
cc61c64b XL |
2587 | |
2588 | fn associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) | |
2589 | -> AssociatedItem | |
2590 | { | |
2591 | let id = tcx.hir.as_local_node_id(def_id).unwrap(); | |
2592 | let parent_id = tcx.hir.get_parent(id); | |
2593 | let parent_def_id = tcx.hir.local_def_id(parent_id); | |
2594 | let parent_item = tcx.hir.expect_item(parent_id); | |
2595 | match parent_item.node { | |
7cac9316 | 2596 | hir::ItemImpl(.., ref impl_item_refs) => { |
cc61c64b | 2597 | if let Some(impl_item_ref) = impl_item_refs.iter().find(|i| i.id.node_id == id) { |
7cac9316 XL |
2598 | let assoc_item = tcx.associated_item_from_impl_item_ref(parent_def_id, |
2599 | impl_item_ref); | |
cc61c64b XL |
2600 | debug_assert_eq!(assoc_item.def_id, def_id); |
2601 | return assoc_item; | |
2602 | } | |
2603 | } | |
2604 | ||
2605 | hir::ItemTrait(.., ref trait_item_refs) => { | |
2606 | if let Some(trait_item_ref) = trait_item_refs.iter().find(|i| i.id.node_id == id) { | |
7cac9316 XL |
2607 | let assoc_item = tcx.associated_item_from_trait_item_ref(parent_def_id, |
2608 | &parent_item.vis, | |
2609 | trait_item_ref); | |
cc61c64b XL |
2610 | debug_assert_eq!(assoc_item.def_id, def_id); |
2611 | return assoc_item; | |
2612 | } | |
2613 | } | |
2614 | ||
7cac9316 | 2615 | _ => { } |
cc61c64b | 2616 | } |
7cac9316 XL |
2617 | |
2618 | span_bug!(parent_item.span, | |
2619 | "unexpected parent of trait or impl item or item not found: {:?}", | |
2620 | parent_item.node) | |
cc61c64b XL |
2621 | } |
2622 | ||
2623 | /// Calculates the Sized-constraint. | |
2624 | /// | |
2625 | /// In fact, there are only a few options for the types in the constraint: | |
2626 | /// - an obviously-unsized type | |
2627 | /// - a type parameter or projection whose Sizedness can't be known | |
2628 | /// - a tuple of type parameters or projections, if there are multiple | |
2629 | /// such. | |
2630 | /// - a TyError, if a type contained itself. The representability | |
2631 | /// check should catch this case. | |
2632 | fn adt_sized_constraint<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, | |
2633 | def_id: DefId) | |
2634 | -> &'tcx [Ty<'tcx>] { | |
7cac9316 | 2635 | let def = tcx.adt_def(def_id); |
cc61c64b XL |
2636 | |
2637 | let result = tcx.intern_type_list(&def.variants.iter().flat_map(|v| { | |
2638 | v.fields.last() | |
2639 | }).flat_map(|f| { | |
7cac9316 | 2640 | def.sized_constraint_for_ty(tcx, tcx.type_of(f.did)) |
cc61c64b XL |
2641 | }).collect::<Vec<_>>()); |
2642 | ||
2643 | debug!("adt_sized_constraint: {:?} => {:?}", def, result); | |
2644 | ||
2645 | result | |
2646 | } | |
2647 | ||
cc61c64b XL |
2648 | fn associated_item_def_ids<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, |
2649 | def_id: DefId) | |
0531ce1d | 2650 | -> Lrc<Vec<DefId>> { |
cc61c64b XL |
2651 | let id = tcx.hir.as_local_node_id(def_id).unwrap(); |
2652 | let item = tcx.hir.expect_item(id); | |
2653 | let vec: Vec<_> = match item.node { | |
2654 | hir::ItemTrait(.., ref trait_item_refs) => { | |
2655 | trait_item_refs.iter() | |
2656 | .map(|trait_item_ref| trait_item_ref.id) | |
2657 | .map(|id| tcx.hir.local_def_id(id.node_id)) | |
2658 | .collect() | |
2659 | } | |
2660 | hir::ItemImpl(.., ref impl_item_refs) => { | |
2661 | impl_item_refs.iter() | |
2662 | .map(|impl_item_ref| impl_item_ref.id) | |
2663 | .map(|id| tcx.hir.local_def_id(id.node_id)) | |
2664 | .collect() | |
2665 | } | |
ff7c6d11 | 2666 | hir::ItemTraitAlias(..) => vec![], |
cc61c64b XL |
2667 | _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait") |
2668 | }; | |
0531ce1d | 2669 | Lrc::new(vec) |
cc61c64b XL |
2670 | } |
2671 | ||
7cac9316 XL |
2672 | fn def_span<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Span { |
2673 | tcx.hir.span_if_local(def_id).unwrap() | |
2674 | } | |
2675 | ||
2676 | /// If the given def ID describes an item belonging to a trait, | |
2677 | /// return the ID of the trait that the trait item belongs to. | |
2678 | /// Otherwise, return `None`. | |
2679 | fn trait_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option<DefId> { | |
2680 | tcx.opt_associated_item(def_id) | |
2681 | .and_then(|associated_item| { | |
2682 | match associated_item.container { | |
2683 | TraitContainer(def_id) => Some(def_id), | |
2684 | ImplContainer(_) => None | |
2685 | } | |
2686 | }) | |
2687 | } | |
2688 | ||
2689 | /// See `ParamEnv` struct def'n for details. | |
2690 | fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, | |
2691 | def_id: DefId) | |
2692 | -> ParamEnv<'tcx> { | |
2693 | // Compute the bounds on Self and the type parameters. | |
2694 | ||
2695 | let bounds = tcx.predicates_of(def_id).instantiate_identity(tcx); | |
2696 | let predicates = bounds.predicates; | |
2697 | ||
2698 | // Finally, we have to normalize the bounds in the environment, in | |
2699 | // case they contain any associated type projections. This process | |
2700 | // can yield errors if the put in illegal associated types, like | |
2701 | // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We | |
2702 | // report these errors right here; this doesn't actually feel | |
2703 | // right to me, because constructing the environment feels like a | |
2704 | // kind of a "idempotent" action, but I'm not sure where would be | |
2705 | // a better place. In practice, we construct environments for | |
2706 | // every fn once during type checking, and we'll abort if there | |
2707 | // are any errors at that point, so after type checking you can be | |
2708 | // sure that this will succeed without errors anyway. | |
2709 | ||
2710 | let unnormalized_env = ty::ParamEnv::new(tcx.intern_predicates(&predicates), | |
2711 | traits::Reveal::UserFacing); | |
2712 | ||
2713 | let body_id = tcx.hir.as_local_node_id(def_id).map_or(DUMMY_NODE_ID, |id| { | |
2714 | tcx.hir.maybe_body_owned_by(id).map_or(id, |body| body.node_id) | |
2715 | }); | |
2716 | let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id); | |
2717 | traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause) | |
2718 | } | |
2719 | ||
ea8adc8c | 2720 | fn crate_disambiguator<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, |
abe05a73 | 2721 | crate_num: CrateNum) -> CrateDisambiguator { |
ea8adc8c XL |
2722 | assert_eq!(crate_num, LOCAL_CRATE); |
2723 | tcx.sess.local_crate_disambiguator() | |
2724 | } | |
2725 | ||
2726 | fn original_crate_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, | |
2727 | crate_num: CrateNum) -> Symbol { | |
2728 | assert_eq!(crate_num, LOCAL_CRATE); | |
2729 | tcx.crate_name.clone() | |
2730 | } | |
2731 | ||
ff7c6d11 XL |
2732 | fn crate_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, |
2733 | crate_num: CrateNum) | |
2734 | -> Svh { | |
2735 | assert_eq!(crate_num, LOCAL_CRATE); | |
2736 | tcx.hir.crate_hash | |
2737 | } | |
2738 | ||
2c00a5a8 XL |
2739 | fn instance_def_size_estimate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, |
2740 | instance_def: InstanceDef<'tcx>) | |
2741 | -> usize { | |
2742 | match instance_def { | |
2743 | InstanceDef::Item(..) | | |
2744 | InstanceDef::DropGlue(..) => { | |
2745 | let mir = tcx.instance_mir(instance_def); | |
2746 | mir.basic_blocks().iter().map(|bb| bb.statements.len()).sum() | |
2747 | }, | |
2748 | // Estimate the size of other compiler-generated shims to be 1. | |
2749 | _ => 1 | |
2750 | } | |
2751 | } | |
2752 | ||
cc61c64b | 2753 | pub fn provide(providers: &mut ty::maps::Providers) { |
ea8adc8c | 2754 | context::provide(providers); |
abe05a73 | 2755 | erase_regions::provide(providers); |
ff7c6d11 XL |
2756 | layout::provide(providers); |
2757 | util::provide(providers); | |
cc61c64b XL |
2758 | *providers = ty::maps::Providers { |
2759 | associated_item, | |
2760 | associated_item_def_ids, | |
2761 | adt_sized_constraint, | |
7cac9316 XL |
2762 | def_span, |
2763 | param_env, | |
2764 | trait_of_item, | |
ea8adc8c XL |
2765 | crate_disambiguator, |
2766 | original_crate_name, | |
ff7c6d11 | 2767 | crate_hash, |
7cac9316 | 2768 | trait_impls_of: trait_def::trait_impls_of_provider, |
2c00a5a8 | 2769 | instance_def_size_estimate, |
cc61c64b XL |
2770 | ..*providers |
2771 | }; | |
2772 | } | |
2773 | ||
cc61c64b XL |
2774 | /// A map for the local crate mapping each type to a vector of its |
2775 | /// inherent impls. This is not meant to be used outside of coherence; | |
2776 | /// rather, you should request the vector for a specific type via | |
7cac9316 XL |
2777 | /// `tcx.inherent_impls(def_id)` so as to minimize your dependencies |
2778 | /// (constructing this map requires touching the entire crate). | |
cc61c64b XL |
2779 | #[derive(Clone, Debug)] |
2780 | pub struct CrateInherentImpls { | |
0531ce1d | 2781 | pub inherent_impls: DefIdMap<Lrc<Vec<DefId>>>, |
cc61c64b XL |
2782 | } |
2783 | ||
0531ce1d | 2784 | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable)] |
7cac9316 XL |
2785 | pub struct SymbolName { |
2786 | // FIXME: we don't rely on interning or equality here - better have | |
2787 | // this be a `&'tcx str`. | |
2788 | pub name: InternedString | |
2789 | } | |
2790 | ||
ea8adc8c XL |
2791 | impl_stable_hash_for!(struct self::SymbolName { |
2792 | name | |
2793 | }); | |
2794 | ||
0531ce1d XL |
2795 | impl SymbolName { |
2796 | pub fn new(name: &str) -> SymbolName { | |
2797 | SymbolName { | |
2798 | name: Symbol::intern(name).as_str() | |
2799 | } | |
2800 | } | |
2801 | } | |
2802 | ||
7cac9316 XL |
2803 | impl Deref for SymbolName { |
2804 | type Target = str; | |
2805 | ||
2806 | fn deref(&self) -> &str { &self.name } | |
2807 | } | |
2808 | ||
2809 | impl fmt::Display for SymbolName { | |
2810 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | |
2811 | fmt::Display::fmt(&self.name, fmt) | |
2812 | } | |
2813 | } | |
0531ce1d XL |
2814 | |
2815 | impl fmt::Debug for SymbolName { | |
2816 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | |
2817 | fmt::Display::fmt(&self.name, fmt) | |
2818 | } | |
2819 | } |