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::DtorKind
::*;
13 pub use self::ImplOrTraitItemContainer
::*;
14 pub use self::BorrowKind
::*;
15 pub use self::ImplOrTraitItem
::*;
16 pub use self::IntVarValue
::*;
17 pub use self::LvaluePreference
::*;
18 pub use self::fold
::TypeFoldable
;
20 use dep_graph
::{self, DepNode}
;
21 use hir
::map
as ast_map
;
23 use hir
::def
::{Def, CtorKind, PathResolution, ExportMap}
;
24 use hir
::def_id
::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}
;
25 use middle
::lang_items
::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}
;
26 use middle
::region
::{CodeExtent, ROOT_CODE_EXTENT}
;
30 use ty
::subst
::{Subst, Substs}
;
31 use ty
::walk
::TypeWalker
;
32 use util
::common
::MemoizationMap
;
33 use util
::nodemap
::NodeSet
;
34 use util
::nodemap
::FnvHashMap
;
36 use serialize
::{self, Encodable, Encoder}
;
38 use std
::cell
::{Cell, RefCell, Ref}
;
39 use std
::hash
::{Hash, Hasher}
;
44 use std
::vec
::IntoIter
;
46 use syntax
::ast
::{self, Name, NodeId}
;
48 use syntax
::parse
::token
::{self, InternedString}
;
49 use syntax_pos
::{DUMMY_SP, Span}
;
51 use rustc_const_math
::ConstInt
;
54 use hir
::intravisit
::Visitor
;
56 pub use self::sty
::{Binder, DebruijnIndex}
;
57 pub use self::sty
::{BuiltinBound, BuiltinBounds}
;
58 pub use self::sty
::{BareFnTy, FnSig, PolyFnSig}
;
59 pub use self::sty
::{ClosureTy, InferTy, ParamTy, ProjectionTy, TraitObject}
;
60 pub use self::sty
::{ClosureSubsts, TypeAndMut}
;
61 pub use self::sty
::{TraitRef, TypeVariants, PolyTraitRef}
;
62 pub use self::sty
::{ExistentialTraitRef, PolyExistentialTraitRef}
;
63 pub use self::sty
::{ExistentialProjection, PolyExistentialProjection}
;
64 pub use self::sty
::{BoundRegion, EarlyBoundRegion, FreeRegion, Region}
;
65 pub use self::sty
::Issue32330
;
66 pub use self::sty
::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid}
;
67 pub use self::sty
::BoundRegion
::*;
68 pub use self::sty
::InferTy
::*;
69 pub use self::sty
::Region
::*;
70 pub use self::sty
::TypeVariants
::*;
72 pub use self::sty
::BuiltinBound
::Send
as BoundSend
;
73 pub use self::sty
::BuiltinBound
::Sized
as BoundSized
;
74 pub use self::sty
::BuiltinBound
::Copy
as BoundCopy
;
75 pub use self::sty
::BuiltinBound
::Sync
as BoundSync
;
77 pub use self::contents
::TypeContents
;
78 pub use self::context
::{TyCtxt, tls}
;
79 pub use self::context
::{CtxtArenas, Lift, Tables}
;
81 pub use self::trait_def
::{TraitDef, TraitFlags}
;
104 mod structural_impls
;
107 pub type Disr
= ConstInt
;
111 /// The complete set of all analyses described in this module. This is
112 /// produced by the driver and fed to trans and later passes.
114 pub struct CrateAnalysis
<'a
> {
115 pub export_map
: ExportMap
,
116 pub access_levels
: middle
::privacy
::AccessLevels
,
117 pub reachable
: NodeSet
,
119 pub glob_map
: Option
<hir
::GlobMap
>,
122 #[derive(Copy, Clone)]
129 pub fn is_present(&self) -> bool
{
137 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
138 pub enum ImplOrTraitItemContainer
{
139 TraitContainer(DefId
),
140 ImplContainer(DefId
),
143 impl ImplOrTraitItemContainer
{
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 impl<'a
, 'gcx
, 'tcx
> ImplHeader
<'tcx
> {
164 pub fn with_fresh_ty_vars(selcx
: &mut traits
::SelectionContext
<'a
, 'gcx
, 'tcx
>,
168 let tcx
= selcx
.tcx();
169 let impl_substs
= selcx
.infcx().fresh_substs_for_item(DUMMY_SP
, impl_def_id
);
171 let header
= ImplHeader
{
172 impl_def_id
: impl_def_id
,
173 self_ty
: tcx
.lookup_item_type(impl_def_id
).ty
,
174 trait_ref
: tcx
.impl_trait_ref(impl_def_id
),
175 predicates
: tcx
.lookup_predicates(impl_def_id
).predicates
176 }.subst(tcx
, impl_substs
);
178 let traits
::Normalized { value: mut header, obligations }
=
179 traits
::normalize(selcx
, traits
::ObligationCause
::dummy(), &header
);
181 header
.predicates
.extend(obligations
.into_iter().map(|o
| o
.predicate
));
187 pub enum ImplOrTraitItem
<'tcx
> {
188 ConstTraitItem(Rc
<AssociatedConst
<'tcx
>>),
189 MethodTraitItem(Rc
<Method
<'tcx
>>),
190 TypeTraitItem(Rc
<AssociatedType
<'tcx
>>),
193 impl<'tcx
> ImplOrTraitItem
<'tcx
> {
194 pub fn def(&self) -> Def
{
196 ConstTraitItem(ref associated_const
) => Def
::AssociatedConst(associated_const
.def_id
),
197 MethodTraitItem(ref method
) => Def
::Method(method
.def_id
),
198 TypeTraitItem(ref ty
) => Def
::AssociatedTy(ty
.def_id
),
202 pub fn def_id(&self) -> DefId
{
204 ConstTraitItem(ref associated_const
) => associated_const
.def_id
,
205 MethodTraitItem(ref method
) => method
.def_id
,
206 TypeTraitItem(ref associated_type
) => associated_type
.def_id
,
210 pub fn name(&self) -> Name
{
212 ConstTraitItem(ref associated_const
) => associated_const
.name
,
213 MethodTraitItem(ref method
) => method
.name
,
214 TypeTraitItem(ref associated_type
) => associated_type
.name
,
218 pub fn vis(&self) -> Visibility
{
220 ConstTraitItem(ref associated_const
) => associated_const
.vis
,
221 MethodTraitItem(ref method
) => method
.vis
,
222 TypeTraitItem(ref associated_type
) => associated_type
.vis
,
226 pub fn container(&self) -> ImplOrTraitItemContainer
{
228 ConstTraitItem(ref associated_const
) => associated_const
.container
,
229 MethodTraitItem(ref method
) => method
.container
,
230 TypeTraitItem(ref associated_type
) => associated_type
.container
,
234 pub fn as_opt_method(&self) -> Option
<Rc
<Method
<'tcx
>>> {
236 MethodTraitItem(ref m
) => Some((*m
).clone()),
242 #[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable)]
243 pub enum Visibility
{
244 /// Visible everywhere (including in other crates).
246 /// Visible only in the given crate-local module.
248 /// Not visible anywhere in the local crate. This is the visibility of private external items.
252 pub trait NodeIdTree
{
253 fn is_descendant_of(&self, node
: NodeId
, ancestor
: NodeId
) -> bool
;
256 impl<'a
> NodeIdTree
for ast_map
::Map
<'a
> {
257 fn is_descendant_of(&self, node
: NodeId
, ancestor
: NodeId
) -> bool
{
258 let mut node_ancestor
= node
;
259 while node_ancestor
!= ancestor
{
260 let node_ancestor_parent
= self.get_module_parent(node_ancestor
);
261 if node_ancestor_parent
== node_ancestor
{
264 node_ancestor
= node_ancestor_parent
;
271 pub fn from_hir(visibility
: &hir
::Visibility
, id
: NodeId
, tcx
: TyCtxt
) -> Self {
273 hir
::Public
=> Visibility
::Public
,
274 hir
::Visibility
::Crate
=> Visibility
::Restricted(ast
::CRATE_NODE_ID
),
275 hir
::Visibility
::Restricted { id, .. }
=> match tcx
.expect_def(id
) {
276 // If there is no resolution, `resolve` will have already reported an error, so
277 // assume that the visibility is public to avoid reporting more privacy errors.
278 Def
::Err
=> Visibility
::Public
,
279 def
=> Visibility
::Restricted(tcx
.map
.as_local_node_id(def
.def_id()).unwrap()),
281 hir
::Inherited
=> Visibility
::Restricted(tcx
.map
.get_module_parent(id
)),
285 /// Returns true if an item with this visibility is accessible from the given block.
286 pub fn is_accessible_from
<T
: NodeIdTree
>(self, block
: NodeId
, tree
: &T
) -> bool
{
287 let restriction
= match self {
288 // Public items are visible everywhere.
289 Visibility
::Public
=> return true,
290 // Private items from other crates are visible nowhere.
291 Visibility
::PrivateExternal
=> return false,
292 // Restricted items are visible in an arbitrary local module.
293 Visibility
::Restricted(module
) => module
,
296 tree
.is_descendant_of(block
, restriction
)
299 /// Returns true if this visibility is at least as accessible as the given visibility
300 pub fn is_at_least
<T
: NodeIdTree
>(self, vis
: Visibility
, tree
: &T
) -> bool
{
301 let vis_restriction
= match vis
{
302 Visibility
::Public
=> return self == Visibility
::Public
,
303 Visibility
::PrivateExternal
=> return true,
304 Visibility
::Restricted(module
) => module
,
307 self.is_accessible_from(vis_restriction
, tree
)
311 #[derive(Clone, Debug)]
312 pub struct Method
<'tcx
> {
314 pub generics
: &'tcx Generics
<'tcx
>,
315 pub predicates
: GenericPredicates
<'tcx
>,
316 pub fty
: &'tcx BareFnTy
<'tcx
>,
317 pub explicit_self
: ExplicitSelfCategory
<'tcx
>,
319 pub defaultness
: hir
::Defaultness
,
322 pub container
: ImplOrTraitItemContainer
,
325 impl<'tcx
> Method
<'tcx
> {
326 pub fn container_id(&self) -> DefId
{
327 match self.container
{
328 TraitContainer(id
) => id
,
329 ImplContainer(id
) => id
,
334 impl<'tcx
> PartialEq
for Method
<'tcx
> {
336 fn eq(&self, other
: &Self) -> bool { self.def_id == other.def_id }
339 impl<'tcx
> Eq
for Method
<'tcx
> {}
341 impl<'tcx
> Hash
for Method
<'tcx
> {
343 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
348 #[derive(Clone, Copy, Debug)]
349 pub struct AssociatedConst
<'tcx
> {
353 pub defaultness
: hir
::Defaultness
,
355 pub container
: ImplOrTraitItemContainer
,
359 #[derive(Clone, Copy, Debug)]
360 pub struct AssociatedType
<'tcx
> {
362 pub ty
: Option
<Ty
<'tcx
>>,
364 pub defaultness
: hir
::Defaultness
,
366 pub container
: ImplOrTraitItemContainer
,
369 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Copy)]
371 Covariant
, // T<A> <: T<B> iff A <: B -- e.g., function return type
372 Invariant
, // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
373 Contravariant
, // T<A> <: T<B> iff B <: A -- e.g., function param type
374 Bivariant
, // T<A> <: T<B> -- e.g., unused type parameter
377 #[derive(Clone, Copy, Debug, RustcDecodable, RustcEncodable)]
378 pub struct MethodCallee
<'tcx
> {
379 /// Impl method ID, for inherent methods, or trait method ID, otherwise.
382 pub substs
: &'tcx Substs
<'tcx
>
385 /// With method calls, we store some extra information in
386 /// side tables (i.e method_map). We use
387 /// MethodCall as a key to index into these tables instead of
388 /// just directly using the expression's NodeId. The reason
389 /// for this being that we may apply adjustments (coercions)
390 /// with the resulting expression also needing to use the
391 /// side tables. The problem with this is that we don't
392 /// assign a separate NodeId to this new expression
393 /// and so it would clash with the base expression if both
394 /// needed to add to the side tables. Thus to disambiguate
395 /// we also keep track of whether there's an adjustment in
397 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
398 pub struct MethodCall
{
404 pub fn expr(id
: NodeId
) -> MethodCall
{
411 pub fn autoderef(expr_id
: NodeId
, autoderef
: u32) -> MethodCall
{
414 autoderef
: 1 + autoderef
419 // maps from an expression id that corresponds to a method call to the details
420 // of the method to be invoked
421 pub type MethodMap
<'tcx
> = FnvHashMap
<MethodCall
, MethodCallee
<'tcx
>>;
423 // Contains information needed to resolve types and (in the future) look up
424 // the types of AST nodes.
425 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
426 pub struct CReaderCacheKey
{
431 /// Describes the fragment-state associated with a NodeId.
433 /// Currently only unfragmented paths have entries in the table,
434 /// but longer-term this enum is expected to expand to also
435 /// include data for fragmented paths.
436 #[derive(Copy, Clone, Debug)]
437 pub enum FragmentInfo
{
438 Moved { var: NodeId, move_expr: NodeId }
,
439 Assigned { var: NodeId, assign_expr: NodeId, assignee_id: NodeId }
,
442 // Flags that we track on types. These flags are propagated upwards
443 // through the type during type construction, so that we can quickly
444 // check whether the type has various kinds of types in it without
445 // recursing over the type itself.
447 flags TypeFlags
: u32 {
448 const HAS_PARAMS
= 1 << 0,
449 const HAS_SELF
= 1 << 1,
450 const HAS_TY_INFER
= 1 << 2,
451 const HAS_RE_INFER
= 1 << 3,
452 const HAS_RE_SKOL
= 1 << 4,
453 const HAS_RE_EARLY_BOUND
= 1 << 5,
454 const HAS_FREE_REGIONS
= 1 << 6,
455 const HAS_TY_ERR
= 1 << 7,
456 const HAS_PROJECTION
= 1 << 8,
457 const HAS_TY_CLOSURE
= 1 << 9,
459 // true if there are "names" of types and regions and so forth
460 // that are local to a particular fn
461 const HAS_LOCAL_NAMES
= 1 << 10,
463 // Present if the type belongs in a local type context.
464 // Only set for TyInfer other than Fresh.
465 const KEEP_IN_LOCAL_TCX
= 1 << 11,
467 // Is there a projection that does not involve a bound region?
468 // Currently we can't normalize projections w/ bound regions.
469 const HAS_NORMALIZABLE_PROJECTION
= 1 << 12,
471 const NEEDS_SUBST
= TypeFlags
::HAS_PARAMS
.bits
|
472 TypeFlags
::HAS_SELF
.bits
|
473 TypeFlags
::HAS_RE_EARLY_BOUND
.bits
,
475 // Flags representing the nominal content of a type,
476 // computed by FlagsComputation. If you add a new nominal
477 // flag, it should be added here too.
478 const NOMINAL_FLAGS
= TypeFlags
::HAS_PARAMS
.bits
|
479 TypeFlags
::HAS_SELF
.bits
|
480 TypeFlags
::HAS_TY_INFER
.bits
|
481 TypeFlags
::HAS_RE_INFER
.bits
|
482 TypeFlags
::HAS_RE_SKOL
.bits
|
483 TypeFlags
::HAS_RE_EARLY_BOUND
.bits
|
484 TypeFlags
::HAS_FREE_REGIONS
.bits
|
485 TypeFlags
::HAS_TY_ERR
.bits
|
486 TypeFlags
::HAS_PROJECTION
.bits
|
487 TypeFlags
::HAS_TY_CLOSURE
.bits
|
488 TypeFlags
::HAS_LOCAL_NAMES
.bits
|
489 TypeFlags
::KEEP_IN_LOCAL_TCX
.bits
,
491 // Caches for type_is_sized, type_moves_by_default
492 const SIZEDNESS_CACHED
= 1 << 16,
493 const IS_SIZED
= 1 << 17,
494 const MOVENESS_CACHED
= 1 << 18,
495 const MOVES_BY_DEFAULT
= 1 << 19,
499 pub struct TyS
<'tcx
> {
500 pub sty
: TypeVariants
<'tcx
>,
501 pub flags
: Cell
<TypeFlags
>,
503 // the maximal depth of any bound regions appearing in this type.
507 impl<'tcx
> PartialEq
for TyS
<'tcx
> {
509 fn eq(&self, other
: &TyS
<'tcx
>) -> bool
{
510 // (self as *const _) == (other as *const _)
511 (self as *const TyS
<'tcx
>) == (other
as *const TyS
<'tcx
>)
514 impl<'tcx
> Eq
for TyS
<'tcx
> {}
516 impl<'tcx
> Hash
for TyS
<'tcx
> {
517 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
518 (self as *const TyS
).hash(s
)
522 pub type Ty
<'tcx
> = &'tcx TyS
<'tcx
>;
524 impl<'tcx
> serialize
::UseSpecializedEncodable
for Ty
<'tcx
> {}
525 impl<'tcx
> serialize
::UseSpecializedDecodable
for Ty
<'tcx
> {}
527 /// A wrapper for slices with the additional invariant
528 /// that the slice is interned and no other slice with
529 /// the same contents can exist in the same context.
530 /// This means we can use pointer + length for both
531 /// equality comparisons and hashing.
532 #[derive(Debug, RustcEncodable)]
533 pub struct Slice
<T
>([T
]);
535 impl<T
> PartialEq
for Slice
<T
> {
537 fn eq(&self, other
: &Slice
<T
>) -> bool
{
538 (&self.0 as *const [T
]) == (&other
.0 as *const [T
])
541 impl<T
> Eq
for Slice
<T
> {}
543 impl<T
> Hash
for Slice
<T
> {
544 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
545 (self.as_ptr(), self.len()).hash(s
)
549 impl<T
> Deref
for Slice
<T
> {
551 fn deref(&self) -> &[T
] {
556 impl<'a
, T
> IntoIterator
for &'a Slice
<T
> {
558 type IntoIter
= <&'a
[T
] as IntoIterator
>::IntoIter
;
559 fn into_iter(self) -> Self::IntoIter
{
564 impl<'tcx
> serialize
::UseSpecializedDecodable
for &'tcx Slice
<Ty
<'tcx
>> {}
567 pub fn empty
<'a
>() -> &'a Slice
<T
> {
569 mem
::transmute(slice
::from_raw_parts(0x1 as *const T
, 0))
574 /// Upvars do not get their own node-id. Instead, we use the pair of
575 /// the original var id (that is, the root variable that is referenced
576 /// by the upvar) and the id of the closure expression.
577 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
580 pub closure_expr_id
: NodeId
,
583 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)]
584 pub enum BorrowKind
{
585 /// Data must be immutable and is aliasable.
588 /// Data must be immutable but not aliasable. This kind of borrow
589 /// cannot currently be expressed by the user and is used only in
590 /// implicit closure bindings. It is needed when you the closure
591 /// is borrowing or mutating a mutable referent, e.g.:
593 /// let x: &mut isize = ...;
594 /// let y = || *x += 5;
596 /// If we were to try to translate this closure into a more explicit
597 /// form, we'd encounter an error with the code as written:
599 /// struct Env { x: & &mut isize }
600 /// let x: &mut isize = ...;
601 /// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn
602 /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
604 /// This is then illegal because you cannot mutate a `&mut` found
605 /// in an aliasable location. To solve, you'd have to translate with
606 /// an `&mut` borrow:
608 /// struct Env { x: & &mut isize }
609 /// let x: &mut isize = ...;
610 /// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
611 /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
613 /// Now the assignment to `**env.x` is legal, but creating a
614 /// mutable pointer to `x` is not because `x` is not mutable. We
615 /// could fix this by declaring `x` as `let mut x`. This is ok in
616 /// user code, if awkward, but extra weird for closures, since the
617 /// borrow is hidden.
619 /// So we introduce a "unique imm" borrow -- the referent is
620 /// immutable, but not aliasable. This solves the problem. For
621 /// simplicity, we don't give users the way to express this
622 /// borrow, it's just used when translating closures.
625 /// Data is mutable and not aliasable.
629 /// Information describing the capture of an upvar. This is computed
630 /// during `typeck`, specifically by `regionck`.
631 #[derive(PartialEq, Clone, Debug, Copy, RustcEncodable, RustcDecodable)]
632 pub enum UpvarCapture
<'tcx
> {
633 /// Upvar is captured by value. This is always true when the
634 /// closure is labeled `move`, but can also be true in other cases
635 /// depending on inference.
638 /// Upvar is captured by reference.
639 ByRef(UpvarBorrow
<'tcx
>),
642 #[derive(PartialEq, Clone, Copy, RustcEncodable, RustcDecodable)]
643 pub struct UpvarBorrow
<'tcx
> {
644 /// The kind of borrow: by-ref upvars have access to shared
645 /// immutable borrows, which are not part of the normal language
647 pub kind
: BorrowKind
,
649 /// Region of the resulting reference.
650 pub region
: &'tcx ty
::Region
,
653 pub type UpvarCaptureMap
<'tcx
> = FnvHashMap
<UpvarId
, UpvarCapture
<'tcx
>>;
655 #[derive(Copy, Clone)]
656 pub struct ClosureUpvar
<'tcx
> {
662 #[derive(Clone, Copy, PartialEq)]
663 pub enum IntVarValue
{
665 UintType(ast
::UintTy
),
668 /// Default region to use for the bound of objects that are
669 /// supplied as the value for this type parameter. This is derived
670 /// from `T:'a` annotations appearing in the type definition. If
671 /// this is `None`, then the default is inherited from the
672 /// surrounding context. See RFC #599 for details.
673 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
674 pub enum ObjectLifetimeDefault
<'tcx
> {
675 /// Require an explicit annotation. Occurs when multiple
676 /// `T:'a` constraints are found.
679 /// Use the base default, typically 'static, but in a fn body it is a fresh variable
682 /// Use the given region as the default.
683 Specific(&'tcx Region
),
686 #[derive(Clone, RustcEncodable, RustcDecodable)]
687 pub struct TypeParameterDef
<'tcx
> {
691 pub default_def_id
: DefId
, // for use in error reporing about defaults
692 pub default: Option
<Ty
<'tcx
>>,
693 pub object_lifetime_default
: ObjectLifetimeDefault
<'tcx
>,
695 /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute
696 /// on generic parameter `T`, asserts data behind the parameter
697 /// `T` won't be accessed during the parent type's `Drop` impl.
698 pub pure_wrt_drop
: bool
,
701 #[derive(Clone, RustcEncodable, RustcDecodable)]
702 pub struct RegionParameterDef
<'tcx
> {
706 pub bounds
: Vec
<&'tcx ty
::Region
>,
708 /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute
709 /// on generic parameter `'a`, asserts data of lifetime `'a`
710 /// won't be accessed during the parent type's `Drop` impl.
711 pub pure_wrt_drop
: bool
,
714 impl<'tcx
> RegionParameterDef
<'tcx
> {
715 pub fn to_early_bound_region(&self) -> ty
::Region
{
716 ty
::ReEarlyBound(self.to_early_bound_region_data())
719 pub fn to_early_bound_region_data(&self) -> ty
::EarlyBoundRegion
{
720 ty
::EarlyBoundRegion
{
726 pub fn to_bound_region(&self) -> ty
::BoundRegion
{
727 // this is an early bound region, so unaffected by #32330
728 ty
::BoundRegion
::BrNamed(self.def_id
, self.name
, Issue32330
::WontChange
)
732 /// Information about the formal type/lifetime parameters associated
733 /// with an item or method. Analogous to hir::Generics.
734 #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
735 pub struct Generics
<'tcx
> {
736 pub parent
: Option
<DefId
>,
737 pub parent_regions
: u32,
738 pub parent_types
: u32,
739 pub regions
: Vec
<RegionParameterDef
<'tcx
>>,
740 pub types
: Vec
<TypeParameterDef
<'tcx
>>,
744 impl<'tcx
> Generics
<'tcx
> {
745 pub fn parent_count(&self) -> usize {
746 self.parent_regions
as usize + self.parent_types
as usize
749 pub fn own_count(&self) -> usize {
750 self.regions
.len() + self.types
.len()
753 pub fn count(&self) -> usize {
754 self.parent_count() + self.own_count()
757 pub fn region_param(&self, param
: &EarlyBoundRegion
) -> &RegionParameterDef
<'tcx
> {
758 &self.regions
[param
.index
as usize - self.has_self
as usize]
761 pub fn type_param(&self, param
: &ParamTy
) -> &TypeParameterDef
<'tcx
> {
762 &self.types
[param
.idx
as usize - self.has_self
as usize - self.regions
.len()]
766 /// Bounds on generics.
768 pub struct GenericPredicates
<'tcx
> {
769 pub parent
: Option
<DefId
>,
770 pub predicates
: Vec
<Predicate
<'tcx
>>,
773 impl<'tcx
> serialize
::UseSpecializedEncodable
for GenericPredicates
<'tcx
> {}
774 impl<'tcx
> serialize
::UseSpecializedDecodable
for GenericPredicates
<'tcx
> {}
776 impl<'a
, 'gcx
, 'tcx
> GenericPredicates
<'tcx
> {
777 pub fn instantiate(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>, substs
: &Substs
<'tcx
>)
778 -> InstantiatedPredicates
<'tcx
> {
779 let mut instantiated
= InstantiatedPredicates
::empty();
780 self.instantiate_into(tcx
, &mut instantiated
, substs
);
783 pub fn instantiate_own(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>, substs
: &Substs
<'tcx
>)
784 -> InstantiatedPredicates
<'tcx
> {
785 InstantiatedPredicates
{
786 predicates
: self.predicates
.subst(tcx
, substs
)
790 fn instantiate_into(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
791 instantiated
: &mut InstantiatedPredicates
<'tcx
>,
792 substs
: &Substs
<'tcx
>) {
793 if let Some(def_id
) = self.parent
{
794 tcx
.lookup_predicates(def_id
).instantiate_into(tcx
, instantiated
, substs
);
796 instantiated
.predicates
.extend(self.predicates
.iter().map(|p
| p
.subst(tcx
, substs
)))
799 pub fn instantiate_supertrait(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
800 poly_trait_ref
: &ty
::PolyTraitRef
<'tcx
>)
801 -> InstantiatedPredicates
<'tcx
>
803 assert_eq
!(self.parent
, None
);
804 InstantiatedPredicates
{
805 predicates
: self.predicates
.iter().map(|pred
| {
806 pred
.subst_supertrait(tcx
, poly_trait_ref
)
812 #[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
813 pub enum Predicate
<'tcx
> {
814 /// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
815 /// the `Self` type of the trait reference and `A`, `B`, and `C`
816 /// would be the type parameters.
817 Trait(PolyTraitPredicate
<'tcx
>),
819 /// where `T1 == T2`.
820 Equate(PolyEquatePredicate
<'tcx
>),
823 RegionOutlives(PolyRegionOutlivesPredicate
<'tcx
>),
826 TypeOutlives(PolyTypeOutlivesPredicate
<'tcx
>),
828 /// where <T as TraitRef>::Name == X, approximately.
829 /// See `ProjectionPredicate` struct for details.
830 Projection(PolyProjectionPredicate
<'tcx
>),
833 WellFormed(Ty
<'tcx
>),
835 /// trait must be object-safe
838 /// No direct syntax. May be thought of as `where T : FnFoo<...>`
839 /// for some substitutions `...` and T being a closure type.
840 /// Satisfied (or refuted) once we know the closure's kind.
841 ClosureKind(DefId
, ClosureKind
),
844 impl<'a
, 'gcx
, 'tcx
> Predicate
<'tcx
> {
845 /// Performs a substitution suitable for going from a
846 /// poly-trait-ref to supertraits that must hold if that
847 /// poly-trait-ref holds. This is slightly different from a normal
848 /// substitution in terms of what happens with bound regions. See
849 /// lengthy comment below for details.
850 pub fn subst_supertrait(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
851 trait_ref
: &ty
::PolyTraitRef
<'tcx
>)
852 -> ty
::Predicate
<'tcx
>
854 // The interaction between HRTB and supertraits is not entirely
855 // obvious. Let me walk you (and myself) through an example.
857 // Let's start with an easy case. Consider two traits:
859 // trait Foo<'a> : Bar<'a,'a> { }
860 // trait Bar<'b,'c> { }
862 // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
863 // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
864 // knew that `Foo<'x>` (for any 'x) then we also know that
865 // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
866 // normal substitution.
868 // In terms of why this is sound, the idea is that whenever there
869 // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
870 // holds. So if there is an impl of `T:Foo<'a>` that applies to
871 // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
874 // Another example to be careful of is this:
876 // trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
877 // trait Bar1<'b,'c> { }
879 // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
880 // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
881 // reason is similar to the previous example: any impl of
882 // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`. So
883 // basically we would want to collapse the bound lifetimes from
884 // the input (`trait_ref`) and the supertraits.
886 // To achieve this in practice is fairly straightforward. Let's
887 // consider the more complicated scenario:
889 // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
890 // has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
891 // where both `'x` and `'b` would have a DB index of 1.
892 // The substitution from the input trait-ref is therefore going to be
893 // `'a => 'x` (where `'x` has a DB index of 1).
894 // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
895 // early-bound parameter and `'b' is a late-bound parameter with a
897 // - If we replace `'a` with `'x` from the input, it too will have
898 // a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
899 // just as we wanted.
901 // There is only one catch. If we just apply the substitution `'a
902 // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
903 // adjust the DB index because we substituting into a binder (it
904 // tries to be so smart...) resulting in `for<'x> for<'b>
905 // Bar1<'x,'b>` (we have no syntax for this, so use your
906 // imagination). Basically the 'x will have DB index of 2 and 'b
907 // will have DB index of 1. Not quite what we want. So we apply
908 // the substitution to the *contents* of the trait reference,
909 // rather than the trait reference itself (put another way, the
910 // substitution code expects equal binding levels in the values
911 // from the substitution and the value being substituted into, and
912 // this trick achieves that).
914 let substs
= &trait_ref
.0.substs
;
916 Predicate
::Trait(ty
::Binder(ref data
)) =>
917 Predicate
::Trait(ty
::Binder(data
.subst(tcx
, substs
))),
918 Predicate
::Equate(ty
::Binder(ref data
)) =>
919 Predicate
::Equate(ty
::Binder(data
.subst(tcx
, substs
))),
920 Predicate
::RegionOutlives(ty
::Binder(ref data
)) =>
921 Predicate
::RegionOutlives(ty
::Binder(data
.subst(tcx
, substs
))),
922 Predicate
::TypeOutlives(ty
::Binder(ref data
)) =>
923 Predicate
::TypeOutlives(ty
::Binder(data
.subst(tcx
, substs
))),
924 Predicate
::Projection(ty
::Binder(ref data
)) =>
925 Predicate
::Projection(ty
::Binder(data
.subst(tcx
, substs
))),
926 Predicate
::WellFormed(data
) =>
927 Predicate
::WellFormed(data
.subst(tcx
, substs
)),
928 Predicate
::ObjectSafe(trait_def_id
) =>
929 Predicate
::ObjectSafe(trait_def_id
),
930 Predicate
::ClosureKind(closure_def_id
, kind
) =>
931 Predicate
::ClosureKind(closure_def_id
, kind
),
936 #[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
937 pub struct TraitPredicate
<'tcx
> {
938 pub trait_ref
: TraitRef
<'tcx
>
940 pub type PolyTraitPredicate
<'tcx
> = ty
::Binder
<TraitPredicate
<'tcx
>>;
942 impl<'tcx
> TraitPredicate
<'tcx
> {
943 pub fn def_id(&self) -> DefId
{
944 self.trait_ref
.def_id
947 /// Creates the dep-node for selecting/evaluating this trait reference.
948 fn dep_node(&self) -> DepNode
<DefId
> {
949 // Ideally, the dep-node would just have all the input types
950 // in it. But they are limited to including def-ids. So as an
951 // approximation we include the def-ids for all nominal types
952 // found somewhere. This means that we will e.g. conflate the
953 // dep-nodes for `u32: SomeTrait` and `u64: SomeTrait`, but we
954 // would have distinct dep-nodes for `Vec<u32>: SomeTrait`,
955 // `Rc<u32>: SomeTrait`, and `(Vec<u32>, Rc<u32>): SomeTrait`.
956 // Note that it's always sound to conflate dep-nodes, it just
957 // leads to more recompilation.
958 let def_ids
: Vec
<_
> =
960 .flat_map(|t
| t
.walk())
961 .filter_map(|t
| match t
.sty
{
962 ty
::TyAdt(adt_def
, _
) =>
967 .chain(iter
::once(self.def_id()))
969 DepNode
::TraitSelect(def_ids
)
972 pub fn input_types
<'a
>(&'a
self) -> impl DoubleEndedIterator
<Item
=Ty
<'tcx
>> + 'a
{
973 self.trait_ref
.input_types()
976 pub fn self_ty(&self) -> Ty
<'tcx
> {
977 self.trait_ref
.self_ty()
981 impl<'tcx
> PolyTraitPredicate
<'tcx
> {
982 pub fn def_id(&self) -> DefId
{
983 // ok to skip binder since trait def-id does not care about regions
987 pub fn dep_node(&self) -> DepNode
<DefId
> {
988 // ok to skip binder since depnode does not care about regions
993 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
994 pub struct EquatePredicate
<'tcx
>(pub Ty
<'tcx
>, pub Ty
<'tcx
>); // `0 == 1`
995 pub type PolyEquatePredicate
<'tcx
> = ty
::Binder
<EquatePredicate
<'tcx
>>;
997 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
998 pub struct OutlivesPredicate
<A
,B
>(pub A
, pub B
); // `A : B`
999 pub type PolyOutlivesPredicate
<A
,B
> = ty
::Binder
<OutlivesPredicate
<A
,B
>>;
1000 pub type PolyRegionOutlivesPredicate
<'tcx
> = PolyOutlivesPredicate
<&'tcx ty
::Region
,
1002 pub type PolyTypeOutlivesPredicate
<'tcx
> = PolyOutlivesPredicate
<Ty
<'tcx
>, &'tcx ty
::Region
>;
1004 /// This kind of predicate has no *direct* correspondent in the
1005 /// syntax, but it roughly corresponds to the syntactic forms:
1007 /// 1. `T : TraitRef<..., Item=Type>`
1008 /// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
1010 /// In particular, form #1 is "desugared" to the combination of a
1011 /// normal trait predicate (`T : TraitRef<...>`) and one of these
1012 /// predicates. Form #2 is a broader form in that it also permits
1013 /// equality between arbitrary types. Processing an instance of Form
1014 /// #2 eventually yields one of these `ProjectionPredicate`
1015 /// instances to normalize the LHS.
1016 #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
1017 pub struct ProjectionPredicate
<'tcx
> {
1018 pub projection_ty
: ProjectionTy
<'tcx
>,
1022 pub type PolyProjectionPredicate
<'tcx
> = Binder
<ProjectionPredicate
<'tcx
>>;
1024 impl<'tcx
> PolyProjectionPredicate
<'tcx
> {
1025 pub fn item_name(&self) -> Name
{
1026 self.0.projection_ty
.item_name
// safe to skip the binder to access a name
1030 pub trait ToPolyTraitRef
<'tcx
> {
1031 fn to_poly_trait_ref(&self) -> PolyTraitRef
<'tcx
>;
1034 impl<'tcx
> ToPolyTraitRef
<'tcx
> for TraitRef
<'tcx
> {
1035 fn to_poly_trait_ref(&self) -> PolyTraitRef
<'tcx
> {
1036 assert
!(!self.has_escaping_regions());
1037 ty
::Binder(self.clone())
1041 impl<'tcx
> ToPolyTraitRef
<'tcx
> for PolyTraitPredicate
<'tcx
> {
1042 fn to_poly_trait_ref(&self) -> PolyTraitRef
<'tcx
> {
1043 self.map_bound_ref(|trait_pred
| trait_pred
.trait_ref
)
1047 impl<'tcx
> ToPolyTraitRef
<'tcx
> for PolyProjectionPredicate
<'tcx
> {
1048 fn to_poly_trait_ref(&self) -> PolyTraitRef
<'tcx
> {
1049 // Note: unlike with TraitRef::to_poly_trait_ref(),
1050 // self.0.trait_ref is permitted to have escaping regions.
1051 // This is because here `self` has a `Binder` and so does our
1052 // return value, so we are preserving the number of binding
1054 ty
::Binder(self.0.projection_ty
.trait_ref
)
1058 pub trait ToPredicate
<'tcx
> {
1059 fn to_predicate(&self) -> Predicate
<'tcx
>;
1062 impl<'tcx
> ToPredicate
<'tcx
> for TraitRef
<'tcx
> {
1063 fn to_predicate(&self) -> Predicate
<'tcx
> {
1064 // we're about to add a binder, so let's check that we don't
1065 // accidentally capture anything, or else that might be some
1066 // weird debruijn accounting.
1067 assert
!(!self.has_escaping_regions());
1069 ty
::Predicate
::Trait(ty
::Binder(ty
::TraitPredicate
{
1070 trait_ref
: self.clone()
1075 impl<'tcx
> ToPredicate
<'tcx
> for PolyTraitRef
<'tcx
> {
1076 fn to_predicate(&self) -> Predicate
<'tcx
> {
1077 ty
::Predicate
::Trait(self.to_poly_trait_predicate())
1081 impl<'tcx
> ToPredicate
<'tcx
> for PolyEquatePredicate
<'tcx
> {
1082 fn to_predicate(&self) -> Predicate
<'tcx
> {
1083 Predicate
::Equate(self.clone())
1087 impl<'tcx
> ToPredicate
<'tcx
> for PolyRegionOutlivesPredicate
<'tcx
> {
1088 fn to_predicate(&self) -> Predicate
<'tcx
> {
1089 Predicate
::RegionOutlives(self.clone())
1093 impl<'tcx
> ToPredicate
<'tcx
> for PolyTypeOutlivesPredicate
<'tcx
> {
1094 fn to_predicate(&self) -> Predicate
<'tcx
> {
1095 Predicate
::TypeOutlives(self.clone())
1099 impl<'tcx
> ToPredicate
<'tcx
> for PolyProjectionPredicate
<'tcx
> {
1100 fn to_predicate(&self) -> Predicate
<'tcx
> {
1101 Predicate
::Projection(self.clone())
1105 impl<'tcx
> Predicate
<'tcx
> {
1106 /// Iterates over the types in this predicate. Note that in all
1107 /// cases this is skipping over a binder, so late-bound regions
1108 /// with depth 0 are bound by the predicate.
1109 pub fn walk_tys(&self) -> IntoIter
<Ty
<'tcx
>> {
1110 let vec
: Vec
<_
> = match *self {
1111 ty
::Predicate
::Trait(ref data
) => {
1112 data
.skip_binder().input_types().collect()
1114 ty
::Predicate
::Equate(ty
::Binder(ref data
)) => {
1115 vec
![data
.0, data
.1]
1117 ty
::Predicate
::TypeOutlives(ty
::Binder(ref data
)) => {
1120 ty
::Predicate
::RegionOutlives(..) => {
1123 ty
::Predicate
::Projection(ref data
) => {
1124 let trait_inputs
= data
.0.projection_ty
.trait_ref
.input_types();
1125 trait_inputs
.chain(Some(data
.0.ty
)).collect()
1127 ty
::Predicate
::WellFormed(data
) => {
1130 ty
::Predicate
::ObjectSafe(_trait_def_id
) => {
1133 ty
::Predicate
::ClosureKind(_closure_def_id
, _kind
) => {
1138 // The only reason to collect into a vector here is that I was
1139 // too lazy to make the full (somewhat complicated) iterator
1140 // type that would be needed here. But I wanted this fn to
1141 // return an iterator conceptually, rather than a `Vec`, so as
1142 // to be closer to `Ty::walk`.
1146 pub fn to_opt_poly_trait_ref(&self) -> Option
<PolyTraitRef
<'tcx
>> {
1148 Predicate
::Trait(ref t
) => {
1149 Some(t
.to_poly_trait_ref())
1151 Predicate
::Projection(..) |
1152 Predicate
::Equate(..) |
1153 Predicate
::RegionOutlives(..) |
1154 Predicate
::WellFormed(..) |
1155 Predicate
::ObjectSafe(..) |
1156 Predicate
::ClosureKind(..) |
1157 Predicate
::TypeOutlives(..) => {
1164 /// Represents the bounds declared on a particular set of type
1165 /// parameters. Should eventually be generalized into a flag list of
1166 /// where clauses. You can obtain a `InstantiatedPredicates` list from a
1167 /// `GenericPredicates` by using the `instantiate` method. Note that this method
1168 /// reflects an important semantic invariant of `InstantiatedPredicates`: while
1169 /// the `GenericPredicates` are expressed in terms of the bound type
1170 /// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance
1171 /// represented a set of bounds for some particular instantiation,
1172 /// meaning that the generic parameters have been substituted with
1177 /// struct Foo<T,U:Bar<T>> { ... }
1179 /// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
1180 /// `[[], [U:Bar<T>]]`. Now if there were some particular reference
1181 /// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
1182 /// [usize:Bar<isize>]]`.
1184 pub struct InstantiatedPredicates
<'tcx
> {
1185 pub predicates
: Vec
<Predicate
<'tcx
>>,
1188 impl<'tcx
> InstantiatedPredicates
<'tcx
> {
1189 pub fn empty() -> InstantiatedPredicates
<'tcx
> {
1190 InstantiatedPredicates { predicates: vec![] }
1193 pub fn is_empty(&self) -> bool
{
1194 self.predicates
.is_empty()
1198 impl<'tcx
> TraitRef
<'tcx
> {
1199 pub fn new(def_id
: DefId
, substs
: &'tcx Substs
<'tcx
>) -> TraitRef
<'tcx
> {
1200 TraitRef { def_id: def_id, substs: substs }
1203 pub fn self_ty(&self) -> Ty
<'tcx
> {
1204 self.substs
.type_at(0)
1207 pub fn input_types
<'a
>(&'a
self) -> impl DoubleEndedIterator
<Item
=Ty
<'tcx
>> + 'a
{
1208 // Select only the "input types" from a trait-reference. For
1209 // now this is all the types that appear in the
1210 // trait-reference, but it should eventually exclude
1211 // associated types.
1216 /// When type checking, we use the `ParameterEnvironment` to track
1217 /// details about the type/lifetime parameters that are in scope.
1218 /// It primarily stores the bounds information.
1220 /// Note: This information might seem to be redundant with the data in
1221 /// `tcx.ty_param_defs`, but it is not. That table contains the
1222 /// parameter definitions from an "outside" perspective, but this
1223 /// struct will contain the bounds for a parameter as seen from inside
1224 /// the function body. Currently the only real distinction is that
1225 /// bound lifetime parameters are replaced with free ones, but in the
1226 /// future I hope to refine the representation of types so as to make
1227 /// more distinctions clearer.
1229 pub struct ParameterEnvironment
<'tcx
> {
1230 /// See `construct_free_substs` for details.
1231 pub free_substs
: &'tcx Substs
<'tcx
>,
1233 /// Each type parameter has an implicit region bound that
1234 /// indicates it must outlive at least the function body (the user
1235 /// may specify stronger requirements). This field indicates the
1236 /// region of the callee.
1237 pub implicit_region_bound
: &'tcx ty
::Region
,
1239 /// Obligations that the caller must satisfy. This is basically
1240 /// the set of bounds on the in-scope type parameters, translated
1241 /// into Obligations, and elaborated and normalized.
1242 pub caller_bounds
: Vec
<ty
::Predicate
<'tcx
>>,
1244 /// Scope that is attached to free regions for this scope. This
1245 /// is usually the id of the fn body, but for more abstract scopes
1246 /// like structs we often use the node-id of the struct.
1248 /// FIXME(#3696). It would be nice to refactor so that free
1249 /// regions don't have this implicit scope and instead introduce
1250 /// relationships in the environment.
1251 pub free_id_outlive
: CodeExtent
,
1253 /// A cache for `moves_by_default`.
1254 pub is_copy_cache
: RefCell
<FnvHashMap
<Ty
<'tcx
>, bool
>>,
1256 /// A cache for `type_is_sized`
1257 pub is_sized_cache
: RefCell
<FnvHashMap
<Ty
<'tcx
>, bool
>>,
1260 impl<'a
, 'tcx
> ParameterEnvironment
<'tcx
> {
1261 pub fn with_caller_bounds(&self,
1262 caller_bounds
: Vec
<ty
::Predicate
<'tcx
>>)
1263 -> ParameterEnvironment
<'tcx
>
1265 ParameterEnvironment
{
1266 free_substs
: self.free_substs
,
1267 implicit_region_bound
: self.implicit_region_bound
,
1268 caller_bounds
: caller_bounds
,
1269 free_id_outlive
: self.free_id_outlive
,
1270 is_copy_cache
: RefCell
::new(FnvHashMap()),
1271 is_sized_cache
: RefCell
::new(FnvHashMap()),
1275 /// Construct a parameter environment given an item, impl item, or trait item
1276 pub fn for_item(tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>, id
: NodeId
)
1277 -> ParameterEnvironment
<'tcx
> {
1278 match tcx
.map
.find(id
) {
1279 Some(ast_map
::NodeImplItem(ref impl_item
)) => {
1280 match impl_item
.node
{
1281 hir
::ImplItemKind
::Type(_
) | hir
::ImplItemKind
::Const(..) => {
1282 // associated types don't have their own entry (for some reason),
1283 // so for now just grab environment for the impl
1284 let impl_id
= tcx
.map
.get_parent(id
);
1285 let impl_def_id
= tcx
.map
.local_def_id(impl_id
);
1286 tcx
.construct_parameter_environment(impl_item
.span
,
1288 tcx
.region_maps
.item_extent(id
))
1290 hir
::ImplItemKind
::Method(_
, ref body
) => {
1291 let method_def_id
= tcx
.map
.local_def_id(id
);
1292 match tcx
.impl_or_trait_item(method_def_id
) {
1293 MethodTraitItem(ref method_ty
) => {
1294 tcx
.construct_parameter_environment(
1297 tcx
.region_maps
.call_site_extent(id
, body
.id
))
1300 bug
!("ParameterEnvironment::for_item(): \
1301 got non-method item from impl method?!")
1307 Some(ast_map
::NodeTraitItem(trait_item
)) => {
1308 match trait_item
.node
{
1309 hir
::TypeTraitItem(..) | hir
::ConstTraitItem(..) => {
1310 // associated types don't have their own entry (for some reason),
1311 // so for now just grab environment for the trait
1312 let trait_id
= tcx
.map
.get_parent(id
);
1313 let trait_def_id
= tcx
.map
.local_def_id(trait_id
);
1314 tcx
.construct_parameter_environment(trait_item
.span
,
1316 tcx
.region_maps
.item_extent(id
))
1318 hir
::MethodTraitItem(_
, ref body
) => {
1319 // Use call-site for extent (unless this is a
1320 // trait method with no default; then fallback
1321 // to the method id).
1322 let method_def_id
= tcx
.map
.local_def_id(id
);
1323 match tcx
.impl_or_trait_item(method_def_id
) {
1324 MethodTraitItem(ref method_ty
) => {
1325 let extent
= if let Some(ref body
) = *body
{
1326 // default impl: use call_site extent as free_id_outlive bound.
1327 tcx
.region_maps
.call_site_extent(id
, body
.id
)
1329 // no default impl: use item extent as free_id_outlive bound.
1330 tcx
.region_maps
.item_extent(id
)
1332 tcx
.construct_parameter_environment(
1338 bug
!("ParameterEnvironment::for_item(): \
1339 got non-method item from provided \
1346 Some(ast_map
::NodeItem(item
)) => {
1348 hir
::ItemFn(.., ref body
) => {
1349 // We assume this is a function.
1350 let fn_def_id
= tcx
.map
.local_def_id(id
);
1352 tcx
.construct_parameter_environment(
1355 tcx
.region_maps
.call_site_extent(id
, body
.id
))
1358 hir
::ItemStruct(..) |
1359 hir
::ItemUnion(..) |
1362 hir
::ItemConst(..) |
1363 hir
::ItemStatic(..) => {
1364 let def_id
= tcx
.map
.local_def_id(id
);
1365 tcx
.construct_parameter_environment(item
.span
,
1367 tcx
.region_maps
.item_extent(id
))
1369 hir
::ItemTrait(..) => {
1370 let def_id
= tcx
.map
.local_def_id(id
);
1371 tcx
.construct_parameter_environment(item
.span
,
1373 tcx
.region_maps
.item_extent(id
))
1376 span_bug
!(item
.span
,
1377 "ParameterEnvironment::for_item():
1378 can't create a parameter \
1379 environment for this kind of item")
1383 Some(ast_map
::NodeExpr(expr
)) => {
1384 // This is a convenience to allow closures to work.
1385 if let hir
::ExprClosure(..) = expr
.node
{
1386 ParameterEnvironment
::for_item(tcx
, tcx
.map
.get_parent(id
))
1388 tcx
.empty_parameter_environment()
1391 Some(ast_map
::NodeForeignItem(item
)) => {
1392 let def_id
= tcx
.map
.local_def_id(id
);
1393 tcx
.construct_parameter_environment(item
.span
,
1398 bug
!("ParameterEnvironment::from_item(): \
1399 `{}` is not an item",
1400 tcx
.map
.node_to_string(id
))
1406 /// A "type scheme", in ML terminology, is a type combined with some
1407 /// set of generic types that the type is, well, generic over. In Rust
1408 /// terms, it is the "type" of a fn item or struct -- this type will
1409 /// include various generic parameters that must be substituted when
1410 /// the item/struct is referenced. That is called converting the type
1411 /// scheme to a monotype.
1413 /// - `generics`: the set of type parameters and their bounds
1414 /// - `ty`: the base types, which may reference the parameters defined
1417 /// Note that TypeSchemes are also sometimes called "polytypes" (and
1418 /// in fact this struct used to carry that name, so you may find some
1419 /// stray references in a comment or something). We try to reserve the
1420 /// "poly" prefix to refer to higher-ranked things, as in
1423 /// Note that each item also comes with predicates, see
1424 /// `lookup_predicates`.
1425 #[derive(Clone, Debug)]
1426 pub struct TypeScheme
<'tcx
> {
1427 pub generics
: &'tcx Generics
<'tcx
>,
1432 flags AdtFlags
: u32 {
1433 const NO_ADT_FLAGS
= 0,
1434 const IS_ENUM
= 1 << 0,
1435 const IS_DTORCK
= 1 << 1, // is this a dtorck type?
1436 const IS_DTORCK_VALID
= 1 << 2,
1437 const IS_PHANTOM_DATA
= 1 << 3,
1438 const IS_SIMD
= 1 << 4,
1439 const IS_FUNDAMENTAL
= 1 << 5,
1440 const IS_UNION
= 1 << 6,
1444 pub type AdtDef
<'tcx
> = &'tcx AdtDefData
<'tcx
, '
static>;
1445 pub type VariantDef
<'tcx
> = &'tcx VariantDefData
<'tcx
, '
static>;
1446 pub type FieldDef
<'tcx
> = &'tcx FieldDefData
<'tcx
, '
static>;
1448 // See comment on AdtDefData for explanation
1449 pub type AdtDefMaster
<'tcx
> = &'tcx AdtDefData
<'tcx
, 'tcx
>;
1450 pub type VariantDefMaster
<'tcx
> = &'tcx VariantDefData
<'tcx
, 'tcx
>;
1451 pub type FieldDefMaster
<'tcx
> = &'tcx FieldDefData
<'tcx
, 'tcx
>;
1453 pub struct VariantDefData
<'tcx
, 'container
: 'tcx
> {
1454 /// The variant's DefId. If this is a tuple-like struct,
1455 /// this is the DefId of the struct's ctor.
1457 pub name
: Name
, // struct's name if this is a struct
1459 pub fields
: Vec
<FieldDefData
<'tcx
, 'container
>>,
1460 pub ctor_kind
: CtorKind
,
1463 pub struct FieldDefData
<'tcx
, 'container
: 'tcx
> {
1464 /// The field's DefId. NOTE: the fields of tuple-like enum variants
1465 /// are not real items, and don't have entries in tcache etc.
1468 pub vis
: Visibility
,
1469 /// TyIVar is used here to allow for variance (see the doc at
1472 /// Note: direct accesses to `ty` must also add dep edges.
1473 ty
: ivar
::TyIVar
<'tcx
, 'container
>
1476 /// The definition of an abstract data type - a struct or enum.
1478 /// These are all interned (by intern_adt_def) into the adt_defs
1481 /// Because of the possibility of nested tcx-s, this type
1482 /// needs 2 lifetimes: the traditional variant lifetime ('tcx)
1483 /// bounding the lifetime of the inner types is of course necessary.
1484 /// However, it is not sufficient - types from a child tcx must
1485 /// not be leaked into the master tcx by being stored in an AdtDefData.
1487 /// The 'container lifetime ensures that by outliving the container
1488 /// tcx and preventing shorter-lived types from being inserted. When
1489 /// write access is not needed, the 'container lifetime can be
1490 /// erased to 'static, which can be done by the AdtDef wrapper.
1491 pub struct AdtDefData
<'tcx
, 'container
: 'tcx
> {
1493 pub variants
: Vec
<VariantDefData
<'tcx
, 'container
>>,
1494 destructor
: Cell
<Option
<DefId
>>,
1495 flags
: Cell
<AdtFlags
>,
1496 sized_constraint
: ivar
::TyIVar
<'tcx
, 'container
>,
1499 impl<'tcx
, 'container
> PartialEq
for AdtDefData
<'tcx
, 'container
> {
1500 // AdtDefData are always interned and this is part of TyS equality
1502 fn eq(&self, other
: &Self) -> bool { self as *const _ == other as *const _ }
1505 impl<'tcx
, 'container
> Eq
for AdtDefData
<'tcx
, 'container
> {}
1507 impl<'tcx
, 'container
> Hash
for AdtDefData
<'tcx
, 'container
> {
1509 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
1510 (self as *const AdtDefData
).hash(s
)
1514 impl<'tcx
> serialize
::UseSpecializedEncodable
for AdtDef
<'tcx
> {
1515 fn default_encode
<S
: Encoder
>(&self, s
: &mut S
) -> Result
<(), S
::Error
> {
1520 impl<'tcx
> serialize
::UseSpecializedDecodable
for AdtDef
<'tcx
> {}
1522 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
1523 pub enum AdtKind { Struct, Union, Enum }
1525 impl<'a
, 'gcx
, 'tcx
, 'container
> AdtDefData
<'gcx
, 'container
> {
1526 fn new(tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
1529 variants
: Vec
<VariantDefData
<'gcx
, 'container
>>) -> Self {
1530 let mut flags
= AdtFlags
::NO_ADT_FLAGS
;
1531 let attrs
= tcx
.get_attrs(did
);
1532 if attr
::contains_name(&attrs
, "fundamental") {
1533 flags
= flags
| AdtFlags
::IS_FUNDAMENTAL
;
1535 if tcx
.lookup_simd(did
) {
1536 flags
= flags
| AdtFlags
::IS_SIMD
;
1538 if Some(did
) == tcx
.lang_items
.phantom_data() {
1539 flags
= flags
| AdtFlags
::IS_PHANTOM_DATA
;
1542 AdtKind
::Enum
=> flags
= flags
| AdtFlags
::IS_ENUM
,
1543 AdtKind
::Union
=> flags
= flags
| AdtFlags
::IS_UNION
,
1544 AdtKind
::Struct
=> {}
1549 flags
: Cell
::new(flags
),
1550 destructor
: Cell
::new(None
),
1551 sized_constraint
: ivar
::TyIVar
::new(),
1555 fn calculate_dtorck(&'gcx
self, tcx
: TyCtxt
) {
1556 if tcx
.is_adt_dtorck(self) {
1557 self.flags
.set(self.flags
.get() | AdtFlags
::IS_DTORCK
);
1559 self.flags
.set(self.flags
.get() | AdtFlags
::IS_DTORCK_VALID
)
1563 pub fn is_struct(&self) -> bool
{
1564 !self.is_union() && !self.is_enum()
1568 pub fn is_union(&self) -> bool
{
1569 self.flags
.get().intersects(AdtFlags
::IS_UNION
)
1573 pub fn is_enum(&self) -> bool
{
1574 self.flags
.get().intersects(AdtFlags
::IS_ENUM
)
1577 /// Returns the kind of the ADT - Struct or Enum.
1579 pub fn adt_kind(&self) -> AdtKind
{
1582 } else if self.is_union() {
1589 pub fn descr(&self) -> &'
static str {
1590 match self.adt_kind() {
1591 AdtKind
::Struct
=> "struct",
1592 AdtKind
::Union
=> "union",
1593 AdtKind
::Enum
=> "enum",
1597 pub fn variant_descr(&self) -> &'
static str {
1598 match self.adt_kind() {
1599 AdtKind
::Struct
=> "struct",
1600 AdtKind
::Union
=> "union",
1601 AdtKind
::Enum
=> "variant",
1605 /// Returns whether this is a dtorck type. If this returns
1606 /// true, this type being safe for destruction requires it to be
1607 /// alive; Otherwise, only the contents are required to be.
1609 pub fn is_dtorck(&'gcx
self, tcx
: TyCtxt
) -> bool
{
1610 if !self.flags
.get().intersects(AdtFlags
::IS_DTORCK_VALID
) {
1611 self.calculate_dtorck(tcx
)
1613 self.flags
.get().intersects(AdtFlags
::IS_DTORCK
)
1616 /// Returns whether this type is #[fundamental] for the purposes
1617 /// of coherence checking.
1619 pub fn is_fundamental(&self) -> bool
{
1620 self.flags
.get().intersects(AdtFlags
::IS_FUNDAMENTAL
)
1624 pub fn is_simd(&self) -> bool
{
1625 self.flags
.get().intersects(AdtFlags
::IS_SIMD
)
1628 /// Returns true if this is PhantomData<T>.
1630 pub fn is_phantom_data(&self) -> bool
{
1631 self.flags
.get().intersects(AdtFlags
::IS_PHANTOM_DATA
)
1634 /// Returns whether this type has a destructor.
1635 pub fn has_dtor(&self) -> bool
{
1636 self.dtor_kind().is_present()
1639 /// Asserts this is a struct and returns the struct's unique
1641 pub fn struct_variant(&self) -> &VariantDefData
<'gcx
, 'container
> {
1642 assert
!(!self.is_enum());
1647 pub fn type_scheme(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>) -> TypeScheme
<'gcx
> {
1648 tcx
.lookup_item_type(self.did
)
1652 pub fn predicates(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>) -> GenericPredicates
<'gcx
> {
1653 tcx
.lookup_predicates(self.did
)
1656 /// Returns an iterator over all fields contained
1659 pub fn all_fields(&self) ->
1661 slice
::Iter
<VariantDefData
<'gcx
, 'container
>>,
1662 slice
::Iter
<FieldDefData
<'gcx
, 'container
>>,
1663 for<'s
> fn(&'s VariantDefData
<'gcx
, 'container
>)
1664 -> slice
::Iter
<'s
, FieldDefData
<'gcx
, 'container
>>
1666 self.variants
.iter().flat_map(VariantDefData
::fields_iter
)
1670 pub fn is_empty(&self) -> bool
{
1671 self.variants
.is_empty()
1675 pub fn is_univariant(&self) -> bool
{
1676 self.variants
.len() == 1
1679 pub fn is_payloadfree(&self) -> bool
{
1680 !self.variants
.is_empty() &&
1681 self.variants
.iter().all(|v
| v
.fields
.is_empty())
1684 pub fn variant_with_id(&self, vid
: DefId
) -> &VariantDefData
<'gcx
, 'container
> {
1687 .find(|v
| v
.did
== vid
)
1688 .expect("variant_with_id: unknown variant")
1691 pub fn variant_index_with_id(&self, vid
: DefId
) -> usize {
1694 .position(|v
| v
.did
== vid
)
1695 .expect("variant_index_with_id: unknown variant")
1698 pub fn variant_of_def(&self, def
: Def
) -> &VariantDefData
<'gcx
, 'container
> {
1700 Def
::Variant(vid
) | Def
::VariantCtor(vid
, ..) => self.variant_with_id(vid
),
1701 Def
::Struct(..) | Def
::StructCtor(..) | Def
::Union(..) |
1702 Def
::TyAlias(..) | Def
::AssociatedTy(..) | Def
::SelfTy(..) => self.struct_variant(),
1703 _
=> bug
!("unexpected def {:?} in variant_of_def", def
)
1707 pub fn destructor(&self) -> Option
<DefId
> {
1708 self.destructor
.get()
1711 pub fn set_destructor(&self, dtor
: DefId
) {
1712 self.destructor
.set(Some(dtor
));
1715 pub fn dtor_kind(&self) -> DtorKind
{
1716 match self.destructor
.get() {
1717 Some(_
) => TraitDtor
,
1723 impl<'a
, 'gcx
, 'tcx
, 'container
> AdtDefData
<'tcx
, 'container
> {
1724 /// Returns a simpler type such that `Self: Sized` if and only
1725 /// if that type is Sized, or `TyErr` if this type is recursive.
1727 /// HACK: instead of returning a list of types, this function can
1728 /// return a tuple. In that case, the result is Sized only if
1729 /// all elements of the tuple are Sized.
1731 /// This is generally the `struct_tail` if this is a struct, or a
1732 /// tuple of them if this is an enum.
1734 /// Oddly enough, checking that the sized-constraint is Sized is
1735 /// actually more expressive than checking all members:
1736 /// the Sized trait is inductive, so an associated type that references
1737 /// Self would prevent its containing ADT from being Sized.
1739 /// Due to normalization being eager, this applies even if
1740 /// the associated type is behind a pointer, e.g. issue #31299.
1741 pub fn sized_constraint(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>) -> Ty
<'tcx
> {
1742 match self.sized_constraint
.get(DepNode
::SizedConstraint(self.did
)) {
1744 let global_tcx
= tcx
.global_tcx();
1745 let this
= global_tcx
.lookup_adt_def_master(self.did
);
1746 this
.calculate_sized_constraint_inner(global_tcx
, &mut Vec
::new());
1747 self.sized_constraint(tcx
)
1754 impl<'a
, 'tcx
> AdtDefData
<'tcx
, 'tcx
> {
1755 /// Calculates the Sized-constraint.
1757 /// As the Sized-constraint of enums can be a *set* of types,
1758 /// the Sized-constraint may need to be a set also. Because introducing
1759 /// a new type of IVar is currently a complex affair, the Sized-constraint
1762 /// In fact, there are only a few options for the constraint:
1763 /// - `bool`, if the type is always Sized
1764 /// - an obviously-unsized type
1765 /// - a type parameter or projection whose Sizedness can't be known
1766 /// - a tuple of type parameters or projections, if there are multiple
1768 /// - a TyError, if a type contained itself. The representability
1769 /// check should catch this case.
1770 fn calculate_sized_constraint_inner(&'tcx
self,
1771 tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
1772 stack
: &mut Vec
<AdtDefMaster
<'tcx
>>)
1774 let dep_node
= || DepNode
::SizedConstraint(self.did
);
1776 // Follow the memoization pattern: push the computation of
1777 // DepNode::SizedConstraint as our current task.
1778 let _task
= tcx
.dep_graph
.in_task(dep_node());
1779 if self.sized_constraint
.untracked_get().is_some() {
1781 // can skip the dep-graph read since we just pushed the task
1785 if stack
.contains(&self) {
1786 debug
!("calculate_sized_constraint: {:?} is recursive", self);
1787 // This should be reported as an error by `check_representable`.
1789 // Consider the type as Sized in the meanwhile to avoid
1791 self.sized_constraint
.fulfill(dep_node(), tcx
.types
.err
);
1798 self.variants
.iter().flat_map(|v
| {
1801 self.sized_constraint_for_ty(tcx
, stack
, f
.unsubst_ty())
1804 let self_
= stack
.pop().unwrap();
1805 assert_eq
!(self_
, self);
1807 let ty
= match tys
.len() {
1808 _
if tys
.references_error() => tcx
.types
.err
,
1809 0 => tcx
.types
.bool
,
1811 _
=> tcx
.intern_tup(&tys
[..])
1814 match self.sized_constraint
.get(dep_node()) {
1816 debug
!("calculate_sized_constraint: {:?} recurred", self);
1817 assert_eq
!(old_ty
, tcx
.types
.err
)
1820 debug
!("calculate_sized_constraint: {:?} => {:?}", self, ty
);
1821 self.sized_constraint
.fulfill(dep_node(), ty
)
1826 fn sized_constraint_for_ty(
1828 tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
1829 stack
: &mut Vec
<AdtDefMaster
<'tcx
>>,
1831 ) -> Vec
<Ty
<'tcx
>> {
1832 let result
= match ty
.sty
{
1833 TyBool
| TyChar
| TyInt(..) | TyUint(..) | TyFloat(..) |
1834 TyBox(..) | TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_
) |
1835 TyArray(..) | TyClosure(..) | TyNever
=> {
1839 TyStr
| TyTrait(..) | TySlice(_
) | TyError
=> {
1840 // these are never sized - return the target type
1844 TyTuple(ref tys
) => {
1847 Some(ty
) => self.sized_constraint_for_ty(tcx
, stack
, ty
)
1851 TyAdt(adt
, substs
) => {
1853 let adt
= tcx
.lookup_adt_def_master(adt
.did
);
1854 adt
.calculate_sized_constraint_inner(tcx
, stack
);
1856 adt
.sized_constraint
1857 .unwrap(DepNode
::SizedConstraint(adt
.did
))
1858 .subst(tcx
, substs
);
1859 debug
!("sized_constraint_for_ty({:?}) intermediate = {:?}",
1861 if let ty
::TyTuple(ref tys
) = adt_ty
.sty
{
1862 tys
.iter().flat_map(|ty
| {
1863 self.sized_constraint_for_ty(tcx
, stack
, ty
)
1866 self.sized_constraint_for_ty(tcx
, stack
, adt_ty
)
1870 TyProjection(..) | TyAnon(..) => {
1871 // must calculate explicitly.
1872 // FIXME: consider special-casing always-Sized projections
1877 // perf hack: if there is a `T: Sized` bound, then
1878 // we know that `T` is Sized and do not need to check
1881 let sized_trait
= match tcx
.lang_items
.sized_trait() {
1883 _
=> return vec
![ty
]
1885 let sized_predicate
= Binder(TraitRef
{
1886 def_id
: sized_trait
,
1887 substs
: tcx
.mk_substs_trait(ty
, &[])
1889 let predicates
= tcx
.lookup_predicates(self.did
).predicates
;
1890 if predicates
.into_iter().any(|p
| p
== sized_predicate
) {
1898 bug
!("unexpected type `{:?}` in sized_constraint_for_ty",
1902 debug
!("sized_constraint_for_ty({:?}) = {:?}", ty
, result
);
1907 impl<'tcx
, 'container
> VariantDefData
<'tcx
, 'container
> {
1909 fn fields_iter(&self) -> slice
::Iter
<FieldDefData
<'tcx
, 'container
>> {
1914 pub fn find_field_named(&self,
1916 -> Option
<&FieldDefData
<'tcx
, 'container
>> {
1917 self.fields
.iter().find(|f
| f
.name
== name
)
1921 pub fn index_of_field_named(&self,
1924 self.fields
.iter().position(|f
| f
.name
== name
)
1928 pub fn field_named(&self, name
: ast
::Name
) -> &FieldDefData
<'tcx
, 'container
> {
1929 self.find_field_named(name
).unwrap()
1933 impl<'a
, 'gcx
, 'tcx
, 'container
> FieldDefData
<'tcx
, 'container
> {
1934 pub fn new(did
: DefId
,
1936 vis
: Visibility
) -> Self {
1941 ty
: ivar
::TyIVar
::new()
1945 pub fn ty(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>, subst
: &Substs
<'tcx
>) -> Ty
<'tcx
> {
1946 self.unsubst_ty().subst(tcx
, subst
)
1949 pub fn unsubst_ty(&self) -> Ty
<'tcx
> {
1950 self.ty
.unwrap(DepNode
::FieldTy(self.did
))
1953 pub fn fulfill_ty(&self, ty
: Ty
<'container
>) {
1954 self.ty
.fulfill(DepNode
::FieldTy(self.did
), ty
);
1958 /// Records the substitutions used to translate the polytype for an
1959 /// item into the monotype of an item reference.
1960 #[derive(Clone, RustcEncodable, RustcDecodable)]
1961 pub struct ItemSubsts
<'tcx
> {
1962 pub substs
: &'tcx Substs
<'tcx
>,
1965 #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
1966 pub enum ClosureKind
{
1967 // Warning: Ordering is significant here! The ordering is chosen
1968 // because the trait Fn is a subtrait of FnMut and so in turn, and
1969 // hence we order it so that Fn < FnMut < FnOnce.
1975 impl<'a
, 'tcx
> ClosureKind
{
1976 pub fn trait_did(&self, tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>) -> DefId
{
1977 let result
= match *self {
1978 ClosureKind
::Fn
=> tcx
.lang_items
.require(FnTraitLangItem
),
1979 ClosureKind
::FnMut
=> {
1980 tcx
.lang_items
.require(FnMutTraitLangItem
)
1982 ClosureKind
::FnOnce
=> {
1983 tcx
.lang_items
.require(FnOnceTraitLangItem
)
1987 Ok(trait_did
) => trait_did
,
1988 Err(err
) => tcx
.sess
.fatal(&err
[..]),
1992 /// True if this a type that impls this closure kind
1993 /// must also implement `other`.
1994 pub fn extends(self, other
: ty
::ClosureKind
) -> bool
{
1995 match (self, other
) {
1996 (ClosureKind
::Fn
, ClosureKind
::Fn
) => true,
1997 (ClosureKind
::Fn
, ClosureKind
::FnMut
) => true,
1998 (ClosureKind
::Fn
, ClosureKind
::FnOnce
) => true,
1999 (ClosureKind
::FnMut
, ClosureKind
::FnMut
) => true,
2000 (ClosureKind
::FnMut
, ClosureKind
::FnOnce
) => true,
2001 (ClosureKind
::FnOnce
, ClosureKind
::FnOnce
) => true,
2007 impl<'tcx
> TyS
<'tcx
> {
2008 /// Iterator that walks `self` and any types reachable from
2009 /// `self`, in depth-first order. Note that just walks the types
2010 /// that appear in `self`, it does not descend into the fields of
2011 /// structs or variants. For example:
2014 /// isize => { isize }
2015 /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
2016 /// [isize] => { [isize], isize }
2018 pub fn walk(&'tcx
self) -> TypeWalker
<'tcx
> {
2019 TypeWalker
::new(self)
2022 /// Iterator that walks the immediate children of `self`. Hence
2023 /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
2024 /// (but not `i32`, like `walk`).
2025 pub fn walk_shallow(&'tcx
self) -> IntoIter
<Ty
<'tcx
>> {
2026 walk
::walk_shallow(self)
2029 /// Walks `ty` and any types appearing within `ty`, invoking the
2030 /// callback `f` on each type. If the callback returns false, then the
2031 /// children of the current type are ignored.
2033 /// Note: prefer `ty.walk()` where possible.
2034 pub fn maybe_walk
<F
>(&'tcx
self, mut f
: F
)
2035 where F
: FnMut(Ty
<'tcx
>) -> bool
2037 let mut walker
= self.walk();
2038 while let Some(ty
) = walker
.next() {
2040 walker
.skip_current_subtree();
2046 impl<'tcx
> ItemSubsts
<'tcx
> {
2047 pub fn is_noop(&self) -> bool
{
2048 self.substs
.is_noop()
2052 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2053 pub enum LvaluePreference
{
2058 impl LvaluePreference
{
2059 pub fn from_mutbl(m
: hir
::Mutability
) -> Self {
2061 hir
::MutMutable
=> PreferMutLvalue
,
2062 hir
::MutImmutable
=> NoPreference
,
2067 /// Helper for looking things up in the various maps that are populated during
2068 /// typeck::collect (e.g., `tcx.impl_or_trait_items`, `tcx.tcache`, etc). All of
2069 /// these share the pattern that if the id is local, it should have been loaded
2070 /// into the map by the `typeck::collect` phase. If the def-id is external,
2071 /// then we have to go consult the crate loading code (and cache the result for
2073 fn lookup_locally_or_in_crate_store
<M
, F
>(descr
: &str,
2078 M
: MemoizationMap
<Key
=DefId
>,
2079 F
: FnOnce() -> M
::Value
,
2081 map
.memoize(def_id
, || {
2082 if def_id
.is_local() {
2083 bug
!("No def'n found for {:?} in tcx.{}", def_id
, descr
);
2090 pub fn from_mutbl(m
: hir
::Mutability
) -> BorrowKind
{
2092 hir
::MutMutable
=> MutBorrow
,
2093 hir
::MutImmutable
=> ImmBorrow
,
2097 /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow
2098 /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a
2099 /// mutability that is stronger than necessary so that it at least *would permit* the borrow in
2101 pub fn to_mutbl_lossy(self) -> hir
::Mutability
{
2103 MutBorrow
=> hir
::MutMutable
,
2104 ImmBorrow
=> hir
::MutImmutable
,
2106 // We have no type corresponding to a unique imm borrow, so
2107 // use `&mut`. It gives all the capabilities of an `&uniq`
2108 // and hence is a safe "over approximation".
2109 UniqueImmBorrow
=> hir
::MutMutable
,
2113 pub fn to_user_str(&self) -> &'
static str {
2115 MutBorrow
=> "mutable",
2116 ImmBorrow
=> "immutable",
2117 UniqueImmBorrow
=> "uniquely immutable",
2122 impl<'a
, 'gcx
, 'tcx
> TyCtxt
<'a
, 'gcx
, 'tcx
> {
2123 pub fn tables(self) -> Ref
<'a
, Tables
<'gcx
>> {
2124 self.tables
.borrow()
2127 pub fn expr_span(self, id
: NodeId
) -> Span
{
2128 match self.map
.find(id
) {
2129 Some(ast_map
::NodeExpr(e
)) => {
2133 bug
!("Node id {} is not an expr: {:?}", id
, f
);
2136 bug
!("Node id {} is not present in the node map", id
);
2141 pub fn local_var_name_str(self, id
: NodeId
) -> InternedString
{
2142 match self.map
.find(id
) {
2143 Some(ast_map
::NodeLocal(pat
)) => {
2145 hir
::PatKind
::Binding(_
, ref path1
, _
) => path1
.node
.as_str(),
2147 bug
!("Variable id {} maps to {:?}, not local", id
, pat
);
2151 r
=> bug
!("Variable id {} maps to {:?}, not local", id
, r
),
2155 pub fn expr_is_lval(self, expr
: &hir
::Expr
) -> bool
{
2157 hir
::ExprPath(..) => {
2158 // This function can be used during type checking when not all paths are
2159 // fully resolved. Partially resolved paths in expressions can only legally
2160 // refer to associated items which are always rvalues.
2161 match self.expect_resolution(expr
.id
).base_def
{
2162 Def
::Local(..) | Def
::Upvar(..) | Def
::Static(..) | Def
::Err
=> true,
2167 hir
::ExprType(ref e
, _
) => {
2168 self.expr_is_lval(e
)
2171 hir
::ExprUnary(hir
::UnDeref
, _
) |
2172 hir
::ExprField(..) |
2173 hir
::ExprTupField(..) |
2174 hir
::ExprIndex(..) => {
2179 hir
::ExprMethodCall(..) |
2180 hir
::ExprStruct(..) |
2183 hir
::ExprMatch(..) |
2184 hir
::ExprClosure(..) |
2185 hir
::ExprBlock(..) |
2186 hir
::ExprRepeat(..) |
2187 hir
::ExprArray(..) |
2188 hir
::ExprBreak(..) |
2189 hir
::ExprAgain(..) |
2191 hir
::ExprWhile(..) |
2193 hir
::ExprAssign(..) |
2194 hir
::ExprInlineAsm(..) |
2195 hir
::ExprAssignOp(..) |
2197 hir
::ExprUnary(..) |
2199 hir
::ExprAddrOf(..) |
2200 hir
::ExprBinary(..) |
2201 hir
::ExprCast(..) => {
2207 pub fn provided_trait_methods(self, id
: DefId
) -> Vec
<Rc
<Method
<'gcx
>>> {
2208 self.impl_or_trait_items(id
).iter().filter_map(|&def_id
| {
2209 match self.impl_or_trait_item(def_id
) {
2210 MethodTraitItem(ref m
) if m
.has_body
=> Some(m
.clone()),
2216 pub fn trait_impl_polarity(self, id
: DefId
) -> hir
::ImplPolarity
{
2217 if let Some(id
) = self.map
.as_local_node_id(id
) {
2218 match self.map
.expect_item(id
).node
{
2219 hir
::ItemImpl(_
, polarity
, ..) => polarity
,
2220 ref item
=> bug
!("trait_impl_polarity: {:?} not an impl", item
)
2223 self.sess
.cstore
.impl_polarity(id
)
2227 pub fn custom_coerce_unsized_kind(self, did
: DefId
) -> adjustment
::CustomCoerceUnsized
{
2228 self.custom_coerce_unsized_kinds
.memoize(did
, || {
2229 let (kind
, src
) = if did
.krate
!= LOCAL_CRATE
{
2230 (self.sess
.cstore
.custom_coerce_unsized_kind(did
), "external")
2238 bug
!("custom_coerce_unsized_kind: \
2239 {} impl `{}` is missing its kind",
2240 src
, self.item_path_str(did
));
2246 pub fn impl_or_trait_item(self, id
: DefId
) -> ImplOrTraitItem
<'gcx
> {
2247 lookup_locally_or_in_crate_store(
2248 "impl_or_trait_items", id
, &self.impl_or_trait_items
,
2249 || self.sess
.cstore
.impl_or_trait_item(self.global_tcx(), id
)
2250 .expect("missing ImplOrTraitItem in metadata"))
2253 pub fn impl_or_trait_items(self, id
: DefId
) -> Rc
<Vec
<DefId
>> {
2254 lookup_locally_or_in_crate_store(
2255 "impl_or_trait_items", id
, &self.impl_or_trait_item_def_ids
,
2256 || Rc
::new(self.sess
.cstore
.impl_or_trait_items(id
)))
2259 /// Returns the trait-ref corresponding to a given impl, or None if it is
2260 /// an inherent impl.
2261 pub fn impl_trait_ref(self, id
: DefId
) -> Option
<TraitRef
<'gcx
>> {
2262 lookup_locally_or_in_crate_store(
2263 "impl_trait_refs", id
, &self.impl_trait_refs
,
2264 || self.sess
.cstore
.impl_trait_ref(self.global_tcx(), id
))
2267 /// Returns a path resolution for node id if it exists, panics otherwise.
2268 pub fn expect_resolution(self, id
: NodeId
) -> PathResolution
{
2269 *self.def_map
.borrow().get(&id
).expect("no def-map entry for node id")
2272 /// Returns a fully resolved definition for node id if it exists, panics otherwise.
2273 pub fn expect_def(self, id
: NodeId
) -> Def
{
2274 self.expect_resolution(id
).full_def()
2277 /// Returns a fully resolved definition for node id if it exists, or none if no
2278 /// definition exists, panics on partial resolutions to catch errors.
2279 pub fn expect_def_or_none(self, id
: NodeId
) -> Option
<Def
> {
2280 self.def_map
.borrow().get(&id
).map(|resolution
| resolution
.full_def())
2283 // Returns `ty::VariantDef` if `def` refers to a struct,
2284 // or variant or their constructors, panics otherwise.
2285 pub fn expect_variant_def(self, def
: Def
) -> VariantDef
<'tcx
> {
2287 Def
::Variant(did
) | Def
::VariantCtor(did
, ..) => {
2288 let enum_did
= self.parent_def_id(did
).unwrap();
2289 self.lookup_adt_def(enum_did
).variant_with_id(did
)
2291 Def
::Struct(did
) | Def
::Union(did
) => {
2292 self.lookup_adt_def(did
).struct_variant()
2294 Def
::StructCtor(ctor_did
, ..) => {
2295 let did
= self.parent_def_id(ctor_did
).expect("struct ctor has no parent");
2296 self.lookup_adt_def(did
).struct_variant()
2298 _
=> bug
!("expect_variant_def used with unexpected def {:?}", def
)
2302 pub fn def_key(self, id
: DefId
) -> ast_map
::DefKey
{
2304 self.map
.def_key(id
)
2306 self.sess
.cstore
.def_key(id
)
2310 /// Convert a `DefId` into its fully expanded `DefPath` (every
2311 /// `DefId` is really just an interned def-path).
2313 /// Note that if `id` is not local to this crate -- or is
2314 /// inlined into this crate -- the result will be a non-local
2317 /// This function is only safe to use when you are sure that the
2318 /// full def-path is accessible. Examples that are known to be
2319 /// safe are local def-ids or items; see `opt_def_path` for more
2321 pub fn def_path(self, id
: DefId
) -> ast_map
::DefPath
{
2322 self.opt_def_path(id
).unwrap_or_else(|| {
2323 bug
!("could not load def-path for {:?}", id
)
2327 /// Convert a `DefId` into its fully expanded `DefPath` (every
2328 /// `DefId` is really just an interned def-path).
2330 /// When going across crates, we do not save the full info for
2331 /// every cross-crate def-id, and hence we may not always be able
2332 /// to create a def-path. Therefore, this returns
2333 /// `Option<DefPath>` to cover that possibility. It will always
2334 /// return `Some` for local def-ids, however, as well as for
2335 /// items. The problems arise with "minor" def-ids like those
2336 /// associated with a pattern, `impl Trait`, or other internal
2339 /// Note that if `id` is not local to this crate -- or is
2340 /// inlined into this crate -- the result will be a non-local
2342 pub fn opt_def_path(self, id
: DefId
) -> Option
<ast_map
::DefPath
> {
2344 Some(self.map
.def_path(id
))
2346 self.sess
.cstore
.relative_def_path(id
)
2350 pub fn item_name(self, id
: DefId
) -> ast
::Name
{
2351 if let Some(id
) = self.map
.as_local_node_id(id
) {
2353 } else if id
.index
== CRATE_DEF_INDEX
{
2354 token
::intern(&self.sess
.cstore
.original_crate_name(id
.krate
))
2356 let def_key
= self.sess
.cstore
.def_key(id
);
2357 // The name of a StructCtor is that of its struct parent.
2358 if let ast_map
::DefPathData
::StructCtor
= def_key
.disambiguated_data
.data
{
2359 self.item_name(DefId
{
2361 index
: def_key
.parent
.unwrap()
2364 def_key
.disambiguated_data
.data
.get_opt_name().unwrap_or_else(|| {
2365 bug
!("item_name: no name for {:?}", self.def_path(id
));
2371 // Register a given item type
2372 pub fn register_item_type(self, did
: DefId
, scheme
: TypeScheme
<'gcx
>) {
2373 self.tcache
.borrow_mut().insert(did
, scheme
.ty
);
2374 self.generics
.borrow_mut().insert(did
, scheme
.generics
);
2377 // If the given item is in an external crate, looks up its type and adds it to
2378 // the type cache. Returns the type parameters and type.
2379 pub fn lookup_item_type(self, did
: DefId
) -> TypeScheme
<'gcx
> {
2380 let ty
= lookup_locally_or_in_crate_store(
2381 "tcache", did
, &self.tcache
,
2382 || self.sess
.cstore
.item_type(self.global_tcx(), did
));
2386 generics
: self.lookup_generics(did
)
2390 pub fn opt_lookup_item_type(self, did
: DefId
) -> Option
<TypeScheme
<'gcx
>> {
2391 if did
.krate
!= LOCAL_CRATE
{
2392 return Some(self.lookup_item_type(did
));
2395 if let Some(ty
) = self.tcache
.borrow().get(&did
).cloned() {
2398 generics
: self.lookup_generics(did
)
2405 /// Given the did of a trait, returns its canonical trait ref.
2406 pub fn lookup_trait_def(self, did
: DefId
) -> &'gcx TraitDef
<'gcx
> {
2407 lookup_locally_or_in_crate_store(
2408 "trait_defs", did
, &self.trait_defs
,
2409 || self.alloc_trait_def(self.sess
.cstore
.trait_def(self.global_tcx(), did
))
2413 /// Given the did of an ADT, return a master reference to its
2414 /// definition. Unless you are planning on fulfilling the ADT's fields,
2415 /// use lookup_adt_def instead.
2416 pub fn lookup_adt_def_master(self, did
: DefId
) -> AdtDefMaster
<'gcx
> {
2417 lookup_locally_or_in_crate_store(
2418 "adt_defs", did
, &self.adt_defs
,
2419 || self.sess
.cstore
.adt_def(self.global_tcx(), did
)
2423 /// Given the did of an ADT, return a reference to its definition.
2424 pub fn lookup_adt_def(self, did
: DefId
) -> AdtDef
<'gcx
> {
2425 // when reverse-variance goes away, a transmute::<AdtDefMaster,AdtDef>
2426 // would be needed here.
2427 self.lookup_adt_def_master(did
)
2430 /// Given the did of an item, returns its generics.
2431 pub fn lookup_generics(self, did
: DefId
) -> &'gcx Generics
<'gcx
> {
2432 lookup_locally_or_in_crate_store(
2433 "generics", did
, &self.generics
,
2434 || self.alloc_generics(self.sess
.cstore
.item_generics(self.global_tcx(), did
)))
2437 /// Given the did of an item, returns its full set of predicates.
2438 pub fn lookup_predicates(self, did
: DefId
) -> GenericPredicates
<'gcx
> {
2439 lookup_locally_or_in_crate_store(
2440 "predicates", did
, &self.predicates
,
2441 || self.sess
.cstore
.item_predicates(self.global_tcx(), did
))
2444 /// Given the did of a trait, returns its superpredicates.
2445 pub fn lookup_super_predicates(self, did
: DefId
) -> GenericPredicates
<'gcx
> {
2446 lookup_locally_or_in_crate_store(
2447 "super_predicates", did
, &self.super_predicates
,
2448 || self.sess
.cstore
.item_super_predicates(self.global_tcx(), did
))
2451 /// Given the did of an item, returns its MIR, borrowed immutably.
2452 pub fn item_mir(self, did
: DefId
) -> Ref
<'gcx
, Mir
<'gcx
>> {
2453 lookup_locally_or_in_crate_store("mir_map", did
, &self.mir_map
, || {
2454 let mir
= self.sess
.cstore
.get_item_mir(self.global_tcx(), did
);
2455 let mir
= self.alloc_mir(mir
);
2457 // Perma-borrow MIR from extern crates to prevent mutation.
2458 mem
::forget(mir
.borrow());
2464 /// If `type_needs_drop` returns true, then `ty` is definitely
2465 /// non-copy and *might* have a destructor attached; if it returns
2466 /// false, then `ty` definitely has no destructor (i.e. no drop glue).
2468 /// (Note that this implies that if `ty` has a destructor attached,
2469 /// then `type_needs_drop` will definitely return `true` for `ty`.)
2470 pub fn type_needs_drop_given_env(self,
2472 param_env
: &ty
::ParameterEnvironment
<'gcx
>) -> bool
{
2473 // Issue #22536: We first query type_moves_by_default. It sees a
2474 // normalized version of the type, and therefore will definitely
2475 // know whether the type implements Copy (and thus needs no
2476 // cleanup/drop/zeroing) ...
2477 let tcx
= self.global_tcx();
2478 let implements_copy
= !ty
.moves_by_default(tcx
, param_env
, DUMMY_SP
);
2480 if implements_copy { return false; }
2482 // ... (issue #22536 continued) but as an optimization, still use
2483 // prior logic of asking if the `needs_drop` bit is set; we need
2484 // not zero non-Copy types if they have no destructor.
2486 // FIXME(#22815): Note that calling `ty::type_contents` is a
2487 // conservative heuristic; it may report that `needs_drop` is set
2488 // when actual type does not actually have a destructor associated
2489 // with it. But since `ty` absolutely did not have the `Copy`
2490 // bound attached (see above), it is sound to treat it as having a
2491 // destructor (e.g. zero its memory on move).
2493 let contents
= ty
.type_contents(tcx
);
2494 debug
!("type_needs_drop ty={:?} contents={:?}", ty
, contents
);
2495 contents
.needs_drop(tcx
)
2498 /// Get the attributes of a definition.
2499 pub fn get_attrs(self, did
: DefId
) -> Cow
<'gcx
, [ast
::Attribute
]> {
2500 if let Some(id
) = self.map
.as_local_node_id(did
) {
2501 Cow
::Borrowed(self.map
.attrs(id
))
2503 Cow
::Owned(self.sess
.cstore
.item_attrs(did
))
2507 /// Determine whether an item is annotated with an attribute
2508 pub fn has_attr(self, did
: DefId
, attr
: &str) -> bool
{
2509 self.get_attrs(did
).iter().any(|item
| item
.check_name(attr
))
2512 /// Determine whether an item is annotated with `#[repr(packed)]`
2513 pub fn lookup_packed(self, did
: DefId
) -> bool
{
2514 self.lookup_repr_hints(did
).contains(&attr
::ReprPacked
)
2517 /// Determine whether an item is annotated with `#[simd]`
2518 pub fn lookup_simd(self, did
: DefId
) -> bool
{
2519 self.has_attr(did
, "simd")
2520 || self.lookup_repr_hints(did
).contains(&attr
::ReprSimd
)
2523 pub fn item_variances(self, item_id
: DefId
) -> Rc
<Vec
<ty
::Variance
>> {
2524 lookup_locally_or_in_crate_store(
2525 "item_variance_map", item_id
, &self.item_variance_map
,
2526 || Rc
::new(self.sess
.cstore
.item_variances(item_id
)))
2529 pub fn trait_has_default_impl(self, trait_def_id
: DefId
) -> bool
{
2530 self.populate_implementations_for_trait_if_necessary(trait_def_id
);
2532 let def
= self.lookup_trait_def(trait_def_id
);
2533 def
.flags
.get().intersects(TraitFlags
::HAS_DEFAULT_IMPL
)
2536 /// Records a trait-to-implementation mapping.
2537 pub fn record_trait_has_default_impl(self, trait_def_id
: DefId
) {
2538 let def
= self.lookup_trait_def(trait_def_id
);
2539 def
.flags
.set(def
.flags
.get() | TraitFlags
::HAS_DEFAULT_IMPL
)
2542 /// Load primitive inherent implementations if necessary
2543 pub fn populate_implementations_for_primitive_if_necessary(self,
2544 primitive_def_id
: DefId
) {
2545 if primitive_def_id
.is_local() {
2549 // The primitive is not local, hence we are reading this out
2551 let _ignore
= self.dep_graph
.in_ignore();
2553 if self.populated_external_primitive_impls
.borrow().contains(&primitive_def_id
) {
2557 debug
!("populate_implementations_for_primitive_if_necessary: searching for {:?}",
2560 let impl_items
= self.sess
.cstore
.impl_or_trait_items(primitive_def_id
);
2562 // Store the implementation info.
2563 self.impl_or_trait_item_def_ids
.borrow_mut().insert(primitive_def_id
, Rc
::new(impl_items
));
2564 self.populated_external_primitive_impls
.borrow_mut().insert(primitive_def_id
);
2567 /// Populates the type context with all the inherent implementations for
2568 /// the given type if necessary.
2569 pub fn populate_inherent_implementations_for_type_if_necessary(self,
2571 if type_id
.is_local() {
2575 // The type is not local, hence we are reading this out of
2576 // metadata and don't need to track edges.
2577 let _ignore
= self.dep_graph
.in_ignore();
2579 if self.populated_external_types
.borrow().contains(&type_id
) {
2583 debug
!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}",
2586 let inherent_impls
= self.sess
.cstore
.inherent_implementations_for_type(type_id
);
2587 for &impl_def_id
in &inherent_impls
{
2588 // Store the implementation info.
2589 let impl_items
= self.sess
.cstore
.impl_or_trait_items(impl_def_id
);
2590 self.impl_or_trait_item_def_ids
.borrow_mut().insert(impl_def_id
, Rc
::new(impl_items
));
2593 self.inherent_impls
.borrow_mut().insert(type_id
, inherent_impls
);
2594 self.populated_external_types
.borrow_mut().insert(type_id
);
2597 /// Populates the type context with all the implementations for the given
2598 /// trait if necessary.
2599 pub fn populate_implementations_for_trait_if_necessary(self, trait_id
: DefId
) {
2600 if trait_id
.is_local() {
2604 // The type is not local, hence we are reading this out of
2605 // metadata and don't need to track edges.
2606 let _ignore
= self.dep_graph
.in_ignore();
2608 let def
= self.lookup_trait_def(trait_id
);
2609 if def
.flags
.get().intersects(TraitFlags
::IMPLS_VALID
) {
2613 debug
!("populate_implementations_for_trait_if_necessary: searching for {:?}", def
);
2615 if self.sess
.cstore
.is_defaulted_trait(trait_id
) {
2616 self.record_trait_has_default_impl(trait_id
);
2619 for impl_def_id
in self.sess
.cstore
.implementations_of_trait(Some(trait_id
)) {
2620 let impl_items
= self.sess
.cstore
.impl_or_trait_items(impl_def_id
);
2621 let trait_ref
= self.impl_trait_ref(impl_def_id
).unwrap();
2623 // Record the trait->implementation mapping.
2624 let parent
= self.sess
.cstore
.impl_parent(impl_def_id
).unwrap_or(trait_id
);
2625 def
.record_remote_impl(self, impl_def_id
, trait_ref
, parent
);
2627 // For any methods that use a default implementation, add them to
2628 // the map. This is a bit unfortunate.
2629 for &impl_item_def_id
in &impl_items
{
2630 // load impl items eagerly for convenience
2631 // FIXME: we may want to load these lazily
2632 self.impl_or_trait_item(impl_item_def_id
);
2635 // Store the implementation info.
2636 self.impl_or_trait_item_def_ids
.borrow_mut().insert(impl_def_id
, Rc
::new(impl_items
));
2639 def
.flags
.set(def
.flags
.get() | TraitFlags
::IMPLS_VALID
);
2642 pub fn closure_kind(self, def_id
: DefId
) -> ty
::ClosureKind
{
2643 // If this is a local def-id, it should be inserted into the
2644 // tables by typeck; else, it will be retreived from
2645 // the external crate metadata.
2646 if let Some(&kind
) = self.tables
.borrow().closure_kinds
.get(&def_id
) {
2650 let kind
= self.sess
.cstore
.closure_kind(def_id
);
2651 self.tables
.borrow_mut().closure_kinds
.insert(def_id
, kind
);
2655 pub fn closure_type(self,
2657 substs
: ClosureSubsts
<'tcx
>)
2658 -> ty
::ClosureTy
<'tcx
>
2660 // If this is a local def-id, it should be inserted into the
2661 // tables by typeck; else, it will be retreived from
2662 // the external crate metadata.
2663 if let Some(ty
) = self.tables
.borrow().closure_tys
.get(&def_id
) {
2664 return ty
.subst(self, substs
.func_substs
);
2667 let ty
= self.sess
.cstore
.closure_ty(self.global_tcx(), def_id
);
2668 self.tables
.borrow_mut().closure_tys
.insert(def_id
, ty
.clone());
2669 ty
.subst(self, substs
.func_substs
)
2672 /// Given the def_id of an impl, return the def_id of the trait it implements.
2673 /// If it implements no trait, return `None`.
2674 pub fn trait_id_of_impl(self, def_id
: DefId
) -> Option
<DefId
> {
2675 self.impl_trait_ref(def_id
).map(|tr
| tr
.def_id
)
2678 /// If the given def ID describes a method belonging to an impl, return the
2679 /// ID of the impl that the method belongs to. Otherwise, return `None`.
2680 pub fn impl_of_method(self, def_id
: DefId
) -> Option
<DefId
> {
2681 if def_id
.krate
!= LOCAL_CRATE
{
2682 return self.sess
.cstore
.impl_or_trait_item(self.global_tcx(), def_id
)
2684 match item
.container() {
2685 TraitContainer(_
) => None
,
2686 ImplContainer(def_id
) => Some(def_id
),
2690 match self.impl_or_trait_items
.borrow().get(&def_id
).cloned() {
2691 Some(trait_item
) => {
2692 match trait_item
.container() {
2693 TraitContainer(_
) => None
,
2694 ImplContainer(def_id
) => Some(def_id
),
2701 /// If the given def ID describes an item belonging to a trait,
2702 /// return the ID of the trait that the trait item belongs to.
2703 /// Otherwise, return `None`.
2704 pub fn trait_of_item(self, def_id
: DefId
) -> Option
<DefId
> {
2705 if def_id
.krate
!= LOCAL_CRATE
{
2706 return self.sess
.cstore
.trait_of_item(def_id
);
2708 match self.impl_or_trait_items
.borrow().get(&def_id
) {
2709 Some(impl_or_trait_item
) => {
2710 match impl_or_trait_item
.container() {
2711 TraitContainer(def_id
) => Some(def_id
),
2712 ImplContainer(_
) => None
2719 /// If the given def ID describes an item belonging to a trait, (either a
2720 /// default method or an implementation of a trait method), return the ID of
2721 /// the method inside trait definition (this means that if the given def ID
2722 /// is already that of the original trait method, then the return value is
2724 /// Otherwise, return `None`.
2725 pub fn trait_item_of_item(self, def_id
: DefId
) -> Option
<DefId
> {
2726 let impl_or_trait_item
= match self.impl_or_trait_items
.borrow().get(&def_id
) {
2727 Some(m
) => m
.clone(),
2728 None
=> return None
,
2730 match impl_or_trait_item
.container() {
2731 TraitContainer(_
) => Some(impl_or_trait_item
.def_id()),
2732 ImplContainer(def_id
) => {
2733 self.trait_id_of_impl(def_id
).and_then(|trait_did
| {
2734 let name
= impl_or_trait_item
.name();
2735 self.trait_items(trait_did
).iter()
2736 .find(|item
| item
.name() == name
)
2737 .map(|item
| item
.def_id())
2743 /// Construct a parameter environment suitable for static contexts or other contexts where there
2744 /// are no free type/lifetime parameters in scope.
2745 pub fn empty_parameter_environment(self) -> ParameterEnvironment
<'tcx
> {
2747 // for an empty parameter environment, there ARE no free
2748 // regions, so it shouldn't matter what we use for the free id
2749 let free_id_outlive
= self.region_maps
.node_extent(ast
::DUMMY_NODE_ID
);
2750 ty
::ParameterEnvironment
{
2751 free_substs
: self.intern_substs(&[]),
2752 caller_bounds
: Vec
::new(),
2753 implicit_region_bound
: self.mk_region(ty
::ReEmpty
),
2754 free_id_outlive
: free_id_outlive
,
2755 is_copy_cache
: RefCell
::new(FnvHashMap()),
2756 is_sized_cache
: RefCell
::new(FnvHashMap()),
2760 /// Constructs and returns a substitution that can be applied to move from
2761 /// the "outer" view of a type or method to the "inner" view.
2762 /// In general, this means converting from bound parameters to
2763 /// free parameters. Since we currently represent bound/free type
2764 /// parameters in the same way, this only has an effect on regions.
2765 pub fn construct_free_substs(self, def_id
: DefId
,
2766 free_id_outlive
: CodeExtent
)
2767 -> &'gcx Substs
<'gcx
> {
2769 let substs
= Substs
::for_item(self.global_tcx(), def_id
, |def
, _
| {
2770 // map bound 'a => free 'a
2771 self.global_tcx().mk_region(ReFree(FreeRegion
{
2772 scope
: free_id_outlive
,
2773 bound_region
: def
.to_bound_region()
2777 self.global_tcx().mk_param_from_def(def
)
2780 debug
!("construct_parameter_environment: {:?}", substs
);
2784 /// See `ParameterEnvironment` struct def'n for details.
2785 /// If you were using `free_id: NodeId`, you might try `self.region_maps.item_extent(free_id)`
2786 /// for the `free_id_outlive` parameter. (But note that this is not always quite right.)
2787 pub fn construct_parameter_environment(self,
2790 free_id_outlive
: CodeExtent
)
2791 -> ParameterEnvironment
<'gcx
>
2794 // Construct the free substs.
2797 let free_substs
= self.construct_free_substs(def_id
, free_id_outlive
);
2800 // Compute the bounds on Self and the type parameters.
2803 let tcx
= self.global_tcx();
2804 let generic_predicates
= tcx
.lookup_predicates(def_id
);
2805 let bounds
= generic_predicates
.instantiate(tcx
, free_substs
);
2806 let bounds
= tcx
.liberate_late_bound_regions(free_id_outlive
, &ty
::Binder(bounds
));
2807 let predicates
= bounds
.predicates
;
2809 // Finally, we have to normalize the bounds in the environment, in
2810 // case they contain any associated type projections. This process
2811 // can yield errors if the put in illegal associated types, like
2812 // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
2813 // report these errors right here; this doesn't actually feel
2814 // right to me, because constructing the environment feels like a
2815 // kind of a "idempotent" action, but I'm not sure where would be
2816 // a better place. In practice, we construct environments for
2817 // every fn once during type checking, and we'll abort if there
2818 // are any errors at that point, so after type checking you can be
2819 // sure that this will succeed without errors anyway.
2822 let unnormalized_env
= ty
::ParameterEnvironment
{
2823 free_substs
: free_substs
,
2824 implicit_region_bound
: tcx
.mk_region(ty
::ReScope(free_id_outlive
)),
2825 caller_bounds
: predicates
,
2826 free_id_outlive
: free_id_outlive
,
2827 is_copy_cache
: RefCell
::new(FnvHashMap()),
2828 is_sized_cache
: RefCell
::new(FnvHashMap()),
2831 let cause
= traits
::ObligationCause
::misc(span
, free_id_outlive
.node_id(&self.region_maps
));
2832 traits
::normalize_param_env_or_error(tcx
, unnormalized_env
, cause
)
2835 pub fn node_scope_region(self, id
: NodeId
) -> &'tcx Region
{
2836 self.mk_region(ty
::ReScope(self.region_maps
.node_extent(id
)))
2839 pub fn visit_all_items_in_krate
<V
,F
>(self,
2842 where F
: FnMut(DefId
) -> DepNode
<DefId
>, V
: Visitor
<'gcx
>
2844 dep_graph
::visit_all_items_in_krate(self.global_tcx(), dep_node_fn
, visitor
);
2847 /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
2848 /// with the name of the crate containing the impl.
2849 pub fn span_of_impl(self, impl_did
: DefId
) -> Result
<Span
, InternedString
> {
2850 if impl_did
.is_local() {
2851 let node_id
= self.map
.as_local_node_id(impl_did
).unwrap();
2852 Ok(self.map
.span(node_id
))
2854 Err(self.sess
.cstore
.crate_name(impl_did
.krate
))
2859 /// The category of explicit self.
2860 #[derive(Clone, Copy, Eq, PartialEq, Debug, RustcEncodable, RustcDecodable)]
2861 pub enum ExplicitSelfCategory
<'tcx
> {
2864 ByReference(&'tcx Region
, hir
::Mutability
),
2868 impl<'a
, 'gcx
, 'tcx
> TyCtxt
<'a
, 'gcx
, 'tcx
> {
2869 pub fn with_freevars
<T
, F
>(self, fid
: NodeId
, f
: F
) -> T
where
2870 F
: FnOnce(&[hir
::Freevar
]) -> T
,
2872 match self.freevars
.borrow().get(&fid
) {
2874 Some(d
) => f(&d
[..])