]>
Commit | Line | Data |
---|---|---|
48663c56 XL |
1 | // ignore-tidy-filelength |
2 | ||
e9174d1e | 3 | pub use self::Variance::*; |
dc9dc135 | 4 | pub use self::AssocItemContainer::*; |
e9174d1e | 5 | pub use self::BorrowKind::*; |
e9174d1e | 6 | pub use self::IntVarValue::*; |
e74abb32 | 7 | pub use self::fold::{TypeFoldable, TypeVisitor}; |
e9174d1e | 8 | |
dc9dc135 | 9 | use crate::hir::{map as hir_map, GlobMap, TraitMap}; |
48663c56 XL |
10 | use crate::hir::Node; |
11 | use crate::hir::def::{Res, DefKind, CtorOf, CtorKind, ExportMap}; | |
9fa01778 | 12 | use crate::hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; |
b7449926 | 13 | use rustc_data_structures::svh::Svh; |
532ac7d7 | 14 | use rustc_macros::HashStable; |
9fa01778 XL |
15 | use crate::ich::Fingerprint; |
16 | use crate::ich::StableHashingContext; | |
17 | use crate::infer::canonical::Canonical; | |
e74abb32 | 18 | use crate::middle::cstore::CrateStoreDyn; |
9fa01778 XL |
19 | use crate::middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; |
20 | use crate::middle::resolve_lifetime::ObjectLifetimeDefault; | |
60c5eb7d | 21 | use crate::mir::ReadOnlyBodyAndCache; |
9fa01778 XL |
22 | use crate::mir::interpret::{GlobalId, ErrorHandled}; |
23 | use crate::mir::GeneratorLayout; | |
24 | use crate::session::CrateDisambiguator; | |
25 | use crate::traits::{self, Reveal}; | |
26 | use crate::ty; | |
27 | use crate::ty::layout::VariantIdx; | |
532ac7d7 | 28 | use crate::ty::subst::{Subst, InternalSubsts, SubstsRef}; |
9fa01778 XL |
29 | use crate::ty::util::{IntTypeExt, Discr}; |
30 | use crate::ty::walk::TypeWalker; | |
31 | use crate::util::captures::Captures; | |
e74abb32 | 32 | use crate::util::nodemap::{NodeMap, NodeSet, DefIdMap, FxHashMap}; |
94b46f34 | 33 | use arena::SyncDroplessArena; |
9fa01778 | 34 | use crate::session::DataTypeKind; |
e9174d1e | 35 | |
416331ca | 36 | use rustc_serialize::{self, Encodable, Encoder}; |
e1599b0c | 37 | use rustc_target::abi::Align; |
2c00a5a8 | 38 | use std::cell::RefCell; |
94b46f34 | 39 | use std::cmp::{self, Ordering}; |
7cac9316 | 40 | use std::fmt; |
e9174d1e | 41 | use std::hash::{Hash, Hasher}; |
9e0c209e | 42 | use std::ops::Deref; |
94b46f34 | 43 | use rustc_data_structures::sync::{self, Lrc, ParallelIterator, par_iter}; |
e9174d1e | 44 | use std::slice; |
8faf50e0 | 45 | use std::{mem, ptr}; |
48663c56 | 46 | use std::ops::Range; |
9fa01778 | 47 | use syntax::ast::{self, Name, Ident, NodeId}; |
9e0c209e | 48 | use syntax::attr; |
e74abb32 XL |
49 | use syntax_pos::symbol::{kw, sym, Symbol}; |
50 | use syntax_pos::hygiene::ExpnId; | |
9fa01778 | 51 | use syntax_pos::Span; |
8bb4bdeb | 52 | |
b7449926 | 53 | use smallvec; |
e74abb32 XL |
54 | use rustc_data_structures::fx::{FxIndexMap}; |
55 | use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; | |
56 | use rustc_index::vec::{Idx, IndexVec}; | |
54a0048b | 57 | |
9fa01778 | 58 | use crate::hir; |
e9174d1e | 59 | |
a1dfa0c6 | 60 | pub use self::sty::{Binder, BoundTy, BoundTyKind, BoundVar, DebruijnIndex, INNERMOST}; |
0bf4aa26 | 61 | pub use self::sty::{FnSig, GenSig, CanonicalPolyFnSig, PolyFnSig, PolyGenSig}; |
532ac7d7 | 62 | pub use self::sty::{InferTy, ParamTy, ParamConst, InferConst, ProjectionTy, ExistentialPredicate}; |
94b46f34 | 63 | pub use self::sty::{ClosureSubsts, GeneratorSubsts, UpvarSubsts, TypeAndMut}; |
b7449926 | 64 | pub use self::sty::{TraitRef, TyKind, PolyTraitRef}; |
9e0c209e | 65 | pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef}; |
60c5eb7d | 66 | pub use self::sty::{ExistentialProjection, PolyExistentialProjection, Const, ConstKind}; |
e9174d1e | 67 | pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region}; |
7cac9316 | 68 | pub use self::sty::RegionKind; |
532ac7d7 | 69 | pub use self::sty::{TyVid, IntVid, FloatVid, ConstVid, RegionVid}; |
e9174d1e | 70 | pub use self::sty::BoundRegion::*; |
e9174d1e | 71 | pub use self::sty::InferTy::*; |
7cac9316 | 72 | pub use self::sty::RegionKind::*; |
b7449926 | 73 | pub use self::sty::TyKind::*; |
60c5eb7d | 74 | pub use crate::ty::diagnostics::*; |
e9174d1e | 75 | |
3b2f2976 XL |
76 | pub use self::binding::BindingMode; |
77 | pub use self::binding::BindingMode::*; | |
78 | ||
dc9dc135 | 79 | pub use self::context::{TyCtxt, FreeRegionInfo, AllArenas, tls, keep_local}; |
e1599b0c | 80 | pub use self::context::{Lift, GeneratorInteriorTypeCause, TypeckTables, CtxtInterners, GlobalCtxt}; |
0731742a | 81 | pub use self::context::{ |
9fa01778 XL |
82 | UserTypeAnnotationIndex, UserType, CanonicalUserType, |
83 | CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, ResolvedOpaqueTy, | |
0731742a | 84 | }; |
e9174d1e | 85 | |
cc61c64b XL |
86 | pub use self::instance::{Instance, InstanceDef}; |
87 | ||
e74abb32 XL |
88 | pub use self::structural_match::search_for_structural_match_violation; |
89 | pub use self::structural_match::type_marked_structural; | |
90 | pub use self::structural_match::NonStructuralMatchTy; | |
91 | ||
7cac9316 | 92 | pub use self::trait_def::TraitDef; |
9cc50fc6 | 93 | |
94b46f34 | 94 | pub use self::query::queries; |
8bb4bdeb | 95 | |
e9174d1e | 96 | pub mod adjustment; |
3b2f2976 | 97 | pub mod binding; |
e9174d1e | 98 | pub mod cast; |
abe05a73 XL |
99 | #[macro_use] |
100 | pub mod codec; | |
0bf4aa26 | 101 | mod constness; |
e9174d1e | 102 | pub mod error; |
abe05a73 | 103 | mod erase_regions; |
e9174d1e | 104 | pub mod fast_reject; |
48663c56 | 105 | pub mod flags; |
e9174d1e | 106 | pub mod fold; |
32a655c1 | 107 | pub mod inhabitedness; |
54a0048b | 108 | pub mod layout; |
e9174d1e SL |
109 | pub mod _match; |
110 | pub mod outlives; | |
532ac7d7 | 111 | pub mod print; |
94b46f34 | 112 | pub mod query; |
e9174d1e | 113 | pub mod relate; |
7cac9316 | 114 | pub mod steal; |
54a0048b | 115 | pub mod subst; |
9cc50fc6 | 116 | pub mod trait_def; |
e9174d1e SL |
117 | pub mod walk; |
118 | pub mod wf; | |
119 | pub mod util; | |
120 | ||
e9174d1e | 121 | mod context; |
cc61c64b | 122 | mod instance; |
e9174d1e | 123 | mod structural_impls; |
e74abb32 | 124 | mod structural_match; |
e9174d1e | 125 | mod sty; |
60c5eb7d | 126 | mod diagnostics; |
e9174d1e | 127 | |
e9174d1e SL |
128 | // Data types |
129 | ||
e74abb32 XL |
130 | pub struct ResolverOutputs { |
131 | pub definitions: hir_map::Definitions, | |
132 | pub cstore: Box<CrateStoreDyn>, | |
133 | pub extern_crate_map: NodeMap<CrateNum>, | |
32a655c1 SL |
134 | pub trait_map: TraitMap, |
135 | pub maybe_unused_trait_imports: NodeSet, | |
3b2f2976 | 136 | pub maybe_unused_extern_crates: Vec<(NodeId, Span)>, |
48663c56 | 137 | pub export_map: ExportMap<NodeId>, |
9fa01778 | 138 | pub glob_map: GlobMap, |
0bf4aa26 XL |
139 | /// Extern prelude entries. The value is `true` if the entry was introduced |
140 | /// via `extern crate` item and not `--extern` option or compiler built-in. | |
141 | pub extern_prelude: FxHashMap<Name, bool>, | |
e9174d1e SL |
142 | } |
143 | ||
532ac7d7 | 144 | #[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable)] |
dc9dc135 | 145 | pub enum AssocItemContainer { |
e9174d1e SL |
146 | TraitContainer(DefId), |
147 | ImplContainer(DefId), | |
148 | } | |
149 | ||
dc9dc135 | 150 | impl AssocItemContainer { |
9fa01778 XL |
151 | /// Asserts that this is the `DefId` of an associated item declared |
152 | /// in a trait, and returns the trait `DefId`. | |
abe05a73 XL |
153 | pub fn assert_trait(&self) -> DefId { |
154 | match *self { | |
155 | TraitContainer(id) => id, | |
156 | _ => bug!("associated item has wrong container type: {:?}", self) | |
157 | } | |
158 | } | |
159 | ||
e9174d1e SL |
160 | pub fn id(&self) -> DefId { |
161 | match *self { | |
162 | TraitContainer(id) => id, | |
163 | ImplContainer(id) => id, | |
164 | } | |
165 | } | |
166 | } | |
167 | ||
54a0048b SL |
168 | /// The "header" of an impl is everything outside the body: a Self type, a trait |
169 | /// ref (in the case of a trait impl), and a set of predicates (from the | |
9fa01778 | 170 | /// bounds / where-clauses). |
60c5eb7d | 171 | #[derive(Clone, Debug, TypeFoldable)] |
54a0048b SL |
172 | pub struct ImplHeader<'tcx> { |
173 | pub impl_def_id: DefId, | |
174 | pub self_ty: Ty<'tcx>, | |
175 | pub trait_ref: Option<TraitRef<'tcx>>, | |
176 | pub predicates: Vec<Predicate<'tcx>>, | |
177 | } | |
178 | ||
e74abb32 XL |
179 | #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)] |
180 | pub enum ImplPolarity { | |
181 | /// `impl Trait for Type` | |
182 | Positive, | |
183 | /// `impl !Trait for Type` | |
184 | Negative, | |
185 | /// `#[rustc_reservation_impl] impl Trait for Type` | |
186 | /// | |
187 | /// This is a "stability hack", not a real Rust feature. | |
188 | /// See #64631 for details. | |
189 | Reservation, | |
190 | } | |
191 | ||
532ac7d7 | 192 | #[derive(Copy, Clone, Debug, PartialEq, HashStable)] |
dc9dc135 | 193 | pub struct AssocItem { |
476ff2be | 194 | pub def_id: DefId, |
532ac7d7 | 195 | #[stable_hasher(project(name))] |
8faf50e0 | 196 | pub ident: Ident, |
dc9dc135 | 197 | pub kind: AssocKind, |
476ff2be SL |
198 | pub vis: Visibility, |
199 | pub defaultness: hir::Defaultness, | |
dc9dc135 | 200 | pub container: AssocItemContainer, |
e9174d1e | 201 | |
476ff2be SL |
202 | /// Whether this is a method with an explicit self |
203 | /// as its first argument, allowing method calls. | |
204 | pub method_has_self_argument: bool, | |
205 | } | |
e9174d1e | 206 | |
e74abb32 | 207 | #[derive(Copy, Clone, PartialEq, Debug, HashStable)] |
dc9dc135 | 208 | pub enum AssocKind { |
476ff2be SL |
209 | Const, |
210 | Method, | |
416331ca | 211 | OpaqueTy, |
476ff2be SL |
212 | Type |
213 | } | |
e9174d1e | 214 | |
dc9dc135 | 215 | impl AssocItem { |
48663c56 | 216 | pub fn def_kind(&self) -> DefKind { |
476ff2be | 217 | match self.kind { |
dc9dc135 XL |
218 | AssocKind::Const => DefKind::AssocConst, |
219 | AssocKind::Method => DefKind::Method, | |
220 | AssocKind::Type => DefKind::AssocTy, | |
416331ca | 221 | AssocKind::OpaqueTy => DefKind::AssocOpaqueTy, |
e9174d1e SL |
222 | } |
223 | } | |
8bb4bdeb XL |
224 | |
225 | /// Tests whether the associated item admits a non-trivial implementation | |
226 | /// for ! | |
dc9dc135 | 227 | pub fn relevant_for_never(&self) -> bool { |
8bb4bdeb | 228 | match self.kind { |
416331ca | 229 | AssocKind::OpaqueTy | |
dc9dc135 XL |
230 | AssocKind::Const | |
231 | AssocKind::Type => true, | |
8bb4bdeb | 232 | // FIXME(canndrew): Be more thorough here, check if any argument is uninhabited. |
dc9dc135 | 233 | AssocKind::Method => !self.method_has_self_argument, |
8bb4bdeb XL |
234 | } |
235 | } | |
7cac9316 | 236 | |
dc9dc135 | 237 | pub fn signature(&self, tcx: TyCtxt<'_>) -> String { |
7cac9316 | 238 | match self.kind { |
dc9dc135 | 239 | ty::AssocKind::Method => { |
7cac9316 XL |
240 | // We skip the binder here because the binder would deanonymize all |
241 | // late-bound regions, and we don't want method signatures to show up | |
242 | // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound | |
243 | // regions just fine, showing `fn(&MyType)`. | |
8faf50e0 | 244 | tcx.fn_sig(self.def_id).skip_binder().to_string() |
7cac9316 | 245 | } |
dc9dc135 | 246 | ty::AssocKind::Type => format!("type {};", self.ident), |
416331ca XL |
247 | // FIXME(type_alias_impl_trait): we should print bounds here too. |
248 | ty::AssocKind::OpaqueTy => format!("type {};", self.ident), | |
dc9dc135 | 249 | ty::AssocKind::Const => { |
8faf50e0 | 250 | format!("const {}: {:?};", self.ident, tcx.type_of(self.def_id)) |
7cac9316 XL |
251 | } |
252 | } | |
253 | } | |
e9174d1e SL |
254 | } |
255 | ||
532ac7d7 | 256 | #[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable, HashStable)] |
54a0048b SL |
257 | pub enum Visibility { |
258 | /// Visible everywhere (including in other crates). | |
259 | Public, | |
260 | /// Visible only in the given crate-local module. | |
32a655c1 | 261 | Restricted(DefId), |
54a0048b | 262 | /// Not visible anywhere in the local crate. This is the visibility of private external items. |
32a655c1 | 263 | Invisible, |
54a0048b SL |
264 | } |
265 | ||
32a655c1 SL |
266 | pub trait DefIdTree: Copy { |
267 | fn parent(self, id: DefId) -> Option<DefId>; | |
a7813a04 | 268 | |
32a655c1 SL |
269 | fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool { |
270 | if descendant.krate != ancestor.krate { | |
271 | return false; | |
272 | } | |
273 | ||
274 | while descendant != ancestor { | |
275 | match self.parent(descendant) { | |
276 | Some(parent) => descendant = parent, | |
277 | None => return false, | |
a7813a04 | 278 | } |
a7813a04 XL |
279 | } |
280 | true | |
281 | } | |
282 | } | |
283 | ||
dc9dc135 | 284 | impl<'tcx> DefIdTree for TyCtxt<'tcx> { |
32a655c1 SL |
285 | fn parent(self, id: DefId) -> Option<DefId> { |
286 | self.def_key(id).parent.map(|index| DefId { index: index, ..id }) | |
287 | } | |
288 | } | |
289 | ||
54a0048b | 290 | impl Visibility { |
dc9dc135 | 291 | pub fn from_hir(visibility: &hir::Visibility, id: hir::HirId, tcx: TyCtxt<'_>) -> Self { |
8faf50e0 XL |
292 | match visibility.node { |
293 | hir::VisibilityKind::Public => Visibility::Public, | |
294 | hir::VisibilityKind::Crate(_) => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)), | |
48663c56 | 295 | hir::VisibilityKind::Restricted { ref path, .. } => match path.res { |
a7813a04 XL |
296 | // If there is no resolution, `resolve` will have already reported an error, so |
297 | // assume that the visibility is public to avoid reporting more privacy errors. | |
48663c56 | 298 | Res::Err => Visibility::Public, |
32a655c1 | 299 | def => Visibility::Restricted(def.def_id()), |
a7813a04 | 300 | }, |
8faf50e0 | 301 | hir::VisibilityKind::Inherited => { |
dc9dc135 | 302 | Visibility::Restricted(tcx.hir().get_module_parent(id)) |
32a655c1 | 303 | } |
54a0048b SL |
304 | } |
305 | } | |
306 | ||
a1dfa0c6 | 307 | /// Returns `true` if an item with this visibility is accessible from the given block. |
32a655c1 | 308 | pub fn is_accessible_from<T: DefIdTree>(self, module: DefId, tree: T) -> bool { |
54a0048b SL |
309 | let restriction = match self { |
310 | // Public items are visible everywhere. | |
311 | Visibility::Public => return true, | |
312 | // Private items from other crates are visible nowhere. | |
32a655c1 | 313 | Visibility::Invisible => return false, |
54a0048b | 314 | // Restricted items are visible in an arbitrary local module. |
32a655c1 | 315 | Visibility::Restricted(other) if other.krate != module.krate => return false, |
54a0048b SL |
316 | Visibility::Restricted(module) => module, |
317 | }; | |
318 | ||
32a655c1 | 319 | tree.is_descendant_of(module, restriction) |
54a0048b SL |
320 | } |
321 | ||
a1dfa0c6 | 322 | /// Returns `true` if this visibility is at least as accessible as the given visibility |
32a655c1 | 323 | pub fn is_at_least<T: DefIdTree>(self, vis: Visibility, tree: T) -> bool { |
54a0048b SL |
324 | let vis_restriction = match vis { |
325 | Visibility::Public => return self == Visibility::Public, | |
32a655c1 | 326 | Visibility::Invisible => return true, |
54a0048b SL |
327 | Visibility::Restricted(module) => module, |
328 | }; | |
329 | ||
a7813a04 | 330 | self.is_accessible_from(vis_restriction, tree) |
54a0048b | 331 | } |
ff7c6d11 | 332 | |
a1dfa0c6 | 333 | // Returns `true` if this item is visible anywhere in the local crate. |
ff7c6d11 XL |
334 | pub fn is_visible_locally(self) -> bool { |
335 | match self { | |
336 | Visibility::Public => true, | |
337 | Visibility::Restricted(def_id) => def_id.is_local(), | |
338 | Visibility::Invisible => false, | |
339 | } | |
340 | } | |
54a0048b SL |
341 | } |
342 | ||
e74abb32 | 343 | #[derive(Copy, Clone, PartialEq, RustcDecodable, RustcEncodable, HashStable)] |
e9174d1e SL |
344 | pub enum Variance { |
345 | Covariant, // T<A> <: T<B> iff A <: B -- e.g., function return type | |
346 | Invariant, // T<A> <: T<B> iff B == A -- e.g., type of mutable cell | |
347 | Contravariant, // T<A> <: T<B> iff B <: A -- e.g., function param type | |
348 | Bivariant, // T<A> <: T<B> -- e.g., unused type parameter | |
349 | } | |
350 | ||
7cac9316 XL |
351 | /// The crate variances map is computed during typeck and contains the |
352 | /// variance of every item in the local crate. You should not use it | |
353 | /// directly, because to do so will make your pass dependent on the | |
354 | /// HIR of every item in the local crate. Instead, use | |
355 | /// `tcx.variances_of()` to get the variance for a *particular* | |
356 | /// item. | |
532ac7d7 | 357 | #[derive(HashStable)] |
48663c56 | 358 | pub struct CrateVariancesMap<'tcx> { |
7cac9316 | 359 | /// For each item with generics, maps to a vector of the variance |
9fa01778 | 360 | /// of its generics. If an item has no generics, it will have no |
7cac9316 | 361 | /// entry. |
48663c56 | 362 | pub variances: FxHashMap<DefId, &'tcx [ty::Variance]>, |
7cac9316 XL |
363 | } |
364 | ||
cc61c64b XL |
365 | impl Variance { |
366 | /// `a.xform(b)` combines the variance of a context with the | |
9fa01778 | 367 | /// variance of a type with the following meaning. If we are in a |
cc61c64b XL |
368 | /// context with variance `a`, and we encounter a type argument in |
369 | /// a position with variance `b`, then `a.xform(b)` is the new | |
370 | /// variance with which the argument appears. | |
371 | /// | |
372 | /// Example 1: | |
373 | /// | |
374 | /// *mut Vec<i32> | |
375 | /// | |
376 | /// Here, the "ambient" variance starts as covariant. `*mut T` is | |
377 | /// invariant with respect to `T`, so the variance in which the | |
378 | /// `Vec<i32>` appears is `Covariant.xform(Invariant)`, which | |
379 | /// yields `Invariant`. Now, the type `Vec<T>` is covariant with | |
380 | /// respect to its type argument `T`, and hence the variance of | |
381 | /// the `i32` here is `Invariant.xform(Covariant)`, which results | |
382 | /// (again) in `Invariant`. | |
383 | /// | |
384 | /// Example 2: | |
385 | /// | |
386 | /// fn(*const Vec<i32>, *mut Vec<i32) | |
387 | /// | |
388 | /// The ambient variance is covariant. A `fn` type is | |
389 | /// contravariant with respect to its parameters, so the variance | |
390 | /// within which both pointer types appear is | |
9fa01778 | 391 | /// `Covariant.xform(Contravariant)`, or `Contravariant`. `*const |
cc61c64b XL |
392 | /// T` is covariant with respect to `T`, so the variance within |
393 | /// which the first `Vec<i32>` appears is | |
9fa01778 | 394 | /// `Contravariant.xform(Covariant)` or `Contravariant`. The same |
cc61c64b XL |
395 | /// is true for its `i32` argument. In the `*mut T` case, the |
396 | /// variance of `Vec<i32>` is `Contravariant.xform(Invariant)`, | |
397 | /// and hence the outermost type is `Invariant` with respect to | |
398 | /// `Vec<i32>` (and its `i32` argument). | |
399 | /// | |
400 | /// Source: Figure 1 of "Taming the Wildcards: | |
401 | /// Combining Definition- and Use-Site Variance" published in PLDI'11. | |
402 | pub fn xform(self, v: ty::Variance) -> ty::Variance { | |
403 | match (self, v) { | |
404 | // Figure 1, column 1. | |
405 | (ty::Covariant, ty::Covariant) => ty::Covariant, | |
406 | (ty::Covariant, ty::Contravariant) => ty::Contravariant, | |
407 | (ty::Covariant, ty::Invariant) => ty::Invariant, | |
408 | (ty::Covariant, ty::Bivariant) => ty::Bivariant, | |
409 | ||
410 | // Figure 1, column 2. | |
411 | (ty::Contravariant, ty::Covariant) => ty::Contravariant, | |
412 | (ty::Contravariant, ty::Contravariant) => ty::Covariant, | |
413 | (ty::Contravariant, ty::Invariant) => ty::Invariant, | |
414 | (ty::Contravariant, ty::Bivariant) => ty::Bivariant, | |
415 | ||
416 | // Figure 1, column 3. | |
417 | (ty::Invariant, _) => ty::Invariant, | |
418 | ||
419 | // Figure 1, column 4. | |
420 | (ty::Bivariant, _) => ty::Bivariant, | |
421 | } | |
422 | } | |
423 | } | |
424 | ||
e9174d1e SL |
425 | // Contains information needed to resolve types and (in the future) look up |
426 | // the types of AST nodes. | |
427 | #[derive(Copy, Clone, PartialEq, Eq, Hash)] | |
428 | pub struct CReaderCacheKey { | |
429 | pub cnum: CrateNum, | |
430 | pub pos: usize, | |
e9174d1e SL |
431 | } |
432 | ||
e9174d1e SL |
433 | // Flags that we track on types. These flags are propagated upwards |
434 | // through the type during type construction, so that we can quickly | |
435 | // check whether the type has various kinds of types in it without | |
436 | // recursing over the type itself. | |
437 | bitflags! { | |
ea8adc8c XL |
438 | pub struct TypeFlags: u32 { |
439 | const HAS_PARAMS = 1 << 0; | |
e1599b0c XL |
440 | const HAS_TY_INFER = 1 << 1; |
441 | const HAS_RE_INFER = 1 << 2; | |
442 | const HAS_RE_PLACEHOLDER = 1 << 3; | |
ff7c6d11 XL |
443 | |
444 | /// Does this have any `ReEarlyBound` regions? Used to | |
445 | /// determine whether substitition is required, since those | |
446 | /// represent regions that are bound in a `ty::Generics` and | |
447 | /// hence may be substituted. | |
e1599b0c | 448 | const HAS_RE_EARLY_BOUND = 1 << 4; |
ff7c6d11 XL |
449 | |
450 | /// Does this have any region that "appears free" in the type? | |
451 | /// Basically anything but `ReLateBound` and `ReErased`. | |
e1599b0c | 452 | const HAS_FREE_REGIONS = 1 << 5; |
ff7c6d11 XL |
453 | |
454 | /// Is an error type reachable? | |
e1599b0c XL |
455 | const HAS_TY_ERR = 1 << 6; |
456 | const HAS_PROJECTION = 1 << 7; | |
ea8adc8c XL |
457 | |
458 | // FIXME: Rename this to the actual property since it's used for generators too | |
e1599b0c | 459 | const HAS_TY_CLOSURE = 1 << 8; |
e9174d1e | 460 | |
48663c56 XL |
461 | /// `true` if there are "names" of types and regions and so forth |
462 | /// that are local to a particular fn | |
e74abb32 | 463 | const HAS_FREE_LOCAL_NAMES = 1 << 9; |
e9174d1e | 464 | |
48663c56 XL |
465 | /// Present if the type belongs in a local type context. |
466 | /// Only set for Infer other than Fresh. | |
e1599b0c | 467 | const KEEP_IN_LOCAL_TCX = 1 << 10; |
1bb2cb6e | 468 | |
94b46f34 XL |
469 | /// Does this have any `ReLateBound` regions? Used to check |
470 | /// if a global bound is safe to evaluate. | |
e74abb32 | 471 | const HAS_RE_LATE_BOUND = 1 << 11; |
a1dfa0c6 | 472 | |
e1599b0c | 473 | const HAS_TY_PLACEHOLDER = 1 << 12; |
94b46f34 | 474 | |
e74abb32 | 475 | const HAS_CT_INFER = 1 << 13; |
e1599b0c | 476 | const HAS_CT_PLACEHOLDER = 1 << 14; |
532ac7d7 | 477 | |
e9174d1e | 478 | const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits | |
ea8adc8c | 479 | TypeFlags::HAS_RE_EARLY_BOUND.bits; |
e9174d1e | 480 | |
48663c56 XL |
481 | /// Flags representing the nominal content of a type, |
482 | /// computed by FlagsComputation. If you add a new nominal | |
483 | /// flag, it should be added here too. | |
e9174d1e | 484 | const NOMINAL_FLAGS = TypeFlags::HAS_PARAMS.bits | |
e9174d1e SL |
485 | TypeFlags::HAS_TY_INFER.bits | |
486 | TypeFlags::HAS_RE_INFER.bits | | |
a1dfa0c6 | 487 | TypeFlags::HAS_RE_PLACEHOLDER.bits | |
e9174d1e SL |
488 | TypeFlags::HAS_RE_EARLY_BOUND.bits | |
489 | TypeFlags::HAS_FREE_REGIONS.bits | | |
490 | TypeFlags::HAS_TY_ERR.bits | | |
491 | TypeFlags::HAS_PROJECTION.bits | | |
492 | TypeFlags::HAS_TY_CLOSURE.bits | | |
94b46f34 | 493 | TypeFlags::HAS_FREE_LOCAL_NAMES.bits | |
0531ce1d | 494 | TypeFlags::KEEP_IN_LOCAL_TCX.bits | |
a1dfa0c6 | 495 | TypeFlags::HAS_RE_LATE_BOUND.bits | |
48663c56 | 496 | TypeFlags::HAS_TY_PLACEHOLDER.bits | |
e1599b0c | 497 | TypeFlags::HAS_CT_INFER.bits | |
48663c56 | 498 | TypeFlags::HAS_CT_PLACEHOLDER.bits; |
e9174d1e SL |
499 | } |
500 | } | |
501 | ||
e1599b0c | 502 | #[allow(rustc::usage_of_ty_tykind)] |
e9174d1e | 503 | pub struct TyS<'tcx> { |
e74abb32 | 504 | pub kind: TyKind<'tcx>, |
7cac9316 | 505 | pub flags: TypeFlags, |
e9174d1e | 506 | |
94b46f34 XL |
507 | /// This is a kind of confusing thing: it stores the smallest |
508 | /// binder such that | |
509 | /// | |
510 | /// (a) the binder itself captures nothing but | |
511 | /// (b) all the late-bound things within the type are captured | |
512 | /// by some sub-binder. | |
513 | /// | |
514 | /// So, for a type without any late-bound things, like `u32`, this | |
0731742a | 515 | /// will be *innermost*, because that is the innermost binder that |
94b46f34 | 516 | /// captures nothing. But for a type `&'D u32`, where `'D` is a |
9fa01778 | 517 | /// late-bound region with De Bruijn index `D`, this would be `D + 1` |
0731742a XL |
518 | /// -- the binder itself does not capture `D`, but `D` is captured |
519 | /// by an inner binder. | |
94b46f34 | 520 | /// |
0731742a | 521 | /// We call this concept an "exclusive" binder `D` because all |
9fa01778 | 522 | /// De Bruijn indices within the type are contained within `0..D` |
0731742a | 523 | /// (exclusive). |
94b46f34 XL |
524 | outer_exclusive_binder: ty::DebruijnIndex, |
525 | } | |
526 | ||
a1dfa0c6 XL |
527 | // `TyS` is used a lot. Make sure it doesn't unintentionally get bigger. |
528 | #[cfg(target_arch = "x86_64")] | |
48663c56 | 529 | static_assert_size!(TyS<'_>, 32); |
a1dfa0c6 | 530 | |
94b46f34 XL |
531 | impl<'tcx> Ord for TyS<'tcx> { |
532 | fn cmp(&self, other: &TyS<'tcx>) -> Ordering { | |
e74abb32 | 533 | self.kind.cmp(&other.kind) |
94b46f34 XL |
534 | } |
535 | } | |
536 | ||
537 | impl<'tcx> PartialOrd for TyS<'tcx> { | |
538 | fn partial_cmp(&self, other: &TyS<'tcx>) -> Option<Ordering> { | |
e74abb32 | 539 | Some(self.kind.cmp(&other.kind)) |
94b46f34 | 540 | } |
e9174d1e SL |
541 | } |
542 | ||
543 | impl<'tcx> PartialEq for TyS<'tcx> { | |
544 | #[inline] | |
545 | fn eq(&self, other: &TyS<'tcx>) -> bool { | |
8faf50e0 | 546 | ptr::eq(self, other) |
e9174d1e SL |
547 | } |
548 | } | |
549 | impl<'tcx> Eq for TyS<'tcx> {} | |
550 | ||
551 | impl<'tcx> Hash for TyS<'tcx> { | |
552 | fn hash<H: Hasher>(&self, s: &mut H) { | |
0bf4aa26 | 553 | (self as *const TyS<'_>).hash(s) |
e9174d1e SL |
554 | } |
555 | } | |
556 | ||
dc9dc135 | 557 | impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::TyS<'tcx> { |
e74abb32 | 558 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
cc61c64b | 559 | let ty::TyS { |
e74abb32 | 560 | ref kind, |
cc61c64b XL |
561 | |
562 | // The other fields just provide fast access to information that is | |
e74abb32 | 563 | // also contained in `kind`, so no need to hash them. |
cc61c64b | 564 | flags: _, |
94b46f34 XL |
565 | |
566 | outer_exclusive_binder: _, | |
cc61c64b XL |
567 | } = *self; |
568 | ||
e74abb32 | 569 | kind.hash_stable(hcx, hasher); |
cc61c64b XL |
570 | } |
571 | } | |
572 | ||
e74abb32 | 573 | #[rustc_diagnostic_item = "Ty"] |
e9174d1e SL |
574 | pub type Ty<'tcx> = &'tcx TyS<'tcx>; |
575 | ||
416331ca XL |
576 | impl<'tcx> rustc_serialize::UseSpecializedEncodable for Ty<'tcx> {} |
577 | impl<'tcx> rustc_serialize::UseSpecializedDecodable for Ty<'tcx> {} | |
9e0c209e | 578 | |
dc9dc135 | 579 | pub type CanonicalTy<'tcx> = Canonical<'tcx, Ty<'tcx>>; |
0531ce1d | 580 | |
94b46f34 | 581 | extern { |
e74abb32 XL |
582 | /// A dummy type used to force `List` to be unsized while not requiring references to it be wide |
583 | /// pointers. | |
b7449926 | 584 | type OpaqueListContents; |
94b46f34 XL |
585 | } |
586 | ||
c30ab7b3 | 587 | /// A wrapper for slices with the additional invariant |
9e0c209e SL |
588 | /// that the slice is interned and no other slice with |
589 | /// the same contents can exist in the same context. | |
94b46f34 | 590 | /// This means we can use pointer for both |
9e0c209e | 591 | /// equality comparisons and hashing. |
b7449926 | 592 | /// Note: `Slice` was already taken by the `Ty`. |
94b46f34 | 593 | #[repr(C)] |
b7449926 | 594 | pub struct List<T> { |
94b46f34 XL |
595 | len: usize, |
596 | data: [T; 0], | |
b7449926 | 597 | opaque: OpaqueListContents, |
94b46f34 XL |
598 | } |
599 | ||
b7449926 | 600 | unsafe impl<T: Sync> Sync for List<T> {} |
9e0c209e | 601 | |
b7449926 | 602 | impl<T: Copy> List<T> { |
94b46f34 | 603 | #[inline] |
b7449926 | 604 | fn from_arena<'tcx>(arena: &'tcx SyncDroplessArena, slice: &[T]) -> &'tcx List<T> { |
94b46f34 XL |
605 | assert!(!mem::needs_drop::<T>()); |
606 | assert!(mem::size_of::<T>() != 0); | |
607 | assert!(slice.len() != 0); | |
608 | ||
609 | // Align up the size of the len (usize) field | |
610 | let align = mem::align_of::<T>(); | |
611 | let align_mask = align - 1; | |
612 | let offset = mem::size_of::<usize>(); | |
613 | let offset = (offset + align_mask) & !align_mask; | |
614 | ||
615 | let size = offset + slice.len() * mem::size_of::<T>(); | |
616 | ||
617 | let mem = arena.alloc_raw( | |
618 | size, | |
619 | cmp::max(mem::align_of::<T>(), mem::align_of::<usize>())); | |
620 | unsafe { | |
b7449926 | 621 | let result = &mut *(mem.as_mut_ptr() as *mut List<T>); |
94b46f34 XL |
622 | // Write the length |
623 | result.len = slice.len(); | |
624 | ||
625 | // Write the elements | |
626 | let arena_slice = slice::from_raw_parts_mut(result.data.as_mut_ptr(), result.len); | |
627 | arena_slice.copy_from_slice(slice); | |
628 | ||
629 | result | |
630 | } | |
631 | } | |
632 | } | |
633 | ||
b7449926 | 634 | impl<T: fmt::Debug> fmt::Debug for List<T> { |
0bf4aa26 | 635 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
94b46f34 XL |
636 | (**self).fmt(f) |
637 | } | |
638 | } | |
639 | ||
b7449926 | 640 | impl<T: Encodable> Encodable for List<T> { |
94b46f34 XL |
641 | #[inline] |
642 | fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { | |
643 | (**self).encode(s) | |
644 | } | |
645 | } | |
646 | ||
b7449926 XL |
647 | impl<T> Ord for List<T> where T: Ord { |
648 | fn cmp(&self, other: &List<T>) -> Ordering { | |
94b46f34 XL |
649 | if self == other { Ordering::Equal } else { |
650 | <[T] as Ord>::cmp(&**self, &**other) | |
651 | } | |
652 | } | |
653 | } | |
654 | ||
b7449926 XL |
655 | impl<T> PartialOrd for List<T> where T: PartialOrd { |
656 | fn partial_cmp(&self, other: &List<T>) -> Option<Ordering> { | |
94b46f34 XL |
657 | if self == other { Some(Ordering::Equal) } else { |
658 | <[T] as PartialOrd>::partial_cmp(&**self, &**other) | |
659 | } | |
660 | } | |
661 | } | |
662 | ||
b7449926 | 663 | impl<T: PartialEq> PartialEq for List<T> { |
9e0c209e | 664 | #[inline] |
b7449926 | 665 | fn eq(&self, other: &List<T>) -> bool { |
8faf50e0 | 666 | ptr::eq(self, other) |
9cc50fc6 SL |
667 | } |
668 | } | |
b7449926 | 669 | impl<T: Eq> Eq for List<T> {} |
9cc50fc6 | 670 | |
b7449926 | 671 | impl<T> Hash for List<T> { |
94b46f34 | 672 | #[inline] |
9e0c209e | 673 | fn hash<H: Hasher>(&self, s: &mut H) { |
b7449926 | 674 | (self as *const List<T>).hash(s) |
9e0c209e SL |
675 | } |
676 | } | |
677 | ||
b7449926 | 678 | impl<T> Deref for List<T> { |
9e0c209e | 679 | type Target = [T]; |
94b46f34 | 680 | #[inline(always)] |
9e0c209e | 681 | fn deref(&self) -> &[T] { |
e74abb32 XL |
682 | self.as_ref() |
683 | } | |
684 | } | |
685 | ||
686 | impl<T> AsRef<[T]> for List<T> { | |
687 | #[inline(always)] | |
688 | fn as_ref(&self) -> &[T] { | |
94b46f34 XL |
689 | unsafe { |
690 | slice::from_raw_parts(self.data.as_ptr(), self.len) | |
691 | } | |
9e0c209e SL |
692 | } |
693 | } | |
694 | ||
b7449926 | 695 | impl<'a, T> IntoIterator for &'a List<T> { |
9e0c209e SL |
696 | type Item = &'a T; |
697 | type IntoIter = <&'a [T] as IntoIterator>::IntoIter; | |
94b46f34 | 698 | #[inline(always)] |
9e0c209e SL |
699 | fn into_iter(self) -> Self::IntoIter { |
700 | self[..].iter() | |
9cc50fc6 SL |
701 | } |
702 | } | |
703 | ||
416331ca | 704 | impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx List<Ty<'tcx>> {} |
9cc50fc6 | 705 | |
b7449926 | 706 | impl<T> List<T> { |
94b46f34 | 707 | #[inline(always)] |
b7449926 | 708 | pub fn empty<'a>() -> &'a List<T> { |
94b46f34 XL |
709 | #[repr(align(64), C)] |
710 | struct EmptySlice([u8; 64]); | |
711 | static EMPTY_SLICE: EmptySlice = EmptySlice([0; 64]); | |
712 | assert!(mem::align_of::<T>() <= 64); | |
c30ab7b3 | 713 | unsafe { |
b7449926 | 714 | &*(&EMPTY_SLICE as *const _ as *const List<T>) |
c30ab7b3 SL |
715 | } |
716 | } | |
717 | } | |
718 | ||
532ac7d7 | 719 | #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)] |
a1dfa0c6 XL |
720 | pub struct UpvarPath { |
721 | pub hir_id: hir::HirId, | |
722 | } | |
723 | ||
9fa01778 XL |
724 | /// Upvars do not get their own `NodeId`. Instead, we use the pair of |
725 | /// the original var ID (that is, the root variable that is referenced | |
726 | /// by the upvar) and the ID of the closure expression. | |
532ac7d7 | 727 | #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)] |
e9174d1e | 728 | pub struct UpvarId { |
a1dfa0c6 | 729 | pub var_path: UpvarPath, |
abe05a73 | 730 | pub closure_expr_id: LocalDefId, |
e9174d1e SL |
731 | } |
732 | ||
e74abb32 | 733 | #[derive(Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, HashStable)] |
e9174d1e SL |
734 | pub enum BorrowKind { |
735 | /// Data must be immutable and is aliasable. | |
736 | ImmBorrow, | |
737 | ||
9fa01778 | 738 | /// Data must be immutable but not aliasable. This kind of borrow |
e9174d1e | 739 | /// cannot currently be expressed by the user and is used only in |
32a655c1 | 740 | /// implicit closure bindings. It is needed when the closure |
e9174d1e SL |
741 | /// is borrowing or mutating a mutable referent, e.g.: |
742 | /// | |
743 | /// let x: &mut isize = ...; | |
744 | /// let y = || *x += 5; | |
745 | /// | |
746 | /// If we were to try to translate this closure into a more explicit | |
747 | /// form, we'd encounter an error with the code as written: | |
748 | /// | |
749 | /// struct Env { x: & &mut isize } | |
750 | /// let x: &mut isize = ...; | |
751 | /// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn | |
752 | /// fn fn_ptr(env: &mut Env) { **env.x += 5; } | |
753 | /// | |
754 | /// This is then illegal because you cannot mutate a `&mut` found | |
755 | /// in an aliasable location. To solve, you'd have to translate with | |
756 | /// an `&mut` borrow: | |
757 | /// | |
758 | /// struct Env { x: & &mut isize } | |
759 | /// let x: &mut isize = ...; | |
760 | /// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x | |
761 | /// fn fn_ptr(env: &mut Env) { **env.x += 5; } | |
762 | /// | |
763 | /// Now the assignment to `**env.x` is legal, but creating a | |
764 | /// mutable pointer to `x` is not because `x` is not mutable. We | |
765 | /// could fix this by declaring `x` as `let mut x`. This is ok in | |
766 | /// user code, if awkward, but extra weird for closures, since the | |
767 | /// borrow is hidden. | |
768 | /// | |
769 | /// So we introduce a "unique imm" borrow -- the referent is | |
770 | /// immutable, but not aliasable. This solves the problem. For | |
771 | /// simplicity, we don't give users the way to express this | |
772 | /// borrow, it's just used when translating closures. | |
773 | UniqueImmBorrow, | |
774 | ||
775 | /// Data is mutable and not aliasable. | |
776 | MutBorrow | |
777 | } | |
778 | ||
779 | /// Information describing the capture of an upvar. This is computed | |
780 | /// during `typeck`, specifically by `regionck`. | |
532ac7d7 | 781 | #[derive(PartialEq, Clone, Debug, Copy, RustcEncodable, RustcDecodable, HashStable)] |
9e0c209e | 782 | pub enum UpvarCapture<'tcx> { |
e9174d1e SL |
783 | /// Upvar is captured by value. This is always true when the |
784 | /// closure is labeled `move`, but can also be true in other cases | |
785 | /// depending on inference. | |
786 | ByValue, | |
787 | ||
788 | /// Upvar is captured by reference. | |
9e0c209e | 789 | ByRef(UpvarBorrow<'tcx>), |
e9174d1e SL |
790 | } |
791 | ||
532ac7d7 | 792 | #[derive(PartialEq, Clone, Copy, RustcEncodable, RustcDecodable, HashStable)] |
9e0c209e | 793 | pub struct UpvarBorrow<'tcx> { |
e9174d1e SL |
794 | /// The kind of borrow: by-ref upvars have access to shared |
795 | /// immutable borrows, which are not part of the normal language | |
796 | /// syntax. | |
797 | pub kind: BorrowKind, | |
798 | ||
799 | /// Region of the resulting reference. | |
7cac9316 | 800 | pub region: ty::Region<'tcx>, |
e9174d1e SL |
801 | } |
802 | ||
dc9dc135 | 803 | pub type UpvarListMap = FxHashMap<DefId, FxIndexMap<hir::HirId, UpvarId>>; |
476ff2be | 804 | pub type UpvarCaptureMap<'tcx> = FxHashMap<UpvarId, UpvarCapture<'tcx>>; |
e9174d1e | 805 | |
60c5eb7d | 806 | #[derive(Copy, Clone, TypeFoldable)] |
e9174d1e | 807 | pub struct ClosureUpvar<'tcx> { |
48663c56 | 808 | pub res: Res, |
e9174d1e SL |
809 | pub span: Span, |
810 | pub ty: Ty<'tcx>, | |
811 | } | |
812 | ||
0531ce1d | 813 | #[derive(Clone, Copy, PartialEq, Eq)] |
e9174d1e | 814 | pub enum IntVarValue { |
b039eaaf SL |
815 | IntType(ast::IntTy), |
816 | UintType(ast::UintTy), | |
e9174d1e SL |
817 | } |
818 | ||
0531ce1d XL |
819 | #[derive(Clone, Copy, PartialEq, Eq)] |
820 | pub struct FloatVarValue(pub ast::FloatTy); | |
821 | ||
94b46f34 XL |
822 | impl ty::EarlyBoundRegion { |
823 | pub fn to_bound_region(&self) -> ty::BoundRegion { | |
824 | ty::BoundRegion::BrNamed(self.def_id, self.name) | |
825 | } | |
b7449926 XL |
826 | |
827 | /// Does this early bound region have a name? Early bound regions normally | |
828 | /// always have names except when using anonymous lifetimes (`'_`). | |
829 | pub fn has_name(&self) -> bool { | |
e74abb32 | 830 | self.name != kw::UnderscoreLifetime |
b7449926 | 831 | } |
94b46f34 | 832 | } |
ea8adc8c | 833 | |
532ac7d7 | 834 | #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)] |
94b46f34 XL |
835 | pub enum GenericParamDefKind { |
836 | Lifetime, | |
837 | Type { | |
838 | has_default: bool, | |
839 | object_lifetime_default: ObjectLifetimeDefault, | |
840 | synthetic: Option<hir::SyntheticTyParamKind>, | |
532ac7d7 XL |
841 | }, |
842 | Const, | |
e9174d1e SL |
843 | } |
844 | ||
532ac7d7 | 845 | #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] |
94b46f34 | 846 | pub struct GenericParamDef { |
e74abb32 | 847 | pub name: Symbol, |
e9174d1e | 848 | pub def_id: DefId, |
e9174d1e | 849 | pub index: u32, |
c30ab7b3 SL |
850 | |
851 | /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute | |
94b46f34 XL |
852 | /// on generic parameter `'a`/`T`, asserts data behind the parameter |
853 | /// `'a`/`T` won't be accessed during the parent type's `Drop` impl. | |
c30ab7b3 | 854 | pub pure_wrt_drop: bool, |
94b46f34 XL |
855 | |
856 | pub kind: GenericParamDefKind, | |
e9174d1e SL |
857 | } |
858 | ||
94b46f34 | 859 | impl GenericParamDef { |
9e0c209e | 860 | pub fn to_early_bound_region_data(&self) -> ty::EarlyBoundRegion { |
0bf4aa26 XL |
861 | if let GenericParamDefKind::Lifetime = self.kind { |
862 | ty::EarlyBoundRegion { | |
863 | def_id: self.def_id, | |
864 | index: self.index, | |
865 | name: self.name, | |
94b46f34 | 866 | } |
0bf4aa26 XL |
867 | } else { |
868 | bug!("cannot convert a non-lifetime parameter def to an early bound region") | |
9e0c209e | 869 | } |
e9174d1e | 870 | } |
9e0c209e | 871 | |
7cac9316 | 872 | pub fn to_bound_region(&self) -> ty::BoundRegion { |
0bf4aa26 XL |
873 | if let GenericParamDefKind::Lifetime = self.kind { |
874 | self.to_early_bound_region_data().to_bound_region() | |
875 | } else { | |
876 | bug!("cannot convert a non-lifetime parameter def to an early bound region") | |
94b46f34 | 877 | } |
7cac9316 XL |
878 | } |
879 | } | |
880 | ||
b7449926 | 881 | #[derive(Default)] |
94b46f34 XL |
882 | pub struct GenericParamCount { |
883 | pub lifetimes: usize, | |
884 | pub types: usize, | |
532ac7d7 | 885 | pub consts: usize, |
e9174d1e SL |
886 | } |
887 | ||
888 | /// Information about the formal type/lifetime parameters associated | |
0731742a | 889 | /// with an item or method. Analogous to `hir::Generics`. |
ea8adc8c | 890 | /// |
0731742a XL |
891 | /// The ordering of parameters is the same as in `Subst` (excluding child generics): |
892 | /// `Self` (optionally), `Lifetime` params..., `Type` params... | |
532ac7d7 | 893 | #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)] |
8bb4bdeb | 894 | pub struct Generics { |
9e0c209e | 895 | pub parent: Option<DefId>, |
94b46f34 XL |
896 | pub parent_count: usize, |
897 | pub params: Vec<GenericParamDef>, | |
8bb4bdeb | 898 | |
416331ca | 899 | /// Reverse map to the `index` field of each `GenericParamDef`. |
532ac7d7 | 900 | #[stable_hasher(ignore)] |
94b46f34 | 901 | pub param_def_id_to_index: FxHashMap<DefId, u32>, |
8bb4bdeb | 902 | |
9e0c209e | 903 | pub has_self: bool, |
3b2f2976 | 904 | pub has_late_bound_regions: Option<Span>, |
e9174d1e SL |
905 | } |
906 | ||
dc9dc135 | 907 | impl<'tcx> Generics { |
94b46f34 XL |
908 | pub fn count(&self) -> usize { |
909 | self.parent_count + self.params.len() | |
e9174d1e SL |
910 | } |
911 | ||
94b46f34 XL |
912 | pub fn own_counts(&self) -> GenericParamCount { |
913 | // We could cache this as a property of `GenericParamCount`, but | |
914 | // the aim is to refactor this away entirely eventually and the | |
915 | // presence of this method will be a constant reminder. | |
b7449926 | 916 | let mut own_counts: GenericParamCount = Default::default(); |
94b46f34 XL |
917 | |
918 | for param in &self.params { | |
919 | match param.kind { | |
920 | GenericParamDefKind::Lifetime => own_counts.lifetimes += 1, | |
b7449926 | 921 | GenericParamDefKind::Type { .. } => own_counts.types += 1, |
532ac7d7 | 922 | GenericParamDefKind::Const => own_counts.consts += 1, |
94b46f34 XL |
923 | }; |
924 | } | |
925 | ||
926 | own_counts | |
e9174d1e SL |
927 | } |
928 | ||
dc9dc135 | 929 | pub fn requires_monomorphization(&self, tcx: TyCtxt<'tcx>) -> bool { |
48663c56 XL |
930 | if self.own_requires_monomorphization() { |
931 | return true; | |
94b46f34 | 932 | } |
48663c56 | 933 | |
94b46f34 XL |
934 | if let Some(parent_def_id) = self.parent { |
935 | let parent = tcx.generics_of(parent_def_id); | |
936 | parent.requires_monomorphization(tcx) | |
937 | } else { | |
938 | false | |
939 | } | |
e9174d1e | 940 | } |
c30ab7b3 | 941 | |
48663c56 XL |
942 | pub fn own_requires_monomorphization(&self) -> bool { |
943 | for param in &self.params { | |
944 | match param.kind { | |
945 | GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => return true, | |
946 | GenericParamDefKind::Lifetime => {} | |
947 | } | |
948 | } | |
949 | false | |
950 | } | |
951 | ||
dc9dc135 XL |
952 | pub fn region_param( |
953 | &'tcx self, | |
954 | param: &EarlyBoundRegion, | |
955 | tcx: TyCtxt<'tcx>, | |
956 | ) -> &'tcx GenericParamDef { | |
94b46f34 XL |
957 | if let Some(index) = param.index.checked_sub(self.parent_count as u32) { |
958 | let param = &self.params[index as usize]; | |
959 | match param.kind { | |
532ac7d7 | 960 | GenericParamDefKind::Lifetime => param, |
94b46f34 XL |
961 | _ => bug!("expected lifetime parameter, but found another generic parameter") |
962 | } | |
ea8adc8c | 963 | } else { |
a1dfa0c6 | 964 | tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?")) |
0bf4aa26 | 965 | .region_param(param, tcx) |
ea8adc8c XL |
966 | } |
967 | } | |
968 | ||
94b46f34 | 969 | /// Returns the `GenericParamDef` associated with this `ParamTy`. |
dc9dc135 | 970 | pub fn type_param(&'tcx self, param: &ParamTy, tcx: TyCtxt<'tcx>) -> &'tcx GenericParamDef { |
48663c56 | 971 | if let Some(index) = param.index.checked_sub(self.parent_count as u32) { |
94b46f34 XL |
972 | let param = &self.params[index as usize]; |
973 | match param.kind { | |
532ac7d7 | 974 | GenericParamDefKind::Type { .. } => param, |
94b46f34 | 975 | _ => bug!("expected type parameter, but found another generic parameter") |
ea8adc8c XL |
976 | } |
977 | } else { | |
a1dfa0c6 | 978 | tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?")) |
0bf4aa26 | 979 | .type_param(param, tcx) |
ea8adc8c | 980 | } |
c30ab7b3 | 981 | } |
532ac7d7 XL |
982 | |
983 | /// Returns the `ConstParameterDef` associated with this `ParamConst`. | |
dc9dc135 | 984 | pub fn const_param(&'tcx self, param: &ParamConst, tcx: TyCtxt<'tcx>) -> &GenericParamDef { |
532ac7d7 XL |
985 | if let Some(index) = param.index.checked_sub(self.parent_count as u32) { |
986 | let param = &self.params[index as usize]; | |
987 | match param.kind { | |
988 | GenericParamDefKind::Const => param, | |
989 | _ => bug!("expected const parameter, but found another generic parameter") | |
990 | } | |
991 | } else { | |
992 | tcx.generics_of(self.parent.expect("parent_count>0 but no parent?")) | |
993 | .const_param(param, tcx) | |
994 | } | |
995 | } | |
e9174d1e SL |
996 | } |
997 | ||
998 | /// Bounds on generics. | |
e74abb32 | 999 | #[derive(Copy, Clone, Default, Debug, RustcEncodable, RustcDecodable, HashStable)] |
e9174d1e | 1000 | pub struct GenericPredicates<'tcx> { |
9e0c209e | 1001 | pub parent: Option<DefId>, |
e74abb32 | 1002 | pub predicates: &'tcx [(Predicate<'tcx>, Span)], |
e9174d1e SL |
1003 | } |
1004 | ||
dc9dc135 XL |
1005 | impl<'tcx> GenericPredicates<'tcx> { |
1006 | pub fn instantiate( | |
1007 | &self, | |
1008 | tcx: TyCtxt<'tcx>, | |
1009 | substs: SubstsRef<'tcx>, | |
1010 | ) -> InstantiatedPredicates<'tcx> { | |
9e0c209e SL |
1011 | let mut instantiated = InstantiatedPredicates::empty(); |
1012 | self.instantiate_into(tcx, &mut instantiated, substs); | |
1013 | instantiated | |
1014 | } | |
a1dfa0c6 | 1015 | |
dc9dc135 XL |
1016 | pub fn instantiate_own( |
1017 | &self, | |
1018 | tcx: TyCtxt<'tcx>, | |
1019 | substs: SubstsRef<'tcx>, | |
1020 | ) -> InstantiatedPredicates<'tcx> { | |
e9174d1e | 1021 | InstantiatedPredicates { |
0bf4aa26 | 1022 | predicates: self.predicates.iter().map(|(p, _)| p.subst(tcx, substs)).collect(), |
e9174d1e SL |
1023 | } |
1024 | } | |
1025 | ||
dc9dc135 XL |
1026 | fn instantiate_into( |
1027 | &self, | |
1028 | tcx: TyCtxt<'tcx>, | |
1029 | instantiated: &mut InstantiatedPredicates<'tcx>, | |
1030 | substs: SubstsRef<'tcx>, | |
1031 | ) { | |
9e0c209e | 1032 | if let Some(def_id) = self.parent { |
7cac9316 | 1033 | tcx.predicates_of(def_id).instantiate_into(tcx, instantiated, substs); |
9e0c209e | 1034 | } |
0bf4aa26 XL |
1035 | instantiated.predicates.extend( |
1036 | self.predicates.iter().map(|(p, _)| p.subst(tcx, substs)), | |
1037 | ); | |
9e0c209e SL |
1038 | } |
1039 | ||
dc9dc135 | 1040 | pub fn instantiate_identity(&self, tcx: TyCtxt<'tcx>) -> InstantiatedPredicates<'tcx> { |
7cac9316 XL |
1041 | let mut instantiated = InstantiatedPredicates::empty(); |
1042 | self.instantiate_identity_into(tcx, &mut instantiated); | |
1043 | instantiated | |
1044 | } | |
1045 | ||
dc9dc135 XL |
1046 | fn instantiate_identity_into( |
1047 | &self, | |
1048 | tcx: TyCtxt<'tcx>, | |
1049 | instantiated: &mut InstantiatedPredicates<'tcx>, | |
1050 | ) { | |
7cac9316 XL |
1051 | if let Some(def_id) = self.parent { |
1052 | tcx.predicates_of(def_id).instantiate_identity_into(tcx, instantiated); | |
1053 | } | |
0bf4aa26 | 1054 | instantiated.predicates.extend(self.predicates.iter().map(|&(p, _)| p)) |
7cac9316 XL |
1055 | } |
1056 | ||
dc9dc135 XL |
1057 | pub fn instantiate_supertrait( |
1058 | &self, | |
1059 | tcx: TyCtxt<'tcx>, | |
1060 | poly_trait_ref: &ty::PolyTraitRef<'tcx>, | |
1061 | ) -> InstantiatedPredicates<'tcx> { | |
9e0c209e | 1062 | assert_eq!(self.parent, None); |
e9174d1e | 1063 | InstantiatedPredicates { |
0bf4aa26 | 1064 | predicates: self.predicates.iter().map(|(pred, _)| { |
a7813a04 | 1065 | pred.subst_supertrait(tcx, poly_trait_ref) |
9e0c209e | 1066 | }).collect() |
e9174d1e SL |
1067 | } |
1068 | } | |
1069 | } | |
1070 | ||
60c5eb7d XL |
1071 | #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] |
1072 | #[derive(HashStable, TypeFoldable)] | |
e9174d1e | 1073 | pub enum Predicate<'tcx> { |
dc9dc135 | 1074 | /// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be |
e9174d1e | 1075 | /// the `Self` type of the trait reference and `A`, `B`, and `C` |
9e0c209e | 1076 | /// would be the type parameters. |
e9174d1e SL |
1077 | Trait(PolyTraitPredicate<'tcx>), |
1078 | ||
dc9dc135 | 1079 | /// `where 'a: 'b` |
9e0c209e | 1080 | RegionOutlives(PolyRegionOutlivesPredicate<'tcx>), |
e9174d1e | 1081 | |
dc9dc135 | 1082 | /// `where T: 'a` |
e9174d1e SL |
1083 | TypeOutlives(PolyTypeOutlivesPredicate<'tcx>), |
1084 | ||
dc9dc135 | 1085 | /// `where <T as TraitRef>::Name == X`, approximately. |
a1dfa0c6 | 1086 | /// See the `ProjectionPredicate` struct for details. |
e9174d1e SL |
1087 | Projection(PolyProjectionPredicate<'tcx>), |
1088 | ||
dc9dc135 | 1089 | /// No syntax: `T` well-formed. |
e9174d1e SL |
1090 | WellFormed(Ty<'tcx>), |
1091 | ||
dc9dc135 | 1092 | /// Trait must be object-safe. |
e9174d1e | 1093 | ObjectSafe(DefId), |
a7813a04 | 1094 | |
a1dfa0c6 XL |
1095 | /// No direct syntax. May be thought of as `where T: FnFoo<...>` |
1096 | /// for some substitutions `...` and `T` being a closure type. | |
9e0c209e | 1097 | /// Satisfied (or refuted) once we know the closure's kind. |
e74abb32 | 1098 | ClosureKind(DefId, SubstsRef<'tcx>, ClosureKind), |
cc61c64b XL |
1099 | |
1100 | /// `T1 <: T2` | |
1101 | Subtype(PolySubtypePredicate<'tcx>), | |
ea8adc8c XL |
1102 | |
1103 | /// Constant initializer must evaluate successfully. | |
532ac7d7 | 1104 | ConstEvaluatable(DefId, SubstsRef<'tcx>), |
e9174d1e SL |
1105 | } |
1106 | ||
83c7162d XL |
1107 | /// The crate outlives map is computed during typeck and contains the |
1108 | /// outlives of every item in the local crate. You should not use it | |
1109 | /// directly, because to do so will make your pass dependent on the | |
1110 | /// HIR of every item in the local crate. Instead, use | |
1111 | /// `tcx.inferred_outlives_of()` to get the outlives for a *particular* | |
1112 | /// item. | |
532ac7d7 | 1113 | #[derive(HashStable)] |
83c7162d XL |
1114 | pub struct CratePredicatesMap<'tcx> { |
1115 | /// For each struct with outlive bounds, maps to a vector of the | |
1116 | /// predicate of its outlive bounds. If an item has no outlives | |
1117 | /// bounds, it will have no entry. | |
e74abb32 | 1118 | pub predicates: FxHashMap<DefId, &'tcx [(ty::Predicate<'tcx>, Span)]>, |
83c7162d XL |
1119 | } |
1120 | ||
abe05a73 XL |
1121 | impl<'tcx> AsRef<Predicate<'tcx>> for Predicate<'tcx> { |
1122 | fn as_ref(&self) -> &Predicate<'tcx> { | |
1123 | self | |
1124 | } | |
1125 | } | |
1126 | ||
dc9dc135 | 1127 | impl<'tcx> Predicate<'tcx> { |
e9174d1e SL |
1128 | /// Performs a substitution suitable for going from a |
1129 | /// poly-trait-ref to supertraits that must hold if that | |
1130 | /// poly-trait-ref holds. This is slightly different from a normal | |
9fa01778 | 1131 | /// substitution in terms of what happens with bound regions. See |
e9174d1e | 1132 | /// lengthy comment below for details. |
dc9dc135 XL |
1133 | pub fn subst_supertrait( |
1134 | &self, | |
1135 | tcx: TyCtxt<'tcx>, | |
1136 | trait_ref: &ty::PolyTraitRef<'tcx>, | |
1137 | ) -> ty::Predicate<'tcx> { | |
e9174d1e SL |
1138 | // The interaction between HRTB and supertraits is not entirely |
1139 | // obvious. Let me walk you (and myself) through an example. | |
1140 | // | |
1141 | // Let's start with an easy case. Consider two traits: | |
1142 | // | |
a1dfa0c6 | 1143 | // trait Foo<'a>: Bar<'a,'a> { } |
e9174d1e SL |
1144 | // trait Bar<'b,'c> { } |
1145 | // | |
a1dfa0c6 XL |
1146 | // Now, if we have a trait reference `for<'x> T: Foo<'x>`, then |
1147 | // we can deduce that `for<'x> T: Bar<'x,'x>`. Basically, if we | |
e9174d1e SL |
1148 | // knew that `Foo<'x>` (for any 'x) then we also know that |
1149 | // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from | |
1150 | // normal substitution. | |
1151 | // | |
1152 | // In terms of why this is sound, the idea is that whenever there | |
1153 | // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>` | |
1154 | // holds. So if there is an impl of `T:Foo<'a>` that applies to | |
1155 | // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all | |
1156 | // `'a`. | |
1157 | // | |
1158 | // Another example to be careful of is this: | |
1159 | // | |
a1dfa0c6 | 1160 | // trait Foo1<'a>: for<'b> Bar1<'a,'b> { } |
e9174d1e SL |
1161 | // trait Bar1<'b,'c> { } |
1162 | // | |
a1dfa0c6 XL |
1163 | // Here, if we have `for<'x> T: Foo1<'x>`, then what do we know? |
1164 | // The answer is that we know `for<'x,'b> T: Bar1<'x,'b>`. The | |
e9174d1e | 1165 | // reason is similar to the previous example: any impl of |
a1dfa0c6 | 1166 | // `T:Foo1<'x>` must show that `for<'b> T: Bar1<'x, 'b>`. So |
e9174d1e SL |
1167 | // basically we would want to collapse the bound lifetimes from |
1168 | // the input (`trait_ref`) and the supertraits. | |
1169 | // | |
1170 | // To achieve this in practice is fairly straightforward. Let's | |
1171 | // consider the more complicated scenario: | |
1172 | // | |
a1dfa0c6 XL |
1173 | // - We start out with `for<'x> T: Foo1<'x>`. In this case, `'x` |
1174 | // has a De Bruijn index of 1. We want to produce `for<'x,'b> T: Bar1<'x,'b>`, | |
e9174d1e SL |
1175 | // where both `'x` and `'b` would have a DB index of 1. |
1176 | // The substitution from the input trait-ref is therefore going to be | |
1177 | // `'a => 'x` (where `'x` has a DB index of 1). | |
1178 | // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an | |
1179 | // early-bound parameter and `'b' is a late-bound parameter with a | |
1180 | // DB index of 1. | |
1181 | // - If we replace `'a` with `'x` from the input, it too will have | |
1182 | // a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>` | |
1183 | // just as we wanted. | |
1184 | // | |
1185 | // There is only one catch. If we just apply the substitution `'a | |
1186 | // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will | |
1187 | // adjust the DB index because we substituting into a binder (it | |
1188 | // tries to be so smart...) resulting in `for<'x> for<'b> | |
1189 | // Bar1<'x,'b>` (we have no syntax for this, so use your | |
1190 | // imagination). Basically the 'x will have DB index of 2 and 'b | |
1191 | // will have DB index of 1. Not quite what we want. So we apply | |
1192 | // the substitution to the *contents* of the trait reference, | |
1193 | // rather than the trait reference itself (put another way, the | |
1194 | // substitution code expects equal binding levels in the values | |
1195 | // from the substitution and the value being substituted into, and | |
1196 | // this trick achieves that). | |
1197 | ||
83c7162d | 1198 | let substs = &trait_ref.skip_binder().substs; |
e9174d1e | 1199 | match *self { |
83c7162d XL |
1200 | Predicate::Trait(ref binder) => |
1201 | Predicate::Trait(binder.map_bound(|data| data.subst(tcx, substs))), | |
1202 | Predicate::Subtype(ref binder) => | |
1203 | Predicate::Subtype(binder.map_bound(|data| data.subst(tcx, substs))), | |
1204 | Predicate::RegionOutlives(ref binder) => | |
1205 | Predicate::RegionOutlives(binder.map_bound(|data| data.subst(tcx, substs))), | |
1206 | Predicate::TypeOutlives(ref binder) => | |
1207 | Predicate::TypeOutlives(binder.map_bound(|data| data.subst(tcx, substs))), | |
1208 | Predicate::Projection(ref binder) => | |
1209 | Predicate::Projection(binder.map_bound(|data| data.subst(tcx, substs))), | |
e9174d1e SL |
1210 | Predicate::WellFormed(data) => |
1211 | Predicate::WellFormed(data.subst(tcx, substs)), | |
1212 | Predicate::ObjectSafe(trait_def_id) => | |
1213 | Predicate::ObjectSafe(trait_def_id), | |
ff7c6d11 XL |
1214 | Predicate::ClosureKind(closure_def_id, closure_substs, kind) => |
1215 | Predicate::ClosureKind(closure_def_id, closure_substs.subst(tcx, substs), kind), | |
ea8adc8c XL |
1216 | Predicate::ConstEvaluatable(def_id, const_substs) => |
1217 | Predicate::ConstEvaluatable(def_id, const_substs.subst(tcx, substs)), | |
e9174d1e SL |
1218 | } |
1219 | } | |
1220 | } | |
1221 | ||
60c5eb7d XL |
1222 | #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] |
1223 | #[derive(HashStable, TypeFoldable)] | |
e9174d1e SL |
1224 | pub struct TraitPredicate<'tcx> { |
1225 | pub trait_ref: TraitRef<'tcx> | |
1226 | } | |
a1dfa0c6 | 1227 | |
e9174d1e SL |
1228 | pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>; |
1229 | ||
1230 | impl<'tcx> TraitPredicate<'tcx> { | |
1231 | pub fn def_id(&self) -> DefId { | |
1232 | self.trait_ref.def_id | |
1233 | } | |
1234 | ||
dc9dc135 | 1235 | pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'a { |
9e0c209e | 1236 | self.trait_ref.input_types() |
e9174d1e SL |
1237 | } |
1238 | ||
1239 | pub fn self_ty(&self) -> Ty<'tcx> { | |
1240 | self.trait_ref.self_ty() | |
1241 | } | |
1242 | } | |
1243 | ||
1244 | impl<'tcx> PolyTraitPredicate<'tcx> { | |
1245 | pub fn def_id(&self) -> DefId { | |
416331ca | 1246 | // Ok to skip binder since trait `DefId` does not care about regions. |
83c7162d | 1247 | self.skip_binder().def_id() |
e9174d1e SL |
1248 | } |
1249 | } | |
1250 | ||
60c5eb7d XL |
1251 | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] |
1252 | #[derive(HashStable, TypeFoldable)] | |
dc9dc135 XL |
1253 | pub struct OutlivesPredicate<A, B>(pub A, pub B); // `A: B` |
1254 | pub type PolyOutlivesPredicate<A, B> = ty::Binder<OutlivesPredicate<A, B>>; | |
1255 | pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>; | |
1256 | pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>; | |
0531ce1d XL |
1257 | pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<RegionOutlivesPredicate<'tcx>>; |
1258 | pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<TypeOutlivesPredicate<'tcx>>; | |
e9174d1e | 1259 | |
60c5eb7d XL |
1260 | #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] |
1261 | #[derive(HashStable, TypeFoldable)] | |
cc61c64b XL |
1262 | pub struct SubtypePredicate<'tcx> { |
1263 | pub a_is_expected: bool, | |
1264 | pub a: Ty<'tcx>, | |
1265 | pub b: Ty<'tcx> | |
1266 | } | |
1267 | pub type PolySubtypePredicate<'tcx> = ty::Binder<SubtypePredicate<'tcx>>; | |
1268 | ||
e9174d1e SL |
1269 | /// This kind of predicate has no *direct* correspondent in the |
1270 | /// syntax, but it roughly corresponds to the syntactic forms: | |
1271 | /// | |
9fa01778 | 1272 | /// 1. `T: TraitRef<..., Item = Type>` |
e9174d1e SL |
1273 | /// 2. `<T as TraitRef<...>>::Item == Type` (NYI) |
1274 | /// | |
1275 | /// In particular, form #1 is "desugared" to the combination of a | |
a1dfa0c6 | 1276 | /// normal trait predicate (`T: TraitRef<...>`) and one of these |
e9174d1e | 1277 | /// predicates. Form #2 is a broader form in that it also permits |
ff7c6d11 XL |
1278 | /// equality between arbitrary types. Processing an instance of |
1279 | /// Form #2 eventually yields one of these `ProjectionPredicate` | |
e9174d1e | 1280 | /// instances to normalize the LHS. |
60c5eb7d XL |
1281 | #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] |
1282 | #[derive(HashStable, TypeFoldable)] | |
e9174d1e SL |
1283 | pub struct ProjectionPredicate<'tcx> { |
1284 | pub projection_ty: ProjectionTy<'tcx>, | |
1285 | pub ty: Ty<'tcx>, | |
1286 | } | |
1287 | ||
1288 | pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>; | |
1289 | ||
1290 | impl<'tcx> PolyProjectionPredicate<'tcx> { | |
a1dfa0c6 | 1291 | /// Returns the `DefId` of the associated item being projected. |
83c7162d XL |
1292 | pub fn item_def_id(&self) -> DefId { |
1293 | self.skip_binder().projection_ty.item_def_id | |
1294 | } | |
1295 | ||
a1dfa0c6 | 1296 | #[inline] |
dc9dc135 | 1297 | pub fn to_poly_trait_ref(&self, tcx: TyCtxt<'_>) -> PolyTraitRef<'tcx> { |
a1dfa0c6 XL |
1298 | // Note: unlike with `TraitRef::to_poly_trait_ref()`, |
1299 | // `self.0.trait_ref` is permitted to have escaping regions. | |
041b39d2 XL |
1300 | // This is because here `self` has a `Binder` and so does our |
1301 | // return value, so we are preserving the number of binding | |
1302 | // levels. | |
83c7162d | 1303 | self.map_bound(|predicate| predicate.projection_ty.trait_ref(tcx)) |
e9174d1e | 1304 | } |
3b2f2976 XL |
1305 | |
1306 | pub fn ty(&self) -> Binder<Ty<'tcx>> { | |
83c7162d XL |
1307 | self.map_bound(|predicate| predicate.ty) |
1308 | } | |
1309 | ||
a1dfa0c6 | 1310 | /// The `DefId` of the `TraitItem` for the associated type. |
83c7162d | 1311 | /// |
a1dfa0c6 XL |
1312 | /// Note that this is not the `DefId` of the `TraitRef` containing this |
1313 | /// associated type, which is in `tcx.associated_item(projection_def_id()).container`. | |
83c7162d | 1314 | pub fn projection_def_id(&self) -> DefId { |
416331ca | 1315 | // Ok to skip binder since trait `DefId` does not care about regions. |
83c7162d | 1316 | self.skip_binder().projection_ty.item_def_id |
3b2f2976 | 1317 | } |
e9174d1e SL |
1318 | } |
1319 | ||
1320 | pub trait ToPolyTraitRef<'tcx> { | |
1321 | fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>; | |
1322 | } | |
1323 | ||
1324 | impl<'tcx> ToPolyTraitRef<'tcx> for TraitRef<'tcx> { | |
1325 | fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> { | |
83c7162d | 1326 | ty::Binder::dummy(self.clone()) |
e9174d1e SL |
1327 | } |
1328 | } | |
1329 | ||
1330 | impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> { | |
1331 | fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> { | |
7453a54e | 1332 | self.map_bound_ref(|trait_pred| trait_pred.trait_ref) |
e9174d1e SL |
1333 | } |
1334 | } | |
1335 | ||
e9174d1e SL |
1336 | pub trait ToPredicate<'tcx> { |
1337 | fn to_predicate(&self) -> Predicate<'tcx>; | |
1338 | } | |
1339 | ||
1340 | impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> { | |
1341 | fn to_predicate(&self) -> Predicate<'tcx> { | |
83c7162d | 1342 | ty::Predicate::Trait(ty::Binder::dummy(ty::TraitPredicate { |
e9174d1e SL |
1343 | trait_ref: self.clone() |
1344 | })) | |
1345 | } | |
1346 | } | |
1347 | ||
1348 | impl<'tcx> ToPredicate<'tcx> for PolyTraitRef<'tcx> { | |
1349 | fn to_predicate(&self) -> Predicate<'tcx> { | |
1350 | ty::Predicate::Trait(self.to_poly_trait_predicate()) | |
1351 | } | |
1352 | } | |
1353 | ||
9e0c209e | 1354 | impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> { |
e9174d1e SL |
1355 | fn to_predicate(&self) -> Predicate<'tcx> { |
1356 | Predicate::RegionOutlives(self.clone()) | |
1357 | } | |
1358 | } | |
1359 | ||
1360 | impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> { | |
1361 | fn to_predicate(&self) -> Predicate<'tcx> { | |
1362 | Predicate::TypeOutlives(self.clone()) | |
1363 | } | |
1364 | } | |
1365 | ||
1366 | impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> { | |
1367 | fn to_predicate(&self) -> Predicate<'tcx> { | |
1368 | Predicate::Projection(self.clone()) | |
1369 | } | |
1370 | } | |
1371 | ||
dc9dc135 | 1372 | // A custom iterator used by `Predicate::walk_tys`. |
a1dfa0c6 XL |
1373 | enum WalkTysIter<'tcx, I, J, K> |
1374 | where I: Iterator<Item = Ty<'tcx>>, | |
1375 | J: Iterator<Item = Ty<'tcx>>, | |
1376 | K: Iterator<Item = Ty<'tcx>> | |
1377 | { | |
1378 | None, | |
1379 | One(Ty<'tcx>), | |
1380 | Two(Ty<'tcx>, Ty<'tcx>), | |
1381 | Types(I), | |
1382 | InputTypes(J), | |
1383 | ProjectionTypes(K) | |
1384 | } | |
1385 | ||
1386 | impl<'tcx, I, J, K> Iterator for WalkTysIter<'tcx, I, J, K> | |
1387 | where I: Iterator<Item = Ty<'tcx>>, | |
1388 | J: Iterator<Item = Ty<'tcx>>, | |
1389 | K: Iterator<Item = Ty<'tcx>> | |
1390 | { | |
1391 | type Item = Ty<'tcx>; | |
1392 | ||
1393 | fn next(&mut self) -> Option<Ty<'tcx>> { | |
1394 | match *self { | |
1395 | WalkTysIter::None => None, | |
1396 | WalkTysIter::One(item) => { | |
1397 | *self = WalkTysIter::None; | |
1398 | Some(item) | |
1399 | }, | |
1400 | WalkTysIter::Two(item1, item2) => { | |
1401 | *self = WalkTysIter::One(item2); | |
1402 | Some(item1) | |
1403 | }, | |
1404 | WalkTysIter::Types(ref mut iter) => { | |
1405 | iter.next() | |
1406 | }, | |
1407 | WalkTysIter::InputTypes(ref mut iter) => { | |
1408 | iter.next() | |
1409 | }, | |
1410 | WalkTysIter::ProjectionTypes(ref mut iter) => { | |
1411 | iter.next() | |
1412 | } | |
1413 | } | |
1414 | } | |
1415 | } | |
1416 | ||
e9174d1e SL |
1417 | impl<'tcx> Predicate<'tcx> { |
1418 | /// Iterates over the types in this predicate. Note that in all | |
1419 | /// cases this is skipping over a binder, so late-bound regions | |
1420 | /// with depth 0 are bound by the predicate. | |
a1dfa0c6 XL |
1421 | pub fn walk_tys(&'a self) -> impl Iterator<Item = Ty<'tcx>> + 'a { |
1422 | match *self { | |
e9174d1e | 1423 | ty::Predicate::Trait(ref data) => { |
a1dfa0c6 | 1424 | WalkTysIter::InputTypes(data.skip_binder().input_types()) |
a7813a04 | 1425 | } |
83c7162d XL |
1426 | ty::Predicate::Subtype(binder) => { |
1427 | let SubtypePredicate { a, b, a_is_expected: _ } = binder.skip_binder(); | |
a1dfa0c6 | 1428 | WalkTysIter::Two(a, b) |
cc61c64b | 1429 | } |
83c7162d | 1430 | ty::Predicate::TypeOutlives(binder) => { |
a1dfa0c6 | 1431 | WalkTysIter::One(binder.skip_binder().0) |
e9174d1e SL |
1432 | } |
1433 | ty::Predicate::RegionOutlives(..) => { | |
a1dfa0c6 | 1434 | WalkTysIter::None |
e9174d1e SL |
1435 | } |
1436 | ty::Predicate::Projection(ref data) => { | |
83c7162d | 1437 | let inner = data.skip_binder(); |
a1dfa0c6 XL |
1438 | WalkTysIter::ProjectionTypes( |
1439 | inner.projection_ty.substs.types().chain(Some(inner.ty))) | |
e9174d1e SL |
1440 | } |
1441 | ty::Predicate::WellFormed(data) => { | |
a1dfa0c6 | 1442 | WalkTysIter::One(data) |
e9174d1e SL |
1443 | } |
1444 | ty::Predicate::ObjectSafe(_trait_def_id) => { | |
a1dfa0c6 | 1445 | WalkTysIter::None |
e9174d1e | 1446 | } |
ff7c6d11 | 1447 | ty::Predicate::ClosureKind(_closure_def_id, closure_substs, _kind) => { |
e74abb32 | 1448 | WalkTysIter::Types(closure_substs.types()) |
a7813a04 | 1449 | } |
ea8adc8c | 1450 | ty::Predicate::ConstEvaluatable(_, substs) => { |
a1dfa0c6 | 1451 | WalkTysIter::Types(substs.types()) |
ea8adc8c | 1452 | } |
a1dfa0c6 | 1453 | } |
e9174d1e SL |
1454 | } |
1455 | ||
1456 | pub fn to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'tcx>> { | |
1457 | match *self { | |
1458 | Predicate::Trait(ref t) => { | |
1459 | Some(t.to_poly_trait_ref()) | |
1460 | } | |
1461 | Predicate::Projection(..) | | |
cc61c64b | 1462 | Predicate::Subtype(..) | |
e9174d1e SL |
1463 | Predicate::RegionOutlives(..) | |
1464 | Predicate::WellFormed(..) | | |
1465 | Predicate::ObjectSafe(..) | | |
a7813a04 | 1466 | Predicate::ClosureKind(..) | |
ea8adc8c XL |
1467 | Predicate::TypeOutlives(..) | |
1468 | Predicate::ConstEvaluatable(..) => { | |
e9174d1e SL |
1469 | None |
1470 | } | |
1471 | } | |
1472 | } | |
abe05a73 XL |
1473 | |
1474 | pub fn to_opt_type_outlives(&self) -> Option<PolyTypeOutlivesPredicate<'tcx>> { | |
1475 | match *self { | |
1476 | Predicate::TypeOutlives(data) => { | |
1477 | Some(data) | |
1478 | } | |
1479 | Predicate::Trait(..) | | |
1480 | Predicate::Projection(..) | | |
abe05a73 XL |
1481 | Predicate::Subtype(..) | |
1482 | Predicate::RegionOutlives(..) | | |
1483 | Predicate::WellFormed(..) | | |
1484 | Predicate::ObjectSafe(..) | | |
1485 | Predicate::ClosureKind(..) | | |
1486 | Predicate::ConstEvaluatable(..) => { | |
1487 | None | |
1488 | } | |
1489 | } | |
1490 | } | |
e9174d1e SL |
1491 | } |
1492 | ||
1493 | /// Represents the bounds declared on a particular set of type | |
9fa01778 XL |
1494 | /// parameters. Should eventually be generalized into a flag list of |
1495 | /// where-clauses. You can obtain a `InstantiatedPredicates` list from a | |
e9174d1e SL |
1496 | /// `GenericPredicates` by using the `instantiate` method. Note that this method |
1497 | /// reflects an important semantic invariant of `InstantiatedPredicates`: while | |
1498 | /// the `GenericPredicates` are expressed in terms of the bound type | |
1499 | /// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance | |
1500 | /// represented a set of bounds for some particular instantiation, | |
1501 | /// meaning that the generic parameters have been substituted with | |
1502 | /// their values. | |
1503 | /// | |
1504 | /// Example: | |
1505 | /// | |
dc9dc135 | 1506 | /// struct Foo<T, U: Bar<T>> { ... } |
e9174d1e SL |
1507 | /// |
1508 | /// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like | |
9fa01778 | 1509 | /// `[[], [U:Bar<T>]]`. Now if there were some particular reference |
e9174d1e SL |
1510 | /// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[], |
1511 | /// [usize:Bar<isize>]]`. | |
60c5eb7d | 1512 | #[derive(Clone, Debug, TypeFoldable)] |
e9174d1e | 1513 | pub struct InstantiatedPredicates<'tcx> { |
9e0c209e | 1514 | pub predicates: Vec<Predicate<'tcx>>, |
e9174d1e SL |
1515 | } |
1516 | ||
1517 | impl<'tcx> InstantiatedPredicates<'tcx> { | |
1518 | pub fn empty() -> InstantiatedPredicates<'tcx> { | |
9e0c209e | 1519 | InstantiatedPredicates { predicates: vec![] } |
e9174d1e SL |
1520 | } |
1521 | ||
1522 | pub fn is_empty(&self) -> bool { | |
1523 | self.predicates.is_empty() | |
1524 | } | |
1525 | } | |
1526 | ||
e74abb32 | 1527 | rustc_index::newtype_index! { |
532ac7d7 XL |
1528 | /// "Universes" are used during type- and trait-checking in the |
1529 | /// presence of `for<..>` binders to control what sets of names are | |
1530 | /// visible. Universes are arranged into a tree: the root universe | |
1531 | /// contains names that are always visible. Each child then adds a new | |
1532 | /// set of names that are visible, in addition to those of its parent. | |
1533 | /// We say that the child universe "extends" the parent universe with | |
1534 | /// new names. | |
1535 | /// | |
1536 | /// To make this more concrete, consider this program: | |
1537 | /// | |
1538 | /// ``` | |
1539 | /// struct Foo { } | |
1540 | /// fn bar<T>(x: T) { | |
1541 | /// let y: for<'a> fn(&'a u8, Foo) = ...; | |
1542 | /// } | |
1543 | /// ``` | |
1544 | /// | |
1545 | /// The struct name `Foo` is in the root universe U0. But the type | |
1546 | /// parameter `T`, introduced on `bar`, is in an extended universe U1 | |
1547 | /// -- i.e., within `bar`, we can name both `T` and `Foo`, but outside | |
1548 | /// of `bar`, we cannot name `T`. Then, within the type of `y`, the | |
1549 | /// region `'a` is in a universe U2 that extends U1, because we can | |
1550 | /// name it inside the fn type but not outside. | |
1551 | /// | |
1552 | /// Universes are used to do type- and trait-checking around these | |
1553 | /// "forall" binders (also called **universal quantification**). The | |
1554 | /// idea is that when, in the body of `bar`, we refer to `T` as a | |
1555 | /// type, we aren't referring to any type in particular, but rather a | |
1556 | /// kind of "fresh" type that is distinct from all other types we have | |
1557 | /// actually declared. This is called a **placeholder** type, and we | |
1558 | /// use universes to talk about this. In other words, a type name in | |
1559 | /// universe 0 always corresponds to some "ground" type that the user | |
1560 | /// declared, but a type name in a non-zero universe is a placeholder | |
1561 | /// type -- an idealized representative of "types in general" that we | |
1562 | /// use for checking generic functions. | |
0bf4aa26 | 1563 | pub struct UniverseIndex { |
60c5eb7d | 1564 | derive [HashStable] |
0bf4aa26 XL |
1565 | DEBUG_FORMAT = "U{}", |
1566 | } | |
1567 | } | |
0531ce1d | 1568 | |
0bf4aa26 XL |
1569 | impl UniverseIndex { |
1570 | pub const ROOT: UniverseIndex = UniverseIndex::from_u32_const(0); | |
8faf50e0 | 1571 | |
0bf4aa26 XL |
1572 | /// Returns the "next" universe index in order -- this new index |
1573 | /// is considered to extend all previous universes. This | |
9fa01778 | 1574 | /// corresponds to entering a `forall` quantifier. So, for |
0bf4aa26 | 1575 | /// example, suppose we have this type in universe `U`: |
0531ce1d XL |
1576 | /// |
1577 | /// ``` | |
1578 | /// for<'a> fn(&'a u32) | |
1579 | /// ``` | |
1580 | /// | |
1581 | /// Once we "enter" into this `for<'a>` quantifier, we are in a | |
0bf4aa26 XL |
1582 | /// new universe that extends `U` -- in this new universe, we can |
1583 | /// name the region `'a`, but that region was not nameable from | |
1584 | /// `U` because it was not in scope there. | |
1585 | pub fn next_universe(self) -> UniverseIndex { | |
1586 | UniverseIndex::from_u32(self.private.checked_add(1).unwrap()) | |
8faf50e0 XL |
1587 | } |
1588 | ||
a1dfa0c6 | 1589 | /// Returns `true` if `self` can name a name from `other` -- in other words, |
0bf4aa26 | 1590 | /// if the set of names in `self` is a superset of those in |
a1dfa0c6 | 1591 | /// `other` (`self >= other`). |
0bf4aa26 XL |
1592 | pub fn can_name(self, other: UniverseIndex) -> bool { |
1593 | self.private >= other.private | |
83c7162d | 1594 | } |
a1dfa0c6 XL |
1595 | |
1596 | /// Returns `true` if `self` cannot name some names from `other` -- in other | |
1597 | /// words, if the set of names in `self` is a strict subset of | |
1598 | /// those in `other` (`self < other`). | |
1599 | pub fn cannot_name(self, other: UniverseIndex) -> bool { | |
1600 | self.private < other.private | |
1601 | } | |
83c7162d XL |
1602 | } |
1603 | ||
0bf4aa26 XL |
1604 | /// The "placeholder index" fully defines a placeholder region. |
1605 | /// Placeholder regions are identified by both a **universe** as well | |
1606 | /// as a "bound-region" within that universe. The `bound_region` is | |
1607 | /// basically a name -- distinct bound regions within the same | |
1608 | /// universe are just two regions with an unknown relationship to one | |
1609 | /// another. | |
1610 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, PartialOrd, Ord)] | |
a1dfa0c6 | 1611 | pub struct Placeholder<T> { |
0bf4aa26 | 1612 | pub universe: UniverseIndex, |
a1dfa0c6 | 1613 | pub name: T, |
0531ce1d XL |
1614 | } |
1615 | ||
dc9dc135 XL |
1616 | impl<'a, T> HashStable<StableHashingContext<'a>> for Placeholder<T> |
1617 | where | |
1618 | T: HashStable<StableHashingContext<'a>>, | |
a1dfa0c6 | 1619 | { |
e74abb32 | 1620 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
a1dfa0c6 XL |
1621 | self.universe.hash_stable(hcx, hasher); |
1622 | self.name.hash_stable(hcx, hasher); | |
1623 | } | |
1624 | } | |
1625 | ||
1626 | pub type PlaceholderRegion = Placeholder<BoundRegion>; | |
1627 | ||
1628 | pub type PlaceholderType = Placeholder<BoundVar>; | |
1629 | ||
48663c56 XL |
1630 | pub type PlaceholderConst = Placeholder<BoundVar>; |
1631 | ||
7cac9316 XL |
1632 | /// When type checking, we use the `ParamEnv` to track |
1633 | /// details about the set of where-clauses that are in scope at this | |
1634 | /// particular point. | |
60c5eb7d | 1635 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TypeFoldable)] |
7cac9316 | 1636 | pub struct ParamEnv<'tcx> { |
416331ca | 1637 | /// `Obligation`s that the caller must satisfy. This is basically |
e9174d1e | 1638 | /// the set of bounds on the in-scope type parameters, translated |
416331ca | 1639 | /// into `Obligation`s, and elaborated and normalized. |
b7449926 | 1640 | pub caller_bounds: &'tcx List<ty::Predicate<'tcx>>, |
7cac9316 | 1641 | |
94b46f34 | 1642 | /// Typically, this is `Reveal::UserFacing`, but during codegen we |
7cac9316 XL |
1643 | /// want `Reveal::All` -- note that this is always paired with an |
1644 | /// empty environment. To get that, use `ParamEnv::reveal()`. | |
1645 | pub reveal: traits::Reveal, | |
0731742a XL |
1646 | |
1647 | /// If this `ParamEnv` comes from a call to `tcx.param_env(def_id)`, | |
1648 | /// register that `def_id` (useful for transitioning to the chalk trait | |
1649 | /// solver). | |
1650 | pub def_id: Option<DefId>, | |
7cac9316 XL |
1651 | } |
1652 | ||
1653 | impl<'tcx> ParamEnv<'tcx> { | |
0531ce1d | 1654 | /// Construct a trait environment suitable for contexts where |
9fa01778 | 1655 | /// there are no where-clauses in scope. Hidden types (like `impl |
0531ce1d XL |
1656 | /// Trait`) are left hidden, so this is suitable for ordinary |
1657 | /// type-checking. | |
a1dfa0c6 | 1658 | #[inline] |
0531ce1d | 1659 | pub fn empty() -> Self { |
0731742a | 1660 | Self::new(List::empty(), Reveal::UserFacing, None) |
0531ce1d XL |
1661 | } |
1662 | ||
9fa01778 | 1663 | /// Construct a trait environment with no where-clauses in scope |
0531ce1d XL |
1664 | /// where the values of all `impl Trait` and other hidden types |
1665 | /// are revealed. This is suitable for monomorphized, post-typeck | |
94b46f34 | 1666 | /// environments like codegen or doing optimizations. |
0531ce1d | 1667 | /// |
9fa01778 | 1668 | /// N.B., if you want to have predicates in scope, use `ParamEnv::new`, |
0531ce1d | 1669 | /// or invoke `param_env.with_reveal_all()`. |
a1dfa0c6 | 1670 | #[inline] |
0531ce1d | 1671 | pub fn reveal_all() -> Self { |
0731742a | 1672 | Self::new(List::empty(), Reveal::All, None) |
0531ce1d XL |
1673 | } |
1674 | ||
1675 | /// Construct a trait environment with the given set of predicates. | |
a1dfa0c6 | 1676 | #[inline] |
0731742a XL |
1677 | pub fn new( |
1678 | caller_bounds: &'tcx List<ty::Predicate<'tcx>>, | |
1679 | reveal: Reveal, | |
1680 | def_id: Option<DefId> | |
1681 | ) -> Self { | |
1682 | ty::ParamEnv { caller_bounds, reveal, def_id } | |
0531ce1d XL |
1683 | } |
1684 | ||
1685 | /// Returns a new parameter environment with the same clauses, but | |
1686 | /// which "reveals" the true results of projections in all cases | |
9fa01778 | 1687 | /// (even for associated types that are specializable). This is |
94b46f34 | 1688 | /// the desired behavior during codegen and certain other special |
0531ce1d XL |
1689 | /// contexts; normally though we want to use `Reveal::UserFacing`, |
1690 | /// which is the default. | |
1691 | pub fn with_reveal_all(self) -> Self { | |
1692 | ty::ParamEnv { reveal: Reveal::All, ..self } | |
1693 | } | |
1694 | ||
1695 | /// Returns this same environment but with no caller bounds. | |
1696 | pub fn without_caller_bounds(self) -> Self { | |
b7449926 | 1697 | ty::ParamEnv { caller_bounds: List::empty(), ..self } |
0531ce1d XL |
1698 | } |
1699 | ||
7cac9316 | 1700 | /// Creates a suitable environment in which to perform trait |
0531ce1d XL |
1701 | /// queries on the given value. When type-checking, this is simply |
1702 | /// the pair of the environment plus value. But when reveal is set to | |
1703 | /// All, then if `value` does not reference any type parameters, we will | |
1704 | /// pair it with the empty environment. This improves caching and is generally | |
1705 | /// invisible. | |
e9174d1e | 1706 | /// |
0731742a | 1707 | /// N.B., we preserve the environment when type-checking because it |
0531ce1d | 1708 | /// is possible for the user to have wacky where-clauses like |
7cac9316 | 1709 | /// `where Box<u32>: Copy`, which are clearly never |
0531ce1d XL |
1710 | /// satisfiable. We generally want to behave as if they were true, |
1711 | /// although the surrounding function is never reachable. | |
7cac9316 | 1712 | pub fn and<T: TypeFoldable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> { |
0531ce1d XL |
1713 | match self.reveal { |
1714 | Reveal::UserFacing => { | |
1715 | ParamEnvAnd { | |
1716 | param_env: self, | |
1717 | value, | |
1718 | } | |
e9174d1e | 1719 | } |
0531ce1d XL |
1720 | |
1721 | Reveal::All => { | |
a1dfa0c6 | 1722 | if value.has_placeholders() |
83c7162d XL |
1723 | || value.needs_infer() |
1724 | || value.has_param_types() | |
83c7162d | 1725 | { |
0531ce1d XL |
1726 | ParamEnvAnd { |
1727 | param_env: self, | |
1728 | value, | |
1729 | } | |
1730 | } else { | |
1731 | ParamEnvAnd { | |
1732 | param_env: self.without_caller_bounds(), | |
1733 | value, | |
1734 | } | |
1735 | } | |
e9174d1e SL |
1736 | } |
1737 | } | |
1738 | } | |
1739 | } | |
1740 | ||
60c5eb7d | 1741 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)] |
7cac9316 XL |
1742 | pub struct ParamEnvAnd<'tcx, T> { |
1743 | pub param_env: ParamEnv<'tcx>, | |
1744 | pub value: T, | |
1745 | } | |
1746 | ||
1747 | impl<'tcx, T> ParamEnvAnd<'tcx, T> { | |
1748 | pub fn into_parts(self) -> (ParamEnv<'tcx>, T) { | |
1749 | (self.param_env, self.value) | |
1750 | } | |
1751 | } | |
1752 | ||
dc9dc135 XL |
1753 | impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>> for ParamEnvAnd<'tcx, T> |
1754 | where | |
1755 | T: HashStable<StableHashingContext<'a>>, | |
ea8adc8c | 1756 | { |
e74abb32 | 1757 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
ea8adc8c XL |
1758 | let ParamEnvAnd { |
1759 | ref param_env, | |
1760 | ref value | |
1761 | } = *self; | |
1762 | ||
1763 | param_env.hash_stable(hcx, hasher); | |
1764 | value.hash_stable(hcx, hasher); | |
1765 | } | |
1766 | } | |
1767 | ||
532ac7d7 | 1768 | #[derive(Copy, Clone, Debug, HashStable)] |
8bb4bdeb | 1769 | pub struct Destructor { |
9fa01778 | 1770 | /// The `DefId` of the destructor method |
8bb4bdeb | 1771 | pub did: DefId, |
8bb4bdeb XL |
1772 | } |
1773 | ||
e9174d1e | 1774 | bitflags! { |
532ac7d7 | 1775 | #[derive(HashStable)] |
ea8adc8c XL |
1776 | pub struct AdtFlags: u32 { |
1777 | const NO_ADT_FLAGS = 0; | |
532ac7d7 | 1778 | /// Indicates whether the ADT is an enum. |
ea8adc8c | 1779 | const IS_ENUM = 1 << 0; |
532ac7d7 | 1780 | /// Indicates whether the ADT is a union. |
69743fb6 | 1781 | const IS_UNION = 1 << 1; |
532ac7d7 | 1782 | /// Indicates whether the ADT is a struct. |
69743fb6 | 1783 | const IS_STRUCT = 1 << 2; |
532ac7d7 | 1784 | /// Indicates whether the ADT is a struct and has a constructor. |
69743fb6 | 1785 | const HAS_CTOR = 1 << 3; |
532ac7d7 | 1786 | /// Indicates whether the type is a `PhantomData`. |
69743fb6 | 1787 | const IS_PHANTOM_DATA = 1 << 4; |
532ac7d7 | 1788 | /// Indicates whether the type has a `#[fundamental]` attribute. |
69743fb6 | 1789 | const IS_FUNDAMENTAL = 1 << 5; |
532ac7d7 | 1790 | /// Indicates whether the type is a `Box`. |
69743fb6 | 1791 | const IS_BOX = 1 << 6; |
0bf4aa26 | 1792 | /// Indicates whether the type is an `Arc`. |
69743fb6 | 1793 | const IS_ARC = 1 << 7; |
0bf4aa26 | 1794 | /// Indicates whether the type is an `Rc`. |
69743fb6 | 1795 | const IS_RC = 1 << 8; |
b7449926 XL |
1796 | /// Indicates whether the variant list of this ADT is `#[non_exhaustive]`. |
1797 | /// (i.e., this flag is never set unless this ADT is an enum). | |
69743fb6 | 1798 | const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 9; |
b7449926 XL |
1799 | } |
1800 | } | |
1801 | ||
1802 | bitflags! { | |
532ac7d7 | 1803 | #[derive(HashStable)] |
b7449926 XL |
1804 | pub struct VariantFlags: u32 { |
1805 | const NO_VARIANT_FLAGS = 0; | |
1806 | /// Indicates whether the field list of this variant is `#[non_exhaustive]`. | |
1807 | const IS_FIELD_LIST_NON_EXHAUSTIVE = 1 << 0; | |
e9174d1e SL |
1808 | } |
1809 | } | |
1810 | ||
532ac7d7 | 1811 | /// Definition of a variant -- a struct's fields or a enum variant. |
60c5eb7d | 1812 | #[derive(Debug, HashStable)] |
476ff2be | 1813 | pub struct VariantDef { |
532ac7d7 XL |
1814 | /// `DefId` that identifies the variant itself. |
1815 | /// If this variant belongs to a struct or union, then this is a copy of its `DefId`. | |
1816 | pub def_id: DefId, | |
1817 | /// `DefId` that identifies the variant's constructor. | |
1818 | /// If this variant is a struct variant, then this is `None`. | |
1819 | pub ctor_def_id: Option<DefId>, | |
1820 | /// Variant or struct name. | |
60c5eb7d | 1821 | #[stable_hasher(project(name))] |
532ac7d7 XL |
1822 | pub ident: Ident, |
1823 | /// Discriminant of this variant. | |
8bb4bdeb | 1824 | pub discr: VariantDiscr, |
532ac7d7 | 1825 | /// Fields of this variant. |
476ff2be | 1826 | pub fields: Vec<FieldDef>, |
532ac7d7 | 1827 | /// Type of constructor of variant. |
c30ab7b3 | 1828 | pub ctor_kind: CtorKind, |
532ac7d7 | 1829 | /// Flags of the variant (e.g. is field list non-exhaustive)? |
b7449926 | 1830 | flags: VariantFlags, |
416331ca XL |
1831 | /// Variant is obtained as part of recovering from a syntactic error. |
1832 | /// May be incomplete or bogus. | |
532ac7d7 | 1833 | pub recovered: bool, |
e9174d1e SL |
1834 | } |
1835 | ||
dc9dc135 | 1836 | impl<'tcx> VariantDef { |
9fa01778 | 1837 | /// Creates a new `VariantDef`. |
b7449926 | 1838 | /// |
532ac7d7 XL |
1839 | /// `variant_did` is the `DefId` that identifies the enum variant (if this `VariantDef` |
1840 | /// represents an enum variant). | |
1841 | /// | |
1842 | /// `ctor_did` is the `DefId` that identifies the constructor of unit or | |
1843 | /// tuple-variants/structs. If this is a `struct`-variant then this should be `None`. | |
0bf4aa26 | 1844 | /// |
532ac7d7 XL |
1845 | /// `parent_did` is the `DefId` of the `AdtDef` representing the enum or struct that |
1846 | /// owns this variant. It is used for checking if a struct has `#[non_exhaustive]` w/out having | |
1847 | /// to go through the redirect of checking the ctor's attributes - but compiling a small crate | |
1848 | /// requires loading the `AdtDef`s for all the structs in the universe (e.g., coherence for any | |
0bf4aa26 XL |
1849 | /// built-in trait), and we do not want to load attributes twice. |
1850 | /// | |
1851 | /// If someone speeds up attribute loading to not be a performance concern, they can | |
9fa01778 | 1852 | /// remove this hack and use the constructor `DefId` everywhere. |
532ac7d7 | 1853 | pub fn new( |
dc9dc135 | 1854 | tcx: TyCtxt<'tcx>, |
532ac7d7 XL |
1855 | ident: Ident, |
1856 | variant_did: Option<DefId>, | |
1857 | ctor_def_id: Option<DefId>, | |
1858 | discr: VariantDiscr, | |
1859 | fields: Vec<FieldDef>, | |
1860 | ctor_kind: CtorKind, | |
1861 | adt_kind: AdtKind, | |
1862 | parent_did: DefId, | |
1863 | recovered: bool, | |
1864 | ) -> Self { | |
1865 | debug!( | |
1866 | "VariantDef::new(ident = {:?}, variant_did = {:?}, ctor_def_id = {:?}, discr = {:?}, | |
1867 | fields = {:?}, ctor_kind = {:?}, adt_kind = {:?}, parent_did = {:?})", | |
1868 | ident, variant_did, ctor_def_id, discr, fields, ctor_kind, adt_kind, parent_did, | |
1869 | ); | |
1870 | ||
b7449926 | 1871 | let mut flags = VariantFlags::NO_VARIANT_FLAGS; |
48663c56 | 1872 | if adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, sym::non_exhaustive) { |
532ac7d7 | 1873 | debug!("found non-exhaustive field list for {:?}", parent_did); |
b7449926 | 1874 | flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE; |
532ac7d7 | 1875 | } else if let Some(variant_did) = variant_did { |
48663c56 | 1876 | if tcx.has_attr(variant_did, sym::non_exhaustive) { |
532ac7d7 XL |
1877 | debug!("found non-exhaustive field list for {:?}", variant_did); |
1878 | flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE; | |
1879 | } | |
b7449926 | 1880 | } |
532ac7d7 | 1881 | |
b7449926 | 1882 | VariantDef { |
532ac7d7 XL |
1883 | def_id: variant_did.unwrap_or(parent_did), |
1884 | ctor_def_id, | |
0731742a | 1885 | ident, |
b7449926 XL |
1886 | discr, |
1887 | fields, | |
1888 | ctor_kind, | |
532ac7d7 XL |
1889 | flags, |
1890 | recovered, | |
b7449926 XL |
1891 | } |
1892 | } | |
1893 | ||
532ac7d7 | 1894 | /// Is this field list non-exhaustive? |
b7449926 XL |
1895 | #[inline] |
1896 | pub fn is_field_list_non_exhaustive(&self) -> bool { | |
1897 | self.flags.intersects(VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE) | |
1898 | } | |
1899 | } | |
1900 | ||
532ac7d7 | 1901 | #[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)] |
8bb4bdeb | 1902 | pub enum VariantDiscr { |
0731742a | 1903 | /// Explicit value for this variant, i.e., `X = 123`. |
8bb4bdeb XL |
1904 | /// The `DefId` corresponds to the embedded constant. |
1905 | Explicit(DefId), | |
1906 | ||
1907 | /// The previous variant's discriminant plus one. | |
1908 | /// For efficiency reasons, the distance from the | |
1909 | /// last `Explicit` discriminant is being stored, | |
1910 | /// or `0` for the first variant, if it has none. | |
a1dfa0c6 | 1911 | Relative(u32), |
8bb4bdeb XL |
1912 | } |
1913 | ||
532ac7d7 | 1914 | #[derive(Debug, HashStable)] |
476ff2be | 1915 | pub struct FieldDef { |
e9174d1e | 1916 | pub did: DefId, |
532ac7d7 | 1917 | #[stable_hasher(project(name))] |
94b46f34 | 1918 | pub ident: Ident, |
54a0048b | 1919 | pub vis: Visibility, |
e9174d1e SL |
1920 | } |
1921 | ||
e1599b0c | 1922 | /// The definition of a user-defined type, e.g., a `struct`, `enum`, or `union`. |
e9174d1e | 1923 | /// |
532ac7d7 | 1924 | /// These are all interned (by `intern_adt_def`) into the `adt_defs` table. |
e1599b0c | 1925 | /// |
60c5eb7d | 1926 | /// The initialism *ADT* stands for an [*algebraic data type (ADT)*][adt]. |
e1599b0c XL |
1927 | /// This is slightly wrong because `union`s are not ADTs. |
1928 | /// Moreover, Rust only allows recursive data types through indirection. | |
1929 | /// | |
1930 | /// [adt]: https://en.wikipedia.org/wiki/Algebraic_data_type | |
476ff2be | 1931 | pub struct AdtDef { |
60c5eb7d | 1932 | /// The `DefId` of the struct, enum or union item. |
e9174d1e | 1933 | pub did: DefId, |
416331ca | 1934 | /// Variants of the ADT. If this is a struct or union, then there will be a single variant. |
a1dfa0c6 | 1935 | pub variants: IndexVec<self::layout::VariantIdx, VariantDef>, |
60c5eb7d | 1936 | /// Flags of the ADT (e.g., is this a struct? is this non-exhaustive?). |
8bb4bdeb | 1937 | flags: AdtFlags, |
532ac7d7 | 1938 | /// Repr options provided by the user. |
8bb4bdeb | 1939 | pub repr: ReprOptions, |
e9174d1e SL |
1940 | } |
1941 | ||
94b46f34 XL |
1942 | impl PartialOrd for AdtDef { |
1943 | fn partial_cmp(&self, other: &AdtDef) -> Option<Ordering> { | |
1944 | Some(self.cmp(&other)) | |
1945 | } | |
1946 | } | |
1947 | ||
1948 | /// There should be only one AdtDef for each `did`, therefore | |
1949 | /// it is fine to implement `Ord` only based on `did`. | |
1950 | impl Ord for AdtDef { | |
1951 | fn cmp(&self, other: &AdtDef) -> Ordering { | |
1952 | self.did.cmp(&other.did) | |
1953 | } | |
1954 | } | |
1955 | ||
476ff2be | 1956 | impl PartialEq for AdtDef { |
60c5eb7d | 1957 | // `AdtDef`s are always interned, and this is part of `TyS` equality. |
e9174d1e | 1958 | #[inline] |
8faf50e0 | 1959 | fn eq(&self, other: &Self) -> bool { ptr::eq(self, other) } |
e9174d1e SL |
1960 | } |
1961 | ||
476ff2be | 1962 | impl Eq for AdtDef {} |
e9174d1e | 1963 | |
476ff2be | 1964 | impl Hash for AdtDef { |
e9174d1e SL |
1965 | #[inline] |
1966 | fn hash<H: Hasher>(&self, s: &mut H) { | |
476ff2be | 1967 | (self as *const AdtDef).hash(s) |
e9174d1e SL |
1968 | } |
1969 | } | |
1970 | ||
416331ca | 1971 | impl<'tcx> rustc_serialize::UseSpecializedEncodable for &'tcx AdtDef { |
9e0c209e | 1972 | fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { |
9cc50fc6 SL |
1973 | self.did.encode(s) |
1974 | } | |
1975 | } | |
1976 | ||
416331ca | 1977 | impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx AdtDef {} |
e9174d1e | 1978 | |
0531ce1d | 1979 | impl<'a> HashStable<StableHashingContext<'a>> for AdtDef { |
e74abb32 | 1980 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
2c00a5a8 | 1981 | thread_local! { |
0bf4aa26 | 1982 | static CACHE: RefCell<FxHashMap<usize, Fingerprint>> = Default::default(); |
2c00a5a8 XL |
1983 | } |
1984 | ||
1985 | let hash: Fingerprint = CACHE.with(|cache| { | |
1986 | let addr = self as *const AdtDef as usize; | |
1987 | *cache.borrow_mut().entry(addr).or_insert_with(|| { | |
1988 | let ty::AdtDef { | |
1989 | did, | |
1990 | ref variants, | |
1991 | ref flags, | |
1992 | ref repr, | |
1993 | } = *self; | |
cc61c64b | 1994 | |
2c00a5a8 XL |
1995 | let mut hasher = StableHasher::new(); |
1996 | did.hash_stable(hcx, &mut hasher); | |
1997 | variants.hash_stable(hcx, &mut hasher); | |
1998 | flags.hash_stable(hcx, &mut hasher); | |
1999 | repr.hash_stable(hcx, &mut hasher); | |
2000 | ||
2001 | hasher.finish() | |
2002 | }) | |
2003 | }); | |
2004 | ||
2005 | hash.hash_stable(hcx, hasher); | |
cc61c64b XL |
2006 | } |
2007 | } | |
2008 | ||
0531ce1d | 2009 | #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] |
9e0c209e | 2010 | pub enum AdtKind { Struct, Union, Enum } |
e9174d1e | 2011 | |
b7449926 XL |
2012 | impl Into<DataTypeKind> for AdtKind { |
2013 | fn into(self) -> DataTypeKind { | |
2014 | match self { | |
2015 | AdtKind::Struct => DataTypeKind::Struct, | |
2016 | AdtKind::Union => DataTypeKind::Union, | |
2017 | AdtKind::Enum => DataTypeKind::Enum, | |
2018 | } | |
2019 | } | |
2020 | } | |
2021 | ||
cc61c64b | 2022 | bitflags! { |
60c5eb7d | 2023 | #[derive(RustcEncodable, RustcDecodable, Default, HashStable)] |
ea8adc8c XL |
2024 | pub struct ReprFlags: u8 { |
2025 | const IS_C = 1 << 0; | |
83c7162d XL |
2026 | const IS_SIMD = 1 << 1; |
2027 | const IS_TRANSPARENT = 1 << 2; | |
cc61c64b | 2028 | // Internal only for now. If true, don't reorder fields. |
83c7162d | 2029 | const IS_LINEAR = 1 << 3; |
cc61c64b XL |
2030 | |
2031 | // Any of these flags being set prevent field reordering optimisation. | |
2032 | const IS_UNOPTIMISABLE = ReprFlags::IS_C.bits | | |
cc61c64b | 2033 | ReprFlags::IS_SIMD.bits | |
ea8adc8c | 2034 | ReprFlags::IS_LINEAR.bits; |
cc61c64b XL |
2035 | } |
2036 | } | |
2037 | ||
8bb4bdeb | 2038 | /// Represents the repr options provided by the user, |
60c5eb7d XL |
2039 | #[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, |
2040 | Default, HashStable)] | |
8bb4bdeb | 2041 | pub struct ReprOptions { |
8bb4bdeb | 2042 | pub int: Option<attr::IntType>, |
e1599b0c XL |
2043 | pub align: Option<Align>, |
2044 | pub pack: Option<Align>, | |
cc61c64b | 2045 | pub flags: ReprFlags, |
8bb4bdeb XL |
2046 | } |
2047 | ||
2048 | impl ReprOptions { | |
dc9dc135 | 2049 | pub fn new(tcx: TyCtxt<'_>, did: DefId) -> ReprOptions { |
cc61c64b XL |
2050 | let mut flags = ReprFlags::empty(); |
2051 | let mut size = None; | |
e1599b0c XL |
2052 | let mut max_align: Option<Align> = None; |
2053 | let mut min_pack: Option<Align> = None; | |
8bb4bdeb | 2054 | for attr in tcx.get_attrs(did).iter() { |
a1dfa0c6 | 2055 | for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) { |
cc61c64b | 2056 | flags.insert(match r { |
2c00a5a8 | 2057 | attr::ReprC => ReprFlags::IS_C, |
83c7162d | 2058 | attr::ReprPacked(pack) => { |
e1599b0c XL |
2059 | let pack = Align::from_bytes(pack as u64).unwrap(); |
2060 | min_pack = Some(if let Some(min_pack) = min_pack { | |
2061 | min_pack.min(pack) | |
83c7162d XL |
2062 | } else { |
2063 | pack | |
e1599b0c | 2064 | }); |
83c7162d XL |
2065 | ReprFlags::empty() |
2066 | }, | |
2c00a5a8 | 2067 | attr::ReprTransparent => ReprFlags::IS_TRANSPARENT, |
cc61c64b XL |
2068 | attr::ReprSimd => ReprFlags::IS_SIMD, |
2069 | attr::ReprInt(i) => { | |
2070 | size = Some(i); | |
2071 | ReprFlags::empty() | |
2072 | }, | |
2073 | attr::ReprAlign(align) => { | |
e1599b0c | 2074 | max_align = max_align.max(Some(Align::from_bytes(align as u64).unwrap())); |
cc61c64b XL |
2075 | ReprFlags::empty() |
2076 | }, | |
2077 | }); | |
8bb4bdeb XL |
2078 | } |
2079 | } | |
2080 | ||
cc61c64b | 2081 | // This is here instead of layout because the choice must make it into metadata. |
532ac7d7 | 2082 | if !tcx.consider_optimizing(|| format!("Reorder fields of {:?}", tcx.def_path_str(did))) { |
cc61c64b XL |
2083 | flags.insert(ReprFlags::IS_LINEAR); |
2084 | } | |
83c7162d | 2085 | ReprOptions { int: size, align: max_align, pack: min_pack, flags: flags } |
8bb4bdeb XL |
2086 | } |
2087 | ||
cc61c64b XL |
2088 | #[inline] |
2089 | pub fn simd(&self) -> bool { self.flags.contains(ReprFlags::IS_SIMD) } | |
2090 | #[inline] | |
2091 | pub fn c(&self) -> bool { self.flags.contains(ReprFlags::IS_C) } | |
2092 | #[inline] | |
e1599b0c | 2093 | pub fn packed(&self) -> bool { self.pack.is_some() } |
cc61c64b | 2094 | #[inline] |
2c00a5a8 XL |
2095 | pub fn transparent(&self) -> bool { self.flags.contains(ReprFlags::IS_TRANSPARENT) } |
2096 | #[inline] | |
cc61c64b XL |
2097 | pub fn linear(&self) -> bool { self.flags.contains(ReprFlags::IS_LINEAR) } |
2098 | ||
8bb4bdeb | 2099 | pub fn discr_type(&self) -> attr::IntType { |
2c00a5a8 | 2100 | self.int.unwrap_or(attr::SignedInt(ast::IntTy::Isize)) |
8bb4bdeb XL |
2101 | } |
2102 | ||
a1dfa0c6 | 2103 | /// Returns `true` if this `#[repr()]` should inhabit "smart enum |
8bb4bdeb XL |
2104 | /// layout" optimizations, such as representing `Foo<&T>` as a |
2105 | /// single pointer. | |
2106 | pub fn inhibit_enum_layout_opt(&self) -> bool { | |
cc61c64b | 2107 | self.c() || self.int.is_some() |
8bb4bdeb | 2108 | } |
83c7162d | 2109 | |
a1dfa0c6 | 2110 | /// Returns `true` if this `#[repr()]` should inhibit struct field reordering |
9fa01778 | 2111 | /// optimizations, such as with `repr(C)`, `repr(packed(1))`, or `repr(<int>)`. |
83c7162d | 2112 | pub fn inhibit_struct_field_reordering_opt(&self) -> bool { |
e1599b0c XL |
2113 | if let Some(pack) = self.pack { |
2114 | if pack.bytes() == 1 { | |
2115 | return true; | |
2116 | } | |
2117 | } | |
2118 | self.flags.intersects(ReprFlags::IS_UNOPTIMISABLE) || self.int.is_some() | |
83c7162d | 2119 | } |
a1dfa0c6 | 2120 | |
9fa01778 | 2121 | /// Returns `true` if this `#[repr()]` should inhibit union ABI optimisations. |
a1dfa0c6 XL |
2122 | pub fn inhibit_union_abi_opt(&self) -> bool { |
2123 | self.c() | |
2124 | } | |
8bb4bdeb XL |
2125 | } |
2126 | ||
dc9dc135 | 2127 | impl<'tcx> AdtDef { |
532ac7d7 XL |
2128 | /// Creates a new `AdtDef`. |
2129 | fn new( | |
dc9dc135 | 2130 | tcx: TyCtxt<'_>, |
532ac7d7 XL |
2131 | did: DefId, |
2132 | kind: AdtKind, | |
2133 | variants: IndexVec<VariantIdx, VariantDef>, | |
dc9dc135 | 2134 | repr: ReprOptions, |
532ac7d7 | 2135 | ) -> Self { |
b7449926 | 2136 | debug!("AdtDef::new({:?}, {:?}, {:?}, {:?})", did, kind, variants, repr); |
e9174d1e | 2137 | let mut flags = AdtFlags::NO_ADT_FLAGS; |
69743fb6 | 2138 | |
48663c56 | 2139 | if kind == AdtKind::Enum && tcx.has_attr(did, sym::non_exhaustive) { |
69743fb6 XL |
2140 | debug!("found non-exhaustive variant list for {:?}", did); |
2141 | flags = flags | AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE; | |
2142 | } | |
532ac7d7 | 2143 | |
69743fb6 XL |
2144 | flags |= match kind { |
2145 | AdtKind::Enum => AdtFlags::IS_ENUM, | |
2146 | AdtKind::Union => AdtFlags::IS_UNION, | |
2147 | AdtKind::Struct => AdtFlags::IS_STRUCT, | |
2148 | }; | |
2149 | ||
532ac7d7 XL |
2150 | if kind == AdtKind::Struct && variants[VariantIdx::new(0)].ctor_def_id.is_some() { |
2151 | flags |= AdtFlags::HAS_CTOR; | |
69743fb6 XL |
2152 | } |
2153 | ||
e9174d1e | 2154 | let attrs = tcx.get_attrs(did); |
48663c56 | 2155 | if attr::contains_name(&attrs, sym::fundamental) { |
69743fb6 | 2156 | flags |= AdtFlags::IS_FUNDAMENTAL; |
e9174d1e | 2157 | } |
ea8adc8c | 2158 | if Some(did) == tcx.lang_items().phantom_data() { |
69743fb6 | 2159 | flags |= AdtFlags::IS_PHANTOM_DATA; |
e9174d1e | 2160 | } |
ea8adc8c | 2161 | if Some(did) == tcx.lang_items().owned_box() { |
69743fb6 | 2162 | flags |= AdtFlags::IS_BOX; |
32a655c1 | 2163 | } |
0bf4aa26 | 2164 | if Some(did) == tcx.lang_items().arc() { |
69743fb6 | 2165 | flags |= AdtFlags::IS_ARC; |
0bf4aa26 XL |
2166 | } |
2167 | if Some(did) == tcx.lang_items().rc() { | |
69743fb6 | 2168 | flags |= AdtFlags::IS_RC; |
e9174d1e | 2169 | } |
69743fb6 | 2170 | |
476ff2be | 2171 | AdtDef { |
041b39d2 XL |
2172 | did, |
2173 | variants, | |
2174 | flags, | |
2175 | repr, | |
e9174d1e SL |
2176 | } |
2177 | } | |
2178 | ||
532ac7d7 | 2179 | /// Returns `true` if this is a struct. |
9e0c209e SL |
2180 | #[inline] |
2181 | pub fn is_struct(&self) -> bool { | |
69743fb6 | 2182 | self.flags.contains(AdtFlags::IS_STRUCT) |
9e0c209e SL |
2183 | } |
2184 | ||
532ac7d7 | 2185 | /// Returns `true` if this is a union. |
9e0c209e SL |
2186 | #[inline] |
2187 | pub fn is_union(&self) -> bool { | |
69743fb6 | 2188 | self.flags.contains(AdtFlags::IS_UNION) |
9e0c209e SL |
2189 | } |
2190 | ||
532ac7d7 | 2191 | /// Returns `true` if this is a enum. |
9e0c209e SL |
2192 | #[inline] |
2193 | pub fn is_enum(&self) -> bool { | |
69743fb6 | 2194 | self.flags.contains(AdtFlags::IS_ENUM) |
9e0c209e SL |
2195 | } |
2196 | ||
532ac7d7 | 2197 | /// Returns `true` if the variant list of this ADT is `#[non_exhaustive]`. |
abe05a73 | 2198 | #[inline] |
b7449926 | 2199 | pub fn is_variant_list_non_exhaustive(&self) -> bool { |
69743fb6 | 2200 | self.flags.contains(AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE) |
abe05a73 XL |
2201 | } |
2202 | ||
69743fb6 | 2203 | /// Returns the kind of the ADT. |
e9174d1e SL |
2204 | #[inline] |
2205 | pub fn adt_kind(&self) -> AdtKind { | |
9e0c209e | 2206 | if self.is_enum() { |
e9174d1e | 2207 | AdtKind::Enum |
9e0c209e SL |
2208 | } else if self.is_union() { |
2209 | AdtKind::Union | |
e9174d1e SL |
2210 | } else { |
2211 | AdtKind::Struct | |
2212 | } | |
2213 | } | |
2214 | ||
532ac7d7 | 2215 | /// Returns a description of this abstract data type. |
9e0c209e SL |
2216 | pub fn descr(&self) -> &'static str { |
2217 | match self.adt_kind() { | |
2218 | AdtKind::Struct => "struct", | |
2219 | AdtKind::Union => "union", | |
2220 | AdtKind::Enum => "enum", | |
2221 | } | |
2222 | } | |
2223 | ||
532ac7d7 | 2224 | /// Returns a description of a variant of this abstract data type. |
a1dfa0c6 | 2225 | #[inline] |
9e0c209e SL |
2226 | pub fn variant_descr(&self) -> &'static str { |
2227 | match self.adt_kind() { | |
2228 | AdtKind::Struct => "struct", | |
2229 | AdtKind::Union => "union", | |
2230 | AdtKind::Enum => "variant", | |
2231 | } | |
2232 | } | |
2233 | ||
69743fb6 XL |
2234 | /// If this function returns `true`, it implies that `is_struct` must return `true`. |
2235 | #[inline] | |
2236 | pub fn has_ctor(&self) -> bool { | |
2237 | self.flags.contains(AdtFlags::HAS_CTOR) | |
2238 | } | |
2239 | ||
9fa01778 | 2240 | /// Returns `true` if this type is `#[fundamental]` for the purposes |
e9174d1e SL |
2241 | /// of coherence checking. |
2242 | #[inline] | |
2243 | pub fn is_fundamental(&self) -> bool { | |
69743fb6 | 2244 | self.flags.contains(AdtFlags::IS_FUNDAMENTAL) |
e9174d1e SL |
2245 | } |
2246 | ||
9fa01778 | 2247 | /// Returns `true` if this is `PhantomData<T>`. |
e9174d1e SL |
2248 | #[inline] |
2249 | pub fn is_phantom_data(&self) -> bool { | |
69743fb6 | 2250 | self.flags.contains(AdtFlags::IS_PHANTOM_DATA) |
e9174d1e SL |
2251 | } |
2252 | ||
0bf4aa26 XL |
2253 | /// Returns `true` if this is `Arc<T>`. |
2254 | pub fn is_arc(&self) -> bool { | |
69743fb6 | 2255 | self.flags.contains(AdtFlags::IS_ARC) |
0bf4aa26 XL |
2256 | } |
2257 | ||
2258 | /// Returns `true` if this is `Rc<T>`. | |
2259 | pub fn is_rc(&self) -> bool { | |
69743fb6 | 2260 | self.flags.contains(AdtFlags::IS_RC) |
0bf4aa26 XL |
2261 | } |
2262 | ||
a1dfa0c6 | 2263 | /// Returns `true` if this is Box<T>. |
32a655c1 SL |
2264 | #[inline] |
2265 | pub fn is_box(&self) -> bool { | |
69743fb6 | 2266 | self.flags.contains(AdtFlags::IS_BOX) |
32a655c1 SL |
2267 | } |
2268 | ||
9fa01778 | 2269 | /// Returns `true` if this type has a destructor. |
dc9dc135 | 2270 | pub fn has_dtor(&self, tcx: TyCtxt<'tcx>) -> bool { |
8bb4bdeb | 2271 | self.destructor(tcx).is_some() |
e9174d1e SL |
2272 | } |
2273 | ||
2c00a5a8 XL |
2274 | /// Asserts this is a struct or union and returns its unique variant. |
2275 | pub fn non_enum_variant(&self) -> &VariantDef { | |
2276 | assert!(self.is_struct() || self.is_union()); | |
a1dfa0c6 | 2277 | &self.variants[VariantIdx::new(0)] |
e9174d1e SL |
2278 | } |
2279 | ||
e9174d1e | 2280 | #[inline] |
e74abb32 | 2281 | pub fn predicates(&self, tcx: TyCtxt<'tcx>) -> GenericPredicates<'tcx> { |
7cac9316 | 2282 | tcx.predicates_of(self.did) |
e9174d1e SL |
2283 | } |
2284 | ||
2285 | /// Returns an iterator over all fields contained | |
2286 | /// by this ADT. | |
2287 | #[inline] | |
dc9dc135 | 2288 | pub fn all_fields(&self) -> impl Iterator<Item=&FieldDef> + Clone { |
476ff2be | 2289 | self.variants.iter().flat_map(|v| v.fields.iter()) |
e9174d1e SL |
2290 | } |
2291 | ||
e9174d1e SL |
2292 | pub fn is_payloadfree(&self) -> bool { |
2293 | !self.variants.is_empty() && | |
2294 | self.variants.iter().all(|v| v.fields.is_empty()) | |
2295 | } | |
2296 | ||
532ac7d7 | 2297 | /// Return a `VariantDef` given a variant id. |
476ff2be | 2298 | pub fn variant_with_id(&self, vid: DefId) -> &VariantDef { |
532ac7d7 | 2299 | self.variants.iter().find(|v| v.def_id == vid) |
e9174d1e SL |
2300 | .expect("variant_with_id: unknown variant") |
2301 | } | |
2302 | ||
532ac7d7 XL |
2303 | /// Return a `VariantDef` given a constructor id. |
2304 | pub fn variant_with_ctor_id(&self, cid: DefId) -> &VariantDef { | |
2305 | self.variants.iter().find(|v| v.ctor_def_id == Some(cid)) | |
2306 | .expect("variant_with_ctor_id: unknown variant") | |
2307 | } | |
2308 | ||
2309 | /// Return the index of `VariantDef` given a variant id. | |
a1dfa0c6 | 2310 | pub fn variant_index_with_id(&self, vid: DefId) -> VariantIdx { |
532ac7d7 XL |
2311 | self.variants.iter_enumerated().find(|(_, v)| v.def_id == vid) |
2312 | .expect("variant_index_with_id: unknown variant").0 | |
2313 | } | |
2314 | ||
2315 | /// Return the index of `VariantDef` given a constructor id. | |
2316 | pub fn variant_index_with_ctor_id(&self, cid: DefId) -> VariantIdx { | |
2317 | self.variants.iter_enumerated().find(|(_, v)| v.ctor_def_id == Some(cid)) | |
2318 | .expect("variant_index_with_ctor_id: unknown variant").0 | |
e9174d1e SL |
2319 | } |
2320 | ||
48663c56 XL |
2321 | pub fn variant_of_res(&self, res: Res) -> &VariantDef { |
2322 | match res { | |
2323 | Res::Def(DefKind::Variant, vid) => self.variant_with_id(vid), | |
2324 | Res::Def(DefKind::Ctor(..), cid) => self.variant_with_ctor_id(cid), | |
2325 | Res::Def(DefKind::Struct, _) | Res::Def(DefKind::Union, _) | | |
dc9dc135 | 2326 | Res::Def(DefKind::TyAlias, _) | Res::Def(DefKind::AssocTy, _) | Res::SelfTy(..) | |
48663c56 XL |
2327 | Res::SelfCtor(..) => self.non_enum_variant(), |
2328 | _ => bug!("unexpected res {:?} in variant_of_res", res) | |
e9174d1e SL |
2329 | } |
2330 | } | |
2331 | ||
cc61c64b | 2332 | #[inline] |
dc9dc135 | 2333 | pub fn eval_explicit_discr(&self, tcx: TyCtxt<'tcx>, expr_did: DefId) -> Option<Discr<'tcx>> { |
416331ca | 2334 | let param_env = tcx.param_env(expr_did); |
0531ce1d | 2335 | let repr_type = self.repr.discr_type(); |
e74abb32 | 2336 | let substs = InternalSubsts::identity_for_item(tcx, expr_did); |
0531ce1d XL |
2337 | let instance = ty::Instance::new(expr_did, substs); |
2338 | let cid = GlobalId { | |
2339 | instance, | |
2340 | promoted: None | |
2341 | }; | |
2342 | match tcx.const_eval(param_env.and(cid)) { | |
94b46f34 XL |
2343 | Ok(val) => { |
2344 | // FIXME: Find the right type and use it instead of `val.ty` here | |
e74abb32 | 2345 | if let Some(b) = val.try_eval_bits(tcx, param_env, val.ty) { |
94b46f34 XL |
2346 | trace!("discriminants: {} ({:?})", b, repr_type); |
2347 | Some(Discr { | |
2348 | val: b, | |
2349 | ty: val.ty, | |
2350 | }) | |
2351 | } else { | |
2352 | info!("invalid enum discriminant: {:#?}", val); | |
9fa01778 | 2353 | crate::mir::interpret::struct_error( |
94b46f34 XL |
2354 | tcx.at(tcx.def_span(expr_did)), |
2355 | "constant evaluation of enum discriminant resulted in non-integer", | |
2356 | ).emit(); | |
2357 | None | |
2358 | } | |
0531ce1d | 2359 | } |
a1dfa0c6 | 2360 | Err(ErrorHandled::Reported) => { |
0531ce1d XL |
2361 | if !expr_did.is_local() { |
2362 | span_bug!(tcx.def_span(expr_did), | |
2363 | "variant discriminant evaluation succeeded \ | |
0bf4aa26 | 2364 | in its crate but failed locally"); |
0531ce1d XL |
2365 | } |
2366 | None | |
2367 | } | |
a1dfa0c6 XL |
2368 | Err(ErrorHandled::TooGeneric) => span_bug!( |
2369 | tcx.def_span(expr_did), | |
2370 | "enum discriminant depends on generic arguments", | |
2371 | ), | |
0531ce1d XL |
2372 | } |
2373 | } | |
2374 | ||
2375 | #[inline] | |
2376 | pub fn discriminants( | |
dc9dc135 XL |
2377 | &'tcx self, |
2378 | tcx: TyCtxt<'tcx>, | |
2379 | ) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'tcx> { | |
8bb4bdeb | 2380 | let repr_type = self.repr.discr_type(); |
e74abb32 | 2381 | let initial = repr_type.initial_discriminant(tcx); |
0531ce1d | 2382 | let mut prev_discr = None::<Discr<'tcx>>; |
a1dfa0c6 | 2383 | self.variants.iter_enumerated().map(move |(i, v)| { |
0531ce1d | 2384 | let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx)); |
8bb4bdeb | 2385 | if let VariantDiscr::Explicit(expr_did) = v.discr { |
0531ce1d XL |
2386 | if let Some(new_discr) = self.eval_explicit_discr(tcx, expr_did) { |
2387 | discr = new_discr; | |
8bb4bdeb XL |
2388 | } |
2389 | } | |
2390 | prev_discr = Some(discr); | |
2391 | ||
a1dfa0c6 | 2392 | (i, discr) |
8bb4bdeb | 2393 | }) |
e9174d1e SL |
2394 | } |
2395 | ||
48663c56 XL |
2396 | #[inline] |
2397 | pub fn variant_range(&self) -> Range<VariantIdx> { | |
2398 | (VariantIdx::new(0)..VariantIdx::new(self.variants.len())) | |
2399 | } | |
2400 | ||
9fa01778 | 2401 | /// Computes the discriminant value used by a specific variant. |
cc61c64b XL |
2402 | /// Unlike `discriminants`, this is (amortized) constant-time, |
2403 | /// only doing at most one query for evaluating an explicit | |
2404 | /// discriminant (the last one before the requested variant), | |
2405 | /// assuming there are no constant-evaluation errors there. | |
48663c56 | 2406 | #[inline] |
dc9dc135 XL |
2407 | pub fn discriminant_for_variant( |
2408 | &self, | |
2409 | tcx: TyCtxt<'tcx>, | |
2410 | variant_index: VariantIdx, | |
2411 | ) -> Discr<'tcx> { | |
0531ce1d XL |
2412 | let (val, offset) = self.discriminant_def_for_variant(variant_index); |
2413 | let explicit_value = val | |
2414 | .and_then(|expr_did| self.eval_explicit_discr(tcx, expr_did)) | |
e74abb32 | 2415 | .unwrap_or_else(|| self.repr.discr_type().initial_discriminant(tcx)); |
0531ce1d XL |
2416 | explicit_value.checked_add(tcx, offset as u128).0 |
2417 | } | |
2418 | ||
9fa01778 | 2419 | /// Yields a `DefId` for the discriminant and an offset to add to it |
0531ce1d | 2420 | /// Alternatively, if there is no explicit discriminant, returns the |
9fa01778 | 2421 | /// inferred discriminant directly. |
0531ce1d XL |
2422 | pub fn discriminant_def_for_variant( |
2423 | &self, | |
a1dfa0c6 XL |
2424 | variant_index: VariantIdx, |
2425 | ) -> (Option<DefId>, u32) { | |
2426 | let mut explicit_index = variant_index.as_u32(); | |
0531ce1d | 2427 | let expr_did; |
cc61c64b | 2428 | loop { |
a1dfa0c6 | 2429 | match self.variants[VariantIdx::from_u32(explicit_index)].discr { |
0531ce1d XL |
2430 | ty::VariantDiscr::Relative(0) => { |
2431 | expr_did = None; | |
2432 | break; | |
2433 | }, | |
cc61c64b XL |
2434 | ty::VariantDiscr::Relative(distance) => { |
2435 | explicit_index -= distance; | |
2436 | } | |
0531ce1d XL |
2437 | ty::VariantDiscr::Explicit(did) => { |
2438 | expr_did = Some(did); | |
2439 | break; | |
cc61c64b XL |
2440 | } |
2441 | } | |
2442 | } | |
a1dfa0c6 | 2443 | (expr_did, variant_index.as_u32() - explicit_index) |
cc61c64b XL |
2444 | } |
2445 | ||
dc9dc135 | 2446 | pub fn destructor(&self, tcx: TyCtxt<'tcx>) -> Option<Destructor> { |
7cac9316 | 2447 | tcx.adt_destructor(self.did) |
e9174d1e SL |
2448 | } |
2449 | ||
cc61c64b | 2450 | /// Returns a list of types such that `Self: Sized` if and only |
9fa01778 | 2451 | /// if that type is `Sized`, or `TyErr` if this type is recursive. |
a7813a04 | 2452 | /// |
9fa01778 | 2453 | /// Oddly enough, checking that the sized-constraint is `Sized` is |
a7813a04 | 2454 | /// actually more expressive than checking all members: |
9fa01778 XL |
2455 | /// the `Sized` trait is inductive, so an associated type that references |
2456 | /// `Self` would prevent its containing ADT from being `Sized`. | |
a7813a04 XL |
2457 | /// |
2458 | /// Due to normalization being eager, this applies even if | |
9fa01778 | 2459 | /// the associated type is behind a pointer (e.g., issue #31299). |
dc9dc135 | 2460 | pub fn sized_constraint(&self, tcx: TyCtxt<'tcx>) -> &'tcx [Ty<'tcx>] { |
9fa01778 | 2461 | tcx.adt_sized_constraint(self.did).0 |
a7813a04 XL |
2462 | } |
2463 | ||
dc9dc135 | 2464 | fn sized_constraint_for_ty(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Vec<Ty<'tcx>> { |
e74abb32 | 2465 | let result = match ty.kind { |
b7449926 XL |
2466 | Bool | Char | Int(..) | Uint(..) | Float(..) | |
2467 | RawPtr(..) | Ref(..) | FnDef(..) | FnPtr(_) | | |
2468 | Array(..) | Closure(..) | Generator(..) | Never => { | |
a7813a04 XL |
2469 | vec![] |
2470 | } | |
2471 | ||
b7449926 XL |
2472 | Str | |
2473 | Dynamic(..) | | |
2474 | Slice(_) | | |
2475 | Foreign(..) | | |
2476 | Error | | |
2477 | GeneratorWitness(..) => { | |
a7813a04 XL |
2478 | // these are never sized - return the target type |
2479 | vec![ty] | |
2480 | } | |
2481 | ||
b7449926 | 2482 | Tuple(ref tys) => { |
9e0c209e SL |
2483 | match tys.last() { |
2484 | None => vec![], | |
48663c56 | 2485 | Some(ty) => self.sized_constraint_for_ty(tcx, ty.expect_ty()), |
9e0c209e | 2486 | } |
a7813a04 XL |
2487 | } |
2488 | ||
b7449926 | 2489 | Adt(adt, substs) => { |
a7813a04 | 2490 | // recursive case |
cc61c64b | 2491 | let adt_tys = adt.sized_constraint(tcx); |
a7813a04 | 2492 | debug!("sized_constraint_for_ty({:?}) intermediate = {:?}", |
cc61c64b XL |
2493 | ty, adt_tys); |
2494 | adt_tys.iter() | |
0bf4aa26 XL |
2495 | .map(|ty| ty.subst(tcx, substs)) |
2496 | .flat_map(|ty| self.sized_constraint_for_ty(tcx, ty)) | |
2497 | .collect() | |
a7813a04 XL |
2498 | } |
2499 | ||
b7449926 | 2500 | Projection(..) | Opaque(..) => { |
a7813a04 XL |
2501 | // must calculate explicitly. |
2502 | // FIXME: consider special-casing always-Sized projections | |
2503 | vec![ty] | |
2504 | } | |
2505 | ||
0bf4aa26 XL |
2506 | UnnormalizedProjection(..) => bug!("only used with chalk-engine"), |
2507 | ||
b7449926 | 2508 | Param(..) => { |
a7813a04 XL |
2509 | // perf hack: if there is a `T: Sized` bound, then |
2510 | // we know that `T` is Sized and do not need to check | |
2511 | // it on the impl. | |
2512 | ||
ea8adc8c | 2513 | let sized_trait = match tcx.lang_items().sized_trait() { |
a7813a04 XL |
2514 | Some(x) => x, |
2515 | _ => return vec![ty] | |
2516 | }; | |
83c7162d | 2517 | let sized_predicate = Binder::dummy(TraitRef { |
a7813a04 | 2518 | def_id: sized_trait, |
c30ab7b3 | 2519 | substs: tcx.mk_substs_trait(ty, &[]) |
a7813a04 | 2520 | }).to_predicate(); |
e74abb32 | 2521 | let predicates = tcx.predicates_of(self.did).predicates; |
a1dfa0c6 | 2522 | if predicates.iter().any(|(p, _)| *p == sized_predicate) { |
a7813a04 XL |
2523 | vec![] |
2524 | } else { | |
2525 | vec![ty] | |
2526 | } | |
2527 | } | |
2528 | ||
a1dfa0c6 XL |
2529 | Placeholder(..) | |
2530 | Bound(..) | | |
b7449926 | 2531 | Infer(..) => { |
a7813a04 XL |
2532 | bug!("unexpected type `{:?}` in sized_constraint_for_ty", |
2533 | ty) | |
2534 | } | |
2535 | }; | |
2536 | debug!("sized_constraint_for_ty({:?}) = {:?}", ty, result); | |
2537 | result | |
2538 | } | |
2539 | } | |
2540 | ||
dc9dc135 | 2541 | impl<'tcx> FieldDef { |
416331ca XL |
2542 | /// Returns the type of this field. The `subst` is typically obtained |
2543 | /// via the second field of `TyKind::AdtDef`. | |
dc9dc135 | 2544 | pub fn ty(&self, tcx: TyCtxt<'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> { |
7cac9316 | 2545 | tcx.type_of(self.did).subst(tcx, subst) |
e9174d1e | 2546 | } |
e9174d1e SL |
2547 | } |
2548 | ||
9fa01778 | 2549 | /// Represents the various closure traits in the language. This |
ff7c6d11 | 2550 | /// will determine the type of the environment (`self`, in the |
a1dfa0c6 | 2551 | /// desugaring) argument that the closure expects. |
ff7c6d11 XL |
2552 | /// |
2553 | /// You can get the environment type of a closure using | |
2554 | /// `tcx.closure_env_ty()`. | |
532ac7d7 XL |
2555 | #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, |
2556 | RustcEncodable, RustcDecodable, HashStable)] | |
e9174d1e SL |
2557 | pub enum ClosureKind { |
2558 | // Warning: Ordering is significant here! The ordering is chosen | |
2559 | // because the trait Fn is a subtrait of FnMut and so in turn, and | |
2560 | // hence we order it so that Fn < FnMut < FnOnce. | |
54a0048b SL |
2561 | Fn, |
2562 | FnMut, | |
2563 | FnOnce, | |
e9174d1e SL |
2564 | } |
2565 | ||
dc9dc135 | 2566 | impl<'tcx> ClosureKind { |
ff7c6d11 XL |
2567 | // This is the initial value used when doing upvar inference. |
2568 | pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn; | |
2569 | ||
dc9dc135 | 2570 | pub fn trait_did(&self, tcx: TyCtxt<'tcx>) -> DefId { |
476ff2be | 2571 | match *self { |
e1599b0c | 2572 | ClosureKind::Fn => tcx.require_lang_item(FnTraitLangItem, None), |
54a0048b | 2573 | ClosureKind::FnMut => { |
e1599b0c | 2574 | tcx.require_lang_item(FnMutTraitLangItem, None) |
e9174d1e | 2575 | } |
54a0048b | 2576 | ClosureKind::FnOnce => { |
e1599b0c | 2577 | tcx.require_lang_item(FnOnceTraitLangItem, None) |
e9174d1e | 2578 | } |
e9174d1e SL |
2579 | } |
2580 | } | |
2581 | ||
a1dfa0c6 | 2582 | /// Returns `true` if this a type that impls this closure kind |
e9174d1e SL |
2583 | /// must also implement `other`. |
2584 | pub fn extends(self, other: ty::ClosureKind) -> bool { | |
2585 | match (self, other) { | |
54a0048b SL |
2586 | (ClosureKind::Fn, ClosureKind::Fn) => true, |
2587 | (ClosureKind::Fn, ClosureKind::FnMut) => true, | |
2588 | (ClosureKind::Fn, ClosureKind::FnOnce) => true, | |
2589 | (ClosureKind::FnMut, ClosureKind::FnMut) => true, | |
2590 | (ClosureKind::FnMut, ClosureKind::FnOnce) => true, | |
2591 | (ClosureKind::FnOnce, ClosureKind::FnOnce) => true, | |
e9174d1e SL |
2592 | _ => false, |
2593 | } | |
2594 | } | |
ff7c6d11 XL |
2595 | |
2596 | /// Returns the representative scalar type for this closure kind. | |
2597 | /// See `TyS::to_opt_closure_kind` for more details. | |
dc9dc135 | 2598 | pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { |
ff7c6d11 XL |
2599 | match self { |
2600 | ty::ClosureKind::Fn => tcx.types.i8, | |
2601 | ty::ClosureKind::FnMut => tcx.types.i16, | |
2602 | ty::ClosureKind::FnOnce => tcx.types.i32, | |
2603 | } | |
2604 | } | |
e9174d1e SL |
2605 | } |
2606 | ||
2607 | impl<'tcx> TyS<'tcx> { | |
2608 | /// Iterator that walks `self` and any types reachable from | |
2609 | /// `self`, in depth-first order. Note that just walks the types | |
2610 | /// that appear in `self`, it does not descend into the fields of | |
2611 | /// structs or variants. For example: | |
2612 | /// | |
2613 | /// ```notrust | |
2614 | /// isize => { isize } | |
2615 | /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize } | |
2616 | /// [isize] => { [isize], isize } | |
2617 | /// ``` | |
2618 | pub fn walk(&'tcx self) -> TypeWalker<'tcx> { | |
2619 | TypeWalker::new(self) | |
2620 | } | |
2621 | ||
9fa01778 | 2622 | /// Iterator that walks the immediate children of `self`. Hence |
e9174d1e SL |
2623 | /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]` |
2624 | /// (but not `i32`, like `walk`). | |
b7449926 | 2625 | pub fn walk_shallow(&'tcx self) -> smallvec::IntoIter<walk::TypeWalkerArray<'tcx>> { |
e9174d1e SL |
2626 | walk::walk_shallow(self) |
2627 | } | |
2628 | ||
2629 | /// Walks `ty` and any types appearing within `ty`, invoking the | |
9fa01778 | 2630 | /// callback `f` on each type. If the callback returns `false`, then the |
e9174d1e SL |
2631 | /// children of the current type are ignored. |
2632 | /// | |
2633 | /// Note: prefer `ty.walk()` where possible. | |
2634 | pub fn maybe_walk<F>(&'tcx self, mut f: F) | |
a1dfa0c6 | 2635 | where F: FnMut(Ty<'tcx>) -> bool |
e9174d1e SL |
2636 | { |
2637 | let mut walker = self.walk(); | |
2638 | while let Some(ty) = walker.next() { | |
2639 | if !f(ty) { | |
2640 | walker.skip_current_subtree(); | |
2641 | } | |
2642 | } | |
2643 | } | |
2644 | } | |
2645 | ||
e9174d1e SL |
2646 | impl BorrowKind { |
2647 | pub fn from_mutbl(m: hir::Mutability) -> BorrowKind { | |
2648 | match m { | |
60c5eb7d XL |
2649 | hir::Mutability::Mutable => MutBorrow, |
2650 | hir::Mutability::Immutable => ImmBorrow, | |
e9174d1e SL |
2651 | } |
2652 | } | |
2653 | ||
2654 | /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow | |
2655 | /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a | |
2656 | /// mutability that is stronger than necessary so that it at least *would permit* the borrow in | |
2657 | /// question. | |
2658 | pub fn to_mutbl_lossy(self) -> hir::Mutability { | |
2659 | match self { | |
60c5eb7d XL |
2660 | MutBorrow => hir::Mutability::Mutable, |
2661 | ImmBorrow => hir::Mutability::Immutable, | |
e9174d1e SL |
2662 | |
2663 | // We have no type corresponding to a unique imm borrow, so | |
2664 | // use `&mut`. It gives all the capabilities of an `&uniq` | |
2665 | // and hence is a safe "over approximation". | |
60c5eb7d | 2666 | UniqueImmBorrow => hir::Mutability::Mutable, |
e9174d1e SL |
2667 | } |
2668 | } | |
2669 | ||
2670 | pub fn to_user_str(&self) -> &'static str { | |
2671 | match *self { | |
2672 | MutBorrow => "mutable", | |
2673 | ImmBorrow => "immutable", | |
2674 | UniqueImmBorrow => "uniquely immutable", | |
2675 | } | |
2676 | } | |
2677 | } | |
2678 | ||
cc61c64b | 2679 | #[derive(Debug, Clone)] |
dc9dc135 | 2680 | pub enum Attributes<'tcx> { |
0531ce1d | 2681 | Owned(Lrc<[ast::Attribute]>), |
dc9dc135 | 2682 | Borrowed(&'tcx [ast::Attribute]), |
cc61c64b XL |
2683 | } |
2684 | ||
dc9dc135 | 2685 | impl<'tcx> ::std::ops::Deref for Attributes<'tcx> { |
cc61c64b XL |
2686 | type Target = [ast::Attribute]; |
2687 | ||
2688 | fn deref(&self) -> &[ast::Attribute] { | |
2689 | match self { | |
2690 | &Attributes::Owned(ref data) => &data, | |
2691 | &Attributes::Borrowed(data) => data | |
2692 | } | |
2693 | } | |
2694 | } | |
2695 | ||
0731742a XL |
2696 | #[derive(Debug, PartialEq, Eq)] |
2697 | pub enum ImplOverlapKind { | |
2698 | /// These impls are always allowed to overlap. | |
2699 | Permitted, | |
2700 | /// These impls are allowed to overlap, but that raises | |
2701 | /// an issue #33140 future-compatibility warning. | |
2702 | /// | |
2703 | /// Some background: in Rust 1.0, the trait-object types `Send + Sync` (today's | |
2704 | /// `dyn Send + Sync`) and `Sync + Send` (now `dyn Sync + Send`) were different. | |
2705 | /// | |
2706 | /// The widely-used version 0.1.0 of the crate `traitobject` had accidentally relied | |
2707 | /// that difference, making what reduces to the following set of impls: | |
2708 | /// | |
2709 | /// ``` | |
2710 | /// trait Trait {} | |
2711 | /// impl Trait for dyn Send + Sync {} | |
2712 | /// impl Trait for dyn Sync + Send {} | |
2713 | /// ``` | |
2714 | /// | |
2715 | /// Obviously, once we made these types be identical, that code causes a coherence | |
2716 | /// error and a fairly big headache for us. However, luckily for us, the trait | |
2717 | /// `Trait` used in this case is basically a marker trait, and therefore having | |
2718 | /// overlapping impls for it is sound. | |
2719 | /// | |
2720 | /// To handle this, we basically regard the trait as a marker trait, with an additional | |
2721 | /// future-compatibility warning. To avoid accidentally "stabilizing" this feature, | |
2722 | /// it has the following restrictions: | |
2723 | /// | |
2724 | /// 1. The trait must indeed be a marker-like trait (i.e., no items), and must be | |
2725 | /// positive impls. | |
2726 | /// 2. The trait-ref of both impls must be equal. | |
2727 | /// 3. The trait-ref of both impls must be a trait object type consisting only of | |
2728 | /// marker traits. | |
2729 | /// 4. Neither of the impls can have any where-clauses. | |
2730 | /// | |
2731 | /// Once `traitobject` 0.1.0 is no longer an active concern, this hack can be removed. | |
2732 | Issue33140 | |
2733 | } | |
2734 | ||
dc9dc135 XL |
2735 | impl<'tcx> TyCtxt<'tcx> { |
2736 | pub fn body_tables(self, body: hir::BodyId) -> &'tcx TypeckTables<'tcx> { | |
0731742a | 2737 | self.typeck_tables_of(self.hir().body_owner_def_id(body)) |
32a655c1 SL |
2738 | } |
2739 | ||
9fa01778 | 2740 | /// Returns an iterator of the `DefId`s for all body-owners in this |
7cac9316 | 2741 | /// crate. If you would prefer to iterate over the bodies |
0731742a | 2742 | /// themselves, you can do `self.hir().krate().body_ids.iter()`. |
dc9dc135 | 2743 | pub fn body_owners(self) -> impl Iterator<Item = DefId> + Captures<'tcx> + 'tcx { |
0731742a XL |
2744 | self.hir().krate() |
2745 | .body_ids | |
2746 | .iter() | |
2747 | .map(move |&body_id| self.hir().body_owner_def_id(body_id)) | |
7453a54e SL |
2748 | } |
2749 | ||
94b46f34 | 2750 | pub fn par_body_owners<F: Fn(DefId) + sync::Sync + sync::Send>(self, f: F) { |
0731742a XL |
2751 | par_iter(&self.hir().krate().body_ids).for_each(|&body_id| { |
2752 | f(self.hir().body_owner_def_id(body_id)) | |
94b46f34 XL |
2753 | }); |
2754 | } | |
2755 | ||
dc9dc135 | 2756 | pub fn provided_trait_methods(self, id: DefId) -> Vec<AssocItem> { |
476ff2be | 2757 | self.associated_items(id) |
dc9dc135 | 2758 | .filter(|item| item.kind == AssocKind::Method && item.defaultness.has_value()) |
476ff2be | 2759 | .collect() |
e9174d1e SL |
2760 | } |
2761 | ||
8bb4bdeb XL |
2762 | pub fn trait_relevant_for_never(self, did: DefId) -> bool { |
2763 | self.associated_items(did).any(|item| { | |
2764 | item.relevant_for_never() | |
e9174d1e SL |
2765 | }) |
2766 | } | |
2767 | ||
e1599b0c XL |
2768 | pub fn opt_item_name(self, def_id: DefId) -> Option<Ident> { |
2769 | self.hir().as_local_hir_id(def_id).and_then(|hir_id| self.hir().get(hir_id).ident()) | |
2770 | } | |
2771 | ||
dc9dc135 | 2772 | pub fn opt_associated_item(self, def_id: DefId) -> Option<AssocItem> { |
532ac7d7 | 2773 | let is_associated_item = if let Some(hir_id) = self.hir().as_local_hir_id(def_id) { |
dc9dc135 | 2774 | match self.hir().get(hir_id) { |
b7449926 | 2775 | Node::TraitItem(_) | Node::ImplItem(_) => true, |
7cac9316 XL |
2776 | _ => false, |
2777 | } | |
2778 | } else { | |
416331ca | 2779 | match self.def_kind(def_id).expect("no def for `DefId`") { |
dc9dc135 | 2780 | DefKind::AssocConst |
48663c56 | 2781 | | DefKind::Method |
dc9dc135 | 2782 | | DefKind::AssocTy => true, |
7cac9316 XL |
2783 | _ => false, |
2784 | } | |
2785 | }; | |
8bb4bdeb | 2786 | |
60c5eb7d | 2787 | is_associated_item.then(|| self.associated_item(def_id)) |
e9174d1e SL |
2788 | } |
2789 | ||
476ff2be SL |
2790 | fn associated_item_from_trait_item_ref(self, |
2791 | parent_def_id: DefId, | |
7cac9316 | 2792 | parent_vis: &hir::Visibility, |
32a655c1 | 2793 | trait_item_ref: &hir::TraitItemRef) |
dc9dc135 | 2794 | -> AssocItem { |
416331ca | 2795 | let def_id = self.hir().local_def_id(trait_item_ref.id.hir_id); |
32a655c1 | 2796 | let (kind, has_self) = match trait_item_ref.kind { |
dc9dc135 XL |
2797 | hir::AssocItemKind::Const => (ty::AssocKind::Const, false), |
2798 | hir::AssocItemKind::Method { has_self } => { | |
2799 | (ty::AssocKind::Method, has_self) | |
476ff2be | 2800 | } |
dc9dc135 | 2801 | hir::AssocItemKind::Type => (ty::AssocKind::Type, false), |
416331ca | 2802 | hir::AssocItemKind::OpaqueTy => bug!("only impls can have opaque types"), |
476ff2be SL |
2803 | }; |
2804 | ||
dc9dc135 | 2805 | AssocItem { |
8faf50e0 | 2806 | ident: trait_item_ref.ident, |
041b39d2 | 2807 | kind, |
7cac9316 | 2808 | // Visibility of trait items is inherited from their traits. |
532ac7d7 | 2809 | vis: Visibility::from_hir(parent_vis, trait_item_ref.id.hir_id, self), |
32a655c1 | 2810 | defaultness: trait_item_ref.defaultness, |
041b39d2 | 2811 | def_id, |
476ff2be SL |
2812 | container: TraitContainer(parent_def_id), |
2813 | method_has_self_argument: has_self | |
2814 | } | |
2815 | } | |
2816 | ||
2817 | fn associated_item_from_impl_item_ref(self, | |
2818 | parent_def_id: DefId, | |
476ff2be | 2819 | impl_item_ref: &hir::ImplItemRef) |
dc9dc135 | 2820 | -> AssocItem { |
416331ca | 2821 | let def_id = self.hir().local_def_id(impl_item_ref.id.hir_id); |
476ff2be | 2822 | let (kind, has_self) = match impl_item_ref.kind { |
dc9dc135 XL |
2823 | hir::AssocItemKind::Const => (ty::AssocKind::Const, false), |
2824 | hir::AssocItemKind::Method { has_self } => { | |
2825 | (ty::AssocKind::Method, has_self) | |
476ff2be | 2826 | } |
dc9dc135 | 2827 | hir::AssocItemKind::Type => (ty::AssocKind::Type, false), |
416331ca | 2828 | hir::AssocItemKind::OpaqueTy => (ty::AssocKind::OpaqueTy, false), |
476ff2be SL |
2829 | }; |
2830 | ||
dc9dc135 | 2831 | AssocItem { |
8faf50e0 | 2832 | ident: impl_item_ref.ident, |
041b39d2 | 2833 | kind, |
7cac9316 | 2834 | // Visibility of trait impl items doesn't matter. |
532ac7d7 | 2835 | vis: ty::Visibility::from_hir(&impl_item_ref.vis, impl_item_ref.id.hir_id, self), |
476ff2be | 2836 | defaultness: impl_item_ref.defaultness, |
041b39d2 | 2837 | def_id, |
476ff2be SL |
2838 | container: ImplContainer(parent_def_id), |
2839 | method_has_self_argument: has_self | |
2840 | } | |
2841 | } | |
2842 | ||
532ac7d7 | 2843 | pub fn field_index(self, hir_id: hir::HirId, tables: &TypeckTables<'_>) -> usize { |
83c7162d XL |
2844 | tables.field_indices().get(hir_id).cloned().expect("no index for a field") |
2845 | } | |
2846 | ||
2847 | pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option<usize> { | |
2848 | variant.fields.iter().position(|field| { | |
dc9dc135 | 2849 | self.hygienic_eq(ident, field.ident, variant.def_id) |
83c7162d XL |
2850 | }) |
2851 | } | |
2852 | ||
dc9dc135 | 2853 | pub fn associated_items(self, def_id: DefId) -> AssocItemsIterator<'tcx> { |
a1dfa0c6 XL |
2854 | // Ideally, we would use `-> impl Iterator` here, but it falls |
2855 | // afoul of the conservative "capture [restrictions]" we put | |
2856 | // in place, so we use a hand-written iterator. | |
2857 | // | |
2858 | // [restrictions]: https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999 | |
dc9dc135 | 2859 | AssocItemsIterator { |
a1dfa0c6 XL |
2860 | tcx: self, |
2861 | def_ids: self.associated_item_def_ids(def_id), | |
2862 | next_index: 0, | |
2863 | } | |
e9174d1e SL |
2864 | } |
2865 | ||
a1dfa0c6 | 2866 | /// Returns `true` if the impls are the same polarity and the trait either |
0bf4aa26 | 2867 | /// has no items or is annotated #[marker] and prevents item overrides. |
0731742a XL |
2868 | pub fn impls_are_allowed_to_overlap(self, def_id1: DefId, def_id2: DefId) |
2869 | -> Option<ImplOverlapKind> | |
2870 | { | |
e1599b0c XL |
2871 | // If either trait impl references an error, they're allowed to overlap, |
2872 | // as one of them essentially doesn't exist. | |
2873 | if self.impl_trait_ref(def_id1).map_or(false, |tr| tr.references_error()) || | |
2874 | self.impl_trait_ref(def_id2).map_or(false, |tr| tr.references_error()) { | |
2875 | return Some(ImplOverlapKind::Permitted); | |
2876 | } | |
2877 | ||
e74abb32 XL |
2878 | match (self.impl_polarity(def_id1), self.impl_polarity(def_id2)) { |
2879 | (ImplPolarity::Reservation, _) | | |
2880 | (_, ImplPolarity::Reservation) => { | |
2881 | // `#[rustc_reservation_impl]` impls don't overlap with anything | |
2882 | debug!("impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (reservations)", | |
2883 | def_id1, def_id2); | |
2884 | return Some(ImplOverlapKind::Permitted); | |
2885 | } | |
2886 | (ImplPolarity::Positive, ImplPolarity::Negative) | | |
2887 | (ImplPolarity::Negative, ImplPolarity::Positive) => { | |
2888 | // `impl AutoTrait for Type` + `impl !AutoTrait for Type` | |
2889 | debug!("impls_are_allowed_to_overlap({:?}, {:?}) - None (differing polarities)", | |
2890 | def_id1, def_id2); | |
2891 | return None; | |
2892 | } | |
2893 | (ImplPolarity::Positive, ImplPolarity::Positive) | | |
2894 | (ImplPolarity::Negative, ImplPolarity::Negative) => {} | |
2895 | }; | |
2896 | ||
2897 | let is_marker_overlap = if self.features().overlapping_marker_traits { | |
0bf4aa26 XL |
2898 | let trait1_is_empty = self.impl_trait_ref(def_id1) |
2899 | .map_or(false, |trait_ref| { | |
2900 | self.associated_item_def_ids(trait_ref.def_id).is_empty() | |
2901 | }); | |
2902 | let trait2_is_empty = self.impl_trait_ref(def_id2) | |
2903 | .map_or(false, |trait_ref| { | |
2904 | self.associated_item_def_ids(trait_ref.def_id).is_empty() | |
2905 | }); | |
e74abb32 | 2906 | trait1_is_empty && trait2_is_empty |
0731742a | 2907 | } else { |
0bf4aa26 XL |
2908 | let is_marker_impl = |def_id: DefId| -> bool { |
2909 | let trait_ref = self.impl_trait_ref(def_id); | |
2910 | trait_ref.map_or(false, |tr| self.trait_def(tr.def_id).is_marker) | |
2911 | }; | |
e74abb32 | 2912 | is_marker_impl(def_id1) && is_marker_impl(def_id2) |
0731742a XL |
2913 | }; |
2914 | ||
e74abb32 XL |
2915 | |
2916 | if is_marker_overlap { | |
2917 | debug!("impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (marker overlap)", | |
2918 | def_id1, def_id2); | |
0731742a | 2919 | Some(ImplOverlapKind::Permitted) |
0bf4aa26 | 2920 | } else { |
0731742a XL |
2921 | if let Some(self_ty1) = self.issue33140_self_ty(def_id1) { |
2922 | if let Some(self_ty2) = self.issue33140_self_ty(def_id2) { | |
2923 | if self_ty1 == self_ty2 { | |
2924 | debug!("impls_are_allowed_to_overlap({:?}, {:?}) - issue #33140 HACK", | |
2925 | def_id1, def_id2); | |
2926 | return Some(ImplOverlapKind::Issue33140); | |
2927 | } else { | |
2928 | debug!("impls_are_allowed_to_overlap({:?}, {:?}) - found {:?} != {:?}", | |
2929 | def_id1, def_id2, self_ty1, self_ty2); | |
2930 | } | |
2931 | } | |
2932 | } | |
2933 | ||
2934 | debug!("impls_are_allowed_to_overlap({:?}, {:?}) = None", | |
2935 | def_id1, def_id2); | |
2936 | None | |
cc61c64b | 2937 | } |
cc61c64b XL |
2938 | } |
2939 | ||
48663c56 | 2940 | /// Returns `ty::VariantDef` if `res` refers to a struct, |
532ac7d7 | 2941 | /// or variant or their constructors, panics otherwise. |
48663c56 XL |
2942 | pub fn expect_variant_res(self, res: Res) -> &'tcx VariantDef { |
2943 | match res { | |
2944 | Res::Def(DefKind::Variant, did) => { | |
532ac7d7 | 2945 | let enum_did = self.parent(did).unwrap(); |
7cac9316 | 2946 | self.adt_def(enum_did).variant_with_id(did) |
5bcae85e | 2947 | } |
48663c56 | 2948 | Res::Def(DefKind::Struct, did) | Res::Def(DefKind::Union, did) => { |
2c00a5a8 | 2949 | self.adt_def(did).non_enum_variant() |
5bcae85e | 2950 | } |
48663c56 | 2951 | Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_did) => { |
532ac7d7 XL |
2952 | let variant_did = self.parent(variant_ctor_did).unwrap(); |
2953 | let enum_did = self.parent(variant_did).unwrap(); | |
2954 | self.adt_def(enum_did).variant_with_ctor_id(variant_ctor_did) | |
2955 | } | |
48663c56 | 2956 | Res::Def(DefKind::Ctor(CtorOf::Struct, ..), ctor_did) => { |
532ac7d7 XL |
2957 | let struct_did = self.parent(ctor_did).expect("struct ctor has no parent"); |
2958 | self.adt_def(struct_did).non_enum_variant() | |
c30ab7b3 | 2959 | } |
48663c56 | 2960 | _ => bug!("expect_variant_res used with unexpected res {:?}", res) |
5bcae85e SL |
2961 | } |
2962 | } | |
2963 | ||
dc9dc135 | 2964 | pub fn item_name(self, id: DefId) -> Symbol { |
ff7c6d11 | 2965 | if id.index == CRATE_DEF_INDEX { |
dc9dc135 | 2966 | self.original_crate_name(id.krate) |
e9174d1e | 2967 | } else { |
ea8adc8c | 2968 | let def_key = self.def_key(id); |
532ac7d7 XL |
2969 | match def_key.disambiguated_data.data { |
2970 | // The name of a constructor is that of its parent. | |
2971 | hir_map::DefPathData::Ctor => | |
2972 | self.item_name(DefId { | |
2973 | krate: id.krate, | |
2974 | index: def_key.parent.unwrap() | |
2975 | }), | |
2976 | _ => def_key.disambiguated_data.data.get_opt_name().unwrap_or_else(|| { | |
9e0c209e | 2977 | bug!("item_name: no name for {:?}", self.def_path(id)); |
e74abb32 | 2978 | }), |
9e0c209e | 2979 | } |
e9174d1e SL |
2980 | } |
2981 | } | |
2982 | ||
9fa01778 | 2983 | /// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair. |
60c5eb7d | 2984 | pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> ReadOnlyBodyAndCache<'tcx, 'tcx> { |
cc61c64b | 2985 | match instance { |
7cac9316 | 2986 | ty::InstanceDef::Item(did) => { |
60c5eb7d | 2987 | self.optimized_mir(did).unwrap_read_only() |
7cac9316 | 2988 | } |
a1dfa0c6 | 2989 | ty::InstanceDef::VtableShim(..) | |
e74abb32 | 2990 | ty::InstanceDef::ReifyShim(..) | |
7cac9316 XL |
2991 | ty::InstanceDef::Intrinsic(..) | |
2992 | ty::InstanceDef::FnPtrShim(..) | | |
2993 | ty::InstanceDef::Virtual(..) | | |
2994 | ty::InstanceDef::ClosureOnceShim { .. } | | |
3b2f2976 XL |
2995 | ty::InstanceDef::DropGlue(..) | |
2996 | ty::InstanceDef::CloneShim(..) => { | |
60c5eb7d | 2997 | self.mir_shims(instance).unwrap_read_only() |
7cac9316 | 2998 | } |
cc61c64b XL |
2999 | } |
3000 | } | |
3001 | ||
9fa01778 | 3002 | /// Gets the attributes of a definition. |
dc9dc135 | 3003 | pub fn get_attrs(self, did: DefId) -> Attributes<'tcx> { |
9fa01778 | 3004 | if let Some(id) = self.hir().as_local_hir_id(did) { |
dc9dc135 | 3005 | Attributes::Borrowed(self.hir().attrs(id)) |
e9174d1e | 3006 | } else { |
7cac9316 | 3007 | Attributes::Owned(self.item_attrs(did)) |
e9174d1e SL |
3008 | } |
3009 | } | |
3010 | ||
9fa01778 | 3011 | /// Determines whether an item is annotated with an attribute. |
48663c56 | 3012 | pub fn has_attr(self, did: DefId, attr: Symbol) -> bool { |
ff7c6d11 | 3013 | attr::contains_name(&self.get_attrs(did), attr) |
e9174d1e SL |
3014 | } |
3015 | ||
a1dfa0c6 | 3016 | /// Returns `true` if this is an `auto trait`. |
abe05a73 XL |
3017 | pub fn trait_is_auto(self, trait_def_id: DefId) -> bool { |
3018 | self.trait_def(trait_def_id).has_auto_impl | |
b039eaaf SL |
3019 | } |
3020 | ||
ea8adc8c XL |
3021 | pub fn generator_layout(self, def_id: DefId) -> &'tcx GeneratorLayout<'tcx> { |
3022 | self.optimized_mir(def_id).generator_layout.as_ref().unwrap() | |
3023 | } | |
3024 | ||
9fa01778 XL |
3025 | /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements. |
3026 | /// If it implements no trait, returns `None`. | |
a7813a04 | 3027 | pub fn trait_id_of_impl(self, def_id: DefId) -> Option<DefId> { |
e9174d1e SL |
3028 | self.impl_trait_ref(def_id).map(|tr| tr.def_id) |
3029 | } | |
3030 | ||
9fa01778 XL |
3031 | /// If the given defid describes a method belonging to an impl, returns the |
3032 | /// `DefId` of the impl that the method belongs to; otherwise, returns `None`. | |
a7813a04 | 3033 | pub fn impl_of_method(self, def_id: DefId) -> Option<DefId> { |
8bb4bdeb | 3034 | let item = if def_id.krate != LOCAL_CRATE { |
48663c56 | 3035 | if let Some(DefKind::Method) = self.def_kind(def_id) { |
8bb4bdeb XL |
3036 | Some(self.associated_item(def_id)) |
3037 | } else { | |
3038 | None | |
3039 | } | |
3040 | } else { | |
7cac9316 | 3041 | self.opt_associated_item(def_id) |
8bb4bdeb XL |
3042 | }; |
3043 | ||
8faf50e0 XL |
3044 | item.and_then(|trait_item| |
3045 | match trait_item.container { | |
3046 | TraitContainer(_) => None, | |
3047 | ImplContainer(def_id) => Some(def_id), | |
e9174d1e | 3048 | } |
8faf50e0 | 3049 | ) |
e9174d1e SL |
3050 | } |
3051 | ||
54a0048b SL |
3052 | /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err` |
3053 | /// with the name of the crate containing the impl. | |
476ff2be | 3054 | pub fn span_of_impl(self, impl_did: DefId) -> Result<Span, Symbol> { |
54a0048b | 3055 | if impl_did.is_local() { |
9fa01778 | 3056 | let hir_id = self.hir().as_local_hir_id(impl_did).unwrap(); |
dc9dc135 | 3057 | Ok(self.hir().span(hir_id)) |
54a0048b | 3058 | } else { |
ea8adc8c | 3059 | Err(self.crate_name(impl_did.krate)) |
54a0048b SL |
3060 | } |
3061 | } | |
7cac9316 | 3062 | |
9fa01778 XL |
3063 | /// Hygienically compares a use-site name (`use_name`) for a field or an associated item with |
3064 | /// its supposed definition name (`def_name`). The method also needs `DefId` of the supposed | |
3065 | /// definition's parent/scope to perform comparison. | |
8faf50e0 | 3066 | pub fn hygienic_eq(self, use_name: Ident, def_name: Ident, def_parent_def_id: DefId) -> bool { |
dc9dc135 XL |
3067 | // We could use `Ident::eq` here, but we deliberately don't. The name |
3068 | // comparison fails frequently, and we want to avoid the expensive | |
3069 | // `modern()` calls required for the span comparison whenever possible. | |
3070 | use_name.name == def_name.name && | |
3071 | use_name.span.ctxt().hygienic_eq(def_name.span.ctxt(), | |
3072 | self.expansion_that_defined(def_parent_def_id)) | |
7cac9316 XL |
3073 | } |
3074 | ||
416331ca | 3075 | fn expansion_that_defined(self, scope: DefId) -> ExpnId { |
dc9dc135 | 3076 | match scope.krate { |
0731742a | 3077 | LOCAL_CRATE => self.hir().definitions().expansion_that_defined(scope.index), |
416331ca | 3078 | _ => ExpnId::root(), |
dc9dc135 XL |
3079 | } |
3080 | } | |
3081 | ||
3082 | pub fn adjust_ident(self, mut ident: Ident, scope: DefId) -> Ident { | |
3083 | ident.span.modernize_and_adjust(self.expansion_that_defined(scope)); | |
3084 | ident | |
3085 | } | |
3086 | ||
3087 | pub fn adjust_ident_and_get_scope(self, mut ident: Ident, scope: DefId, block: hir::HirId) | |
3088 | -> (Ident, DefId) { | |
3089 | let scope = match ident.span.modernize_and_adjust(self.expansion_that_defined(scope)) { | |
8faf50e0 | 3090 | Some(actual_expansion) => |
0731742a | 3091 | self.hir().definitions().parent_module_of_macro_def(actual_expansion), |
dc9dc135 | 3092 | None => self.hir().get_module_parent(block), |
7cac9316 XL |
3093 | }; |
3094 | (ident, scope) | |
3095 | } | |
e9174d1e SL |
3096 | } |
3097 | ||
e74abb32 | 3098 | #[derive(Clone)] |
dc9dc135 XL |
3099 | pub struct AssocItemsIterator<'tcx> { |
3100 | tcx: TyCtxt<'tcx>, | |
3101 | def_ids: &'tcx [DefId], | |
a1dfa0c6 XL |
3102 | next_index: usize, |
3103 | } | |
3104 | ||
dc9dc135 XL |
3105 | impl Iterator for AssocItemsIterator<'_> { |
3106 | type Item = AssocItem; | |
a1dfa0c6 | 3107 | |
dc9dc135 | 3108 | fn next(&mut self) -> Option<AssocItem> { |
a1dfa0c6 XL |
3109 | let def_id = self.def_ids.get(self.next_index)?; |
3110 | self.next_index += 1; | |
3111 | Some(self.tcx.associated_item(*def_id)) | |
3112 | } | |
3113 | } | |
3114 | ||
dc9dc135 | 3115 | fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> AssocItem { |
532ac7d7 XL |
3116 | let id = tcx.hir().as_local_hir_id(def_id).unwrap(); |
3117 | let parent_id = tcx.hir().get_parent_item(id); | |
416331ca | 3118 | let parent_def_id = tcx.hir().local_def_id(parent_id); |
dc9dc135 | 3119 | let parent_item = tcx.hir().expect_item(parent_id); |
e74abb32 | 3120 | match parent_item.kind { |
8faf50e0 | 3121 | hir::ItemKind::Impl(.., ref impl_item_refs) => { |
532ac7d7 | 3122 | if let Some(impl_item_ref) = impl_item_refs.iter().find(|i| i.id.hir_id == id) { |
7cac9316 XL |
3123 | let assoc_item = tcx.associated_item_from_impl_item_ref(parent_def_id, |
3124 | impl_item_ref); | |
cc61c64b XL |
3125 | debug_assert_eq!(assoc_item.def_id, def_id); |
3126 | return assoc_item; | |
3127 | } | |
3128 | } | |
3129 | ||
8faf50e0 | 3130 | hir::ItemKind::Trait(.., ref trait_item_refs) => { |
532ac7d7 | 3131 | if let Some(trait_item_ref) = trait_item_refs.iter().find(|i| i.id.hir_id == id) { |
7cac9316 XL |
3132 | let assoc_item = tcx.associated_item_from_trait_item_ref(parent_def_id, |
3133 | &parent_item.vis, | |
3134 | trait_item_ref); | |
cc61c64b XL |
3135 | debug_assert_eq!(assoc_item.def_id, def_id); |
3136 | return assoc_item; | |
3137 | } | |
3138 | } | |
3139 | ||
7cac9316 | 3140 | _ => { } |
cc61c64b | 3141 | } |
7cac9316 XL |
3142 | |
3143 | span_bug!(parent_item.span, | |
3144 | "unexpected parent of trait or impl item or item not found: {:?}", | |
e74abb32 | 3145 | parent_item.kind) |
cc61c64b XL |
3146 | } |
3147 | ||
532ac7d7 | 3148 | #[derive(Clone, HashStable)] |
9fa01778 XL |
3149 | pub struct AdtSizedConstraint<'tcx>(pub &'tcx [Ty<'tcx>]); |
3150 | ||
3151 | /// Calculates the `Sized` constraint. | |
cc61c64b XL |
3152 | /// |
3153 | /// In fact, there are only a few options for the types in the constraint: | |
3154 | /// - an obviously-unsized type | |
3155 | /// - a type parameter or projection whose Sizedness can't be known | |
3156 | /// - a tuple of type parameters or projections, if there are multiple | |
3157 | /// such. | |
b7449926 | 3158 | /// - a Error, if a type contained itself. The representability |
cc61c64b | 3159 | /// check should catch this case. |
dc9dc135 | 3160 | fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> AdtSizedConstraint<'_> { |
7cac9316 | 3161 | let def = tcx.adt_def(def_id); |
cc61c64b | 3162 | |
94b46f34 | 3163 | let result = tcx.mk_type_list(def.variants.iter().flat_map(|v| { |
cc61c64b XL |
3164 | v.fields.last() |
3165 | }).flat_map(|f| { | |
7cac9316 | 3166 | def.sized_constraint_for_ty(tcx, tcx.type_of(f.did)) |
94b46f34 | 3167 | })); |
cc61c64b XL |
3168 | |
3169 | debug!("adt_sized_constraint: {:?} => {:?}", def, result); | |
3170 | ||
9fa01778 | 3171 | AdtSizedConstraint(result) |
cc61c64b XL |
3172 | } |
3173 | ||
dc9dc135 | 3174 | fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] { |
9fa01778 | 3175 | let id = tcx.hir().as_local_hir_id(def_id).unwrap(); |
dc9dc135 | 3176 | let item = tcx.hir().expect_item(id); |
e74abb32 | 3177 | match item.kind { |
8faf50e0 | 3178 | hir::ItemKind::Trait(.., ref trait_item_refs) => { |
dc9dc135 XL |
3179 | tcx.arena.alloc_from_iter( |
3180 | trait_item_refs.iter() | |
3181 | .map(|trait_item_ref| trait_item_ref.id) | |
416331ca | 3182 | .map(|id| tcx.hir().local_def_id(id.hir_id)) |
dc9dc135 | 3183 | ) |
cc61c64b | 3184 | } |
8faf50e0 | 3185 | hir::ItemKind::Impl(.., ref impl_item_refs) => { |
dc9dc135 XL |
3186 | tcx.arena.alloc_from_iter( |
3187 | impl_item_refs.iter() | |
3188 | .map(|impl_item_ref| impl_item_ref.id) | |
416331ca | 3189 | .map(|id| tcx.hir().local_def_id(id.hir_id)) |
dc9dc135 | 3190 | ) |
cc61c64b | 3191 | } |
dc9dc135 | 3192 | hir::ItemKind::TraitAlias(..) => &[], |
cc61c64b | 3193 | _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait") |
dc9dc135 | 3194 | } |
cc61c64b XL |
3195 | } |
3196 | ||
dc9dc135 | 3197 | fn def_span(tcx: TyCtxt<'_>, def_id: DefId) -> Span { |
0731742a | 3198 | tcx.hir().span_if_local(def_id).unwrap() |
7cac9316 XL |
3199 | } |
3200 | ||
9fa01778 XL |
3201 | /// If the given `DefId` describes an item belonging to a trait, |
3202 | /// returns the `DefId` of the trait that the trait item belongs to; | |
3203 | /// otherwise, returns `None`. | |
dc9dc135 | 3204 | fn trait_of_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> { |
7cac9316 XL |
3205 | tcx.opt_associated_item(def_id) |
3206 | .and_then(|associated_item| { | |
3207 | match associated_item.container { | |
3208 | TraitContainer(def_id) => Some(def_id), | |
3209 | ImplContainer(_) => None | |
3210 | } | |
3211 | }) | |
3212 | } | |
3213 | ||
a1dfa0c6 | 3214 | /// Yields the parent function's `DefId` if `def_id` is an `impl Trait` definition. |
dc9dc135 | 3215 | pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> { |
532ac7d7 | 3216 | if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) { |
dc9dc135 | 3217 | if let Node::Item(item) = tcx.hir().get(hir_id) { |
e74abb32 | 3218 | if let hir::ItemKind::OpaqueTy(ref opaque_ty) = item.kind { |
416331ca | 3219 | return opaque_ty.impl_trait_fn; |
8faf50e0 XL |
3220 | } |
3221 | } | |
3222 | } | |
3223 | None | |
3224 | } | |
3225 | ||
a1dfa0c6 | 3226 | /// See `ParamEnv` struct definition for details. |
dc9dc135 | 3227 | fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ParamEnv<'_> { |
8faf50e0 XL |
3228 | // The param_env of an impl Trait type is its defining function's param_env |
3229 | if let Some(parent) = is_impl_trait_defn(tcx, def_id) { | |
94b46f34 XL |
3230 | return param_env(tcx, parent); |
3231 | } | |
7cac9316 XL |
3232 | // Compute the bounds on Self and the type parameters. |
3233 | ||
8faf50e0 XL |
3234 | let InstantiatedPredicates { predicates } = |
3235 | tcx.predicates_of(def_id).instantiate_identity(tcx); | |
7cac9316 XL |
3236 | |
3237 | // Finally, we have to normalize the bounds in the environment, in | |
3238 | // case they contain any associated type projections. This process | |
3239 | // can yield errors if the put in illegal associated types, like | |
3240 | // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We | |
3241 | // report these errors right here; this doesn't actually feel | |
3242 | // right to me, because constructing the environment feels like a | |
3243 | // kind of a "idempotent" action, but I'm not sure where would be | |
3244 | // a better place. In practice, we construct environments for | |
3245 | // every fn once during type checking, and we'll abort if there | |
3246 | // are any errors at that point, so after type checking you can be | |
3247 | // sure that this will succeed without errors anyway. | |
3248 | ||
0731742a XL |
3249 | let unnormalized_env = ty::ParamEnv::new( |
3250 | tcx.intern_predicates(&predicates), | |
3251 | traits::Reveal::UserFacing, | |
60c5eb7d | 3252 | tcx.sess.opts.debugging_opts.chalk.then_some(def_id), |
0731742a | 3253 | ); |
7cac9316 | 3254 | |
9fa01778 | 3255 | let body_id = tcx.hir().as_local_hir_id(def_id).map_or(hir::DUMMY_HIR_ID, |id| { |
dc9dc135 | 3256 | tcx.hir().maybe_body_owned_by(id).map_or(id, |body| body.hir_id) |
7cac9316 XL |
3257 | }); |
3258 | let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id); | |
3259 | traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause) | |
3260 | } | |
3261 | ||
dc9dc135 | 3262 | fn crate_disambiguator(tcx: TyCtxt<'_>, crate_num: CrateNum) -> CrateDisambiguator { |
ea8adc8c XL |
3263 | assert_eq!(crate_num, LOCAL_CRATE); |
3264 | tcx.sess.local_crate_disambiguator() | |
3265 | } | |
3266 | ||
dc9dc135 | 3267 | fn original_crate_name(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Symbol { |
ea8adc8c XL |
3268 | assert_eq!(crate_num, LOCAL_CRATE); |
3269 | tcx.crate_name.clone() | |
3270 | } | |
3271 | ||
dc9dc135 | 3272 | fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh { |
ff7c6d11 | 3273 | assert_eq!(crate_num, LOCAL_CRATE); |
0731742a | 3274 | tcx.hir().crate_hash |
ff7c6d11 XL |
3275 | } |
3276 | ||
dc9dc135 | 3277 | fn instance_def_size_estimate<'tcx>(tcx: TyCtxt<'tcx>, instance_def: InstanceDef<'tcx>) -> usize { |
2c00a5a8 XL |
3278 | match instance_def { |
3279 | InstanceDef::Item(..) | | |
3280 | InstanceDef::DropGlue(..) => { | |
3281 | let mir = tcx.instance_mir(instance_def); | |
3282 | mir.basic_blocks().iter().map(|bb| bb.statements.len()).sum() | |
3283 | }, | |
3284 | // Estimate the size of other compiler-generated shims to be 1. | |
3285 | _ => 1 | |
3286 | } | |
3287 | } | |
3288 | ||
9fa01778 | 3289 | /// If `def_id` is an issue 33140 hack impl, returns its self type; otherwise, returns `None`. |
0731742a | 3290 | /// |
9fa01778 | 3291 | /// See [`ImplOverlapKind::Issue33140`] for more details. |
dc9dc135 | 3292 | fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Ty<'_>> { |
0731742a XL |
3293 | debug!("issue33140_self_ty({:?})", def_id); |
3294 | ||
3295 | let trait_ref = tcx.impl_trait_ref(def_id).unwrap_or_else(|| { | |
3296 | bug!("issue33140_self_ty called on inherent impl {:?}", def_id) | |
3297 | }); | |
3298 | ||
3299 | debug!("issue33140_self_ty({:?}), trait-ref={:?}", def_id, trait_ref); | |
3300 | ||
3301 | let is_marker_like = | |
e74abb32 | 3302 | tcx.impl_polarity(def_id) == ty::ImplPolarity::Positive && |
0731742a XL |
3303 | tcx.associated_item_def_ids(trait_ref.def_id).is_empty(); |
3304 | ||
3305 | // Check whether these impls would be ok for a marker trait. | |
3306 | if !is_marker_like { | |
3307 | debug!("issue33140_self_ty - not marker-like!"); | |
3308 | return None; | |
3309 | } | |
3310 | ||
3311 | // impl must be `impl Trait for dyn Marker1 + Marker2 + ...` | |
3312 | if trait_ref.substs.len() != 1 { | |
3313 | debug!("issue33140_self_ty - impl has substs!"); | |
3314 | return None; | |
3315 | } | |
3316 | ||
3317 | let predicates = tcx.predicates_of(def_id); | |
3318 | if predicates.parent.is_some() || !predicates.predicates.is_empty() { | |
3319 | debug!("issue33140_self_ty - impl has predicates {:?}!", predicates); | |
3320 | return None; | |
3321 | } | |
3322 | ||
3323 | let self_ty = trait_ref.self_ty(); | |
e74abb32 | 3324 | let self_ty_matches = match self_ty.kind { |
0731742a XL |
3325 | ty::Dynamic(ref data, ty::ReStatic) => data.principal().is_none(), |
3326 | _ => false | |
3327 | }; | |
3328 | ||
3329 | if self_ty_matches { | |
3330 | debug!("issue33140_self_ty - MATCHES!"); | |
3331 | Some(self_ty) | |
3332 | } else { | |
3333 | debug!("issue33140_self_ty - non-matching self type"); | |
3334 | None | |
3335 | } | |
3336 | } | |
3337 | ||
e1599b0c XL |
3338 | /// Check if a function is async. |
3339 | fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync { | |
3340 | let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap_or_else(|| { | |
3341 | bug!("asyncness: expected local `DefId`, got `{:?}`", def_id) | |
3342 | }); | |
3343 | ||
3344 | let node = tcx.hir().get(hir_id); | |
3345 | ||
3346 | let fn_like = hir::map::blocks::FnLikeNode::from_node(node).unwrap_or_else(|| { | |
3347 | bug!("asyncness: expected fn-like node but got `{:?}`", def_id); | |
3348 | }); | |
3349 | ||
3350 | fn_like.asyncness() | |
3351 | } | |
3352 | ||
0bf4aa26 | 3353 | pub fn provide(providers: &mut ty::query::Providers<'_>) { |
ea8adc8c | 3354 | context::provide(providers); |
abe05a73 | 3355 | erase_regions::provide(providers); |
ff7c6d11 XL |
3356 | layout::provide(providers); |
3357 | util::provide(providers); | |
0bf4aa26 | 3358 | constness::provide(providers); |
94b46f34 | 3359 | *providers = ty::query::Providers { |
e1599b0c | 3360 | asyncness, |
cc61c64b XL |
3361 | associated_item, |
3362 | associated_item_def_ids, | |
3363 | adt_sized_constraint, | |
7cac9316 XL |
3364 | def_span, |
3365 | param_env, | |
3366 | trait_of_item, | |
ea8adc8c XL |
3367 | crate_disambiguator, |
3368 | original_crate_name, | |
ff7c6d11 | 3369 | crate_hash, |
7cac9316 | 3370 | trait_impls_of: trait_def::trait_impls_of_provider, |
2c00a5a8 | 3371 | instance_def_size_estimate, |
0731742a | 3372 | issue33140_self_ty, |
cc61c64b XL |
3373 | ..*providers |
3374 | }; | |
3375 | } | |
3376 | ||
cc61c64b XL |
3377 | /// A map for the local crate mapping each type to a vector of its |
3378 | /// inherent impls. This is not meant to be used outside of coherence; | |
3379 | /// rather, you should request the vector for a specific type via | |
7cac9316 XL |
3380 | /// `tcx.inherent_impls(def_id)` so as to minimize your dependencies |
3381 | /// (constructing this map requires touching the entire crate). | |
532ac7d7 | 3382 | #[derive(Clone, Debug, Default, HashStable)] |
cc61c64b | 3383 | pub struct CrateInherentImpls { |
dc9dc135 | 3384 | pub inherent_impls: DefIdMap<Vec<DefId>>, |
cc61c64b XL |
3385 | } |
3386 | ||
60c5eb7d | 3387 | #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)] |
7cac9316 XL |
3388 | pub struct SymbolName { |
3389 | // FIXME: we don't rely on interning or equality here - better have | |
3390 | // this be a `&'tcx str`. | |
e74abb32 | 3391 | pub name: Symbol |
7cac9316 XL |
3392 | } |
3393 | ||
0531ce1d XL |
3394 | impl SymbolName { |
3395 | pub fn new(name: &str) -> SymbolName { | |
3396 | SymbolName { | |
e74abb32 | 3397 | name: Symbol::intern(name) |
0531ce1d XL |
3398 | } |
3399 | } | |
7cac9316 XL |
3400 | } |
3401 | ||
e74abb32 XL |
3402 | impl PartialOrd for SymbolName { |
3403 | fn partial_cmp(&self, other: &SymbolName) -> Option<Ordering> { | |
3404 | self.name.as_str().partial_cmp(&other.name.as_str()) | |
3405 | } | |
3406 | } | |
3407 | ||
3408 | /// Ordering must use the chars to ensure reproducible builds. | |
3409 | impl Ord for SymbolName { | |
3410 | fn cmp(&self, other: &SymbolName) -> Ordering { | |
3411 | self.name.as_str().cmp(&other.name.as_str()) | |
3412 | } | |
3413 | } | |
3414 | ||
7cac9316 | 3415 | impl fmt::Display for SymbolName { |
0bf4aa26 | 3416 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
7cac9316 XL |
3417 | fmt::Display::fmt(&self.name, fmt) |
3418 | } | |
3419 | } | |
0531ce1d XL |
3420 | |
3421 | impl fmt::Debug for SymbolName { | |
0bf4aa26 | 3422 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
0531ce1d XL |
3423 | fmt::Display::fmt(&self.name, fmt) |
3424 | } | |
3425 | } |