1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 pub use self::Variance
::*;
12 pub use self::AssociatedItemContainer
::*;
13 pub use self::BorrowKind
::*;
14 pub use self::IntVarValue
::*;
15 pub use self::LvaluePreference
::*;
16 pub use self::fold
::TypeFoldable
;
18 use hir
::{map as hir_map, FreevarMap, TraitMap}
;
19 use hir
::def
::{Def, CtorKind, ExportMap}
;
20 use hir
::def_id
::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}
;
21 use ich
::StableHashingContext
;
22 use middle
::const_val
::ConstVal
;
23 use middle
::lang_items
::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}
;
24 use middle
::privacy
::AccessLevels
;
25 use middle
::resolve_lifetime
::ObjectLifetimeDefault
;
27 use mir
::GeneratorLayout
;
30 use ty
::subst
::{Subst, Substs}
;
31 use ty
::util
::IntTypeExt
;
32 use ty
::walk
::TypeWalker
;
33 use util
::common
::ErrorReported
;
34 use util
::nodemap
::{NodeSet, DefIdMap, FxHashMap, FxHashSet}
;
36 use serialize
::{self, Encodable, Encoder}
;
37 use std
::collections
::BTreeMap
;
40 use std
::hash
::{Hash, Hasher}
;
41 use std
::iter
::FromIterator
;
45 use std
::vec
::IntoIter
;
47 use syntax
::ast
::{self, DUMMY_NODE_ID, Name, Ident, NodeId}
;
49 use syntax
::ext
::hygiene
::{Mark, SyntaxContext}
;
50 use syntax
::symbol
::{Symbol, InternedString}
;
51 use syntax_pos
::{DUMMY_SP, Span}
;
52 use rustc_const_math
::ConstInt
;
54 use rustc_data_structures
::accumulate_vec
::IntoIter
as AccIntoIter
;
55 use rustc_data_structures
::stable_hasher
::{StableHasher
, StableHasherResult
,
57 use rustc_data_structures
::transitive_relation
::TransitiveRelation
;
61 pub use self::sty
::{Binder, DebruijnIndex}
;
62 pub use self::sty
::{FnSig, GenSig, PolyFnSig, PolyGenSig}
;
63 pub use self::sty
::{InferTy, ParamTy, ProjectionTy, ExistentialPredicate}
;
64 pub use self::sty
::{ClosureSubsts, GeneratorInterior, TypeAndMut}
;
65 pub use self::sty
::{TraitRef, TypeVariants, PolyTraitRef}
;
66 pub use self::sty
::{ExistentialTraitRef, PolyExistentialTraitRef}
;
67 pub use self::sty
::{ExistentialProjection, PolyExistentialProjection, Const}
;
68 pub use self::sty
::{BoundRegion, EarlyBoundRegion, FreeRegion, Region}
;
69 pub use self::sty
::RegionKind
;
70 pub use self::sty
::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid}
;
71 pub use self::sty
::BoundRegion
::*;
72 pub use self::sty
::InferTy
::*;
73 pub use self::sty
::RegionKind
::*;
74 pub use self::sty
::TypeVariants
::*;
76 pub use self::binding
::BindingMode
;
77 pub use self::binding
::BindingMode
::*;
79 pub use self::context
::{TyCtxt, GlobalArenas, tls, keep_local}
;
80 pub use self::context
::{Lift, TypeckTables}
;
82 pub use self::instance
::{Instance, InstanceDef}
;
84 pub use self::trait_def
::TraitDef
;
86 pub use self::maps
::queries
;
94 pub mod inhabitedness
;
111 mod structural_impls
;
116 /// The complete set of all analyses described in this module. This is
117 /// produced by the driver and fed to trans and later passes.
119 /// NB: These contents are being migrated into queries using the
120 /// *on-demand* infrastructure.
122 pub struct CrateAnalysis
{
123 pub access_levels
: Rc
<AccessLevels
>,
125 pub glob_map
: Option
<hir
::GlobMap
>,
129 pub struct Resolutions
{
130 pub freevars
: FreevarMap
,
131 pub trait_map
: TraitMap
,
132 pub maybe_unused_trait_imports
: NodeSet
,
133 pub maybe_unused_extern_crates
: Vec
<(NodeId
, Span
)>,
134 pub export_map
: ExportMap
,
137 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
138 pub enum AssociatedItemContainer
{
139 TraitContainer(DefId
),
140 ImplContainer(DefId
),
143 impl AssociatedItemContainer
{
144 pub fn id(&self) -> DefId
{
146 TraitContainer(id
) => id
,
147 ImplContainer(id
) => id
,
152 /// The "header" of an impl is everything outside the body: a Self type, a trait
153 /// ref (in the case of a trait impl), and a set of predicates (from the
154 /// bounds/where clauses).
155 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
156 pub struct ImplHeader
<'tcx
> {
157 pub impl_def_id
: DefId
,
158 pub self_ty
: Ty
<'tcx
>,
159 pub trait_ref
: Option
<TraitRef
<'tcx
>>,
160 pub predicates
: Vec
<Predicate
<'tcx
>>,
163 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
164 pub struct AssociatedItem
{
167 pub kind
: AssociatedKind
,
169 pub defaultness
: hir
::Defaultness
,
170 pub container
: AssociatedItemContainer
,
172 /// Whether this is a method with an explicit self
173 /// as its first argument, allowing method calls.
174 pub method_has_self_argument
: bool
,
177 #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, RustcEncodable, RustcDecodable)]
178 pub enum AssociatedKind
{
184 impl AssociatedItem
{
185 pub fn def(&self) -> Def
{
187 AssociatedKind
::Const
=> Def
::AssociatedConst(self.def_id
),
188 AssociatedKind
::Method
=> Def
::Method(self.def_id
),
189 AssociatedKind
::Type
=> Def
::AssociatedTy(self.def_id
),
193 /// Tests whether the associated item admits a non-trivial implementation
195 pub fn relevant_for_never
<'tcx
>(&self) -> bool
{
197 AssociatedKind
::Const
=> true,
198 AssociatedKind
::Type
=> true,
199 // FIXME(canndrew): Be more thorough here, check if any argument is uninhabited.
200 AssociatedKind
::Method
=> !self.method_has_self_argument
,
204 pub fn signature
<'a
, 'tcx
>(&self, tcx
: &TyCtxt
<'a
, 'tcx
, 'tcx
>) -> String
{
206 ty
::AssociatedKind
::Method
=> {
207 // We skip the binder here because the binder would deanonymize all
208 // late-bound regions, and we don't want method signatures to show up
209 // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
210 // regions just fine, showing `fn(&MyType)`.
211 format
!("{}", tcx
.fn_sig(self.def_id
).skip_binder())
213 ty
::AssociatedKind
::Type
=> format
!("type {};", self.name
.to_string()),
214 ty
::AssociatedKind
::Const
=> {
215 format
!("const {}: {:?};", self.name
.to_string(), tcx
.type_of(self.def_id
))
221 #[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable)]
222 pub enum Visibility
{
223 /// Visible everywhere (including in other crates).
225 /// Visible only in the given crate-local module.
227 /// Not visible anywhere in the local crate. This is the visibility of private external items.
231 pub trait DefIdTree
: Copy
{
232 fn parent(self, id
: DefId
) -> Option
<DefId
>;
234 fn is_descendant_of(self, mut descendant
: DefId
, ancestor
: DefId
) -> bool
{
235 if descendant
.krate
!= ancestor
.krate
{
239 while descendant
!= ancestor
{
240 match self.parent(descendant
) {
241 Some(parent
) => descendant
= parent
,
242 None
=> return false,
249 impl<'a
, 'gcx
, 'tcx
> DefIdTree
for TyCtxt
<'a
, 'gcx
, 'tcx
> {
250 fn parent(self, id
: DefId
) -> Option
<DefId
> {
251 self.def_key(id
).parent
.map(|index
| DefId { index: index, ..id }
)
256 pub fn from_hir(visibility
: &hir
::Visibility
, id
: NodeId
, tcx
: TyCtxt
) -> Self {
258 hir
::Public
=> Visibility
::Public
,
259 hir
::Visibility
::Crate
=> Visibility
::Restricted(DefId
::local(CRATE_DEF_INDEX
)),
260 hir
::Visibility
::Restricted { ref path, .. }
=> match path
.def
{
261 // If there is no resolution, `resolve` will have already reported an error, so
262 // assume that the visibility is public to avoid reporting more privacy errors.
263 Def
::Err
=> Visibility
::Public
,
264 def
=> Visibility
::Restricted(def
.def_id()),
267 Visibility
::Restricted(tcx
.hir
.get_module_parent(id
))
272 /// Returns true if an item with this visibility is accessible from the given block.
273 pub fn is_accessible_from
<T
: DefIdTree
>(self, module
: DefId
, tree
: T
) -> bool
{
274 let restriction
= match self {
275 // Public items are visible everywhere.
276 Visibility
::Public
=> return true,
277 // Private items from other crates are visible nowhere.
278 Visibility
::Invisible
=> return false,
279 // Restricted items are visible in an arbitrary local module.
280 Visibility
::Restricted(other
) if other
.krate
!= module
.krate
=> return false,
281 Visibility
::Restricted(module
) => module
,
284 tree
.is_descendant_of(module
, restriction
)
287 /// Returns true if this visibility is at least as accessible as the given visibility
288 pub fn is_at_least
<T
: DefIdTree
>(self, vis
: Visibility
, tree
: T
) -> bool
{
289 let vis_restriction
= match vis
{
290 Visibility
::Public
=> return self == Visibility
::Public
,
291 Visibility
::Invisible
=> return true,
292 Visibility
::Restricted(module
) => module
,
295 self.is_accessible_from(vis_restriction
, tree
)
299 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Copy)]
301 Covariant
, // T<A> <: T<B> iff A <: B -- e.g., function return type
302 Invariant
, // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
303 Contravariant
, // T<A> <: T<B> iff B <: A -- e.g., function param type
304 Bivariant
, // T<A> <: T<B> -- e.g., unused type parameter
307 /// The crate variances map is computed during typeck and contains the
308 /// variance of every item in the local crate. You should not use it
309 /// directly, because to do so will make your pass dependent on the
310 /// HIR of every item in the local crate. Instead, use
311 /// `tcx.variances_of()` to get the variance for a *particular*
313 pub struct CrateVariancesMap
{
314 /// This relation tracks the dependencies between the variance of
315 /// various items. In particular, if `a < b`, then the variance of
316 /// `a` depends on the sources of `b`.
317 pub dependencies
: TransitiveRelation
<DefId
>,
319 /// For each item with generics, maps to a vector of the variance
320 /// of its generics. If an item has no generics, it will have no
322 pub variances
: FxHashMap
<DefId
, Rc
<Vec
<ty
::Variance
>>>,
324 /// An empty vector, useful for cloning.
325 pub empty_variance
: Rc
<Vec
<ty
::Variance
>>,
329 /// `a.xform(b)` combines the variance of a context with the
330 /// variance of a type with the following meaning. If we are in a
331 /// context with variance `a`, and we encounter a type argument in
332 /// a position with variance `b`, then `a.xform(b)` is the new
333 /// variance with which the argument appears.
339 /// Here, the "ambient" variance starts as covariant. `*mut T` is
340 /// invariant with respect to `T`, so the variance in which the
341 /// `Vec<i32>` appears is `Covariant.xform(Invariant)`, which
342 /// yields `Invariant`. Now, the type `Vec<T>` is covariant with
343 /// respect to its type argument `T`, and hence the variance of
344 /// the `i32` here is `Invariant.xform(Covariant)`, which results
345 /// (again) in `Invariant`.
349 /// fn(*const Vec<i32>, *mut Vec<i32)
351 /// The ambient variance is covariant. A `fn` type is
352 /// contravariant with respect to its parameters, so the variance
353 /// within which both pointer types appear is
354 /// `Covariant.xform(Contravariant)`, or `Contravariant`. `*const
355 /// T` is covariant with respect to `T`, so the variance within
356 /// which the first `Vec<i32>` appears is
357 /// `Contravariant.xform(Covariant)` or `Contravariant`. The same
358 /// is true for its `i32` argument. In the `*mut T` case, the
359 /// variance of `Vec<i32>` is `Contravariant.xform(Invariant)`,
360 /// and hence the outermost type is `Invariant` with respect to
361 /// `Vec<i32>` (and its `i32` argument).
363 /// Source: Figure 1 of "Taming the Wildcards:
364 /// Combining Definition- and Use-Site Variance" published in PLDI'11.
365 pub fn xform(self, v
: ty
::Variance
) -> ty
::Variance
{
367 // Figure 1, column 1.
368 (ty
::Covariant
, ty
::Covariant
) => ty
::Covariant
,
369 (ty
::Covariant
, ty
::Contravariant
) => ty
::Contravariant
,
370 (ty
::Covariant
, ty
::Invariant
) => ty
::Invariant
,
371 (ty
::Covariant
, ty
::Bivariant
) => ty
::Bivariant
,
373 // Figure 1, column 2.
374 (ty
::Contravariant
, ty
::Covariant
) => ty
::Contravariant
,
375 (ty
::Contravariant
, ty
::Contravariant
) => ty
::Covariant
,
376 (ty
::Contravariant
, ty
::Invariant
) => ty
::Invariant
,
377 (ty
::Contravariant
, ty
::Bivariant
) => ty
::Bivariant
,
379 // Figure 1, column 3.
380 (ty
::Invariant
, _
) => ty
::Invariant
,
382 // Figure 1, column 4.
383 (ty
::Bivariant
, _
) => ty
::Bivariant
,
388 // Contains information needed to resolve types and (in the future) look up
389 // the types of AST nodes.
390 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
391 pub struct CReaderCacheKey
{
396 // Flags that we track on types. These flags are propagated upwards
397 // through the type during type construction, so that we can quickly
398 // check whether the type has various kinds of types in it without
399 // recursing over the type itself.
401 pub struct TypeFlags
: u32 {
402 const HAS_PARAMS
= 1 << 0;
403 const HAS_SELF
= 1 << 1;
404 const HAS_TY_INFER
= 1 << 2;
405 const HAS_RE_INFER
= 1 << 3;
406 const HAS_RE_SKOL
= 1 << 4;
407 const HAS_RE_EARLY_BOUND
= 1 << 5;
408 const HAS_FREE_REGIONS
= 1 << 6;
409 const HAS_TY_ERR
= 1 << 7;
410 const HAS_PROJECTION
= 1 << 8;
412 // FIXME: Rename this to the actual property since it's used for generators too
413 const HAS_TY_CLOSURE
= 1 << 9;
415 // true if there are "names" of types and regions and so forth
416 // that are local to a particular fn
417 const HAS_LOCAL_NAMES
= 1 << 10;
419 // Present if the type belongs in a local type context.
420 // Only set for TyInfer other than Fresh.
421 const KEEP_IN_LOCAL_TCX
= 1 << 11;
423 // Is there a projection that does not involve a bound region?
424 // Currently we can't normalize projections w/ bound regions.
425 const HAS_NORMALIZABLE_PROJECTION
= 1 << 12;
427 const NEEDS_SUBST
= TypeFlags
::HAS_PARAMS
.bits
|
428 TypeFlags
::HAS_SELF
.bits
|
429 TypeFlags
::HAS_RE_EARLY_BOUND
.bits
;
431 // Flags representing the nominal content of a type,
432 // computed by FlagsComputation. If you add a new nominal
433 // flag, it should be added here too.
434 const NOMINAL_FLAGS
= TypeFlags
::HAS_PARAMS
.bits
|
435 TypeFlags
::HAS_SELF
.bits
|
436 TypeFlags
::HAS_TY_INFER
.bits
|
437 TypeFlags
::HAS_RE_INFER
.bits
|
438 TypeFlags
::HAS_RE_SKOL
.bits
|
439 TypeFlags
::HAS_RE_EARLY_BOUND
.bits
|
440 TypeFlags
::HAS_FREE_REGIONS
.bits
|
441 TypeFlags
::HAS_TY_ERR
.bits
|
442 TypeFlags
::HAS_PROJECTION
.bits
|
443 TypeFlags
::HAS_TY_CLOSURE
.bits
|
444 TypeFlags
::HAS_LOCAL_NAMES
.bits
|
445 TypeFlags
::KEEP_IN_LOCAL_TCX
.bits
;
449 pub struct TyS
<'tcx
> {
450 pub sty
: TypeVariants
<'tcx
>,
451 pub flags
: TypeFlags
,
453 // the maximal depth of any bound regions appearing in this type.
457 impl<'tcx
> PartialEq
for TyS
<'tcx
> {
459 fn eq(&self, other
: &TyS
<'tcx
>) -> bool
{
460 // (self as *const _) == (other as *const _)
461 (self as *const TyS
<'tcx
>) == (other
as *const TyS
<'tcx
>)
464 impl<'tcx
> Eq
for TyS
<'tcx
> {}
466 impl<'tcx
> Hash
for TyS
<'tcx
> {
467 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
468 (self as *const TyS
).hash(s
)
472 impl<'tcx
> TyS
<'tcx
> {
473 pub fn is_primitive_ty(&self) -> bool
{
475 TypeVariants
::TyBool
|
476 TypeVariants
::TyChar
|
477 TypeVariants
::TyInt(_
) |
478 TypeVariants
::TyUint(_
) |
479 TypeVariants
::TyFloat(_
) |
480 TypeVariants
::TyInfer(InferTy
::IntVar(_
)) |
481 TypeVariants
::TyInfer(InferTy
::FloatVar(_
)) |
482 TypeVariants
::TyInfer(InferTy
::FreshIntTy(_
)) |
483 TypeVariants
::TyInfer(InferTy
::FreshFloatTy(_
)) => true,
484 TypeVariants
::TyRef(_
, x
) => x
.ty
.is_primitive_ty(),
489 pub fn is_suggestable(&self) -> bool
{
491 TypeVariants
::TyAnon(..) |
492 TypeVariants
::TyFnDef(..) |
493 TypeVariants
::TyFnPtr(..) |
494 TypeVariants
::TyDynamic(..) |
495 TypeVariants
::TyClosure(..) |
496 TypeVariants
::TyInfer(..) |
497 TypeVariants
::TyProjection(..) => false,
503 impl<'gcx
> HashStable
<StableHashingContext
<'gcx
>> for ty
::TyS
<'gcx
> {
504 fn hash_stable
<W
: StableHasherResult
>(&self,
505 hcx
: &mut StableHashingContext
<'gcx
>,
506 hasher
: &mut StableHasher
<W
>) {
510 // The other fields just provide fast access to information that is
511 // also contained in `sty`, so no need to hash them.
516 sty
.hash_stable(hcx
, hasher
);
520 pub type Ty
<'tcx
> = &'tcx TyS
<'tcx
>;
522 impl<'tcx
> serialize
::UseSpecializedEncodable
for Ty
<'tcx
> {}
523 impl<'tcx
> serialize
::UseSpecializedDecodable
for Ty
<'tcx
> {}
525 /// A wrapper for slices with the additional invariant
526 /// that the slice is interned and no other slice with
527 /// the same contents can exist in the same context.
528 /// This means we can use pointer + length for both
529 /// equality comparisons and hashing.
530 #[derive(Debug, RustcEncodable)]
531 pub struct Slice
<T
>([T
]);
533 impl<T
> PartialEq
for Slice
<T
> {
535 fn eq(&self, other
: &Slice
<T
>) -> bool
{
536 (&self.0 as *const [T
]) == (&other
.0 as *const [T
])
539 impl<T
> Eq
for Slice
<T
> {}
541 impl<T
> Hash
for Slice
<T
> {
542 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
543 (self.as_ptr(), self.len()).hash(s
)
547 impl<T
> Deref
for Slice
<T
> {
549 fn deref(&self) -> &[T
] {
554 impl<'a
, T
> IntoIterator
for &'a Slice
<T
> {
556 type IntoIter
= <&'a
[T
] as IntoIterator
>::IntoIter
;
557 fn into_iter(self) -> Self::IntoIter
{
562 impl<'tcx
> serialize
::UseSpecializedDecodable
for &'tcx Slice
<Ty
<'tcx
>> {}
565 pub fn empty
<'a
>() -> &'a Slice
<T
> {
567 mem
::transmute(slice
::from_raw_parts(0x1 as *const T
, 0))
572 /// Upvars do not get their own node-id. Instead, we use the pair of
573 /// the original var id (that is, the root variable that is referenced
574 /// by the upvar) and the id of the closure expression.
575 #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
577 pub var_id
: hir
::HirId
,
578 pub closure_expr_id
: DefIndex
,
581 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)]
582 pub enum BorrowKind
{
583 /// Data must be immutable and is aliasable.
586 /// Data must be immutable but not aliasable. This kind of borrow
587 /// cannot currently be expressed by the user and is used only in
588 /// implicit closure bindings. It is needed when the closure
589 /// is borrowing or mutating a mutable referent, e.g.:
591 /// let x: &mut isize = ...;
592 /// let y = || *x += 5;
594 /// If we were to try to translate this closure into a more explicit
595 /// form, we'd encounter an error with the code as written:
597 /// struct Env { x: & &mut isize }
598 /// let x: &mut isize = ...;
599 /// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn
600 /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
602 /// This is then illegal because you cannot mutate a `&mut` found
603 /// in an aliasable location. To solve, you'd have to translate with
604 /// an `&mut` borrow:
606 /// struct Env { x: & &mut isize }
607 /// let x: &mut isize = ...;
608 /// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
609 /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
611 /// Now the assignment to `**env.x` is legal, but creating a
612 /// mutable pointer to `x` is not because `x` is not mutable. We
613 /// could fix this by declaring `x` as `let mut x`. This is ok in
614 /// user code, if awkward, but extra weird for closures, since the
615 /// borrow is hidden.
617 /// So we introduce a "unique imm" borrow -- the referent is
618 /// immutable, but not aliasable. This solves the problem. For
619 /// simplicity, we don't give users the way to express this
620 /// borrow, it's just used when translating closures.
623 /// Data is mutable and not aliasable.
627 /// Information describing the capture of an upvar. This is computed
628 /// during `typeck`, specifically by `regionck`.
629 #[derive(PartialEq, Clone, Debug, Copy, RustcEncodable, RustcDecodable)]
630 pub enum UpvarCapture
<'tcx
> {
631 /// Upvar is captured by value. This is always true when the
632 /// closure is labeled `move`, but can also be true in other cases
633 /// depending on inference.
636 /// Upvar is captured by reference.
637 ByRef(UpvarBorrow
<'tcx
>),
640 #[derive(PartialEq, Clone, Copy, RustcEncodable, RustcDecodable)]
641 pub struct UpvarBorrow
<'tcx
> {
642 /// The kind of borrow: by-ref upvars have access to shared
643 /// immutable borrows, which are not part of the normal language
645 pub kind
: BorrowKind
,
647 /// Region of the resulting reference.
648 pub region
: ty
::Region
<'tcx
>,
651 pub type UpvarCaptureMap
<'tcx
> = FxHashMap
<UpvarId
, UpvarCapture
<'tcx
>>;
653 #[derive(Copy, Clone)]
654 pub struct ClosureUpvar
<'tcx
> {
660 #[derive(Clone, Copy, PartialEq)]
661 pub enum IntVarValue
{
663 UintType(ast
::UintTy
),
666 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
667 pub struct TypeParameterDef
{
671 pub has_default
: bool
,
672 pub object_lifetime_default
: ObjectLifetimeDefault
,
674 /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute
675 /// on generic parameter `T`, asserts data behind the parameter
676 /// `T` won't be accessed during the parent type's `Drop` impl.
677 pub pure_wrt_drop
: bool
,
679 pub synthetic
: Option
<hir
::SyntheticTyParamKind
>,
682 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
683 pub struct RegionParameterDef
{
688 /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute
689 /// on generic parameter `'a`, asserts data of lifetime `'a`
690 /// won't be accessed during the parent type's `Drop` impl.
691 pub pure_wrt_drop
: bool
,
694 impl RegionParameterDef
{
695 pub fn to_early_bound_region_data(&self) -> ty
::EarlyBoundRegion
{
696 ty
::EarlyBoundRegion
{
703 pub fn to_bound_region(&self) -> ty
::BoundRegion
{
704 self.to_early_bound_region_data().to_bound_region()
708 impl ty
::EarlyBoundRegion
{
709 pub fn to_bound_region(&self) -> ty
::BoundRegion
{
710 ty
::BoundRegion
::BrNamed(self.def_id
, self.name
)
714 /// Information about the formal type/lifetime parameters associated
715 /// with an item or method. Analogous to hir::Generics.
717 /// Note that in the presence of a `Self` parameter, the ordering here
718 /// is different from the ordering in a Substs. Substs are ordered as
719 /// Self, *Regions, *Other Type Params, (...child generics)
720 /// while this struct is ordered as
721 /// regions = Regions
722 /// types = [Self, *Other Type Params]
723 #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
724 pub struct Generics
{
725 pub parent
: Option
<DefId
>,
726 pub parent_regions
: u32,
727 pub parent_types
: u32,
728 pub regions
: Vec
<RegionParameterDef
>,
729 pub types
: Vec
<TypeParameterDef
>,
731 /// Reverse map to each `TypeParameterDef`'s `index` field, from
732 /// `def_id.index` (`def_id.krate` is the same as the item's).
733 pub type_param_to_index
: BTreeMap
<DefIndex
, u32>,
736 pub has_late_bound_regions
: Option
<Span
>,
739 impl<'a
, 'gcx
, 'tcx
> Generics
{
740 pub fn parent_count(&self) -> usize {
741 self.parent_regions
as usize + self.parent_types
as usize
744 pub fn own_count(&self) -> usize {
745 self.regions
.len() + self.types
.len()
748 pub fn count(&self) -> usize {
749 self.parent_count() + self.own_count()
752 pub fn region_param(&'tcx
self,
753 param
: &EarlyBoundRegion
,
754 tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>)
755 -> &'tcx RegionParameterDef
757 if let Some(index
) = param
.index
.checked_sub(self.parent_count() as u32) {
758 &self.regions
[index
as usize - self.has_self
as usize]
760 tcx
.generics_of(self.parent
.expect("parent_count>0 but no parent?"))
761 .region_param(param
, tcx
)
765 /// Returns the `TypeParameterDef` associated with this `ParamTy`.
766 pub fn type_param(&'tcx
self,
768 tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>)
769 -> &TypeParameterDef
{
770 if let Some(idx
) = param
.idx
.checked_sub(self.parent_count() as u32) {
771 // non-Self type parameters are always offset by exactly
772 // `self.regions.len()`. In the absence of a Self, this is obvious,
773 // but even in the absence of a `Self` we just have to "compensate"
776 // For example, for `trait Foo<'a, 'b, T1, T2>`, the
784 // And it can be seen that to move from a substs offset to a
785 // generics offset you just have to offset by the number of regions.
786 let type_param_offset
= self.regions
.len();
787 if let Some(idx
) = (idx
as usize).checked_sub(type_param_offset
) {
788 assert
!(!(self.has_self
&& idx
== 0));
791 assert
!(self.has_self
&& idx
== 0);
795 tcx
.generics_of(self.parent
.expect("parent_count>0 but no parent?"))
796 .type_param(param
, tcx
)
801 /// Bounds on generics.
802 #[derive(Clone, Default)]
803 pub struct GenericPredicates
<'tcx
> {
804 pub parent
: Option
<DefId
>,
805 pub predicates
: Vec
<Predicate
<'tcx
>>,
808 impl<'tcx
> serialize
::UseSpecializedEncodable
for GenericPredicates
<'tcx
> {}
809 impl<'tcx
> serialize
::UseSpecializedDecodable
for GenericPredicates
<'tcx
> {}
811 impl<'a
, 'gcx
, 'tcx
> GenericPredicates
<'tcx
> {
812 pub fn instantiate(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>, substs
: &Substs
<'tcx
>)
813 -> InstantiatedPredicates
<'tcx
> {
814 let mut instantiated
= InstantiatedPredicates
::empty();
815 self.instantiate_into(tcx
, &mut instantiated
, substs
);
818 pub fn instantiate_own(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>, substs
: &Substs
<'tcx
>)
819 -> InstantiatedPredicates
<'tcx
> {
820 InstantiatedPredicates
{
821 predicates
: self.predicates
.subst(tcx
, substs
)
825 fn instantiate_into(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
826 instantiated
: &mut InstantiatedPredicates
<'tcx
>,
827 substs
: &Substs
<'tcx
>) {
828 if let Some(def_id
) = self.parent
{
829 tcx
.predicates_of(def_id
).instantiate_into(tcx
, instantiated
, substs
);
831 instantiated
.predicates
.extend(self.predicates
.iter().map(|p
| p
.subst(tcx
, substs
)))
834 pub fn instantiate_identity(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>)
835 -> InstantiatedPredicates
<'tcx
> {
836 let mut instantiated
= InstantiatedPredicates
::empty();
837 self.instantiate_identity_into(tcx
, &mut instantiated
);
841 fn instantiate_identity_into(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
842 instantiated
: &mut InstantiatedPredicates
<'tcx
>) {
843 if let Some(def_id
) = self.parent
{
844 tcx
.predicates_of(def_id
).instantiate_identity_into(tcx
, instantiated
);
846 instantiated
.predicates
.extend(&self.predicates
)
849 pub fn instantiate_supertrait(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
850 poly_trait_ref
: &ty
::PolyTraitRef
<'tcx
>)
851 -> InstantiatedPredicates
<'tcx
>
853 assert_eq
!(self.parent
, None
);
854 InstantiatedPredicates
{
855 predicates
: self.predicates
.iter().map(|pred
| {
856 pred
.subst_supertrait(tcx
, poly_trait_ref
)
862 #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
863 pub enum Predicate
<'tcx
> {
864 /// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
865 /// the `Self` type of the trait reference and `A`, `B`, and `C`
866 /// would be the type parameters.
867 Trait(PolyTraitPredicate
<'tcx
>),
869 /// where `T1 == T2`.
870 Equate(PolyEquatePredicate
<'tcx
>),
873 RegionOutlives(PolyRegionOutlivesPredicate
<'tcx
>),
876 TypeOutlives(PolyTypeOutlivesPredicate
<'tcx
>),
878 /// where <T as TraitRef>::Name == X, approximately.
879 /// See `ProjectionPredicate` struct for details.
880 Projection(PolyProjectionPredicate
<'tcx
>),
883 WellFormed(Ty
<'tcx
>),
885 /// trait must be object-safe
888 /// No direct syntax. May be thought of as `where T : FnFoo<...>`
889 /// for some substitutions `...` and T being a closure type.
890 /// Satisfied (or refuted) once we know the closure's kind.
891 ClosureKind(DefId
, ClosureKind
),
894 Subtype(PolySubtypePredicate
<'tcx
>),
896 /// Constant initializer must evaluate successfully.
897 ConstEvaluatable(DefId
, &'tcx Substs
<'tcx
>),
900 impl<'a
, 'gcx
, 'tcx
> Predicate
<'tcx
> {
901 /// Performs a substitution suitable for going from a
902 /// poly-trait-ref to supertraits that must hold if that
903 /// poly-trait-ref holds. This is slightly different from a normal
904 /// substitution in terms of what happens with bound regions. See
905 /// lengthy comment below for details.
906 pub fn subst_supertrait(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
907 trait_ref
: &ty
::PolyTraitRef
<'tcx
>)
908 -> ty
::Predicate
<'tcx
>
910 // The interaction between HRTB and supertraits is not entirely
911 // obvious. Let me walk you (and myself) through an example.
913 // Let's start with an easy case. Consider two traits:
915 // trait Foo<'a> : Bar<'a,'a> { }
916 // trait Bar<'b,'c> { }
918 // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
919 // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
920 // knew that `Foo<'x>` (for any 'x) then we also know that
921 // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
922 // normal substitution.
924 // In terms of why this is sound, the idea is that whenever there
925 // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
926 // holds. So if there is an impl of `T:Foo<'a>` that applies to
927 // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
930 // Another example to be careful of is this:
932 // trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
933 // trait Bar1<'b,'c> { }
935 // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
936 // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
937 // reason is similar to the previous example: any impl of
938 // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`. So
939 // basically we would want to collapse the bound lifetimes from
940 // the input (`trait_ref`) and the supertraits.
942 // To achieve this in practice is fairly straightforward. Let's
943 // consider the more complicated scenario:
945 // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
946 // has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
947 // where both `'x` and `'b` would have a DB index of 1.
948 // The substitution from the input trait-ref is therefore going to be
949 // `'a => 'x` (where `'x` has a DB index of 1).
950 // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
951 // early-bound parameter and `'b' is a late-bound parameter with a
953 // - If we replace `'a` with `'x` from the input, it too will have
954 // a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
955 // just as we wanted.
957 // There is only one catch. If we just apply the substitution `'a
958 // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
959 // adjust the DB index because we substituting into a binder (it
960 // tries to be so smart...) resulting in `for<'x> for<'b>
961 // Bar1<'x,'b>` (we have no syntax for this, so use your
962 // imagination). Basically the 'x will have DB index of 2 and 'b
963 // will have DB index of 1. Not quite what we want. So we apply
964 // the substitution to the *contents* of the trait reference,
965 // rather than the trait reference itself (put another way, the
966 // substitution code expects equal binding levels in the values
967 // from the substitution and the value being substituted into, and
968 // this trick achieves that).
970 let substs
= &trait_ref
.0.substs
;
972 Predicate
::Trait(ty
::Binder(ref data
)) =>
973 Predicate
::Trait(ty
::Binder(data
.subst(tcx
, substs
))),
974 Predicate
::Equate(ty
::Binder(ref data
)) =>
975 Predicate
::Equate(ty
::Binder(data
.subst(tcx
, substs
))),
976 Predicate
::Subtype(ty
::Binder(ref data
)) =>
977 Predicate
::Subtype(ty
::Binder(data
.subst(tcx
, substs
))),
978 Predicate
::RegionOutlives(ty
::Binder(ref data
)) =>
979 Predicate
::RegionOutlives(ty
::Binder(data
.subst(tcx
, substs
))),
980 Predicate
::TypeOutlives(ty
::Binder(ref data
)) =>
981 Predicate
::TypeOutlives(ty
::Binder(data
.subst(tcx
, substs
))),
982 Predicate
::Projection(ty
::Binder(ref data
)) =>
983 Predicate
::Projection(ty
::Binder(data
.subst(tcx
, substs
))),
984 Predicate
::WellFormed(data
) =>
985 Predicate
::WellFormed(data
.subst(tcx
, substs
)),
986 Predicate
::ObjectSafe(trait_def_id
) =>
987 Predicate
::ObjectSafe(trait_def_id
),
988 Predicate
::ClosureKind(closure_def_id
, kind
) =>
989 Predicate
::ClosureKind(closure_def_id
, kind
),
990 Predicate
::ConstEvaluatable(def_id
, const_substs
) =>
991 Predicate
::ConstEvaluatable(def_id
, const_substs
.subst(tcx
, substs
)),
996 #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
997 pub struct TraitPredicate
<'tcx
> {
998 pub trait_ref
: TraitRef
<'tcx
>
1000 pub type PolyTraitPredicate
<'tcx
> = ty
::Binder
<TraitPredicate
<'tcx
>>;
1002 impl<'tcx
> TraitPredicate
<'tcx
> {
1003 pub fn def_id(&self) -> DefId
{
1004 self.trait_ref
.def_id
1007 pub fn input_types
<'a
>(&'a
self) -> impl DoubleEndedIterator
<Item
=Ty
<'tcx
>> + 'a
{
1008 self.trait_ref
.input_types()
1011 pub fn self_ty(&self) -> Ty
<'tcx
> {
1012 self.trait_ref
.self_ty()
1016 impl<'tcx
> PolyTraitPredicate
<'tcx
> {
1017 pub fn def_id(&self) -> DefId
{
1018 // ok to skip binder since trait def-id does not care about regions
1023 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
1024 pub struct EquatePredicate
<'tcx
>(pub Ty
<'tcx
>, pub Ty
<'tcx
>); // `0 == 1`
1025 pub type PolyEquatePredicate
<'tcx
> = ty
::Binder
<EquatePredicate
<'tcx
>>;
1027 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
1028 pub struct OutlivesPredicate
<A
,B
>(pub A
, pub B
); // `A : B`
1029 pub type PolyOutlivesPredicate
<A
,B
> = ty
::Binder
<OutlivesPredicate
<A
,B
>>;
1030 pub type PolyRegionOutlivesPredicate
<'tcx
> = PolyOutlivesPredicate
<ty
::Region
<'tcx
>,
1032 pub type PolyTypeOutlivesPredicate
<'tcx
> = PolyOutlivesPredicate
<Ty
<'tcx
>, ty
::Region
<'tcx
>>;
1034 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
1035 pub struct SubtypePredicate
<'tcx
> {
1036 pub a_is_expected
: bool
,
1040 pub type PolySubtypePredicate
<'tcx
> = ty
::Binder
<SubtypePredicate
<'tcx
>>;
1042 /// This kind of predicate has no *direct* correspondent in the
1043 /// syntax, but it roughly corresponds to the syntactic forms:
1045 /// 1. `T : TraitRef<..., Item=Type>`
1046 /// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
1048 /// In particular, form #1 is "desugared" to the combination of a
1049 /// normal trait predicate (`T : TraitRef<...>`) and one of these
1050 /// predicates. Form #2 is a broader form in that it also permits
1051 /// equality between arbitrary types. Processing an instance of Form
1052 /// #2 eventually yields one of these `ProjectionPredicate`
1053 /// instances to normalize the LHS.
1054 #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
1055 pub struct ProjectionPredicate
<'tcx
> {
1056 pub projection_ty
: ProjectionTy
<'tcx
>,
1060 pub type PolyProjectionPredicate
<'tcx
> = Binder
<ProjectionPredicate
<'tcx
>>;
1062 impl<'tcx
> PolyProjectionPredicate
<'tcx
> {
1063 pub fn to_poly_trait_ref(&self, tcx
: TyCtxt
) -> PolyTraitRef
<'tcx
> {
1064 // Note: unlike with TraitRef::to_poly_trait_ref(),
1065 // self.0.trait_ref is permitted to have escaping regions.
1066 // This is because here `self` has a `Binder` and so does our
1067 // return value, so we are preserving the number of binding
1069 ty
::Binder(self.0.projection_ty
.trait_ref(tcx
))
1072 pub fn ty(&self) -> Binder
<Ty
<'tcx
>> {
1073 Binder(self.skip_binder().ty
) // preserves binding levels
1077 pub trait ToPolyTraitRef
<'tcx
> {
1078 fn to_poly_trait_ref(&self) -> PolyTraitRef
<'tcx
>;
1081 impl<'tcx
> ToPolyTraitRef
<'tcx
> for TraitRef
<'tcx
> {
1082 fn to_poly_trait_ref(&self) -> PolyTraitRef
<'tcx
> {
1083 assert
!(!self.has_escaping_regions());
1084 ty
::Binder(self.clone())
1088 impl<'tcx
> ToPolyTraitRef
<'tcx
> for PolyTraitPredicate
<'tcx
> {
1089 fn to_poly_trait_ref(&self) -> PolyTraitRef
<'tcx
> {
1090 self.map_bound_ref(|trait_pred
| trait_pred
.trait_ref
)
1094 pub trait ToPredicate
<'tcx
> {
1095 fn to_predicate(&self) -> Predicate
<'tcx
>;
1098 impl<'tcx
> ToPredicate
<'tcx
> for TraitRef
<'tcx
> {
1099 fn to_predicate(&self) -> Predicate
<'tcx
> {
1100 // we're about to add a binder, so let's check that we don't
1101 // accidentally capture anything, or else that might be some
1102 // weird debruijn accounting.
1103 assert
!(!self.has_escaping_regions());
1105 ty
::Predicate
::Trait(ty
::Binder(ty
::TraitPredicate
{
1106 trait_ref
: self.clone()
1111 impl<'tcx
> ToPredicate
<'tcx
> for PolyTraitRef
<'tcx
> {
1112 fn to_predicate(&self) -> Predicate
<'tcx
> {
1113 ty
::Predicate
::Trait(self.to_poly_trait_predicate())
1117 impl<'tcx
> ToPredicate
<'tcx
> for PolyEquatePredicate
<'tcx
> {
1118 fn to_predicate(&self) -> Predicate
<'tcx
> {
1119 Predicate
::Equate(self.clone())
1123 impl<'tcx
> ToPredicate
<'tcx
> for PolyRegionOutlivesPredicate
<'tcx
> {
1124 fn to_predicate(&self) -> Predicate
<'tcx
> {
1125 Predicate
::RegionOutlives(self.clone())
1129 impl<'tcx
> ToPredicate
<'tcx
> for PolyTypeOutlivesPredicate
<'tcx
> {
1130 fn to_predicate(&self) -> Predicate
<'tcx
> {
1131 Predicate
::TypeOutlives(self.clone())
1135 impl<'tcx
> ToPredicate
<'tcx
> for PolyProjectionPredicate
<'tcx
> {
1136 fn to_predicate(&self) -> Predicate
<'tcx
> {
1137 Predicate
::Projection(self.clone())
1141 impl<'tcx
> Predicate
<'tcx
> {
1142 /// Iterates over the types in this predicate. Note that in all
1143 /// cases this is skipping over a binder, so late-bound regions
1144 /// with depth 0 are bound by the predicate.
1145 pub fn walk_tys(&self) -> IntoIter
<Ty
<'tcx
>> {
1146 let vec
: Vec
<_
> = match *self {
1147 ty
::Predicate
::Trait(ref data
) => {
1148 data
.skip_binder().input_types().collect()
1150 ty
::Predicate
::Equate(ty
::Binder(ref data
)) => {
1151 vec
![data
.0, data
.1]
1153 ty
::Predicate
::Subtype(ty
::Binder(SubtypePredicate { a, b, a_is_expected: _ }
)) => {
1156 ty
::Predicate
::TypeOutlives(ty
::Binder(ref data
)) => {
1159 ty
::Predicate
::RegionOutlives(..) => {
1162 ty
::Predicate
::Projection(ref data
) => {
1163 data
.0.projection_ty
.substs
.types().chain(Some(data
.0.ty
)).collect()
1165 ty
::Predicate
::WellFormed(data
) => {
1168 ty
::Predicate
::ObjectSafe(_trait_def_id
) => {
1171 ty
::Predicate
::ClosureKind(_closure_def_id
, _kind
) => {
1174 ty
::Predicate
::ConstEvaluatable(_
, substs
) => {
1175 substs
.types().collect()
1179 // The only reason to collect into a vector here is that I was
1180 // too lazy to make the full (somewhat complicated) iterator
1181 // type that would be needed here. But I wanted this fn to
1182 // return an iterator conceptually, rather than a `Vec`, so as
1183 // to be closer to `Ty::walk`.
1187 pub fn to_opt_poly_trait_ref(&self) -> Option
<PolyTraitRef
<'tcx
>> {
1189 Predicate
::Trait(ref t
) => {
1190 Some(t
.to_poly_trait_ref())
1192 Predicate
::Projection(..) |
1193 Predicate
::Equate(..) |
1194 Predicate
::Subtype(..) |
1195 Predicate
::RegionOutlives(..) |
1196 Predicate
::WellFormed(..) |
1197 Predicate
::ObjectSafe(..) |
1198 Predicate
::ClosureKind(..) |
1199 Predicate
::TypeOutlives(..) |
1200 Predicate
::ConstEvaluatable(..) => {
1207 /// Represents the bounds declared on a particular set of type
1208 /// parameters. Should eventually be generalized into a flag list of
1209 /// where clauses. You can obtain a `InstantiatedPredicates` list from a
1210 /// `GenericPredicates` by using the `instantiate` method. Note that this method
1211 /// reflects an important semantic invariant of `InstantiatedPredicates`: while
1212 /// the `GenericPredicates` are expressed in terms of the bound type
1213 /// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance
1214 /// represented a set of bounds for some particular instantiation,
1215 /// meaning that the generic parameters have been substituted with
1220 /// struct Foo<T,U:Bar<T>> { ... }
1222 /// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
1223 /// `[[], [U:Bar<T>]]`. Now if there were some particular reference
1224 /// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
1225 /// [usize:Bar<isize>]]`.
1227 pub struct InstantiatedPredicates
<'tcx
> {
1228 pub predicates
: Vec
<Predicate
<'tcx
>>,
1231 impl<'tcx
> InstantiatedPredicates
<'tcx
> {
1232 pub fn empty() -> InstantiatedPredicates
<'tcx
> {
1233 InstantiatedPredicates { predicates: vec![] }
1236 pub fn is_empty(&self) -> bool
{
1237 self.predicates
.is_empty()
1241 /// When type checking, we use the `ParamEnv` to track
1242 /// details about the set of where-clauses that are in scope at this
1243 /// particular point.
1244 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1245 pub struct ParamEnv
<'tcx
> {
1246 /// Obligations that the caller must satisfy. This is basically
1247 /// the set of bounds on the in-scope type parameters, translated
1248 /// into Obligations, and elaborated and normalized.
1249 pub caller_bounds
: &'tcx Slice
<ty
::Predicate
<'tcx
>>,
1251 /// Typically, this is `Reveal::UserFacing`, but during trans we
1252 /// want `Reveal::All` -- note that this is always paired with an
1253 /// empty environment. To get that, use `ParamEnv::reveal()`.
1254 pub reveal
: traits
::Reveal
,
1257 impl<'tcx
> ParamEnv
<'tcx
> {
1258 /// Creates a suitable environment in which to perform trait
1259 /// queries on the given value. This will either be `self` *or*
1260 /// the empty environment, depending on whether `value` references
1261 /// type parameters that are in scope. (If it doesn't, then any
1262 /// judgements should be completely independent of the context,
1263 /// and hence we can safely use the empty environment so as to
1264 /// enable more sharing across functions.)
1266 /// NB: This is a mildly dubious thing to do, in that a function
1267 /// (or other environment) might have wacky where-clauses like
1268 /// `where Box<u32>: Copy`, which are clearly never
1269 /// satisfiable. The code will at present ignore these,
1270 /// effectively, when type-checking the body of said
1271 /// function. This preserves existing behavior in any
1272 /// case. --nmatsakis
1273 pub fn and
<T
: TypeFoldable
<'tcx
>>(self, value
: T
) -> ParamEnvAnd
<'tcx
, T
> {
1274 assert
!(!value
.needs_infer());
1275 if value
.has_param_types() || value
.has_self_ty() {
1282 param_env
: ParamEnv
::empty(self.reveal
),
1289 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1290 pub struct ParamEnvAnd
<'tcx
, T
> {
1291 pub param_env
: ParamEnv
<'tcx
>,
1295 impl<'tcx
, T
> ParamEnvAnd
<'tcx
, T
> {
1296 pub fn into_parts(self) -> (ParamEnv
<'tcx
>, T
) {
1297 (self.param_env
, self.value
)
1301 impl<'gcx
, T
> HashStable
<StableHashingContext
<'gcx
>> for ParamEnvAnd
<'gcx
, T
>
1302 where T
: HashStable
<StableHashingContext
<'gcx
>>
1304 fn hash_stable
<W
: StableHasherResult
>(&self,
1305 hcx
: &mut StableHashingContext
<'gcx
>,
1306 hasher
: &mut StableHasher
<W
>) {
1312 param_env
.hash_stable(hcx
, hasher
);
1313 value
.hash_stable(hcx
, hasher
);
1317 #[derive(Copy, Clone, Debug)]
1318 pub struct Destructor
{
1319 /// The def-id of the destructor method
1324 pub struct AdtFlags
: u32 {
1325 const NO_ADT_FLAGS
= 0;
1326 const IS_ENUM
= 1 << 0;
1327 const IS_PHANTOM_DATA
= 1 << 1;
1328 const IS_FUNDAMENTAL
= 1 << 2;
1329 const IS_UNION
= 1 << 3;
1330 const IS_BOX
= 1 << 4;
1335 pub struct VariantDef
{
1336 /// The variant's DefId. If this is a tuple-like struct,
1337 /// this is the DefId of the struct's ctor.
1339 pub name
: Name
, // struct's name if this is a struct
1340 pub discr
: VariantDiscr
,
1341 pub fields
: Vec
<FieldDef
>,
1342 pub ctor_kind
: CtorKind
,
1345 #[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
1346 pub enum VariantDiscr
{
1347 /// Explicit value for this variant, i.e. `X = 123`.
1348 /// The `DefId` corresponds to the embedded constant.
1351 /// The previous variant's discriminant plus one.
1352 /// For efficiency reasons, the distance from the
1353 /// last `Explicit` discriminant is being stored,
1354 /// or `0` for the first variant, if it has none.
1359 pub struct FieldDef
{
1362 pub vis
: Visibility
,
1365 /// The definition of an abstract data type - a struct or enum.
1367 /// These are all interned (by intern_adt_def) into the adt_defs
1371 pub variants
: Vec
<VariantDef
>,
1373 pub repr
: ReprOptions
,
1376 impl PartialEq
for AdtDef
{
1377 // AdtDef are always interned and this is part of TyS equality
1379 fn eq(&self, other
: &Self) -> bool { self as *const _ == other as *const _ }
1382 impl Eq
for AdtDef {}
1384 impl Hash
for AdtDef
{
1386 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
1387 (self as *const AdtDef
).hash(s
)
1391 impl<'tcx
> serialize
::UseSpecializedEncodable
for &'tcx AdtDef
{
1392 fn default_encode
<S
: Encoder
>(&self, s
: &mut S
) -> Result
<(), S
::Error
> {
1397 impl<'tcx
> serialize
::UseSpecializedDecodable
for &'tcx AdtDef {}
1400 impl<'gcx
> HashStable
<StableHashingContext
<'gcx
>> for AdtDef
{
1401 fn hash_stable
<W
: StableHasherResult
>(&self,
1402 hcx
: &mut StableHashingContext
<'gcx
>,
1403 hasher
: &mut StableHasher
<W
>) {
1411 did
.hash_stable(hcx
, hasher
);
1412 variants
.hash_stable(hcx
, hasher
);
1413 flags
.hash_stable(hcx
, hasher
);
1414 repr
.hash_stable(hcx
, hasher
);
1418 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
1419 pub enum AdtKind { Struct, Union, Enum }
1422 #[derive(RustcEncodable, RustcDecodable, Default)]
1423 pub struct ReprFlags
: u8 {
1424 const IS_C
= 1 << 0;
1425 const IS_PACKED
= 1 << 1;
1426 const IS_SIMD
= 1 << 2;
1427 // Internal only for now. If true, don't reorder fields.
1428 const IS_LINEAR
= 1 << 3;
1430 // Any of these flags being set prevent field reordering optimisation.
1431 const IS_UNOPTIMISABLE
= ReprFlags
::IS_C
.bits
|
1432 ReprFlags
::IS_PACKED
.bits
|
1433 ReprFlags
::IS_SIMD
.bits
|
1434 ReprFlags
::IS_LINEAR
.bits
;
1438 impl_stable_hash_for
!(struct ReprFlags
{
1444 /// Represents the repr options provided by the user,
1445 #[derive(Copy, Clone, Eq, PartialEq, RustcEncodable, RustcDecodable, Default)]
1446 pub struct ReprOptions
{
1447 pub int
: Option
<attr
::IntType
>,
1449 pub flags
: ReprFlags
,
1452 impl_stable_hash_for
!(struct ReprOptions
{
1459 pub fn new(tcx
: TyCtxt
, did
: DefId
) -> ReprOptions
{
1460 let mut flags
= ReprFlags
::empty();
1461 let mut size
= None
;
1462 let mut max_align
= 0;
1463 for attr
in tcx
.get_attrs(did
).iter() {
1464 for r
in attr
::find_repr_attrs(tcx
.sess
.diagnostic(), attr
) {
1465 flags
.insert(match r
{
1466 attr
::ReprExtern
=> ReprFlags
::IS_C
,
1467 attr
::ReprPacked
=> ReprFlags
::IS_PACKED
,
1468 attr
::ReprSimd
=> ReprFlags
::IS_SIMD
,
1469 attr
::ReprInt(i
) => {
1473 attr
::ReprAlign(align
) => {
1474 max_align
= cmp
::max(align
, max_align
);
1481 // FIXME(eddyb) This is deprecated and should be removed.
1482 if tcx
.has_attr(did
, "simd") {
1483 flags
.insert(ReprFlags
::IS_SIMD
);
1486 // This is here instead of layout because the choice must make it into metadata.
1487 if !tcx
.consider_optimizing(|| format
!("Reorder fields of {:?}", tcx
.item_path_str(did
))) {
1488 flags
.insert(ReprFlags
::IS_LINEAR
);
1490 ReprOptions { int: size, align: max_align, flags: flags }
1494 pub fn simd(&self) -> bool { self.flags.contains(ReprFlags::IS_SIMD) }
1496 pub fn c(&self) -> bool { self.flags.contains(ReprFlags::IS_C) }
1498 pub fn packed(&self) -> bool { self.flags.contains(ReprFlags::IS_PACKED) }
1500 pub fn linear(&self) -> bool { self.flags.contains(ReprFlags::IS_LINEAR) }
1502 pub fn discr_type(&self) -> attr
::IntType
{
1503 self.int
.unwrap_or(attr
::SignedInt(ast
::IntTy
::Is
))
1506 /// Returns true if this `#[repr()]` should inhabit "smart enum
1507 /// layout" optimizations, such as representing `Foo<&T>` as a
1509 pub fn inhibit_enum_layout_opt(&self) -> bool
{
1510 self.c() || self.int
.is_some()
1514 impl<'a
, 'gcx
, 'tcx
> AdtDef
{
1518 variants
: Vec
<VariantDef
>,
1519 repr
: ReprOptions
) -> Self {
1520 let mut flags
= AdtFlags
::NO_ADT_FLAGS
;
1521 let attrs
= tcx
.get_attrs(did
);
1522 if attr
::contains_name(&attrs
, "fundamental") {
1523 flags
= flags
| AdtFlags
::IS_FUNDAMENTAL
;
1525 if Some(did
) == tcx
.lang_items().phantom_data() {
1526 flags
= flags
| AdtFlags
::IS_PHANTOM_DATA
;
1528 if Some(did
) == tcx
.lang_items().owned_box() {
1529 flags
= flags
| AdtFlags
::IS_BOX
;
1532 AdtKind
::Enum
=> flags
= flags
| AdtFlags
::IS_ENUM
,
1533 AdtKind
::Union
=> flags
= flags
| AdtFlags
::IS_UNION
,
1534 AdtKind
::Struct
=> {}
1545 pub fn is_struct(&self) -> bool
{
1546 !self.is_union() && !self.is_enum()
1550 pub fn is_union(&self) -> bool
{
1551 self.flags
.intersects(AdtFlags
::IS_UNION
)
1555 pub fn is_enum(&self) -> bool
{
1556 self.flags
.intersects(AdtFlags
::IS_ENUM
)
1559 /// Returns the kind of the ADT - Struct or Enum.
1561 pub fn adt_kind(&self) -> AdtKind
{
1564 } else if self.is_union() {
1571 pub fn descr(&self) -> &'
static str {
1572 match self.adt_kind() {
1573 AdtKind
::Struct
=> "struct",
1574 AdtKind
::Union
=> "union",
1575 AdtKind
::Enum
=> "enum",
1579 pub fn variant_descr(&self) -> &'
static str {
1580 match self.adt_kind() {
1581 AdtKind
::Struct
=> "struct",
1582 AdtKind
::Union
=> "union",
1583 AdtKind
::Enum
=> "variant",
1587 /// Returns whether this type is #[fundamental] for the purposes
1588 /// of coherence checking.
1590 pub fn is_fundamental(&self) -> bool
{
1591 self.flags
.intersects(AdtFlags
::IS_FUNDAMENTAL
)
1594 /// Returns true if this is PhantomData<T>.
1596 pub fn is_phantom_data(&self) -> bool
{
1597 self.flags
.intersects(AdtFlags
::IS_PHANTOM_DATA
)
1600 /// Returns true if this is Box<T>.
1602 pub fn is_box(&self) -> bool
{
1603 self.flags
.intersects(AdtFlags
::IS_BOX
)
1606 /// Returns whether this type has a destructor.
1607 pub fn has_dtor(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>) -> bool
{
1608 self.destructor(tcx
).is_some()
1611 /// Asserts this is a struct and returns the struct's unique
1613 pub fn struct_variant(&self) -> &VariantDef
{
1614 assert
!(!self.is_enum());
1619 pub fn predicates(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>) -> GenericPredicates
<'gcx
> {
1620 tcx
.predicates_of(self.did
)
1623 /// Returns an iterator over all fields contained
1626 pub fn all_fields
<'s
>(&'s
self) -> impl Iterator
<Item
= &'s FieldDef
> {
1627 self.variants
.iter().flat_map(|v
| v
.fields
.iter())
1631 pub fn is_univariant(&self) -> bool
{
1632 self.variants
.len() == 1
1635 pub fn is_payloadfree(&self) -> bool
{
1636 !self.variants
.is_empty() &&
1637 self.variants
.iter().all(|v
| v
.fields
.is_empty())
1640 pub fn variant_with_id(&self, vid
: DefId
) -> &VariantDef
{
1643 .find(|v
| v
.did
== vid
)
1644 .expect("variant_with_id: unknown variant")
1647 pub fn variant_index_with_id(&self, vid
: DefId
) -> usize {
1650 .position(|v
| v
.did
== vid
)
1651 .expect("variant_index_with_id: unknown variant")
1654 pub fn variant_of_def(&self, def
: Def
) -> &VariantDef
{
1656 Def
::Variant(vid
) | Def
::VariantCtor(vid
, ..) => self.variant_with_id(vid
),
1657 Def
::Struct(..) | Def
::StructCtor(..) | Def
::Union(..) |
1658 Def
::TyAlias(..) | Def
::AssociatedTy(..) | Def
::SelfTy(..) => self.struct_variant(),
1659 _
=> bug
!("unexpected def {:?} in variant_of_def", def
)
1664 pub fn discriminants(&'a
self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>)
1665 -> impl Iterator
<Item
=ConstInt
> + 'a
{
1666 let param_env
= ParamEnv
::empty(traits
::Reveal
::UserFacing
);
1667 let repr_type
= self.repr
.discr_type();
1668 let initial
= repr_type
.initial_discriminant(tcx
.global_tcx());
1669 let mut prev_discr
= None
::<ConstInt
>;
1670 self.variants
.iter().map(move |v
| {
1671 let mut discr
= prev_discr
.map_or(initial
, |d
| d
.wrap_incr());
1672 if let VariantDiscr
::Explicit(expr_did
) = v
.discr
{
1673 let substs
= Substs
::identity_for_item(tcx
.global_tcx(), expr_did
);
1674 match tcx
.const_eval(param_env
.and((expr_did
, substs
))) {
1675 Ok(&ty
::Const { val: ConstVal::Integral(v), .. }
) => {
1679 if !expr_did
.is_local() {
1680 span_bug
!(tcx
.def_span(expr_did
),
1681 "variant discriminant evaluation succeeded \
1682 in its crate but failed locally: {:?}", err
);
1687 prev_discr
= Some(discr
);
1693 /// Compute the discriminant value used by a specific variant.
1694 /// Unlike `discriminants`, this is (amortized) constant-time,
1695 /// only doing at most one query for evaluating an explicit
1696 /// discriminant (the last one before the requested variant),
1697 /// assuming there are no constant-evaluation errors there.
1698 pub fn discriminant_for_variant(&self,
1699 tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
1700 variant_index
: usize)
1702 let param_env
= ParamEnv
::empty(traits
::Reveal
::UserFacing
);
1703 let repr_type
= self.repr
.discr_type();
1704 let mut explicit_value
= repr_type
.initial_discriminant(tcx
.global_tcx());
1705 let mut explicit_index
= variant_index
;
1707 match self.variants
[explicit_index
].discr
{
1708 ty
::VariantDiscr
::Relative(0) => break,
1709 ty
::VariantDiscr
::Relative(distance
) => {
1710 explicit_index
-= distance
;
1712 ty
::VariantDiscr
::Explicit(expr_did
) => {
1713 let substs
= Substs
::identity_for_item(tcx
.global_tcx(), expr_did
);
1714 match tcx
.const_eval(param_env
.and((expr_did
, substs
))) {
1715 Ok(&ty
::Const { val: ConstVal::Integral(v), .. }
) => {
1720 if !expr_did
.is_local() {
1721 span_bug
!(tcx
.def_span(expr_did
),
1722 "variant discriminant evaluation succeeded \
1723 in its crate but failed locally: {:?}", err
);
1725 if explicit_index
== 0 {
1728 explicit_index
-= 1;
1734 let discr
= explicit_value
.to_u128_unchecked()
1735 .wrapping_add((variant_index
- explicit_index
) as u128
);
1737 attr
::UnsignedInt(ty
) => {
1738 ConstInt
::new_unsigned_truncating(discr
, ty
,
1739 tcx
.sess
.target
.usize_ty
)
1741 attr
::SignedInt(ty
) => {
1742 ConstInt
::new_signed_truncating(discr
as i128
, ty
,
1743 tcx
.sess
.target
.isize_ty
)
1748 pub fn destructor(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>) -> Option
<Destructor
> {
1749 tcx
.adt_destructor(self.did
)
1752 /// Returns a list of types such that `Self: Sized` if and only
1753 /// if that type is Sized, or `TyErr` if this type is recursive.
1755 /// Oddly enough, checking that the sized-constraint is Sized is
1756 /// actually more expressive than checking all members:
1757 /// the Sized trait is inductive, so an associated type that references
1758 /// Self would prevent its containing ADT from being Sized.
1760 /// Due to normalization being eager, this applies even if
1761 /// the associated type is behind a pointer, e.g. issue #31299.
1762 pub fn sized_constraint(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>) -> &'tcx
[Ty
<'tcx
>] {
1763 match queries
::adt_sized_constraint
::try_get(tcx
, DUMMY_SP
, self.did
) {
1766 debug
!("adt_sized_constraint: {:?} is recursive", self);
1767 // This should be reported as an error by `check_representable`.
1769 // Consider the type as Sized in the meanwhile to avoid
1770 // further errors. Delay our `bug` diagnostic here to get
1771 // emitted later as well in case we accidentally otherwise don't
1774 tcx
.intern_type_list(&[tcx
.types
.err
])
1779 fn sized_constraint_for_ty(&self,
1780 tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
1783 let result
= match ty
.sty
{
1784 TyBool
| TyChar
| TyInt(..) | TyUint(..) | TyFloat(..) |
1785 TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_
) |
1786 TyArray(..) | TyClosure(..) | TyGenerator(..) | TyNever
=> {
1790 TyStr
| TyDynamic(..) | TySlice(_
) | TyError
=> {
1791 // these are never sized - return the target type
1795 TyTuple(ref tys
, _
) => {
1798 Some(ty
) => self.sized_constraint_for_ty(tcx
, ty
)
1802 TyAdt(adt
, substs
) => {
1804 let adt_tys
= adt
.sized_constraint(tcx
);
1805 debug
!("sized_constraint_for_ty({:?}) intermediate = {:?}",
1808 .map(|ty
| ty
.subst(tcx
, substs
))
1809 .flat_map(|ty
| self.sized_constraint_for_ty(tcx
, ty
))
1813 TyProjection(..) | TyAnon(..) => {
1814 // must calculate explicitly.
1815 // FIXME: consider special-casing always-Sized projections
1820 // perf hack: if there is a `T: Sized` bound, then
1821 // we know that `T` is Sized and do not need to check
1824 let sized_trait
= match tcx
.lang_items().sized_trait() {
1826 _
=> return vec
![ty
]
1828 let sized_predicate
= Binder(TraitRef
{
1829 def_id
: sized_trait
,
1830 substs
: tcx
.mk_substs_trait(ty
, &[])
1832 let predicates
= tcx
.predicates_of(self.did
).predicates
;
1833 if predicates
.into_iter().any(|p
| p
== sized_predicate
) {
1841 bug
!("unexpected type `{:?}` in sized_constraint_for_ty",
1845 debug
!("sized_constraint_for_ty({:?}) = {:?}", ty
, result
);
1850 impl<'a
, 'gcx
, 'tcx
> VariantDef
{
1852 pub fn find_field_named(&self, name
: ast
::Name
) -> Option
<&FieldDef
> {
1853 self.index_of_field_named(name
).map(|index
| &self.fields
[index
])
1856 pub fn index_of_field_named(&self, name
: ast
::Name
) -> Option
<usize> {
1857 if let Some(index
) = self.fields
.iter().position(|f
| f
.name
== name
) {
1860 let mut ident
= name
.to_ident();
1861 while ident
.ctxt
!= SyntaxContext
::empty() {
1862 ident
.ctxt
.remove_mark();
1863 if let Some(field
) = self.fields
.iter().position(|f
| f
.name
.to_ident() == ident
) {
1871 pub fn field_named(&self, name
: ast
::Name
) -> &FieldDef
{
1872 self.find_field_named(name
).unwrap()
1876 impl<'a
, 'gcx
, 'tcx
> FieldDef
{
1877 pub fn ty(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>, subst
: &Substs
<'tcx
>) -> Ty
<'tcx
> {
1878 tcx
.type_of(self.did
).subst(tcx
, subst
)
1882 #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
1883 pub enum ClosureKind
{
1884 // Warning: Ordering is significant here! The ordering is chosen
1885 // because the trait Fn is a subtrait of FnMut and so in turn, and
1886 // hence we order it so that Fn < FnMut < FnOnce.
1892 impl<'a
, 'tcx
> ClosureKind
{
1893 pub fn trait_did(&self, tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>) -> DefId
{
1895 ClosureKind
::Fn
=> tcx
.require_lang_item(FnTraitLangItem
),
1896 ClosureKind
::FnMut
=> {
1897 tcx
.require_lang_item(FnMutTraitLangItem
)
1899 ClosureKind
::FnOnce
=> {
1900 tcx
.require_lang_item(FnOnceTraitLangItem
)
1905 /// True if this a type that impls this closure kind
1906 /// must also implement `other`.
1907 pub fn extends(self, other
: ty
::ClosureKind
) -> bool
{
1908 match (self, other
) {
1909 (ClosureKind
::Fn
, ClosureKind
::Fn
) => true,
1910 (ClosureKind
::Fn
, ClosureKind
::FnMut
) => true,
1911 (ClosureKind
::Fn
, ClosureKind
::FnOnce
) => true,
1912 (ClosureKind
::FnMut
, ClosureKind
::FnMut
) => true,
1913 (ClosureKind
::FnMut
, ClosureKind
::FnOnce
) => true,
1914 (ClosureKind
::FnOnce
, ClosureKind
::FnOnce
) => true,
1920 impl<'tcx
> TyS
<'tcx
> {
1921 /// Iterator that walks `self` and any types reachable from
1922 /// `self`, in depth-first order. Note that just walks the types
1923 /// that appear in `self`, it does not descend into the fields of
1924 /// structs or variants. For example:
1927 /// isize => { isize }
1928 /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
1929 /// [isize] => { [isize], isize }
1931 pub fn walk(&'tcx
self) -> TypeWalker
<'tcx
> {
1932 TypeWalker
::new(self)
1935 /// Iterator that walks the immediate children of `self`. Hence
1936 /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
1937 /// (but not `i32`, like `walk`).
1938 pub fn walk_shallow(&'tcx
self) -> AccIntoIter
<walk
::TypeWalkerArray
<'tcx
>> {
1939 walk
::walk_shallow(self)
1942 /// Walks `ty` and any types appearing within `ty`, invoking the
1943 /// callback `f` on each type. If the callback returns false, then the
1944 /// children of the current type are ignored.
1946 /// Note: prefer `ty.walk()` where possible.
1947 pub fn maybe_walk
<F
>(&'tcx
self, mut f
: F
)
1948 where F
: FnMut(Ty
<'tcx
>) -> bool
1950 let mut walker
= self.walk();
1951 while let Some(ty
) = walker
.next() {
1953 walker
.skip_current_subtree();
1959 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1960 pub enum LvaluePreference
{
1965 impl LvaluePreference
{
1966 pub fn from_mutbl(m
: hir
::Mutability
) -> Self {
1968 hir
::MutMutable
=> PreferMutLvalue
,
1969 hir
::MutImmutable
=> NoPreference
,
1975 pub fn from_mutbl(m
: hir
::Mutability
) -> BorrowKind
{
1977 hir
::MutMutable
=> MutBorrow
,
1978 hir
::MutImmutable
=> ImmBorrow
,
1982 /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow
1983 /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a
1984 /// mutability that is stronger than necessary so that it at least *would permit* the borrow in
1986 pub fn to_mutbl_lossy(self) -> hir
::Mutability
{
1988 MutBorrow
=> hir
::MutMutable
,
1989 ImmBorrow
=> hir
::MutImmutable
,
1991 // We have no type corresponding to a unique imm borrow, so
1992 // use `&mut`. It gives all the capabilities of an `&uniq`
1993 // and hence is a safe "over approximation".
1994 UniqueImmBorrow
=> hir
::MutMutable
,
1998 pub fn to_user_str(&self) -> &'
static str {
2000 MutBorrow
=> "mutable",
2001 ImmBorrow
=> "immutable",
2002 UniqueImmBorrow
=> "uniquely immutable",
2007 #[derive(Debug, Clone)]
2008 pub enum Attributes
<'gcx
> {
2009 Owned(Rc
<[ast
::Attribute
]>),
2010 Borrowed(&'gcx
[ast
::Attribute
])
2013 impl<'gcx
> ::std
::ops
::Deref
for Attributes
<'gcx
> {
2014 type Target
= [ast
::Attribute
];
2016 fn deref(&self) -> &[ast
::Attribute
] {
2018 &Attributes
::Owned(ref data
) => &data
,
2019 &Attributes
::Borrowed(data
) => data
2024 impl<'a
, 'gcx
, 'tcx
> TyCtxt
<'a
, 'gcx
, 'tcx
> {
2025 pub fn body_tables(self, body
: hir
::BodyId
) -> &'gcx TypeckTables
<'gcx
> {
2026 self.typeck_tables_of(self.hir
.body_owner_def_id(body
))
2029 /// Returns an iterator of the def-ids for all body-owners in this
2030 /// crate. If you would prefer to iterate over the bodies
2031 /// themselves, you can do `self.hir.krate().body_ids.iter()`.
2032 pub fn body_owners(self) -> impl Iterator
<Item
= DefId
> + 'a
{
2036 .map(move |&body_id
| self.hir
.body_owner_def_id(body_id
))
2039 pub fn expr_span(self, id
: NodeId
) -> Span
{
2040 match self.hir
.find(id
) {
2041 Some(hir_map
::NodeExpr(e
)) => {
2045 bug
!("Node id {} is not an expr: {:?}", id
, f
);
2048 bug
!("Node id {} is not present in the node map", id
);
2053 pub fn expr_is_lval(self, expr
: &hir
::Expr
) -> bool
{
2055 hir
::ExprPath(hir
::QPath
::Resolved(_
, ref path
)) => {
2057 Def
::Local(..) | Def
::Upvar(..) | Def
::Static(..) | Def
::Err
=> true,
2062 hir
::ExprType(ref e
, _
) => {
2063 self.expr_is_lval(e
)
2066 hir
::ExprUnary(hir
::UnDeref
, _
) |
2067 hir
::ExprField(..) |
2068 hir
::ExprTupField(..) |
2069 hir
::ExprIndex(..) => {
2073 // Partially qualified paths in expressions can only legally
2074 // refer to associated items which are always rvalues.
2075 hir
::ExprPath(hir
::QPath
::TypeRelative(..)) |
2078 hir
::ExprMethodCall(..) |
2079 hir
::ExprStruct(..) |
2082 hir
::ExprMatch(..) |
2083 hir
::ExprClosure(..) |
2084 hir
::ExprBlock(..) |
2085 hir
::ExprRepeat(..) |
2086 hir
::ExprArray(..) |
2087 hir
::ExprBreak(..) |
2088 hir
::ExprAgain(..) |
2090 hir
::ExprWhile(..) |
2092 hir
::ExprAssign(..) |
2093 hir
::ExprInlineAsm(..) |
2094 hir
::ExprAssignOp(..) |
2096 hir
::ExprUnary(..) |
2098 hir
::ExprAddrOf(..) |
2099 hir
::ExprBinary(..) |
2100 hir
::ExprYield(..) |
2101 hir
::ExprCast(..) => {
2107 pub fn provided_trait_methods(self, id
: DefId
) -> Vec
<AssociatedItem
> {
2108 self.associated_items(id
)
2109 .filter(|item
| item
.kind
== AssociatedKind
::Method
&& item
.defaultness
.has_value())
2113 pub fn trait_relevant_for_never(self, did
: DefId
) -> bool
{
2114 self.associated_items(did
).any(|item
| {
2115 item
.relevant_for_never()
2119 pub fn opt_associated_item(self, def_id
: DefId
) -> Option
<AssociatedItem
> {
2120 let is_associated_item
= if let Some(node_id
) = self.hir
.as_local_node_id(def_id
) {
2121 match self.hir
.get(node_id
) {
2122 hir_map
::NodeTraitItem(_
) | hir_map
::NodeImplItem(_
) => true,
2126 match self.describe_def(def_id
).expect("no def for def-id") {
2127 Def
::AssociatedConst(_
) | Def
::Method(_
) | Def
::AssociatedTy(_
) => true,
2132 if is_associated_item
{
2133 Some(self.associated_item(def_id
))
2139 fn associated_item_from_trait_item_ref(self,
2140 parent_def_id
: DefId
,
2141 parent_vis
: &hir
::Visibility
,
2142 trait_item_ref
: &hir
::TraitItemRef
)
2144 let def_id
= self.hir
.local_def_id(trait_item_ref
.id
.node_id
);
2145 let (kind
, has_self
) = match trait_item_ref
.kind
{
2146 hir
::AssociatedItemKind
::Const
=> (ty
::AssociatedKind
::Const
, false),
2147 hir
::AssociatedItemKind
::Method { has_self }
=> {
2148 (ty
::AssociatedKind
::Method
, has_self
)
2150 hir
::AssociatedItemKind
::Type
=> (ty
::AssociatedKind
::Type
, false),
2154 name
: trait_item_ref
.name
,
2156 // Visibility of trait items is inherited from their traits.
2157 vis
: Visibility
::from_hir(parent_vis
, trait_item_ref
.id
.node_id
, self),
2158 defaultness
: trait_item_ref
.defaultness
,
2160 container
: TraitContainer(parent_def_id
),
2161 method_has_self_argument
: has_self
2165 fn associated_item_from_impl_item_ref(self,
2166 parent_def_id
: DefId
,
2167 impl_item_ref
: &hir
::ImplItemRef
)
2169 let def_id
= self.hir
.local_def_id(impl_item_ref
.id
.node_id
);
2170 let (kind
, has_self
) = match impl_item_ref
.kind
{
2171 hir
::AssociatedItemKind
::Const
=> (ty
::AssociatedKind
::Const
, false),
2172 hir
::AssociatedItemKind
::Method { has_self }
=> {
2173 (ty
::AssociatedKind
::Method
, has_self
)
2175 hir
::AssociatedItemKind
::Type
=> (ty
::AssociatedKind
::Type
, false),
2178 ty
::AssociatedItem
{
2179 name
: impl_item_ref
.name
,
2181 // Visibility of trait impl items doesn't matter.
2182 vis
: ty
::Visibility
::from_hir(&impl_item_ref
.vis
, impl_item_ref
.id
.node_id
, self),
2183 defaultness
: impl_item_ref
.defaultness
,
2185 container
: ImplContainer(parent_def_id
),
2186 method_has_self_argument
: has_self
2190 #[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait.
2191 pub fn associated_items(self, def_id
: DefId
)
2192 -> impl Iterator
<Item
= ty
::AssociatedItem
> + 'a
{
2193 let def_ids
= self.associated_item_def_ids(def_id
);
2194 (0..def_ids
.len()).map(move |i
| self.associated_item(def_ids
[i
]))
2197 /// Returns true if the impls are the same polarity and are implementing
2198 /// a trait which contains no items
2199 pub fn impls_are_allowed_to_overlap(self, def_id1
: DefId
, def_id2
: DefId
) -> bool
{
2200 if !self.sess
.features
.borrow().overlapping_marker_traits
{
2203 let trait1_is_empty
= self.impl_trait_ref(def_id1
)
2204 .map_or(false, |trait_ref
| {
2205 self.associated_item_def_ids(trait_ref
.def_id
).is_empty()
2207 let trait2_is_empty
= self.impl_trait_ref(def_id2
)
2208 .map_or(false, |trait_ref
| {
2209 self.associated_item_def_ids(trait_ref
.def_id
).is_empty()
2211 self.impl_polarity(def_id1
) == self.impl_polarity(def_id2
)
2216 // Returns `ty::VariantDef` if `def` refers to a struct,
2217 // or variant or their constructors, panics otherwise.
2218 pub fn expect_variant_def(self, def
: Def
) -> &'tcx VariantDef
{
2220 Def
::Variant(did
) | Def
::VariantCtor(did
, ..) => {
2221 let enum_did
= self.parent_def_id(did
).unwrap();
2222 self.adt_def(enum_did
).variant_with_id(did
)
2224 Def
::Struct(did
) | Def
::Union(did
) => {
2225 self.adt_def(did
).struct_variant()
2227 Def
::StructCtor(ctor_did
, ..) => {
2228 let did
= self.parent_def_id(ctor_did
).expect("struct ctor has no parent");
2229 self.adt_def(did
).struct_variant()
2231 _
=> bug
!("expect_variant_def used with unexpected def {:?}", def
)
2235 pub fn item_name(self, id
: DefId
) -> InternedString
{
2236 if let Some(id
) = self.hir
.as_local_node_id(id
) {
2237 self.hir
.name(id
).as_str()
2238 } else if id
.index
== CRATE_DEF_INDEX
{
2239 self.original_crate_name(id
.krate
).as_str()
2241 let def_key
= self.def_key(id
);
2242 // The name of a StructCtor is that of its struct parent.
2243 if let hir_map
::DefPathData
::StructCtor
= def_key
.disambiguated_data
.data
{
2244 self.item_name(DefId
{
2246 index
: def_key
.parent
.unwrap()
2249 def_key
.disambiguated_data
.data
.get_opt_name().unwrap_or_else(|| {
2250 bug
!("item_name: no name for {:?}", self.def_path(id
));
2256 /// Return the possibly-auto-generated MIR of a (DefId, Subst) pair.
2257 pub fn instance_mir(self, instance
: ty
::InstanceDef
<'gcx
>)
2261 ty
::InstanceDef
::Item(did
) => {
2262 self.optimized_mir(did
)
2264 ty
::InstanceDef
::Intrinsic(..) |
2265 ty
::InstanceDef
::FnPtrShim(..) |
2266 ty
::InstanceDef
::Virtual(..) |
2267 ty
::InstanceDef
::ClosureOnceShim { .. }
|
2268 ty
::InstanceDef
::DropGlue(..) |
2269 ty
::InstanceDef
::CloneShim(..) => {
2270 self.mir_shims(instance
)
2275 /// Given the DefId of an item, returns its MIR, borrowed immutably.
2276 /// Returns None if there is no MIR for the DefId
2277 pub fn maybe_optimized_mir(self, did
: DefId
) -> Option
<&'gcx Mir
<'gcx
>> {
2278 if self.is_mir_available(did
) {
2279 Some(self.optimized_mir(did
))
2285 /// Get the attributes of a definition.
2286 pub fn get_attrs(self, did
: DefId
) -> Attributes
<'gcx
> {
2287 if let Some(id
) = self.hir
.as_local_node_id(did
) {
2288 Attributes
::Borrowed(self.hir
.attrs(id
))
2290 Attributes
::Owned(self.item_attrs(did
))
2294 /// Determine whether an item is annotated with an attribute
2295 pub fn has_attr(self, did
: DefId
, attr
: &str) -> bool
{
2296 self.get_attrs(did
).iter().any(|item
| item
.check_name(attr
))
2299 pub fn trait_has_default_impl(self, trait_def_id
: DefId
) -> bool
{
2300 self.trait_def(trait_def_id
).has_default_impl
2303 pub fn generator_layout(self, def_id
: DefId
) -> &'tcx GeneratorLayout
<'tcx
> {
2304 self.optimized_mir(def_id
).generator_layout
.as_ref().unwrap()
2307 /// Given the def_id of an impl, return the def_id of the trait it implements.
2308 /// If it implements no trait, return `None`.
2309 pub fn trait_id_of_impl(self, def_id
: DefId
) -> Option
<DefId
> {
2310 self.impl_trait_ref(def_id
).map(|tr
| tr
.def_id
)
2313 /// If the given def ID describes a method belonging to an impl, return the
2314 /// ID of the impl that the method belongs to. Otherwise, return `None`.
2315 pub fn impl_of_method(self, def_id
: DefId
) -> Option
<DefId
> {
2316 let item
= if def_id
.krate
!= LOCAL_CRATE
{
2317 if let Some(Def
::Method(_
)) = self.describe_def(def_id
) {
2318 Some(self.associated_item(def_id
))
2323 self.opt_associated_item(def_id
)
2327 Some(trait_item
) => {
2328 match trait_item
.container
{
2329 TraitContainer(_
) => None
,
2330 ImplContainer(def_id
) => Some(def_id
),
2337 /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
2338 /// with the name of the crate containing the impl.
2339 pub fn span_of_impl(self, impl_did
: DefId
) -> Result
<Span
, Symbol
> {
2340 if impl_did
.is_local() {
2341 let node_id
= self.hir
.as_local_node_id(impl_did
).unwrap();
2342 Ok(self.hir
.span(node_id
))
2344 Err(self.crate_name(impl_did
.krate
))
2348 // Hygienically compare a use-site name (`use_name`) for a field or an associated item with its
2349 // supposed definition name (`def_name`). The method also needs `DefId` of the supposed
2350 // definition's parent/scope to perform comparison.
2351 pub fn hygienic_eq(self, use_name
: Name
, def_name
: Name
, def_parent_def_id
: DefId
) -> bool
{
2352 self.adjust(use_name
, def_parent_def_id
, DUMMY_NODE_ID
).0 == def_name
.to_ident()
2355 pub fn adjust(self, name
: Name
, scope
: DefId
, block
: NodeId
) -> (Ident
, DefId
) {
2356 self.adjust_ident(name
.to_ident(), scope
, block
)
2359 pub fn adjust_ident(self, mut ident
: Ident
, scope
: DefId
, block
: NodeId
) -> (Ident
, DefId
) {
2360 let expansion
= match scope
.krate
{
2361 LOCAL_CRATE
=> self.hir
.definitions().expansion(scope
.index
),
2364 let scope
= match ident
.ctxt
.adjust(expansion
) {
2365 Some(macro_def
) => self.hir
.definitions().macro_def_scope(macro_def
),
2366 None
if block
== DUMMY_NODE_ID
=> DefId
::local(CRATE_DEF_INDEX
), // Dummy DefId
2367 None
=> self.hir
.get_module_parent(block
),
2373 impl<'a
, 'gcx
, 'tcx
> TyCtxt
<'a
, 'gcx
, 'tcx
> {
2374 pub fn with_freevars
<T
, F
>(self, fid
: NodeId
, f
: F
) -> T
where
2375 F
: FnOnce(&[hir
::Freevar
]) -> T
,
2377 let def_id
= self.hir
.local_def_id(fid
);
2378 match self.freevars(def_id
) {
2385 fn associated_item
<'a
, 'tcx
>(tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>, def_id
: DefId
)
2388 let id
= tcx
.hir
.as_local_node_id(def_id
).unwrap();
2389 let parent_id
= tcx
.hir
.get_parent(id
);
2390 let parent_def_id
= tcx
.hir
.local_def_id(parent_id
);
2391 let parent_item
= tcx
.hir
.expect_item(parent_id
);
2392 match parent_item
.node
{
2393 hir
::ItemImpl(.., ref impl_item_refs
) => {
2394 if let Some(impl_item_ref
) = impl_item_refs
.iter().find(|i
| i
.id
.node_id
== id
) {
2395 let assoc_item
= tcx
.associated_item_from_impl_item_ref(parent_def_id
,
2397 debug_assert_eq
!(assoc_item
.def_id
, def_id
);
2402 hir
::ItemTrait(.., ref trait_item_refs
) => {
2403 if let Some(trait_item_ref
) = trait_item_refs
.iter().find(|i
| i
.id
.node_id
== id
) {
2404 let assoc_item
= tcx
.associated_item_from_trait_item_ref(parent_def_id
,
2407 debug_assert_eq
!(assoc_item
.def_id
, def_id
);
2415 span_bug
!(parent_item
.span
,
2416 "unexpected parent of trait or impl item or item not found: {:?}",
2420 /// Calculates the Sized-constraint.
2422 /// In fact, there are only a few options for the types in the constraint:
2423 /// - an obviously-unsized type
2424 /// - a type parameter or projection whose Sizedness can't be known
2425 /// - a tuple of type parameters or projections, if there are multiple
2427 /// - a TyError, if a type contained itself. The representability
2428 /// check should catch this case.
2429 fn adt_sized_constraint
<'a
, 'tcx
>(tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
2431 -> &'tcx
[Ty
<'tcx
>] {
2432 let def
= tcx
.adt_def(def_id
);
2434 let result
= tcx
.intern_type_list(&def
.variants
.iter().flat_map(|v
| {
2437 def
.sized_constraint_for_ty(tcx
, tcx
.type_of(f
.did
))
2438 }).collect
::<Vec
<_
>>());
2440 debug
!("adt_sized_constraint: {:?} => {:?}", def
, result
);
2445 /// Calculates the dtorck constraint for a type.
2446 fn adt_dtorck_constraint
<'a
, 'tcx
>(tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
2448 -> DtorckConstraint
<'tcx
> {
2449 let def
= tcx
.adt_def(def_id
);
2450 let span
= tcx
.def_span(def_id
);
2451 debug
!("dtorck_constraint: {:?}", def
);
2453 if def
.is_phantom_data() {
2454 let result
= DtorckConstraint
{
2457 tcx
.mk_param_from_def(&tcx
.generics_of(def_id
).types
[0])
2460 debug
!("dtorck_constraint: {:?} => {:?}", def
, result
);
2464 let mut result
= def
.all_fields()
2465 .map(|field
| tcx
.type_of(field
.did
))
2466 .map(|fty
| tcx
.dtorck_constraint_for_ty(span
, fty
, 0, fty
))
2467 .collect
::<Result
<DtorckConstraint
, ErrorReported
>>()
2468 .unwrap_or(DtorckConstraint
::empty());
2469 result
.outlives
.extend(tcx
.destructor_constraints(def
));
2472 debug
!("dtorck_constraint: {:?} => {:?}", def
, result
);
2477 fn associated_item_def_ids
<'a
, 'tcx
>(tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
2480 let id
= tcx
.hir
.as_local_node_id(def_id
).unwrap();
2481 let item
= tcx
.hir
.expect_item(id
);
2482 let vec
: Vec
<_
> = match item
.node
{
2483 hir
::ItemTrait(.., ref trait_item_refs
) => {
2484 trait_item_refs
.iter()
2485 .map(|trait_item_ref
| trait_item_ref
.id
)
2486 .map(|id
| tcx
.hir
.local_def_id(id
.node_id
))
2489 hir
::ItemImpl(.., ref impl_item_refs
) => {
2490 impl_item_refs
.iter()
2491 .map(|impl_item_ref
| impl_item_ref
.id
)
2492 .map(|id
| tcx
.hir
.local_def_id(id
.node_id
))
2495 _
=> span_bug
!(item
.span
, "associated_item_def_ids: not impl or trait")
2500 fn def_span
<'a
, 'tcx
>(tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>, def_id
: DefId
) -> Span
{
2501 tcx
.hir
.span_if_local(def_id
).unwrap()
2504 /// If the given def ID describes an item belonging to a trait,
2505 /// return the ID of the trait that the trait item belongs to.
2506 /// Otherwise, return `None`.
2507 fn trait_of_item
<'a
, 'tcx
>(tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>, def_id
: DefId
) -> Option
<DefId
> {
2508 tcx
.opt_associated_item(def_id
)
2509 .and_then(|associated_item
| {
2510 match associated_item
.container
{
2511 TraitContainer(def_id
) => Some(def_id
),
2512 ImplContainer(_
) => None
2517 /// See `ParamEnv` struct def'n for details.
2518 fn param_env
<'a
, 'tcx
>(tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
2521 // Compute the bounds on Self and the type parameters.
2523 let bounds
= tcx
.predicates_of(def_id
).instantiate_identity(tcx
);
2524 let predicates
= bounds
.predicates
;
2526 // Finally, we have to normalize the bounds in the environment, in
2527 // case they contain any associated type projections. This process
2528 // can yield errors if the put in illegal associated types, like
2529 // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
2530 // report these errors right here; this doesn't actually feel
2531 // right to me, because constructing the environment feels like a
2532 // kind of a "idempotent" action, but I'm not sure where would be
2533 // a better place. In practice, we construct environments for
2534 // every fn once during type checking, and we'll abort if there
2535 // are any errors at that point, so after type checking you can be
2536 // sure that this will succeed without errors anyway.
2538 let unnormalized_env
= ty
::ParamEnv
::new(tcx
.intern_predicates(&predicates
),
2539 traits
::Reveal
::UserFacing
);
2541 let body_id
= tcx
.hir
.as_local_node_id(def_id
).map_or(DUMMY_NODE_ID
, |id
| {
2542 tcx
.hir
.maybe_body_owned_by(id
).map_or(id
, |body
| body
.node_id
)
2544 let cause
= traits
::ObligationCause
::misc(tcx
.def_span(def_id
), body_id
);
2545 traits
::normalize_param_env_or_error(tcx
, def_id
, unnormalized_env
, cause
)
2548 fn crate_disambiguator
<'a
, 'tcx
>(tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
2549 crate_num
: CrateNum
) -> Symbol
{
2550 assert_eq
!(crate_num
, LOCAL_CRATE
);
2551 tcx
.sess
.local_crate_disambiguator()
2554 fn original_crate_name
<'a
, 'tcx
>(tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
2555 crate_num
: CrateNum
) -> Symbol
{
2556 assert_eq
!(crate_num
, LOCAL_CRATE
);
2557 tcx
.crate_name
.clone()
2560 pub fn provide(providers
: &mut ty
::maps
::Providers
) {
2561 util
::provide(providers
);
2562 context
::provide(providers
);
2563 *providers
= ty
::maps
::Providers
{
2565 associated_item_def_ids
,
2566 adt_sized_constraint
,
2567 adt_dtorck_constraint
,
2571 crate_disambiguator
,
2572 original_crate_name
,
2573 trait_impls_of
: trait_def
::trait_impls_of_provider
,
2578 pub fn provide_extern(providers
: &mut ty
::maps
::Providers
) {
2579 *providers
= ty
::maps
::Providers
{
2580 adt_sized_constraint
,
2581 adt_dtorck_constraint
,
2582 trait_impls_of
: trait_def
::trait_impls_of_provider
,
2589 /// A map for the local crate mapping each type to a vector of its
2590 /// inherent impls. This is not meant to be used outside of coherence;
2591 /// rather, you should request the vector for a specific type via
2592 /// `tcx.inherent_impls(def_id)` so as to minimize your dependencies
2593 /// (constructing this map requires touching the entire crate).
2594 #[derive(Clone, Debug)]
2595 pub struct CrateInherentImpls
{
2596 pub inherent_impls
: DefIdMap
<Rc
<Vec
<DefId
>>>,
2599 /// A set of constraints that need to be satisfied in order for
2600 /// a type to be valid for destruction.
2601 #[derive(Clone, Debug)]
2602 pub struct DtorckConstraint
<'tcx
> {
2603 /// Types that are required to be alive in order for this
2604 /// type to be valid for destruction.
2605 pub outlives
: Vec
<ty
::subst
::Kind
<'tcx
>>,
2606 /// Types that could not be resolved: projections and params.
2607 pub dtorck_types
: Vec
<Ty
<'tcx
>>,
2610 impl<'tcx
> FromIterator
<DtorckConstraint
<'tcx
>> for DtorckConstraint
<'tcx
>
2612 fn from_iter
<I
: IntoIterator
<Item
=DtorckConstraint
<'tcx
>>>(iter
: I
) -> Self {
2613 let mut result
= Self::empty();
2615 for constraint
in iter
{
2616 result
.outlives
.extend(constraint
.outlives
);
2617 result
.dtorck_types
.extend(constraint
.dtorck_types
);
2625 impl<'tcx
> DtorckConstraint
<'tcx
> {
2626 fn empty() -> DtorckConstraint
<'tcx
> {
2629 dtorck_types
: vec
![]
2633 fn dedup
<'a
>(&mut self) {
2634 let mut outlives
= FxHashSet();
2635 let mut dtorck_types
= FxHashSet();
2637 self.outlives
.retain(|&val
| outlives
.replace(val
).is_none());
2638 self.dtorck_types
.retain(|&val
| dtorck_types
.replace(val
).is_none());
2642 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
2643 pub struct SymbolName
{
2644 // FIXME: we don't rely on interning or equality here - better have
2645 // this be a `&'tcx str`.
2646 pub name
: InternedString
2649 impl_stable_hash_for
!(struct self::SymbolName
{
2653 impl Deref
for SymbolName
{
2656 fn deref(&self) -> &str { &self.name }
2659 impl fmt
::Display
for SymbolName
{
2660 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
2661 fmt
::Display
::fmt(&self.name
, fmt
)