1 // Copyright 2012-2014 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 #![allow(non_camel_case_types)]
13 pub use self::terr_vstore_kind
::*;
14 pub use self::type_err
::*;
15 pub use self::InferTy
::*;
16 pub use self::InferRegion
::*;
17 pub use self::ImplOrTraitItemId
::*;
18 pub use self::ClosureKind
::*;
19 pub use self::Variance
::*;
20 pub use self::AutoAdjustment
::*;
21 pub use self::Representability
::*;
22 pub use self::AutoRef
::*;
23 pub use self::DtorKind
::*;
24 pub use self::ExplicitSelfCategory
::*;
25 pub use self::FnOutput
::*;
26 pub use self::Region
::*;
27 pub use self::ImplOrTraitItemContainer
::*;
28 pub use self::BorrowKind
::*;
29 pub use self::ImplOrTraitItem
::*;
30 pub use self::BoundRegion
::*;
31 pub use self::TypeVariants
::*;
32 pub use self::IntVarValue
::*;
33 pub use self::MethodOrigin
::*;
34 pub use self::CopyImplementationError
::*;
36 pub use self::BuiltinBound
::Send
as BoundSend
;
37 pub use self::BuiltinBound
::Sized
as BoundSized
;
38 pub use self::BuiltinBound
::Copy
as BoundCopy
;
39 pub use self::BuiltinBound
::Sync
as BoundSync
;
41 use ast_map
::{self, LinkedPath}
;
45 use metadata
::csearch
;
48 use middle
::check_const
;
49 use middle
::const_eval
::{self, ConstVal}
;
50 use middle
::def
::{self, DefMap, ExportMap}
;
51 use middle
::dependency_format
;
52 use middle
::fast_reject
;
53 use middle
::free_region
::FreeRegionMap
;
54 use middle
::infer
::error_reporting
::note_and_explain_region
;
55 use middle
::lang_items
::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}
;
56 use middle
::mem_categorization
as mc
;
58 use middle
::resolve_lifetime
;
61 use middle
::region
::RegionMaps
;
62 use middle
::stability
;
63 use middle
::subst
::{self, ParamSpace, Subst, Substs, VecPerParamSpace}
;
66 use middle
::ty_fold
::{self, TypeFoldable, TypeFolder}
;
67 use middle
::ty_walk
::{self, TypeWalker}
;
68 use util
::common
::{memoized, ErrorReported}
;
69 use util
::nodemap
::{NodeMap, NodeSet, DefIdMap, DefIdSet}
;
70 use util
::nodemap
::FnvHashMap
;
71 use util
::num
::ToPrimitive
;
73 use arena
::TypedArena
;
74 use std
::borrow
::{Borrow, Cow}
;
75 use std
::cell
::{Cell, RefCell, Ref}
;
78 use std
::hash
::{Hash, SipHasher, Hasher}
;
82 use std
::vec
::IntoIter
;
83 use collections
::enum_set
::{self, EnumSet, CLike}
;
84 use std
::collections
::{HashMap, HashSet}
;
86 use syntax
::ast
::{CrateNum, DefId, ItemImpl, ItemTrait, LOCAL_CRATE}
;
87 use syntax
::ast
::{MutImmutable, MutMutable, Name, NamedField, NodeId}
;
88 use syntax
::ast
::{StmtExpr, StmtSemi, StructField, UnnamedField, Visibility}
;
89 use syntax
::ast_util
::{self, is_local, local_def}
;
90 use syntax
::attr
::{self, AttrMetaMethods, SignedInt, UnsignedInt}
;
91 use syntax
::codemap
::Span
;
92 use syntax
::parse
::token
::{self, InternedString, special_idents}
;
93 use syntax
::print
::pprust
;
99 pub const INITIAL_DISCRIMINANT_VALUE
: Disr
= 0;
103 /// The complete set of all analyses described in this module. This is
104 /// produced by the driver and fed to trans and later passes.
105 pub struct CrateAnalysis
{
106 pub export_map
: ExportMap
,
107 pub exported_items
: middle
::privacy
::ExportedItems
,
108 pub public_items
: middle
::privacy
::PublicItems
,
109 pub reachable
: NodeSet
,
111 pub glob_map
: Option
<GlobMap
>,
114 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
115 pub struct field
<'tcx
> {
120 #[derive(Clone, Copy, Debug)]
121 pub enum ImplOrTraitItemContainer
{
122 TraitContainer(ast
::DefId
),
123 ImplContainer(ast
::DefId
),
126 impl ImplOrTraitItemContainer
{
127 pub fn id(&self) -> ast
::DefId
{
129 TraitContainer(id
) => id
,
130 ImplContainer(id
) => id
,
136 pub enum ImplOrTraitItem
<'tcx
> {
137 ConstTraitItem(Rc
<AssociatedConst
<'tcx
>>),
138 MethodTraitItem(Rc
<Method
<'tcx
>>),
139 TypeTraitItem(Rc
<AssociatedType
<'tcx
>>),
142 impl<'tcx
> ImplOrTraitItem
<'tcx
> {
143 fn id(&self) -> ImplOrTraitItemId
{
145 ConstTraitItem(ref associated_const
) => {
146 ConstTraitItemId(associated_const
.def_id
)
148 MethodTraitItem(ref method
) => MethodTraitItemId(method
.def_id
),
149 TypeTraitItem(ref associated_type
) => {
150 TypeTraitItemId(associated_type
.def_id
)
155 pub fn def_id(&self) -> ast
::DefId
{
157 ConstTraitItem(ref associated_const
) => associated_const
.def_id
,
158 MethodTraitItem(ref method
) => method
.def_id
,
159 TypeTraitItem(ref associated_type
) => associated_type
.def_id
,
163 pub fn name(&self) -> ast
::Name
{
165 ConstTraitItem(ref associated_const
) => associated_const
.name
,
166 MethodTraitItem(ref method
) => method
.name
,
167 TypeTraitItem(ref associated_type
) => associated_type
.name
,
171 pub fn vis(&self) -> ast
::Visibility
{
173 ConstTraitItem(ref associated_const
) => associated_const
.vis
,
174 MethodTraitItem(ref method
) => method
.vis
,
175 TypeTraitItem(ref associated_type
) => associated_type
.vis
,
179 pub fn container(&self) -> ImplOrTraitItemContainer
{
181 ConstTraitItem(ref associated_const
) => associated_const
.container
,
182 MethodTraitItem(ref method
) => method
.container
,
183 TypeTraitItem(ref associated_type
) => associated_type
.container
,
187 pub fn as_opt_method(&self) -> Option
<Rc
<Method
<'tcx
>>> {
189 MethodTraitItem(ref m
) => Some((*m
).clone()),
195 #[derive(Clone, Copy, Debug)]
196 pub enum ImplOrTraitItemId
{
197 ConstTraitItemId(ast
::DefId
),
198 MethodTraitItemId(ast
::DefId
),
199 TypeTraitItemId(ast
::DefId
),
202 impl ImplOrTraitItemId
{
203 pub fn def_id(&self) -> ast
::DefId
{
205 ConstTraitItemId(def_id
) => def_id
,
206 MethodTraitItemId(def_id
) => def_id
,
207 TypeTraitItemId(def_id
) => def_id
,
212 #[derive(Clone, Debug)]
213 pub struct Method
<'tcx
> {
215 pub generics
: Generics
<'tcx
>,
216 pub predicates
: GenericPredicates
<'tcx
>,
217 pub fty
: BareFnTy
<'tcx
>,
218 pub explicit_self
: ExplicitSelfCategory
,
219 pub vis
: ast
::Visibility
,
220 pub def_id
: ast
::DefId
,
221 pub container
: ImplOrTraitItemContainer
,
223 // If this method is provided, we need to know where it came from
224 pub provided_source
: Option
<ast
::DefId
>
227 impl<'tcx
> Method
<'tcx
> {
228 pub fn new(name
: ast
::Name
,
229 generics
: ty
::Generics
<'tcx
>,
230 predicates
: GenericPredicates
<'tcx
>,
232 explicit_self
: ExplicitSelfCategory
,
233 vis
: ast
::Visibility
,
235 container
: ImplOrTraitItemContainer
,
236 provided_source
: Option
<ast
::DefId
>)
241 predicates
: predicates
,
243 explicit_self
: explicit_self
,
246 container
: container
,
247 provided_source
: provided_source
251 pub fn container_id(&self) -> ast
::DefId
{
252 match self.container
{
253 TraitContainer(id
) => id
,
254 ImplContainer(id
) => id
,
259 #[derive(Clone, Copy, Debug)]
260 pub struct AssociatedConst
<'tcx
> {
263 pub vis
: ast
::Visibility
,
264 pub def_id
: ast
::DefId
,
265 pub container
: ImplOrTraitItemContainer
,
266 pub default: Option
<ast
::DefId
>,
269 #[derive(Clone, Copy, Debug)]
270 pub struct AssociatedType
<'tcx
> {
272 pub ty
: Option
<Ty
<'tcx
>>,
273 pub vis
: ast
::Visibility
,
274 pub def_id
: ast
::DefId
,
275 pub container
: ImplOrTraitItemContainer
,
278 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
279 pub struct mt
<'tcx
> {
281 pub mutbl
: ast
::Mutability
,
284 #[derive(Clone, Copy, Debug)]
285 pub struct field_ty
{
288 pub vis
: ast
::Visibility
,
289 pub origin
: ast
::DefId
, // The DefId of the struct in which the field is declared.
292 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable)]
293 pub struct ItemVariances
{
294 pub types
: VecPerParamSpace
<Variance
>,
295 pub regions
: VecPerParamSpace
<Variance
>,
298 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Copy)]
300 Covariant
, // T<A> <: T<B> iff A <: B -- e.g., function return type
301 Invariant
, // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
302 Contravariant
, // T<A> <: T<B> iff B <: A -- e.g., function param type
303 Bivariant
, // T<A> <: T<B> -- e.g., unused type parameter
306 #[derive(Copy, Clone)]
307 pub enum AutoAdjustment
<'tcx
> {
308 AdjustReifyFnPointer
, // go from a fn-item type to a fn-pointer type
309 AdjustUnsafeFnPointer
, // go from a safe fn pointer to an unsafe fn pointer
310 AdjustDerefRef(AutoDerefRef
<'tcx
>),
313 /// Represents coercing a pointer to a different kind of pointer - where 'kind'
314 /// here means either or both of raw vs borrowed vs unique and fat vs thin.
316 /// We transform pointers by following the following steps in order:
317 /// 1. Deref the pointer `self.autoderefs` times (may be 0).
318 /// 2. If `autoref` is `Some(_)`, then take the address and produce either a
319 /// `&` or `*` pointer.
320 /// 3. If `unsize` is `Some(_)`, then apply the unsize transformation,
321 /// which will do things like convert thin pointers to fat
322 /// pointers, or convert structs containing thin pointers to
323 /// structs containing fat pointers, or convert between fat
324 /// pointers. We don't store the details of how the transform is
325 /// done (in fact, we don't know that, because it might depend on
326 /// the precise type parameters). We just store the target
327 /// type. Trans figures out what has to be done at monomorphization
328 /// time based on the precise source/target type at hand.
330 /// To make that more concrete, here are some common scenarios:
332 /// 1. The simplest cases are where the pointer is not adjusted fat vs thin.
333 /// Here the pointer will be dereferenced N times (where a dereference can
334 /// happen to to raw or borrowed pointers or any smart pointer which implements
335 /// Deref, including Box<_>). The number of dereferences is given by
336 /// `autoderefs`. It can then be auto-referenced zero or one times, indicated
337 /// by `autoref`, to either a raw or borrowed pointer. In these cases unsize is
340 /// 2. A thin-to-fat coercon involves unsizing the underlying data. We start
341 /// with a thin pointer, deref a number of times, unsize the underlying data,
342 /// then autoref. The 'unsize' phase may change a fixed length array to a
343 /// dynamically sized one, a concrete object to a trait object, or statically
344 /// sized struct to a dyncamically sized one. E.g., &[i32; 4] -> &[i32] is
349 /// autoderefs: 1, // &[i32; 4] -> [i32; 4]
350 /// autoref: Some(AutoPtr), // [i32] -> &[i32]
351 /// unsize: Some([i32]), // [i32; 4] -> [i32]
355 /// Note that for a struct, the 'deep' unsizing of the struct is not recorded.
356 /// E.g., `struct Foo<T> { x: T }` we can coerce &Foo<[i32; 4]> to &Foo<[i32]>
357 /// The autoderef and -ref are the same as in the above example, but the type
358 /// stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about
359 /// the underlying conversions from `[i32; 4]` to `[i32]`.
361 /// 3. Coercing a `Box<T>` to `Box<Trait>` is an interesting special case. In
362 /// that case, we have the pointer we need coming in, so there are no
363 /// autoderefs, and no autoref. Instead we just do the `Unsize` transformation.
364 /// At some point, of course, `Box` should move out of the compiler, in which
365 /// case this is analogous to transformating a struct. E.g., Box<[i32; 4]> ->
366 /// Box<[i32]> is represented by:
372 /// unsize: Some(Box<[i32]>),
375 #[derive(Copy, Clone)]
376 pub struct AutoDerefRef
<'tcx
> {
377 /// Step 1. Apply a number of dereferences, producing an lvalue.
378 pub autoderefs
: usize,
380 /// Step 2. Optionally produce a pointer/reference from the value.
381 pub autoref
: Option
<AutoRef
<'tcx
>>,
383 /// Step 3. Unsize a pointer/reference value, e.g. `&[T; n]` to
384 /// `&[T]`. The stored type is the target pointer type. Note that
385 /// the source could be a thin or fat pointer.
386 pub unsize
: Option
<Ty
<'tcx
>>,
389 #[derive(Copy, Clone, PartialEq, Debug)]
390 pub enum AutoRef
<'tcx
> {
391 /// Convert from T to &T.
392 AutoPtr(&'tcx Region
, ast
::Mutability
),
394 /// Convert from T to *T.
395 /// Value to thin pointer.
396 AutoUnsafe(ast
::Mutability
),
399 #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
400 pub enum CustomCoerceUnsized
{
401 /// Records the index of the field being coerced.
406 pub enum MethodOrigin
<'tcx
> {
407 // fully statically resolved method
408 MethodStatic(ast
::DefId
),
410 // fully statically resolved closure invocation
411 MethodStaticClosure(ast
::DefId
),
413 // method invoked on a type parameter with a bounded trait
414 MethodTypeParam(MethodParam
<'tcx
>),
416 // method invoked on a trait instance
417 MethodTraitObject(MethodObject
<'tcx
>),
421 // details for a method invoked with a receiver whose type is a type parameter
422 // with a bounded trait.
424 pub struct MethodParam
<'tcx
> {
425 // the precise trait reference that occurs as a bound -- this may
426 // be a supertrait of what the user actually typed. Note that it
427 // never contains bound regions; those regions should have been
428 // instantiated with fresh variables at this point.
429 pub trait_ref
: ty
::TraitRef
<'tcx
>,
431 // index of usize in the list of trait items. Note that this is NOT
432 // the index into the vtable, because the list of trait items
433 // includes associated types.
434 pub method_num
: usize,
436 /// The impl for the trait from which the method comes. This
437 /// should only be used for certain linting/heuristic purposes
438 /// since there is no guarantee that this is Some in every
439 /// situation that it could/should be.
440 pub impl_def_id
: Option
<ast
::DefId
>,
443 // details for a method invoked with a receiver whose type is an object
445 pub struct MethodObject
<'tcx
> {
446 // the (super)trait containing the method to be invoked
447 pub trait_ref
: TraitRef
<'tcx
>,
449 // the actual base trait id of the object
450 pub object_trait_id
: ast
::DefId
,
452 // index of the method to be invoked amongst the trait's items
453 pub method_num
: usize,
455 // index into the actual runtime vtable.
456 // the vtable is formed by concatenating together the method lists of
457 // the base object trait and all supertraits; this is the index into
459 pub vtable_index
: usize,
462 #[derive(Clone, Debug)]
463 pub struct MethodCallee
<'tcx
> {
464 pub origin
: MethodOrigin
<'tcx
>,
466 pub substs
: subst
::Substs
<'tcx
>
469 /// With method calls, we store some extra information in
470 /// side tables (i.e method_map). We use
471 /// MethodCall as a key to index into these tables instead of
472 /// just directly using the expression's NodeId. The reason
473 /// for this being that we may apply adjustments (coercions)
474 /// with the resulting expression also needing to use the
475 /// side tables. The problem with this is that we don't
476 /// assign a separate NodeId to this new expression
477 /// and so it would clash with the base expression if both
478 /// needed to add to the side tables. Thus to disambiguate
479 /// we also keep track of whether there's an adjustment in
481 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
482 pub struct MethodCall
{
483 pub expr_id
: ast
::NodeId
,
488 pub fn expr(id
: ast
::NodeId
) -> MethodCall
{
495 pub fn autoderef(expr_id
: ast
::NodeId
, autoderef
: u32) -> MethodCall
{
498 autoderef
: 1 + autoderef
503 // maps from an expression id that corresponds to a method call to the details
504 // of the method to be invoked
505 pub type MethodMap
<'tcx
> = RefCell
<FnvHashMap
<MethodCall
, MethodCallee
<'tcx
>>>;
507 // Contains information needed to resolve types and (in the future) look up
508 // the types of AST nodes.
509 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
510 pub struct creader_cache_key
{
516 /// A restriction that certain types must be the same size. The use of
517 /// `transmute` gives rise to these restrictions. These generally
518 /// cannot be checked until trans; therefore, each call to `transmute`
519 /// will push one or more such restriction into the
520 /// `transmute_restrictions` vector during `intrinsicck`. They are
521 /// then checked during `trans` by the fn `check_intrinsics`.
522 #[derive(Copy, Clone)]
523 pub struct TransmuteRestriction
<'tcx
> {
524 /// The span whence the restriction comes.
527 /// The type being transmuted from.
528 pub original_from
: Ty
<'tcx
>,
530 /// The type being transmuted to.
531 pub original_to
: Ty
<'tcx
>,
533 /// The type being transmuted from, with all type parameters
534 /// substituted for an arbitrary representative. Not to be shown
536 pub substituted_from
: Ty
<'tcx
>,
538 /// The type being transmuted to, with all type parameters
539 /// substituted for an arbitrary representative. Not to be shown
541 pub substituted_to
: Ty
<'tcx
>,
543 /// NodeId of the transmute intrinsic.
548 pub struct CtxtArenas
<'tcx
> {
550 type_
: TypedArena
<TyS
<'tcx
>>,
551 substs
: TypedArena
<Substs
<'tcx
>>,
552 bare_fn
: TypedArena
<BareFnTy
<'tcx
>>,
553 region
: TypedArena
<Region
>,
554 stability
: TypedArena
<attr
::Stability
>,
557 trait_defs
: TypedArena
<TraitDef
<'tcx
>>,
560 impl<'tcx
> CtxtArenas
<'tcx
> {
561 pub fn new() -> CtxtArenas
<'tcx
> {
563 type_
: TypedArena
::new(),
564 substs
: TypedArena
::new(),
565 bare_fn
: TypedArena
::new(),
566 region
: TypedArena
::new(),
567 stability
: TypedArena
::new(),
569 trait_defs
: TypedArena
::new()
574 pub struct CommonTypes
<'tcx
> {
592 /// The data structure to keep track of all the information that typechecker
593 /// generates so that so that it can be reused and doesn't have to be redone
595 pub struct ctxt
<'tcx
> {
596 /// The arenas that types etc are allocated from.
597 arenas
: &'tcx CtxtArenas
<'tcx
>,
599 /// Specifically use a speedy hash algorithm for this hash map, it's used
601 // FIXME(eddyb) use a FnvHashSet<InternedTy<'tcx>> when equivalent keys can
602 // queried from a HashSet.
603 interner
: RefCell
<FnvHashMap
<InternedTy
<'tcx
>, Ty
<'tcx
>>>,
605 // FIXME as above, use a hashset if equivalent elements can be queried.
606 substs_interner
: RefCell
<FnvHashMap
<&'tcx Substs
<'tcx
>, &'tcx Substs
<'tcx
>>>,
607 bare_fn_interner
: RefCell
<FnvHashMap
<&'tcx BareFnTy
<'tcx
>, &'tcx BareFnTy
<'tcx
>>>,
608 region_interner
: RefCell
<FnvHashMap
<&'tcx Region
, &'tcx Region
>>,
609 stability_interner
: RefCell
<FnvHashMap
<&'tcx attr
::Stability
, &'tcx attr
::Stability
>>,
611 /// Common types, pre-interned for your convenience.
612 pub types
: CommonTypes
<'tcx
>,
617 pub named_region_map
: resolve_lifetime
::NamedRegionMap
,
619 pub region_maps
: RegionMaps
,
621 // For each fn declared in the local crate, type check stores the
622 // free-region relationships that were deduced from its where
623 // clauses and parameter types. These are then read-again by
624 // borrowck. (They are not used during trans, and hence are not
625 // serialized or needed for cross-crate fns.)
626 free_region_maps
: RefCell
<NodeMap
<FreeRegionMap
>>,
628 /// Stores the types for various nodes in the AST. Note that this table
629 /// is not guaranteed to be populated until after typeck. See
630 /// typeck::check::fn_ctxt for details.
631 node_types
: RefCell
<NodeMap
<Ty
<'tcx
>>>,
633 /// Stores the type parameters which were substituted to obtain the type
634 /// of this node. This only applies to nodes that refer to entities
635 /// parameterized by type parameters, such as generic fns, types, or
637 pub item_substs
: RefCell
<NodeMap
<ItemSubsts
<'tcx
>>>,
639 /// Maps from a trait item to the trait item "descriptor"
640 pub impl_or_trait_items
: RefCell
<DefIdMap
<ImplOrTraitItem
<'tcx
>>>,
642 /// Maps from a trait def-id to a list of the def-ids of its trait items
643 pub trait_item_def_ids
: RefCell
<DefIdMap
<Rc
<Vec
<ImplOrTraitItemId
>>>>,
645 /// A cache for the trait_items() routine
646 pub trait_items_cache
: RefCell
<DefIdMap
<Rc
<Vec
<ImplOrTraitItem
<'tcx
>>>>>,
648 pub impl_trait_refs
: RefCell
<DefIdMap
<Option
<TraitRef
<'tcx
>>>>,
649 pub trait_defs
: RefCell
<DefIdMap
<&'tcx TraitDef
<'tcx
>>>,
651 /// Maps from the def-id of an item (trait/struct/enum/fn) to its
652 /// associated predicates.
653 pub predicates
: RefCell
<DefIdMap
<GenericPredicates
<'tcx
>>>,
655 /// Maps from the def-id of a trait to the list of
656 /// super-predicates. This is a subset of the full list of
657 /// predicates. We store these in a separate map because we must
658 /// evaluate them even during type conversion, often before the
659 /// full predicates are available (note that supertraits have
660 /// additional acyclicity requirements).
661 pub super_predicates
: RefCell
<DefIdMap
<GenericPredicates
<'tcx
>>>,
663 pub map
: ast_map
::Map
<'tcx
>,
664 pub freevars
: RefCell
<FreevarMap
>,
665 pub tcache
: RefCell
<DefIdMap
<TypeScheme
<'tcx
>>>,
666 pub rcache
: RefCell
<FnvHashMap
<creader_cache_key
, Ty
<'tcx
>>>,
667 pub tc_cache
: RefCell
<FnvHashMap
<Ty
<'tcx
>, TypeContents
>>,
668 pub ast_ty_to_ty_cache
: RefCell
<NodeMap
<Ty
<'tcx
>>>,
669 pub enum_var_cache
: RefCell
<DefIdMap
<Rc
<Vec
<Rc
<VariantInfo
<'tcx
>>>>>>,
670 pub ty_param_defs
: RefCell
<NodeMap
<TypeParameterDef
<'tcx
>>>,
671 pub adjustments
: RefCell
<NodeMap
<AutoAdjustment
<'tcx
>>>,
672 pub normalized_cache
: RefCell
<FnvHashMap
<Ty
<'tcx
>, Ty
<'tcx
>>>,
673 pub lang_items
: middle
::lang_items
::LanguageItems
,
674 /// A mapping of fake provided method def_ids to the default implementation
675 pub provided_method_sources
: RefCell
<DefIdMap
<ast
::DefId
>>,
676 pub struct_fields
: RefCell
<DefIdMap
<Rc
<Vec
<field_ty
>>>>,
678 /// Maps from def-id of a type or region parameter to its
679 /// (inferred) variance.
680 pub item_variance_map
: RefCell
<DefIdMap
<Rc
<ItemVariances
>>>,
682 /// True if the variance has been computed yet; false otherwise.
683 pub variance_computed
: Cell
<bool
>,
685 /// A mapping from the def ID of an enum or struct type to the def ID
686 /// of the method that implements its destructor. If the type is not
687 /// present in this map, it does not have a destructor. This map is
688 /// populated during the coherence phase of typechecking.
689 pub destructor_for_type
: RefCell
<DefIdMap
<ast
::DefId
>>,
691 /// A method will be in this list if and only if it is a destructor.
692 pub destructors
: RefCell
<DefIdSet
>,
694 /// Maps a DefId of a type to a list of its inherent impls.
695 /// Contains implementations of methods that are inherent to a type.
696 /// Methods in these implementations don't need to be exported.
697 pub inherent_impls
: RefCell
<DefIdMap
<Rc
<Vec
<ast
::DefId
>>>>,
699 /// Maps a DefId of an impl to a list of its items.
700 /// Note that this contains all of the impls that we know about,
701 /// including ones in other crates. It's not clear that this is the best
703 pub impl_items
: RefCell
<DefIdMap
<Vec
<ImplOrTraitItemId
>>>,
705 /// Set of used unsafe nodes (functions or blocks). Unsafe nodes not
706 /// present in this set can be warned about.
707 pub used_unsafe
: RefCell
<NodeSet
>,
709 /// Set of nodes which mark locals as mutable which end up getting used at
710 /// some point. Local variable definitions not in this set can be warned
712 pub used_mut_nodes
: RefCell
<NodeSet
>,
714 /// The set of external nominal types whose implementations have been read.
715 /// This is used for lazy resolution of methods.
716 pub populated_external_types
: RefCell
<DefIdSet
>,
717 /// The set of external primitive types whose implementations have been read.
718 /// FIXME(arielb1): why is this separate from populated_external_types?
719 pub populated_external_primitive_impls
: RefCell
<DefIdSet
>,
722 pub upvar_capture_map
: RefCell
<UpvarCaptureMap
>,
724 /// These caches are used by const_eval when decoding external constants.
725 pub extern_const_statics
: RefCell
<DefIdMap
<ast
::NodeId
>>,
726 pub extern_const_variants
: RefCell
<DefIdMap
<ast
::NodeId
>>,
727 pub extern_const_fns
: RefCell
<DefIdMap
<ast
::NodeId
>>,
729 pub method_map
: MethodMap
<'tcx
>,
731 pub dependency_formats
: RefCell
<dependency_format
::Dependencies
>,
733 /// Records the type of each closure. The def ID is the ID of the
734 /// expression defining the closure.
735 pub closure_kinds
: RefCell
<DefIdMap
<ClosureKind
>>,
737 /// Records the type of each closure. The def ID is the ID of the
738 /// expression defining the closure.
739 pub closure_tys
: RefCell
<DefIdMap
<ClosureTy
<'tcx
>>>,
741 pub node_lint_levels
: RefCell
<FnvHashMap
<(ast
::NodeId
, lint
::LintId
),
744 /// The types that must be asserted to be the same size for `transmute`
745 /// to be valid. We gather up these restrictions in the intrinsicck pass
746 /// and check them in trans.
747 pub transmute_restrictions
: RefCell
<Vec
<TransmuteRestriction
<'tcx
>>>,
749 /// Maps any item's def-id to its stability index.
750 pub stability
: RefCell
<stability
::Index
<'tcx
>>,
752 /// Caches the results of trait selection. This cache is used
753 /// for things that do not have to do with the parameters in scope.
754 pub selection_cache
: traits
::SelectionCache
<'tcx
>,
756 /// A set of predicates that have been fulfilled *somewhere*.
757 /// This is used to avoid duplicate work. Predicates are only
758 /// added to this set when they mention only "global" names
759 /// (i.e., no type or lifetime parameters).
760 pub fulfilled_predicates
: RefCell
<traits
::FulfilledPredicates
<'tcx
>>,
762 /// Caches the representation hints for struct definitions.
763 pub repr_hint_cache
: RefCell
<DefIdMap
<Rc
<Vec
<attr
::ReprAttr
>>>>,
765 /// Maps Expr NodeId's to their constant qualification.
766 pub const_qualif_map
: RefCell
<NodeMap
<check_const
::ConstQualif
>>,
768 /// Caches CoerceUnsized kinds for impls on custom types.
769 pub custom_coerce_unsized_kinds
: RefCell
<DefIdMap
<CustomCoerceUnsized
>>,
771 /// Maps a cast expression to its kind. This is keyed on the
772 /// *from* expression of the cast, not the cast itself.
773 pub cast_kinds
: RefCell
<NodeMap
<cast
::CastKind
>>,
776 impl<'tcx
> ctxt
<'tcx
> {
777 pub fn node_types(&self) -> Ref
<NodeMap
<Ty
<'tcx
>>> { self.node_types.borrow() }
778 pub fn node_type_insert(&self, id
: NodeId
, ty
: Ty
<'tcx
>) {
779 self.node_types
.borrow_mut().insert(id
, ty
);
782 pub fn intern_trait_def(&self, def
: TraitDef
<'tcx
>) -> &'tcx TraitDef
<'tcx
> {
783 let did
= def
.trait_ref
.def_id
;
784 let interned
= self.arenas
.trait_defs
.alloc(def
);
785 self.trait_defs
.borrow_mut().insert(did
, interned
);
789 pub fn intern_stability(&self, stab
: attr
::Stability
) -> &'tcx attr
::Stability
{
790 if let Some(st
) = self.stability_interner
.borrow().get(&stab
) {
794 let interned
= self.arenas
.stability
.alloc(stab
);
795 self.stability_interner
.borrow_mut().insert(interned
, interned
);
799 pub fn store_free_region_map(&self, id
: NodeId
, map
: FreeRegionMap
) {
800 self.free_region_maps
.borrow_mut()
804 pub fn free_region_map(&self, id
: NodeId
) -> FreeRegionMap
{
805 self.free_region_maps
.borrow()[&id
].clone()
808 pub fn lift
<T
: ?Sized
+ Lift
<'tcx
>>(&self, value
: &T
) -> Option
<T
::Lifted
> {
809 value
.lift_to_tcx(self)
813 /// A trait implemented for all X<'a> types which can be safely and
814 /// efficiently converted to X<'tcx> as long as they are part of the
815 /// provided ty::ctxt<'tcx>.
816 /// This can be done, for example, for Ty<'tcx> or &'tcx Substs<'tcx>
817 /// by looking them up in their respective interners.
818 /// None is returned if the value or one of the components is not part
819 /// of the provided context.
820 /// For Ty, None can be returned if either the type interner doesn't
821 /// contain the TypeVariants key or if the address of the interned
822 /// pointer differs. The latter case is possible if a primitive type,
823 /// e.g. `()` or `u8`, was interned in a different context.
824 pub trait Lift
<'tcx
> {
826 fn lift_to_tcx(&self, tcx
: &ctxt
<'tcx
>) -> Option
<Self::Lifted
>;
829 impl<'tcx
, A
: Lift
<'tcx
>, B
: Lift
<'tcx
>> Lift
<'tcx
> for (A
, B
) {
830 type Lifted
= (A
::Lifted
, B
::Lifted
);
831 fn lift_to_tcx(&self, tcx
: &ctxt
<'tcx
>) -> Option
<Self::Lifted
> {
832 tcx
.lift(&self.0).and_then(|a
| tcx
.lift(&self.1).map(|b
| (a
, b
)))
836 impl<'tcx
, T
: Lift
<'tcx
>> Lift
<'tcx
> for [T
] {
837 type Lifted
= Vec
<T
::Lifted
>;
838 fn lift_to_tcx(&self, tcx
: &ctxt
<'tcx
>) -> Option
<Self::Lifted
> {
839 let mut result
= Vec
::with_capacity(self.len());
841 if let Some(value
) = tcx
.lift(x
) {
851 impl<'tcx
> Lift
<'tcx
> for Region
{
853 fn lift_to_tcx(&self, _
: &ctxt
<'tcx
>) -> Option
<Region
> {
858 impl<'a
, 'tcx
> Lift
<'tcx
> for Ty
<'a
> {
859 type Lifted
= Ty
<'tcx
>;
860 fn lift_to_tcx(&self, tcx
: &ctxt
<'tcx
>) -> Option
<Ty
<'tcx
>> {
861 if let Some(&ty
) = tcx
.interner
.borrow().get(&self.sty
) {
862 if *self as *const _
== ty
as *const _
{
870 impl<'a
, 'tcx
> Lift
<'tcx
> for &'a Substs
<'a
> {
871 type Lifted
= &'tcx Substs
<'tcx
>;
872 fn lift_to_tcx(&self, tcx
: &ctxt
<'tcx
>) -> Option
<&'tcx Substs
<'tcx
>> {
873 if let Some(&substs
) = tcx
.substs_interner
.borrow().get(*self) {
874 if *self as *const _
== substs
as *const _
{
882 impl<'a
, 'tcx
> Lift
<'tcx
> for TraitRef
<'a
> {
883 type Lifted
= TraitRef
<'tcx
>;
884 fn lift_to_tcx(&self, tcx
: &ctxt
<'tcx
>) -> Option
<TraitRef
<'tcx
>> {
885 tcx
.lift(&self.substs
).map(|substs
| TraitRef
{
892 impl<'a
, 'tcx
> Lift
<'tcx
> for TraitPredicate
<'a
> {
893 type Lifted
= TraitPredicate
<'tcx
>;
894 fn lift_to_tcx(&self, tcx
: &ctxt
<'tcx
>) -> Option
<TraitPredicate
<'tcx
>> {
895 tcx
.lift(&self.trait_ref
).map(|trait_ref
| TraitPredicate
{
901 impl<'a
, 'tcx
> Lift
<'tcx
> for EquatePredicate
<'a
> {
902 type Lifted
= EquatePredicate
<'tcx
>;
903 fn lift_to_tcx(&self, tcx
: &ctxt
<'tcx
>) -> Option
<EquatePredicate
<'tcx
>> {
904 tcx
.lift(&(self.0, self.1)).map(|(a
, b
)| EquatePredicate(a
, b
))
908 impl<'tcx
, A
: Copy
+Lift
<'tcx
>, B
: Copy
+Lift
<'tcx
>> Lift
<'tcx
> for OutlivesPredicate
<A
, B
> {
909 type Lifted
= OutlivesPredicate
<A
::Lifted
, B
::Lifted
>;
910 fn lift_to_tcx(&self, tcx
: &ctxt
<'tcx
>) -> Option
<Self::Lifted
> {
911 tcx
.lift(&(self.0, self.1)).map(|(a
, b
)| OutlivesPredicate(a
, b
))
915 impl<'a
, 'tcx
> Lift
<'tcx
> for ProjectionPredicate
<'a
> {
916 type Lifted
= ProjectionPredicate
<'tcx
>;
917 fn lift_to_tcx(&self, tcx
: &ctxt
<'tcx
>) -> Option
<ProjectionPredicate
<'tcx
>> {
918 tcx
.lift(&(self.projection_ty
.trait_ref
, self.ty
)).map(|(trait_ref
, ty
)| {
919 ProjectionPredicate
{
920 projection_ty
: ProjectionTy
{
921 trait_ref
: trait_ref
,
922 item_name
: self.projection_ty
.item_name
930 impl<'tcx
, T
: Lift
<'tcx
>> Lift
<'tcx
> for Binder
<T
> {
931 type Lifted
= Binder
<T
::Lifted
>;
932 fn lift_to_tcx(&self, tcx
: &ctxt
<'tcx
>) -> Option
<Self::Lifted
> {
933 tcx
.lift(&self.0).map(|x
| Binder(x
))
940 use session
::Session
;
946 /// Marker type used for the scoped TLS slot.
947 /// The type context cannot be used directly because the scoped TLS
948 /// in libstd doesn't allow types generic over lifetimes.
949 struct ThreadLocalTyCx
;
951 scoped_thread_local
!(static TLS_TCX
: ThreadLocalTyCx
);
953 fn def_id_debug(def_id
: ast
::DefId
, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
954 // Unfortunately, there seems to be no way to attempt to print
955 // a path for a def-id, so I'll just make a best effort for now
956 // and otherwise fallback to just printing the crate/node pair
958 if def_id
.krate
== ast
::LOCAL_CRATE
{
959 match tcx
.map
.find(def_id
.node
) {
960 Some(ast_map
::NodeItem(..)) |
961 Some(ast_map
::NodeForeignItem(..)) |
962 Some(ast_map
::NodeImplItem(..)) |
963 Some(ast_map
::NodeTraitItem(..)) |
964 Some(ast_map
::NodeVariant(..)) |
965 Some(ast_map
::NodeStructCtor(..)) => {
966 return write
!(f
, "{}", ty
::item_path_str(tcx
, def_id
));
975 fn span_debug(span
: codemap
::Span
, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
977 write
!(f
, "{}", tcx
.sess
.codemap().span_to_string(span
))
981 pub fn enter
<'tcx
, F
: FnOnce(&ty
::ctxt
<'tcx
>) -> R
, R
>(tcx
: ty
::ctxt
<'tcx
>, f
: F
)
983 let result
= ast
::DEF_ID_DEBUG
.with(|def_id_dbg
| {
984 codemap
::SPAN_DEBUG
.with(|span_dbg
| {
985 let original_def_id_debug
= def_id_dbg
.get();
986 def_id_dbg
.set(def_id_debug
);
987 let original_span_debug
= span_dbg
.get();
988 span_dbg
.set(span_debug
);
989 let tls_ptr
= &tcx
as *const _
as *const ThreadLocalTyCx
;
990 let result
= TLS_TCX
.set(unsafe { &*tls_ptr }
, || f(&tcx
));
991 def_id_dbg
.set(original_def_id_debug
);
992 span_dbg
.set(original_span_debug
);
999 pub fn with
<F
: FnOnce(&ty
::ctxt
) -> R
, R
>(f
: F
) -> R
{
1000 TLS_TCX
.with(|tcx
| f(unsafe { &*(tcx as *const _ as *const ty::ctxt) }
))
1004 // Flags that we track on types. These flags are propagated upwards
1005 // through the type during type construction, so that we can quickly
1006 // check whether the type has various kinds of types in it without
1007 // recursing over the type itself.
1009 flags TypeFlags
: u32 {
1010 const HAS_PARAMS
= 1 << 0,
1011 const HAS_SELF
= 1 << 1,
1012 const HAS_TY_INFER
= 1 << 2,
1013 const HAS_RE_INFER
= 1 << 3,
1014 const HAS_RE_EARLY_BOUND
= 1 << 4,
1015 const HAS_FREE_REGIONS
= 1 << 5,
1016 const HAS_TY_ERR
= 1 << 6,
1017 const HAS_PROJECTION
= 1 << 7,
1018 const HAS_TY_CLOSURE
= 1 << 8,
1020 // true if there are "names" of types and regions and so forth
1021 // that are local to a particular fn
1022 const HAS_LOCAL_NAMES
= 1 << 9,
1024 const NEEDS_SUBST
= TypeFlags
::HAS_PARAMS
.bits
|
1025 TypeFlags
::HAS_SELF
.bits
|
1026 TypeFlags
::HAS_RE_EARLY_BOUND
.bits
,
1028 // Flags representing the nominal content of a type,
1029 // computed by FlagsComputation. If you add a new nominal
1030 // flag, it should be added here too.
1031 const NOMINAL_FLAGS
= TypeFlags
::HAS_PARAMS
.bits
|
1032 TypeFlags
::HAS_SELF
.bits
|
1033 TypeFlags
::HAS_TY_INFER
.bits
|
1034 TypeFlags
::HAS_RE_INFER
.bits
|
1035 TypeFlags
::HAS_RE_EARLY_BOUND
.bits
|
1036 TypeFlags
::HAS_FREE_REGIONS
.bits
|
1037 TypeFlags
::HAS_TY_ERR
.bits
|
1038 TypeFlags
::HAS_PROJECTION
.bits
|
1039 TypeFlags
::HAS_TY_CLOSURE
.bits
|
1040 TypeFlags
::HAS_LOCAL_NAMES
.bits
,
1042 // Caches for type_is_sized, type_moves_by_default
1043 const SIZEDNESS_CACHED
= 1 << 16,
1044 const IS_SIZED
= 1 << 17,
1045 const MOVENESS_CACHED
= 1 << 18,
1046 const MOVES_BY_DEFAULT
= 1 << 19,
1050 macro_rules
! sty_debug_print
{
1051 ($ctxt
: expr
, $
($variant
: ident
),*) => {{
1052 // curious inner module to allow variant names to be used as
1054 #[allow(non_snake_case)]
1057 #[derive(Copy, Clone)]
1060 region_infer
: usize,
1065 pub fn go(tcx
: &ty
::ctxt
) {
1066 let mut total
= DebugStat
{
1068 region_infer
: 0, ty_infer
: 0, both_infer
: 0,
1070 $
(let mut $variant
= total
;)*
1073 for (_
, t
) in tcx
.interner
.borrow().iter() {
1074 let variant
= match t
.sty
{
1075 ty
::TyBool
| ty
::TyChar
| ty
::TyInt(..) | ty
::TyUint(..) |
1076 ty
::TyFloat(..) | ty
::TyStr
=> continue,
1077 ty
::TyError
=> /* unimportant */ continue,
1078 $
(ty
::$
variant(..) => &mut $variant
,)*
1080 let region
= t
.flags
.get().intersects(ty
::TypeFlags
::HAS_RE_INFER
);
1081 let ty
= t
.flags
.get().intersects(ty
::TypeFlags
::HAS_TY_INFER
);
1085 if region { total.region_infer += 1; variant.region_infer += 1 }
1086 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1087 if region
&& ty { total.both_infer += 1; variant.both_infer += 1 }
1089 println
!("Ty interner total ty region both");
1090 $
(println
!(" {:18}: {uses:6} {usespc:4.1}%, \
1091 {ty:4.1}% {region:5.1}% {both:4.1}%",
1092 stringify
!($variant
),
1093 uses
= $variant
.total
,
1094 usespc
= $variant
.total
as f64 * 100.0 / total
.total
as f64,
1095 ty
= $variant
.ty_infer
as f64 * 100.0 / total
.total
as f64,
1096 region
= $variant
.region_infer
as f64 * 100.0 / total
.total
as f64,
1097 both
= $variant
.both_infer
as f64 * 100.0 / total
.total
as f64);
1099 println
!(" total {uses:6} \
1100 {ty:4.1}% {region:5.1}% {both:4.1}%",
1102 ty
= total
.ty_infer
as f64 * 100.0 / total
.total
as f64,
1103 region
= total
.region_infer
as f64 * 100.0 / total
.total
as f64,
1104 both
= total
.both_infer
as f64 * 100.0 / total
.total
as f64)
1112 impl<'tcx
> ctxt
<'tcx
> {
1113 pub fn print_debug_stats(&self) {
1116 TyEnum
, TyBox
, TyArray
, TySlice
, TyRawPtr
, TyRef
, TyBareFn
, TyTrait
,
1117 TyStruct
, TyClosure
, TyTuple
, TyParam
, TyInfer
, TyProjection
);
1119 println
!("Substs interner: #{}", self.substs_interner
.borrow().len());
1120 println
!("BareFnTy interner: #{}", self.bare_fn_interner
.borrow().len());
1121 println
!("Region interner: #{}", self.region_interner
.borrow().len());
1122 println
!("Stability interner: #{}", self.stability_interner
.borrow().len());
1126 pub struct TyS
<'tcx
> {
1127 pub sty
: TypeVariants
<'tcx
>,
1128 pub flags
: Cell
<TypeFlags
>,
1130 // the maximal depth of any bound regions appearing in this type.
1134 impl fmt
::Debug
for TypeFlags
{
1135 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
1136 write
!(f
, "{}", self.bits
)
1140 impl<'tcx
> PartialEq
for TyS
<'tcx
> {
1142 fn eq(&self, other
: &TyS
<'tcx
>) -> bool
{
1143 // (self as *const _) == (other as *const _)
1144 (self as *const TyS
<'tcx
>) == (other
as *const TyS
<'tcx
>)
1147 impl<'tcx
> Eq
for TyS
<'tcx
> {}
1149 impl<'tcx
> Hash
for TyS
<'tcx
> {
1150 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
1151 (self as *const TyS
).hash(s
)
1155 pub type Ty
<'tcx
> = &'tcx TyS
<'tcx
>;
1157 /// An entry in the type interner.
1158 pub struct InternedTy
<'tcx
> {
1162 // NB: An InternedTy compares and hashes as a sty.
1163 impl<'tcx
> PartialEq
for InternedTy
<'tcx
> {
1164 fn eq(&self, other
: &InternedTy
<'tcx
>) -> bool
{
1165 self.ty
.sty
== other
.ty
.sty
1169 impl<'tcx
> Eq
for InternedTy
<'tcx
> {}
1171 impl<'tcx
> Hash
for InternedTy
<'tcx
> {
1172 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
1177 impl<'tcx
> Borrow
<TypeVariants
<'tcx
>> for InternedTy
<'tcx
> {
1178 fn borrow
<'a
>(&'a
self) -> &'a TypeVariants
<'tcx
> {
1183 pub fn type_has_params(ty
: Ty
) -> bool
{
1184 ty
.flags
.get().intersects(TypeFlags
::HAS_PARAMS
)
1186 pub fn type_has_self(ty
: Ty
) -> bool
{
1187 ty
.flags
.get().intersects(TypeFlags
::HAS_SELF
)
1189 pub fn type_has_ty_infer(ty
: Ty
) -> bool
{
1190 ty
.flags
.get().intersects(TypeFlags
::HAS_TY_INFER
)
1192 pub fn type_needs_infer(ty
: Ty
) -> bool
{
1193 ty
.flags
.get().intersects(TypeFlags
::HAS_TY_INFER
| TypeFlags
::HAS_RE_INFER
)
1195 pub fn type_is_global(ty
: Ty
) -> bool
{
1196 !ty
.flags
.get().intersects(TypeFlags
::HAS_LOCAL_NAMES
)
1198 pub fn type_has_projection(ty
: Ty
) -> bool
{
1199 ty
.flags
.get().intersects(TypeFlags
::HAS_PROJECTION
)
1201 pub fn type_has_ty_closure(ty
: Ty
) -> bool
{
1202 ty
.flags
.get().intersects(TypeFlags
::HAS_TY_CLOSURE
)
1205 pub fn type_has_erasable_regions(ty
: Ty
) -> bool
{
1206 ty
.flags
.get().intersects(TypeFlags
::HAS_RE_EARLY_BOUND
|
1207 TypeFlags
::HAS_RE_INFER
|
1208 TypeFlags
::HAS_FREE_REGIONS
)
1211 /// An "escaping region" is a bound region whose binder is not part of `t`.
1213 /// So, for example, consider a type like the following, which has two binders:
1215 /// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize))
1216 /// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope
1217 /// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope
1219 /// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the
1220 /// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
1221 /// fn type*, that type has an escaping region: `'a`.
1223 /// Note that what I'm calling an "escaping region" is often just called a "free region". However,
1224 /// we already use the term "free region". It refers to the regions that we use to represent bound
1225 /// regions on a fn definition while we are typechecking its body.
1227 /// To clarify, conceptually there is no particular difference between an "escaping" region and a
1228 /// "free" region. However, there is a big difference in practice. Basically, when "entering" a
1229 /// binding level, one is generally required to do some sort of processing to a bound region, such
1230 /// as replacing it with a fresh/skolemized region, or making an entry in the environment to
1231 /// represent the scope to which it is attached, etc. An escaping region represents a bound region
1232 /// for which this processing has not yet been done.
1233 pub fn type_has_escaping_regions(ty
: Ty
) -> bool
{
1234 type_escapes_depth(ty
, 0)
1237 pub fn type_escapes_depth(ty
: Ty
, depth
: u32) -> bool
{
1238 ty
.region_depth
> depth
1241 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
1242 pub struct BareFnTy
<'tcx
> {
1243 pub unsafety
: ast
::Unsafety
,
1245 pub sig
: PolyFnSig
<'tcx
>,
1248 #[derive(Clone, PartialEq, Eq, Hash)]
1249 pub struct ClosureTy
<'tcx
> {
1250 pub unsafety
: ast
::Unsafety
,
1252 pub sig
: PolyFnSig
<'tcx
>,
1255 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1256 pub enum FnOutput
<'tcx
> {
1257 FnConverging(Ty
<'tcx
>),
1261 impl<'tcx
> FnOutput
<'tcx
> {
1262 pub fn diverges(&self) -> bool
{
1263 *self == FnDiverging
1266 pub fn unwrap(self) -> Ty
<'tcx
> {
1268 ty
::FnConverging(t
) => t
,
1269 ty
::FnDiverging
=> unreachable
!()
1273 pub fn unwrap_or(self, def
: Ty
<'tcx
>) -> Ty
<'tcx
> {
1275 ty
::FnConverging(t
) => t
,
1276 ty
::FnDiverging
=> def
1281 pub type PolyFnOutput
<'tcx
> = Binder
<FnOutput
<'tcx
>>;
1283 impl<'tcx
> PolyFnOutput
<'tcx
> {
1284 pub fn diverges(&self) -> bool
{
1289 /// Signature of a function type, which I have arbitrarily
1290 /// decided to use to refer to the input/output types.
1292 /// - `inputs` is the list of arguments and their modes.
1293 /// - `output` is the return type.
1294 /// - `variadic` indicates whether this is a variadic function. (only true for foreign fns)
1295 #[derive(Clone, PartialEq, Eq, Hash)]
1296 pub struct FnSig
<'tcx
> {
1297 pub inputs
: Vec
<Ty
<'tcx
>>,
1298 pub output
: FnOutput
<'tcx
>,
1302 pub type PolyFnSig
<'tcx
> = Binder
<FnSig
<'tcx
>>;
1304 impl<'tcx
> PolyFnSig
<'tcx
> {
1305 pub fn inputs(&self) -> ty
::Binder
<Vec
<Ty
<'tcx
>>> {
1306 self.map_bound_ref(|fn_sig
| fn_sig
.inputs
.clone())
1308 pub fn input(&self, index
: usize) -> ty
::Binder
<Ty
<'tcx
>> {
1309 self.map_bound_ref(|fn_sig
| fn_sig
.inputs
[index
])
1311 pub fn output(&self) -> ty
::Binder
<FnOutput
<'tcx
>> {
1312 self.map_bound_ref(|fn_sig
| fn_sig
.output
.clone())
1314 pub fn variadic(&self) -> bool
{
1315 self.skip_binder().variadic
1319 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
1320 pub struct ParamTy
{
1321 pub space
: subst
::ParamSpace
,
1323 pub name
: ast
::Name
,
1326 /// A [De Bruijn index][dbi] is a standard means of representing
1327 /// regions (and perhaps later types) in a higher-ranked setting. In
1328 /// particular, imagine a type like this:
1330 /// for<'a> fn(for<'b> fn(&'b isize, &'a isize), &'a char)
1333 /// | +------------+ 1 | |
1335 /// +--------------------------------+ 2 |
1337 /// +------------------------------------------+ 1
1339 /// In this type, there are two binders (the outer fn and the inner
1340 /// fn). We need to be able to determine, for any given region, which
1341 /// fn type it is bound by, the inner or the outer one. There are
1342 /// various ways you can do this, but a De Bruijn index is one of the
1343 /// more convenient and has some nice properties. The basic idea is to
1344 /// count the number of binders, inside out. Some examples should help
1345 /// clarify what I mean.
1347 /// Let's start with the reference type `&'b isize` that is the first
1348 /// argument to the inner function. This region `'b` is assigned a De
1349 /// Bruijn index of 1, meaning "the innermost binder" (in this case, a
1350 /// fn). The region `'a` that appears in the second argument type (`&'a
1351 /// isize`) would then be assigned a De Bruijn index of 2, meaning "the
1352 /// second-innermost binder". (These indices are written on the arrays
1353 /// in the diagram).
1355 /// What is interesting is that De Bruijn index attached to a particular
1356 /// variable will vary depending on where it appears. For example,
1357 /// the final type `&'a char` also refers to the region `'a` declared on
1358 /// the outermost fn. But this time, this reference is not nested within
1359 /// any other binders (i.e., it is not an argument to the inner fn, but
1360 /// rather the outer one). Therefore, in this case, it is assigned a
1361 /// De Bruijn index of 1, because the innermost binder in that location
1362 /// is the outer fn.
1364 /// [dbi]: http://en.wikipedia.org/wiki/De_Bruijn_index
1365 #[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, Copy)]
1366 pub struct DebruijnIndex
{
1367 // We maintain the invariant that this is never 0. So 1 indicates
1368 // the innermost binder. To ensure this, create with `DebruijnIndex::new`.
1372 /// Representation of regions:
1373 #[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Copy)]
1375 // Region bound in a type or fn declaration which will be
1376 // substituted 'early' -- that is, at the same time when type
1377 // parameters are substituted.
1378 ReEarlyBound(EarlyBoundRegion
),
1380 // Region bound in a function scope, which will be substituted when the
1381 // function is called.
1382 ReLateBound(DebruijnIndex
, BoundRegion
),
1384 /// When checking a function body, the types of all arguments and so forth
1385 /// that refer to bound region parameters are modified to refer to free
1386 /// region parameters.
1389 /// A concrete region naming some statically determined extent
1390 /// (e.g. an expression or sequence of statements) within the
1391 /// current function.
1392 ReScope(region
::CodeExtent
),
1394 /// Static data that has an "infinite" lifetime. Top in the region lattice.
1397 /// A region variable. Should not exist after typeck.
1398 ReInfer(InferRegion
),
1400 /// Empty lifetime is for data that is never accessed.
1401 /// Bottom in the region lattice. We treat ReEmpty somewhat
1402 /// specially; at least right now, we do not generate instances of
1403 /// it during the GLB computations, but rather
1404 /// generate an error instead. This is to improve error messages.
1405 /// The only way to get an instance of ReEmpty is to have a region
1406 /// variable with no constraints.
1410 #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
1411 pub struct EarlyBoundRegion
{
1412 pub param_id
: ast
::NodeId
,
1413 pub space
: subst
::ParamSpace
,
1415 pub name
: ast
::Name
,
1418 /// Upvars do not get their own node-id. Instead, we use the pair of
1419 /// the original var id (that is, the root variable that is referenced
1420 /// by the upvar) and the id of the closure expression.
1421 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
1422 pub struct UpvarId
{
1423 pub var_id
: ast
::NodeId
,
1424 pub closure_expr_id
: ast
::NodeId
,
1427 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)]
1428 pub enum BorrowKind
{
1429 /// Data must be immutable and is aliasable.
1432 /// Data must be immutable but not aliasable. This kind of borrow
1433 /// cannot currently be expressed by the user and is used only in
1434 /// implicit closure bindings. It is needed when you the closure
1435 /// is borrowing or mutating a mutable referent, e.g.:
1437 /// let x: &mut isize = ...;
1438 /// let y = || *x += 5;
1440 /// If we were to try to translate this closure into a more explicit
1441 /// form, we'd encounter an error with the code as written:
1443 /// struct Env { x: & &mut isize }
1444 /// let x: &mut isize = ...;
1445 /// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn
1446 /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
1448 /// This is then illegal because you cannot mutate a `&mut` found
1449 /// in an aliasable location. To solve, you'd have to translate with
1450 /// an `&mut` borrow:
1452 /// struct Env { x: & &mut isize }
1453 /// let x: &mut isize = ...;
1454 /// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
1455 /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
1457 /// Now the assignment to `**env.x` is legal, but creating a
1458 /// mutable pointer to `x` is not because `x` is not mutable. We
1459 /// could fix this by declaring `x` as `let mut x`. This is ok in
1460 /// user code, if awkward, but extra weird for closures, since the
1461 /// borrow is hidden.
1463 /// So we introduce a "unique imm" borrow -- the referent is
1464 /// immutable, but not aliasable. This solves the problem. For
1465 /// simplicity, we don't give users the way to express this
1466 /// borrow, it's just used when translating closures.
1469 /// Data is mutable and not aliasable.
1473 /// Information describing the capture of an upvar. This is computed
1474 /// during `typeck`, specifically by `regionck`.
1475 #[derive(PartialEq, Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
1476 pub enum UpvarCapture
{
1477 /// Upvar is captured by value. This is always true when the
1478 /// closure is labeled `move`, but can also be true in other cases
1479 /// depending on inference.
1482 /// Upvar is captured by reference.
1486 #[derive(PartialEq, Clone, RustcEncodable, RustcDecodable, Copy)]
1487 pub struct UpvarBorrow
{
1488 /// The kind of borrow: by-ref upvars have access to shared
1489 /// immutable borrows, which are not part of the normal language
1491 pub kind
: BorrowKind
,
1493 /// Region of the resulting reference.
1494 pub region
: ty
::Region
,
1497 pub type UpvarCaptureMap
= FnvHashMap
<UpvarId
, UpvarCapture
>;
1500 pub fn is_global(&self) -> bool
{
1501 // does this represent a region that can be named in a global
1502 // way? used in fulfillment caching.
1504 ty
::ReStatic
| ty
::ReEmpty
=> true,
1509 pub fn is_bound(&self) -> bool
{
1511 ty
::ReEarlyBound(..) => true,
1512 ty
::ReLateBound(..) => true,
1517 pub fn escapes_depth(&self, depth
: u32) -> bool
{
1519 ty
::ReLateBound(debruijn
, _
) => debruijn
.depth
> depth
,
1525 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash,
1526 RustcEncodable
, RustcDecodable
, Copy
)]
1527 /// A "free" region `fr` can be interpreted as "some region
1528 /// at least as big as the scope `fr.scope`".
1529 pub struct FreeRegion
{
1530 pub scope
: region
::DestructionScopeData
,
1531 pub bound_region
: BoundRegion
1534 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash,
1535 RustcEncodable
, RustcDecodable
, Copy
, Debug
)]
1536 pub enum BoundRegion
{
1537 /// An anonymous region parameter for a given fn (&T)
1540 /// Named region parameters for functions (a in &'a T)
1542 /// The def-id is needed to distinguish free regions in
1543 /// the event of shadowing.
1544 BrNamed(ast
::DefId
, ast
::Name
),
1546 /// Fresh bound identifiers created during GLB computations.
1549 // Anonymous region for the implicit env pointer parameter
1554 // NB: If you change this, you'll probably want to change the corresponding
1555 // AST structure in libsyntax/ast.rs as well.
1556 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
1557 pub enum TypeVariants
<'tcx
> {
1558 /// The primitive boolean type. Written as `bool`.
1561 /// The primitive character type; holds a Unicode scalar value
1562 /// (a non-surrogate code point). Written as `char`.
1565 /// A primitive signed integer type. For example, `i32`.
1568 /// A primitive unsigned integer type. For example, `u32`.
1569 TyUint(ast
::UintTy
),
1571 /// A primitive floating-point type. For example, `f64`.
1572 TyFloat(ast
::FloatTy
),
1574 /// An enumerated type, defined with `enum`.
1576 /// Substs here, possibly against intuition, *may* contain `TyParam`s.
1577 /// That is, even after substitution it is possible that there are type
1578 /// variables. This happens when the `TyEnum` corresponds to an enum
1579 /// definition and not a concrete use of it. To get the correct `TyEnum`
1580 /// from the tcx, use the `NodeId` from the `ast::Ty` and look it up in
1581 /// the `ast_ty_to_ty_cache`. This is probably true for `TyStruct` as
1583 TyEnum(DefId
, &'tcx Substs
<'tcx
>),
1585 /// A structure type, defined with `struct`.
1587 /// See warning about substitutions for enumerated types.
1588 TyStruct(DefId
, &'tcx Substs
<'tcx
>),
1590 /// `Box<T>`; this is nominally a struct in the documentation, but is
1591 /// special-cased internally. For example, it is possible to implicitly
1592 /// move the contents of a box out of that box, and methods of any type
1593 /// can have type `Box<Self>`.
1596 /// The pointee of a string slice. Written as `str`.
1599 /// An array with the given length. Written as `[T; n]`.
1600 TyArray(Ty
<'tcx
>, usize),
1602 /// The pointee of an array slice. Written as `[T]`.
1605 /// A raw pointer. Written as `*mut T` or `*const T`
1608 /// A reference; a pointer with an associated lifetime. Written as
1609 /// `&a mut T` or `&'a T`.
1610 TyRef(&'tcx Region
, mt
<'tcx
>),
1612 /// If the def-id is Some(_), then this is the type of a specific
1613 /// fn item. Otherwise, if None(_), it a fn pointer type.
1615 /// FIXME: Conflating function pointers and the type of a
1616 /// function is probably a terrible idea; a function pointer is a
1617 /// value with a specific type, but a function can be polymorphic
1618 /// or dynamically dispatched.
1619 TyBareFn(Option
<DefId
>, &'tcx BareFnTy
<'tcx
>),
1621 /// A trait, defined with `trait`.
1622 TyTrait(Box
<TraitTy
<'tcx
>>),
1624 /// The anonymous type of a closure. Used to represent the type of
1626 TyClosure(DefId
, &'tcx Substs
<'tcx
>),
1628 /// A tuple type. For example, `(i32, bool)`.
1629 TyTuple(Vec
<Ty
<'tcx
>>),
1631 /// The projection of an associated type. For example,
1632 /// `<T as Trait<..>>::N`.
1633 TyProjection(ProjectionTy
<'tcx
>),
1635 /// A type parameter; for example, `T` in `fn f<T>(x: T) {}
1638 /// A type variable used during type-checking.
1641 /// A placeholder for a type which could not be computed; this is
1642 /// propagated to avoid useless error messages.
1646 #[derive(Clone, PartialEq, Eq, Hash)]
1647 pub struct TraitTy
<'tcx
> {
1648 pub principal
: ty
::PolyTraitRef
<'tcx
>,
1649 pub bounds
: ExistentialBounds
<'tcx
>,
1652 impl<'tcx
> TraitTy
<'tcx
> {
1653 pub fn principal_def_id(&self) -> ast
::DefId
{
1654 self.principal
.0.def_id
1657 /// Object types don't have a self-type specified. Therefore, when
1658 /// we convert the principal trait-ref into a normal trait-ref,
1659 /// you must give *some* self-type. A common choice is `mk_err()`
1660 /// or some skolemized type.
1661 pub fn principal_trait_ref_with_self_ty(&self,
1664 -> ty
::PolyTraitRef
<'tcx
>
1666 // otherwise the escaping regions would be captured by the binder
1667 assert
!(!self_ty
.has_escaping_regions());
1669 ty
::Binder(TraitRef
{
1670 def_id
: self.principal
.0.def_id
,
1671 substs
: tcx
.mk_substs(self.principal
.0.substs
.with_self_ty(self_ty
)),
1675 pub fn projection_bounds_with_self_ty(&self,
1678 -> Vec
<ty
::PolyProjectionPredicate
<'tcx
>>
1680 // otherwise the escaping regions would be captured by the binders
1681 assert
!(!self_ty
.has_escaping_regions());
1683 self.bounds
.projection_bounds
.iter()
1684 .map(|in_poly_projection_predicate
| {
1685 let in_projection_ty
= &in_poly_projection_predicate
.0.projection_ty
;
1686 let substs
= tcx
.mk_substs(in_projection_ty
.trait_ref
.substs
.with_self_ty(self_ty
));
1687 let trait_ref
= ty
::TraitRef
::new(in_projection_ty
.trait_ref
.def_id
,
1689 let projection_ty
= ty
::ProjectionTy
{
1690 trait_ref
: trait_ref
,
1691 item_name
: in_projection_ty
.item_name
1693 ty
::Binder(ty
::ProjectionPredicate
{
1694 projection_ty
: projection_ty
,
1695 ty
: in_poly_projection_predicate
.0.ty
1702 /// A complete reference to a trait. These take numerous guises in syntax,
1703 /// but perhaps the most recognizable form is in a where clause:
1707 /// This would be represented by a trait-reference where the def-id is the
1708 /// def-id for the trait `Foo` and the substs defines `T` as parameter 0 in the
1709 /// `SelfSpace` and `U` as parameter 0 in the `TypeSpace`.
1711 /// Trait references also appear in object types like `Foo<U>`, but in
1712 /// that case the `Self` parameter is absent from the substitutions.
1714 /// Note that a `TraitRef` introduces a level of region binding, to
1715 /// account for higher-ranked trait bounds like `T : for<'a> Foo<&'a
1716 /// U>` or higher-ranked object types.
1717 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
1718 pub struct TraitRef
<'tcx
> {
1720 pub substs
: &'tcx Substs
<'tcx
>,
1723 pub type PolyTraitRef
<'tcx
> = Binder
<TraitRef
<'tcx
>>;
1725 impl<'tcx
> PolyTraitRef
<'tcx
> {
1726 pub fn self_ty(&self) -> Ty
<'tcx
> {
1730 pub fn def_id(&self) -> ast
::DefId
{
1734 pub fn substs(&self) -> &'tcx Substs
<'tcx
> {
1735 // FIXME(#20664) every use of this fn is probably a bug, it should yield Binder<>
1739 pub fn input_types(&self) -> &[Ty
<'tcx
>] {
1740 // FIXME(#20664) every use of this fn is probably a bug, it should yield Binder<>
1741 self.0.input_types
()
1744 pub fn to_poly_trait_predicate(&self) -> PolyTraitPredicate
<'tcx
> {
1745 // Note that we preserve binding levels
1746 Binder(TraitPredicate { trait_ref: self.0.clone() }
)
1750 /// Binder is a binder for higher-ranked lifetimes. It is part of the
1751 /// compiler's representation for things like `for<'a> Fn(&'a isize)`
1752 /// (which would be represented by the type `PolyTraitRef ==
1753 /// Binder<TraitRef>`). Note that when we skolemize, instantiate,
1754 /// erase, or otherwise "discharge" these bound regions, we change the
1755 /// type from `Binder<T>` to just `T` (see
1756 /// e.g. `liberate_late_bound_regions`).
1757 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
1758 pub struct Binder
<T
>(pub T
);
1761 /// Skips the binder and returns the "bound" value. This is a
1762 /// risky thing to do because it's easy to get confused about
1763 /// debruijn indices and the like. It is usually better to
1764 /// discharge the binder using `no_late_bound_regions` or
1765 /// `replace_late_bound_regions` or something like
1766 /// that. `skip_binder` is only valid when you are either
1767 /// extracting data that has nothing to do with bound regions, you
1768 /// are doing some sort of test that does not involve bound
1769 /// regions, or you are being very careful about your depth
1772 /// Some examples where `skip_binder` is reasonable:
1773 /// - extracting the def-id from a PolyTraitRef;
1774 /// - comparing the self type of a PolyTraitRef to see if it is equal to
1775 /// a type parameter `X`, since the type `X` does not reference any regions
1776 pub fn skip_binder(&self) -> &T
{
1780 pub fn as_ref(&self) -> Binder
<&T
> {
1784 pub fn map_bound_ref
<F
,U
>(&self, f
: F
) -> Binder
<U
>
1785 where F
: FnOnce(&T
) -> U
1787 self.as_ref().map_bound(f
)
1790 pub fn map_bound
<F
,U
>(self, f
: F
) -> Binder
<U
>
1791 where F
: FnOnce(T
) -> U
1793 ty
::Binder(f(self.0))
1797 #[derive(Clone, Copy, PartialEq)]
1798 pub enum IntVarValue
{
1799 IntType(ast
::IntTy
),
1800 UintType(ast
::UintTy
),
1803 #[derive(Clone, Copy, Debug)]
1804 pub enum terr_vstore_kind
{
1811 #[derive(Clone, Copy, Debug)]
1812 pub struct expected_found
<T
> {
1817 // Data structures used in type unification
1818 #[derive(Clone, Copy, Debug)]
1819 pub enum type_err
<'tcx
> {
1821 terr_unsafety_mismatch(expected_found
<ast
::Unsafety
>),
1822 terr_abi_mismatch(expected_found
<abi
::Abi
>),
1824 terr_box_mutability
,
1825 terr_ptr_mutability
,
1826 terr_ref_mutability
,
1827 terr_vec_mutability
,
1828 terr_tuple_size(expected_found
<usize>),
1829 terr_fixed_array_size(expected_found
<usize>),
1830 terr_ty_param_size(expected_found
<usize>),
1832 terr_regions_does_not_outlive(Region
, Region
),
1833 terr_regions_not_same(Region
, Region
),
1834 terr_regions_no_overlap(Region
, Region
),
1835 terr_regions_insufficiently_polymorphic(BoundRegion
, Region
),
1836 terr_regions_overly_polymorphic(BoundRegion
, Region
),
1837 terr_sorts(expected_found
<Ty
<'tcx
>>),
1838 terr_integer_as_char
,
1839 terr_int_mismatch(expected_found
<IntVarValue
>),
1840 terr_float_mismatch(expected_found
<ast
::FloatTy
>),
1841 terr_traits(expected_found
<ast
::DefId
>),
1842 terr_builtin_bounds(expected_found
<BuiltinBounds
>),
1843 terr_variadic_mismatch(expected_found
<bool
>),
1845 terr_convergence_mismatch(expected_found
<bool
>),
1846 terr_projection_name_mismatched(expected_found
<ast
::Name
>),
1847 terr_projection_bounds_length(expected_found
<usize>),
1850 /// Bounds suitable for an existentially quantified type parameter
1851 /// such as those that appear in object types or closure types.
1852 #[derive(PartialEq, Eq, Hash, Clone)]
1853 pub struct ExistentialBounds
<'tcx
> {
1854 pub region_bound
: ty
::Region
,
1855 pub builtin_bounds
: BuiltinBounds
,
1856 pub projection_bounds
: Vec
<PolyProjectionPredicate
<'tcx
>>,
1858 // If true, this TyTrait used a "default bound" in the surface
1859 // syntax. This makes no difference to the type system but is
1860 // handy for error reporting.
1861 pub region_bound_will_change
: bool
,
1864 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1865 pub struct BuiltinBounds(EnumSet
<BuiltinBound
>);
1867 impl BuiltinBounds
{
1868 pub fn empty() -> BuiltinBounds
{
1869 BuiltinBounds(EnumSet
::new())
1872 pub fn iter(&self) -> enum_set
::Iter
<BuiltinBound
> {
1876 pub fn to_predicates
<'tcx
>(&self,
1877 tcx
: &ty
::ctxt
<'tcx
>,
1878 self_ty
: Ty
<'tcx
>) -> Vec
<Predicate
<'tcx
>> {
1879 self.iter().filter_map(|builtin_bound
|
1880 match traits
::trait_ref_for_builtin_bound(tcx
, builtin_bound
, self_ty
) {
1881 Ok(trait_ref
) => Some(trait_ref
.as_predicate()),
1882 Err(ErrorReported
) => { None }
1888 impl ops
::Deref
for BuiltinBounds
{
1889 type Target
= EnumSet
<BuiltinBound
>;
1890 fn deref(&self) -> &Self::Target { &self.0 }
1893 impl ops
::DerefMut
for BuiltinBounds
{
1894 fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
1897 impl<'a
> IntoIterator
for &'a BuiltinBounds
{
1898 type Item
= BuiltinBound
;
1899 type IntoIter
= enum_set
::Iter
<BuiltinBound
>;
1900 fn into_iter(self) -> Self::IntoIter
{
1901 (**self).into_iter()
1905 #[derive(Clone, RustcEncodable, PartialEq, Eq, RustcDecodable, Hash,
1908 pub enum BuiltinBound
{
1915 /// An existential bound that does not implement any traits.
1916 pub fn region_existential_bound
<'tcx
>(r
: ty
::Region
) -> ExistentialBounds
<'tcx
> {
1917 ty
::ExistentialBounds
{ region_bound
: r
,
1918 builtin_bounds
: BuiltinBounds
::empty(),
1919 projection_bounds
: Vec
::new(),
1920 region_bound_will_change
: false, }
1923 impl CLike
for BuiltinBound
{
1924 fn to_usize(&self) -> usize {
1927 fn from_usize(v
: usize) -> BuiltinBound
{
1928 unsafe { mem::transmute(v) }
1932 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
1937 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
1942 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
1943 pub struct FloatVid
{
1947 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1948 pub struct RegionVid
{
1952 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
1958 /// A `FreshTy` is one that is generated as a replacement for an
1959 /// unbound type variable. This is convenient for caching etc. See
1960 /// `middle::infer::freshen` for more details.
1966 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)]
1967 pub enum UnconstrainedNumeric
{
1974 #[derive(Clone, RustcEncodable, RustcDecodable, Eq, Hash, Debug, Copy)]
1975 pub enum InferRegion
{
1977 ReSkolemized(u32, BoundRegion
)
1980 impl cmp
::PartialEq
for InferRegion
{
1981 fn eq(&self, other
: &InferRegion
) -> bool
{
1982 match ((*self), *other
) {
1983 (ReVar(rva
), ReVar(rvb
)) => {
1986 (ReSkolemized(rva
, _
), ReSkolemized(rvb
, _
)) => {
1992 fn ne(&self, other
: &InferRegion
) -> bool
{
1993 !((*self) == (*other
))
1997 impl fmt
::Debug
for TyVid
{
1998 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
1999 write
!(f
, "_#{}t", self.index
)
2003 impl fmt
::Debug
for IntVid
{
2004 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
2005 write
!(f
, "_#{}i", self.index
)
2009 impl fmt
::Debug
for FloatVid
{
2010 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
2011 write
!(f
, "_#{}f", self.index
)
2015 impl fmt
::Debug
for RegionVid
{
2016 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
2017 write
!(f
, "'_#{}r", self.index
)
2021 impl<'tcx
> fmt
::Debug
for FnSig
<'tcx
> {
2022 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
2023 write
!(f
, "({:?}; variadic: {})->{:?}", self.inputs
, self.variadic
, self.output
)
2027 impl fmt
::Debug
for InferTy
{
2028 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
2030 TyVar(ref v
) => v
.fmt(f
),
2031 IntVar(ref v
) => v
.fmt(f
),
2032 FloatVar(ref v
) => v
.fmt(f
),
2033 FreshTy(v
) => write
!(f
, "FreshTy({:?})", v
),
2034 FreshIntTy(v
) => write
!(f
, "FreshIntTy({:?})", v
),
2035 FreshFloatTy(v
) => write
!(f
, "FreshFloatTy({:?})", v
)
2040 impl fmt
::Debug
for IntVarValue
{
2041 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
2043 IntType(ref v
) => v
.fmt(f
),
2044 UintType(ref v
) => v
.fmt(f
),
2049 /// Default region to use for the bound of objects that are
2050 /// supplied as the value for this type parameter. This is derived
2051 /// from `T:'a` annotations appearing in the type definition. If
2052 /// this is `None`, then the default is inherited from the
2053 /// surrounding context. See RFC #599 for details.
2054 #[derive(Copy, Clone)]
2055 pub enum ObjectLifetimeDefault
{
2056 /// Require an explicit annotation. Occurs when multiple
2057 /// `T:'a` constraints are found.
2060 /// Use the base default, typically 'static, but in a fn body it is a fresh variable
2063 /// Use the given region as the default.
2068 pub struct TypeParameterDef
<'tcx
> {
2069 pub name
: ast
::Name
,
2070 pub def_id
: ast
::DefId
,
2071 pub space
: subst
::ParamSpace
,
2073 pub default: Option
<Ty
<'tcx
>>,
2074 pub object_lifetime_default
: ObjectLifetimeDefault
,
2077 #[derive(RustcEncodable, RustcDecodable, Clone, Debug)]
2078 pub struct RegionParameterDef
{
2079 pub name
: ast
::Name
,
2080 pub def_id
: ast
::DefId
,
2081 pub space
: subst
::ParamSpace
,
2083 pub bounds
: Vec
<ty
::Region
>,
2086 impl RegionParameterDef
{
2087 pub fn to_early_bound_region(&self) -> ty
::Region
{
2088 ty
::ReEarlyBound(ty
::EarlyBoundRegion
{
2089 param_id
: self.def_id
.node
,
2095 pub fn to_bound_region(&self) -> ty
::BoundRegion
{
2096 ty
::BoundRegion
::BrNamed(self.def_id
, self.name
)
2100 /// Information about the formal type/lifetime parameters associated
2101 /// with an item or method. Analogous to ast::Generics.
2102 #[derive(Clone, Debug)]
2103 pub struct Generics
<'tcx
> {
2104 pub types
: VecPerParamSpace
<TypeParameterDef
<'tcx
>>,
2105 pub regions
: VecPerParamSpace
<RegionParameterDef
>,
2108 impl<'tcx
> Generics
<'tcx
> {
2109 pub fn empty() -> Generics
<'tcx
> {
2111 types
: VecPerParamSpace
::empty(),
2112 regions
: VecPerParamSpace
::empty(),
2116 pub fn is_empty(&self) -> bool
{
2117 self.types
.is_empty() && self.regions
.is_empty()
2120 pub fn has_type_params(&self, space
: subst
::ParamSpace
) -> bool
{
2121 !self.types
.is_empty_in(space
)
2124 pub fn has_region_params(&self, space
: subst
::ParamSpace
) -> bool
{
2125 !self.regions
.is_empty_in(space
)
2129 /// Bounds on generics.
2131 pub struct GenericPredicates
<'tcx
> {
2132 pub predicates
: VecPerParamSpace
<Predicate
<'tcx
>>,
2135 impl<'tcx
> GenericPredicates
<'tcx
> {
2136 pub fn empty() -> GenericPredicates
<'tcx
> {
2138 predicates
: VecPerParamSpace
::empty(),
2142 pub fn instantiate(&self, tcx
: &ty
::ctxt
<'tcx
>, substs
: &Substs
<'tcx
>)
2143 -> InstantiatedPredicates
<'tcx
> {
2144 InstantiatedPredicates
{
2145 predicates
: self.predicates
.subst(tcx
, substs
),
2149 pub fn instantiate_supertrait(&self,
2150 tcx
: &ty
::ctxt
<'tcx
>,
2151 poly_trait_ref
: &ty
::PolyTraitRef
<'tcx
>)
2152 -> InstantiatedPredicates
<'tcx
>
2154 InstantiatedPredicates
{
2155 predicates
: self.predicates
.map(|pred
| pred
.subst_supertrait(tcx
, poly_trait_ref
))
2160 #[derive(Clone, PartialEq, Eq, Hash)]
2161 pub enum Predicate
<'tcx
> {
2162 /// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
2163 /// the `Self` type of the trait reference and `A`, `B`, and `C`
2164 /// would be the parameters in the `TypeSpace`.
2165 Trait(PolyTraitPredicate
<'tcx
>),
2167 /// where `T1 == T2`.
2168 Equate(PolyEquatePredicate
<'tcx
>),
2171 RegionOutlives(PolyRegionOutlivesPredicate
),
2174 TypeOutlives(PolyTypeOutlivesPredicate
<'tcx
>),
2176 /// where <T as TraitRef>::Name == X, approximately.
2177 /// See `ProjectionPredicate` struct for details.
2178 Projection(PolyProjectionPredicate
<'tcx
>),
2181 impl<'tcx
> Predicate
<'tcx
> {
2182 /// Performs a substitution suitable for going from a
2183 /// poly-trait-ref to supertraits that must hold if that
2184 /// poly-trait-ref holds. This is slightly different from a normal
2185 /// substitution in terms of what happens with bound regions. See
2186 /// lengthy comment below for details.
2187 pub fn subst_supertrait(&self,
2188 tcx
: &ty
::ctxt
<'tcx
>,
2189 trait_ref
: &ty
::PolyTraitRef
<'tcx
>)
2190 -> ty
::Predicate
<'tcx
>
2192 // The interaction between HRTB and supertraits is not entirely
2193 // obvious. Let me walk you (and myself) through an example.
2195 // Let's start with an easy case. Consider two traits:
2197 // trait Foo<'a> : Bar<'a,'a> { }
2198 // trait Bar<'b,'c> { }
2200 // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
2201 // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
2202 // knew that `Foo<'x>` (for any 'x) then we also know that
2203 // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
2204 // normal substitution.
2206 // In terms of why this is sound, the idea is that whenever there
2207 // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
2208 // holds. So if there is an impl of `T:Foo<'a>` that applies to
2209 // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
2212 // Another example to be careful of is this:
2214 // trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
2215 // trait Bar1<'b,'c> { }
2217 // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
2218 // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
2219 // reason is similar to the previous example: any impl of
2220 // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`. So
2221 // basically we would want to collapse the bound lifetimes from
2222 // the input (`trait_ref`) and the supertraits.
2224 // To achieve this in practice is fairly straightforward. Let's
2225 // consider the more complicated scenario:
2227 // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
2228 // has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
2229 // where both `'x` and `'b` would have a DB index of 1.
2230 // The substitution from the input trait-ref is therefore going to be
2231 // `'a => 'x` (where `'x` has a DB index of 1).
2232 // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
2233 // early-bound parameter and `'b' is a late-bound parameter with a
2235 // - If we replace `'a` with `'x` from the input, it too will have
2236 // a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
2237 // just as we wanted.
2239 // There is only one catch. If we just apply the substitution `'a
2240 // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
2241 // adjust the DB index because we substituting into a binder (it
2242 // tries to be so smart...) resulting in `for<'x> for<'b>
2243 // Bar1<'x,'b>` (we have no syntax for this, so use your
2244 // imagination). Basically the 'x will have DB index of 2 and 'b
2245 // will have DB index of 1. Not quite what we want. So we apply
2246 // the substitution to the *contents* of the trait reference,
2247 // rather than the trait reference itself (put another way, the
2248 // substitution code expects equal binding levels in the values
2249 // from the substitution and the value being substituted into, and
2250 // this trick achieves that).
2252 let substs
= &trait_ref
.0.substs
;
2254 Predicate
::Trait(ty
::Binder(ref data
)) =>
2255 Predicate
::Trait(ty
::Binder(data
.subst(tcx
, substs
))),
2256 Predicate
::Equate(ty
::Binder(ref data
)) =>
2257 Predicate
::Equate(ty
::Binder(data
.subst(tcx
, substs
))),
2258 Predicate
::RegionOutlives(ty
::Binder(ref data
)) =>
2259 Predicate
::RegionOutlives(ty
::Binder(data
.subst(tcx
, substs
))),
2260 Predicate
::TypeOutlives(ty
::Binder(ref data
)) =>
2261 Predicate
::TypeOutlives(ty
::Binder(data
.subst(tcx
, substs
))),
2262 Predicate
::Projection(ty
::Binder(ref data
)) =>
2263 Predicate
::Projection(ty
::Binder(data
.subst(tcx
, substs
))),
2267 // Indicates whether this predicate references only 'global'
2268 // types/lifetimes that are the same regardless of what fn we are
2269 // in. This is used for caching. Errs on the side of returning
2271 pub fn is_global(&self) -> bool
{
2273 ty
::Predicate
::Trait(ref data
) => {
2274 let substs
= data
.skip_binder().trait_ref
.substs
;
2276 substs
.types
.iter().all(|t
| ty
::type_is_global(t
)) && {
2277 match substs
.regions
{
2278 subst
::ErasedRegions
=> true,
2279 subst
::NonerasedRegions(ref r
) => r
.iter().all(|r
| r
.is_global()),
2291 #[derive(Clone, PartialEq, Eq, Hash)]
2292 pub struct TraitPredicate
<'tcx
> {
2293 pub trait_ref
: TraitRef
<'tcx
>
2295 pub type PolyTraitPredicate
<'tcx
> = ty
::Binder
<TraitPredicate
<'tcx
>>;
2297 impl<'tcx
> TraitPredicate
<'tcx
> {
2298 pub fn def_id(&self) -> ast
::DefId
{
2299 self.trait_ref
.def_id
2302 pub fn input_types(&self) -> &[Ty
<'tcx
>] {
2303 self.trait_ref
.substs
.types
.as_slice()
2306 pub fn self_ty(&self) -> Ty
<'tcx
> {
2307 self.trait_ref
.self_ty()
2311 impl<'tcx
> PolyTraitPredicate
<'tcx
> {
2312 pub fn def_id(&self) -> ast
::DefId
{
2317 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
2318 pub struct EquatePredicate
<'tcx
>(pub Ty
<'tcx
>, pub Ty
<'tcx
>); // `0 == 1`
2319 pub type PolyEquatePredicate
<'tcx
> = ty
::Binder
<EquatePredicate
<'tcx
>>;
2321 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
2322 pub struct OutlivesPredicate
<A
,B
>(pub A
, pub B
); // `A : B`
2323 pub type PolyOutlivesPredicate
<A
,B
> = ty
::Binder
<OutlivesPredicate
<A
,B
>>;
2324 pub type PolyRegionOutlivesPredicate
= PolyOutlivesPredicate
<ty
::Region
, ty
::Region
>;
2325 pub type PolyTypeOutlivesPredicate
<'tcx
> = PolyOutlivesPredicate
<Ty
<'tcx
>, ty
::Region
>;
2327 /// This kind of predicate has no *direct* correspondent in the
2328 /// syntax, but it roughly corresponds to the syntactic forms:
2330 /// 1. `T : TraitRef<..., Item=Type>`
2331 /// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
2333 /// In particular, form #1 is "desugared" to the combination of a
2334 /// normal trait predicate (`T : TraitRef<...>`) and one of these
2335 /// predicates. Form #2 is a broader form in that it also permits
2336 /// equality between arbitrary types. Processing an instance of Form
2337 /// #2 eventually yields one of these `ProjectionPredicate`
2338 /// instances to normalize the LHS.
2339 #[derive(Clone, PartialEq, Eq, Hash)]
2340 pub struct ProjectionPredicate
<'tcx
> {
2341 pub projection_ty
: ProjectionTy
<'tcx
>,
2345 pub type PolyProjectionPredicate
<'tcx
> = Binder
<ProjectionPredicate
<'tcx
>>;
2347 impl<'tcx
> PolyProjectionPredicate
<'tcx
> {
2348 pub fn item_name(&self) -> ast
::Name
{
2349 self.0.projection_ty
.item_name
// safe to skip the binder to access a name
2352 pub fn sort_key(&self) -> (ast
::DefId
, ast
::Name
) {
2353 self.0.projection_ty
.sort_key()
2357 /// Represents the projection of an associated type. In explicit UFCS
2358 /// form this would be written `<T as Trait<..>>::N`.
2359 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
2360 pub struct ProjectionTy
<'tcx
> {
2361 /// The trait reference `T as Trait<..>`.
2362 pub trait_ref
: ty
::TraitRef
<'tcx
>,
2364 /// The name `N` of the associated type.
2365 pub item_name
: ast
::Name
,
2368 impl<'tcx
> ProjectionTy
<'tcx
> {
2369 pub fn sort_key(&self) -> (ast
::DefId
, ast
::Name
) {
2370 (self.trait_ref
.def_id
, self.item_name
)
2374 pub trait ToPolyTraitRef
<'tcx
> {
2375 fn to_poly_trait_ref(&self) -> PolyTraitRef
<'tcx
>;
2378 impl<'tcx
> ToPolyTraitRef
<'tcx
> for TraitRef
<'tcx
> {
2379 fn to_poly_trait_ref(&self) -> PolyTraitRef
<'tcx
> {
2380 assert
!(!self.has_escaping_regions());
2381 ty
::Binder(self.clone())
2385 impl<'tcx
> ToPolyTraitRef
<'tcx
> for PolyTraitPredicate
<'tcx
> {
2386 fn to_poly_trait_ref(&self) -> PolyTraitRef
<'tcx
> {
2387 self.map_bound_ref(|trait_pred
| trait_pred
.trait_ref
.clone())
2391 impl<'tcx
> ToPolyTraitRef
<'tcx
> for PolyProjectionPredicate
<'tcx
> {
2392 fn to_poly_trait_ref(&self) -> PolyTraitRef
<'tcx
> {
2393 // Note: unlike with TraitRef::to_poly_trait_ref(),
2394 // self.0.trait_ref is permitted to have escaping regions.
2395 // This is because here `self` has a `Binder` and so does our
2396 // return value, so we are preserving the number of binding
2398 ty
::Binder(self.0.projection_ty
.trait_ref
.clone())
2402 pub trait AsPredicate
<'tcx
> {
2403 fn as_predicate(&self) -> Predicate
<'tcx
>;
2406 impl<'tcx
> AsPredicate
<'tcx
> for TraitRef
<'tcx
> {
2407 fn as_predicate(&self) -> Predicate
<'tcx
> {
2408 // we're about to add a binder, so let's check that we don't
2409 // accidentally capture anything, or else that might be some
2410 // weird debruijn accounting.
2411 assert
!(!self.has_escaping_regions());
2413 ty
::Predicate
::Trait(ty
::Binder(ty
::TraitPredicate
{
2414 trait_ref
: self.clone()
2419 impl<'tcx
> AsPredicate
<'tcx
> for PolyTraitRef
<'tcx
> {
2420 fn as_predicate(&self) -> Predicate
<'tcx
> {
2421 ty
::Predicate
::Trait(self.to_poly_trait_predicate())
2425 impl<'tcx
> AsPredicate
<'tcx
> for PolyEquatePredicate
<'tcx
> {
2426 fn as_predicate(&self) -> Predicate
<'tcx
> {
2427 Predicate
::Equate(self.clone())
2431 impl<'tcx
> AsPredicate
<'tcx
> for PolyRegionOutlivesPredicate
{
2432 fn as_predicate(&self) -> Predicate
<'tcx
> {
2433 Predicate
::RegionOutlives(self.clone())
2437 impl<'tcx
> AsPredicate
<'tcx
> for PolyTypeOutlivesPredicate
<'tcx
> {
2438 fn as_predicate(&self) -> Predicate
<'tcx
> {
2439 Predicate
::TypeOutlives(self.clone())
2443 impl<'tcx
> AsPredicate
<'tcx
> for PolyProjectionPredicate
<'tcx
> {
2444 fn as_predicate(&self) -> Predicate
<'tcx
> {
2445 Predicate
::Projection(self.clone())
2449 impl<'tcx
> Predicate
<'tcx
> {
2450 /// Iterates over the types in this predicate. Note that in all
2451 /// cases this is skipping over a binder, so late-bound regions
2452 /// with depth 0 are bound by the predicate.
2453 pub fn walk_tys(&self) -> IntoIter
<Ty
<'tcx
>> {
2454 let vec
: Vec
<_
> = match *self {
2455 ty
::Predicate
::Trait(ref data
) => {
2456 data
.0.trait_ref
.substs
.types
.as_slice().to_vec()
2458 ty
::Predicate
::Equate(ty
::Binder(ref data
)) => {
2459 vec
![data
.0, data
.1]
2461 ty
::Predicate
::TypeOutlives(ty
::Binder(ref data
)) => {
2464 ty
::Predicate
::RegionOutlives(..) => {
2467 ty
::Predicate
::Projection(ref data
) => {
2468 let trait_inputs
= data
.0.projection_ty
.trait_ref
.substs
.types
.as_slice();
2471 .chain(Some(data
.0.ty
))
2476 // The only reason to collect into a vector here is that I was
2477 // too lazy to make the full (somewhat complicated) iterator
2478 // type that would be needed here. But I wanted this fn to
2479 // return an iterator conceptually, rather than a `Vec`, so as
2480 // to be closer to `Ty::walk`.
2484 pub fn has_escaping_regions(&self) -> bool
{
2486 Predicate
::Trait(ref trait_ref
) => trait_ref
.has_escaping_regions(),
2487 Predicate
::Equate(ref p
) => p
.has_escaping_regions(),
2488 Predicate
::RegionOutlives(ref p
) => p
.has_escaping_regions(),
2489 Predicate
::TypeOutlives(ref p
) => p
.has_escaping_regions(),
2490 Predicate
::Projection(ref p
) => p
.has_escaping_regions(),
2494 pub fn to_opt_poly_trait_ref(&self) -> Option
<PolyTraitRef
<'tcx
>> {
2496 Predicate
::Trait(ref t
) => {
2497 Some(t
.to_poly_trait_ref())
2499 Predicate
::Projection(..) |
2500 Predicate
::Equate(..) |
2501 Predicate
::RegionOutlives(..) |
2502 Predicate
::TypeOutlives(..) => {
2509 /// Represents the bounds declared on a particular set of type
2510 /// parameters. Should eventually be generalized into a flag list of
2511 /// where clauses. You can obtain a `InstantiatedPredicates` list from a
2512 /// `GenericPredicates` by using the `instantiate` method. Note that this method
2513 /// reflects an important semantic invariant of `InstantiatedPredicates`: while
2514 /// the `GenericPredicates` are expressed in terms of the bound type
2515 /// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance
2516 /// represented a set of bounds for some particular instantiation,
2517 /// meaning that the generic parameters have been substituted with
2522 /// struct Foo<T,U:Bar<T>> { ... }
2524 /// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
2525 /// `[[], [U:Bar<T>]]`. Now if there were some particular reference
2526 /// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
2527 /// [usize:Bar<isize>]]`.
2529 pub struct InstantiatedPredicates
<'tcx
> {
2530 pub predicates
: VecPerParamSpace
<Predicate
<'tcx
>>,
2533 impl<'tcx
> InstantiatedPredicates
<'tcx
> {
2534 pub fn empty() -> InstantiatedPredicates
<'tcx
> {
2535 InstantiatedPredicates { predicates: VecPerParamSpace::empty() }
2538 pub fn has_escaping_regions(&self) -> bool
{
2539 self.predicates
.any(|p
| p
.has_escaping_regions())
2542 pub fn is_empty(&self) -> bool
{
2543 self.predicates
.is_empty()
2547 impl<'tcx
> TraitRef
<'tcx
> {
2548 pub fn new(def_id
: ast
::DefId
, substs
: &'tcx Substs
<'tcx
>) -> TraitRef
<'tcx
> {
2549 TraitRef { def_id: def_id, substs: substs }
2552 pub fn self_ty(&self) -> Ty
<'tcx
> {
2553 self.substs
.self_ty().unwrap()
2556 pub fn input_types(&self) -> &[Ty
<'tcx
>] {
2557 // Select only the "input types" from a trait-reference. For
2558 // now this is all the types that appear in the
2559 // trait-reference, but it should eventually exclude
2560 // associated types.
2561 self.substs
.types
.as_slice()
2565 /// When type checking, we use the `ParameterEnvironment` to track
2566 /// details about the type/lifetime parameters that are in scope.
2567 /// It primarily stores the bounds information.
2569 /// Note: This information might seem to be redundant with the data in
2570 /// `tcx.ty_param_defs`, but it is not. That table contains the
2571 /// parameter definitions from an "outside" perspective, but this
2572 /// struct will contain the bounds for a parameter as seen from inside
2573 /// the function body. Currently the only real distinction is that
2574 /// bound lifetime parameters are replaced with free ones, but in the
2575 /// future I hope to refine the representation of types so as to make
2576 /// more distinctions clearer.
2578 pub struct ParameterEnvironment
<'a
, 'tcx
:'a
> {
2579 pub tcx
: &'a ctxt
<'tcx
>,
2581 /// See `construct_free_substs` for details.
2582 pub free_substs
: Substs
<'tcx
>,
2584 /// Each type parameter has an implicit region bound that
2585 /// indicates it must outlive at least the function body (the user
2586 /// may specify stronger requirements). This field indicates the
2587 /// region of the callee.
2588 pub implicit_region_bound
: ty
::Region
,
2590 /// Obligations that the caller must satisfy. This is basically
2591 /// the set of bounds on the in-scope type parameters, translated
2592 /// into Obligations, and elaborated and normalized.
2593 pub caller_bounds
: Vec
<ty
::Predicate
<'tcx
>>,
2595 /// Caches the results of trait selection. This cache is used
2596 /// for things that have to do with the parameters in scope.
2597 pub selection_cache
: traits
::SelectionCache
<'tcx
>,
2600 impl<'a
, 'tcx
> ParameterEnvironment
<'a
, 'tcx
> {
2601 pub fn with_caller_bounds(&self,
2602 caller_bounds
: Vec
<ty
::Predicate
<'tcx
>>)
2603 -> ParameterEnvironment
<'a
,'tcx
>
2605 ParameterEnvironment
{
2607 free_substs
: self.free_substs
.clone(),
2608 implicit_region_bound
: self.implicit_region_bound
,
2609 caller_bounds
: caller_bounds
,
2610 selection_cache
: traits
::SelectionCache
::new(),
2614 pub fn for_item(cx
: &'a ctxt
<'tcx
>, id
: NodeId
) -> ParameterEnvironment
<'a
, 'tcx
> {
2615 match cx
.map
.find(id
) {
2616 Some(ast_map
::NodeImplItem(ref impl_item
)) => {
2617 match impl_item
.node
{
2618 ast
::ConstImplItem(_
, _
) => {
2619 let def_id
= ast_util
::local_def(id
);
2620 let scheme
= lookup_item_type(cx
, def_id
);
2621 let predicates
= lookup_predicates(cx
, def_id
);
2622 construct_parameter_environment(cx
,
2628 ast
::MethodImplItem(_
, ref body
) => {
2629 let method_def_id
= ast_util
::local_def(id
);
2630 match ty
::impl_or_trait_item(cx
, method_def_id
) {
2631 MethodTraitItem(ref method_ty
) => {
2632 let method_generics
= &method_ty
.generics
;
2633 let method_bounds
= &method_ty
.predicates
;
2634 construct_parameter_environment(
2643 .bug("ParameterEnvironment::for_item(): \
2644 got non-method item from impl method?!")
2648 ast
::TypeImplItem(_
) => {
2649 cx
.sess
.bug("ParameterEnvironment::for_item(): \
2650 can't create a parameter environment \
2651 for type impl items")
2653 ast
::MacImplItem(_
) => cx
.sess
.bug("unexpanded macro")
2656 Some(ast_map
::NodeTraitItem(trait_item
)) => {
2657 match trait_item
.node
{
2658 ast
::ConstTraitItem(_
, ref default) => {
2661 let def_id
= ast_util
::local_def(id
);
2662 let scheme
= lookup_item_type(cx
, def_id
);
2663 let predicates
= lookup_predicates(cx
, def_id
);
2664 construct_parameter_environment(cx
,
2671 cx
.sess
.bug("ParameterEnvironment::from_item(): \
2672 can't create a parameter environment \
2673 for const trait items without defaults")
2677 ast
::MethodTraitItem(_
, None
) => {
2678 cx
.sess
.span_bug(trait_item
.span
,
2679 "ParameterEnvironment::for_item():
2680 can't create a parameter \
2681 environment for required trait \
2684 ast
::MethodTraitItem(_
, Some(ref body
)) => {
2685 let method_def_id
= ast_util
::local_def(id
);
2686 match ty
::impl_or_trait_item(cx
, method_def_id
) {
2687 MethodTraitItem(ref method_ty
) => {
2688 let method_generics
= &method_ty
.generics
;
2689 let method_bounds
= &method_ty
.predicates
;
2690 construct_parameter_environment(
2699 .bug("ParameterEnvironment::for_item(): \
2700 got non-method item from provided \
2705 ast
::TypeTraitItem(..) => {
2706 cx
.sess
.bug("ParameterEnvironment::from_item(): \
2707 can't create a parameter environment \
2708 for type trait items")
2712 Some(ast_map
::NodeItem(item
)) => {
2714 ast
::ItemFn(_
, _
, _
, _
, _
, ref body
) => {
2715 // We assume this is a function.
2716 let fn_def_id
= ast_util
::local_def(id
);
2717 let fn_scheme
= lookup_item_type(cx
, fn_def_id
);
2718 let fn_predicates
= lookup_predicates(cx
, fn_def_id
);
2720 construct_parameter_environment(cx
,
2722 &fn_scheme
.generics
,
2727 ast
::ItemStruct(..) |
2729 ast
::ItemConst(..) |
2730 ast
::ItemStatic(..) => {
2731 let def_id
= ast_util
::local_def(id
);
2732 let scheme
= lookup_item_type(cx
, def_id
);
2733 let predicates
= lookup_predicates(cx
, def_id
);
2734 construct_parameter_environment(cx
,
2741 cx
.sess
.span_bug(item
.span
,
2742 "ParameterEnvironment::from_item():
2743 can't create a parameter \
2744 environment for this kind of item")
2748 Some(ast_map
::NodeExpr(..)) => {
2749 // This is a convenience to allow closures to work.
2750 ParameterEnvironment
::for_item(cx
, cx
.map
.get_parent(id
))
2753 cx
.sess
.bug(&format
!("ParameterEnvironment::from_item(): \
2754 `{}` is not an item",
2755 cx
.map
.node_to_string(id
)))
2761 /// A "type scheme", in ML terminology, is a type combined with some
2762 /// set of generic types that the type is, well, generic over. In Rust
2763 /// terms, it is the "type" of a fn item or struct -- this type will
2764 /// include various generic parameters that must be substituted when
2765 /// the item/struct is referenced. That is called converting the type
2766 /// scheme to a monotype.
2768 /// - `generics`: the set of type parameters and their bounds
2769 /// - `ty`: the base types, which may reference the parameters defined
2772 /// Note that TypeSchemes are also sometimes called "polytypes" (and
2773 /// in fact this struct used to carry that name, so you may find some
2774 /// stray references in a comment or something). We try to reserve the
2775 /// "poly" prefix to refer to higher-ranked things, as in
2778 /// Note that each item also comes with predicates, see
2779 /// `lookup_predicates`.
2780 #[derive(Clone, Debug)]
2781 pub struct TypeScheme
<'tcx
> {
2782 pub generics
: Generics
<'tcx
>,
2787 flags TraitFlags
: u32 {
2788 const NO_TRAIT_FLAGS
= 0,
2789 const HAS_DEFAULT_IMPL
= 1 << 0,
2790 const IS_OBJECT_SAFE
= 1 << 1,
2791 const OBJECT_SAFETY_VALID
= 1 << 2,
2792 const IMPLS_VALID
= 1 << 3,
2796 /// As `TypeScheme` but for a trait ref.
2797 pub struct TraitDef
<'tcx
> {
2798 pub unsafety
: ast
::Unsafety
,
2800 /// If `true`, then this trait had the `#[rustc_paren_sugar]`
2801 /// attribute, indicating that it should be used with `Foo()`
2802 /// sugar. This is a temporary thing -- eventually any trait wil
2803 /// be usable with the sugar (or without it).
2804 pub paren_sugar
: bool
,
2806 /// Generic type definitions. Note that `Self` is listed in here
2807 /// as having a single bound, the trait itself (e.g., in the trait
2808 /// `Eq`, there is a single bound `Self : Eq`). This is so that
2809 /// default methods get to assume that the `Self` parameters
2810 /// implements the trait.
2811 pub generics
: Generics
<'tcx
>,
2813 pub trait_ref
: TraitRef
<'tcx
>,
2815 /// A list of the associated types defined in this trait. Useful
2816 /// for resolving `X::Foo` type markers.
2817 pub associated_type_names
: Vec
<ast
::Name
>,
2819 // Impls of this trait. To allow for quicker lookup, the impls are indexed
2820 // by a simplified version of their Self type: impls with a simplifiable
2821 // Self are stored in nonblanket_impls keyed by it, while all other impls
2822 // are stored in blanket_impls.
2824 /// Impls of the trait.
2825 pub nonblanket_impls
: RefCell
<
2826 FnvHashMap
<fast_reject
::SimplifiedType
, Vec
<DefId
>>
2829 /// Blanket impls associated with the trait.
2830 pub blanket_impls
: RefCell
<Vec
<DefId
>>,
2833 pub flags
: Cell
<TraitFlags
>
2836 impl<'tcx
> TraitDef
<'tcx
> {
2837 // returns None if not yet calculated
2838 pub fn object_safety(&self) -> Option
<bool
> {
2839 if self.flags
.get().intersects(TraitFlags
::OBJECT_SAFETY_VALID
) {
2840 Some(self.flags
.get().intersects(TraitFlags
::IS_OBJECT_SAFE
))
2846 pub fn set_object_safety(&self, is_safe
: bool
) {
2847 assert
!(self.object_safety().map(|cs
| cs
== is_safe
).unwrap_or(true));
2849 self.flags
.get() | if is_safe
{
2850 TraitFlags
::OBJECT_SAFETY_VALID
| TraitFlags
::IS_OBJECT_SAFE
2852 TraitFlags
::OBJECT_SAFETY_VALID
2857 /// Records a trait-to-implementation mapping.
2858 pub fn record_impl(&self,
2861 impl_trait_ref
: TraitRef
<'tcx
>) {
2862 debug
!("TraitDef::record_impl for {:?}, from {:?}",
2863 self, impl_trait_ref
);
2865 // We don't want to borrow_mut after we already populated all impls,
2866 // so check if an impl is present with an immutable borrow first.
2867 if let Some(sty
) = fast_reject
::simplify_type(tcx
,
2868 impl_trait_ref
.self_ty(), false) {
2869 if let Some(is
) = self.nonblanket_impls
.borrow().get(&sty
) {
2870 if is
.contains(&impl_def_id
) {
2871 return // duplicate - skip
2875 self.nonblanket_impls
.borrow_mut().entry(sty
).or_insert(vec
![]).push(impl_def_id
)
2877 if self.blanket_impls
.borrow().contains(&impl_def_id
) {
2878 return // duplicate - skip
2880 self.blanket_impls
.borrow_mut().push(impl_def_id
)
2885 pub fn for_each_impl
<F
: FnMut(DefId
)>(&self, tcx
: &ctxt
<'tcx
>, mut f
: F
) {
2886 ty
::populate_implementations_for_trait_if_necessary(tcx
, self.trait_ref
.def_id
);
2888 for &impl_def_id
in self.blanket_impls
.borrow().iter() {
2892 for v
in self.nonblanket_impls
.borrow().values() {
2893 for &impl_def_id
in v
{
2899 pub fn for_each_relevant_impl
<F
: FnMut(DefId
)>(&self,
2904 ty
::populate_implementations_for_trait_if_necessary(tcx
, self.trait_ref
.def_id
);
2906 for &impl_def_id
in self.blanket_impls
.borrow().iter() {
2910 if let Some(simp
) = fast_reject
::simplify_type(tcx
, self_ty
, false) {
2911 if let Some(impls
) = self.nonblanket_impls
.borrow().get(&simp
) {
2912 for &impl_def_id
in impls
{
2915 return; // we don't need to process the other non-blanket impls
2919 for v
in self.nonblanket_impls
.borrow().values() {
2920 for &impl_def_id
in v
{
2928 /// Records the substitutions used to translate the polytype for an
2929 /// item into the monotype of an item reference.
2931 pub struct ItemSubsts
<'tcx
> {
2932 pub substs
: Substs
<'tcx
>,
2935 #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
2936 pub enum ClosureKind
{
2937 // Warning: Ordering is significant here! The ordering is chosen
2938 // because the trait Fn is a subtrait of FnMut and so in turn, and
2939 // hence we order it so that Fn < FnMut < FnOnce.
2946 pub fn trait_did(&self, cx
: &ctxt
) -> ast
::DefId
{
2947 let result
= match *self {
2948 FnClosureKind
=> cx
.lang_items
.require(FnTraitLangItem
),
2949 FnMutClosureKind
=> {
2950 cx
.lang_items
.require(FnMutTraitLangItem
)
2952 FnOnceClosureKind
=> {
2953 cx
.lang_items
.require(FnOnceTraitLangItem
)
2957 Ok(trait_did
) => trait_did
,
2958 Err(err
) => cx
.sess
.fatal(&err
[..]),
2962 /// True if this a type that impls this closure kind
2963 /// must also implement `other`.
2964 pub fn extends(self, other
: ty
::ClosureKind
) -> bool
{
2965 match (self, other
) {
2966 (FnClosureKind
, FnClosureKind
) => true,
2967 (FnClosureKind
, FnMutClosureKind
) => true,
2968 (FnClosureKind
, FnOnceClosureKind
) => true,
2969 (FnMutClosureKind
, FnMutClosureKind
) => true,
2970 (FnMutClosureKind
, FnOnceClosureKind
) => true,
2971 (FnOnceClosureKind
, FnOnceClosureKind
) => true,
2977 pub trait ClosureTyper
<'tcx
> {
2978 fn tcx(&self) -> &ty
::ctxt
<'tcx
> {
2979 self.param_env().tcx
2982 fn param_env
<'a
>(&'a
self) -> &'a ty
::ParameterEnvironment
<'a
, 'tcx
>;
2984 /// Is this a `Fn`, `FnMut` or `FnOnce` closure? During typeck,
2985 /// returns `None` if the kind of this closure has not yet been
2987 fn closure_kind(&self,
2989 -> Option
<ty
::ClosureKind
>;
2991 /// Returns the argument/return types of this closure.
2992 fn closure_type(&self,
2994 substs
: &subst
::Substs
<'tcx
>)
2995 -> ty
::ClosureTy
<'tcx
>;
2997 /// Returns the set of all upvars and their transformed
2998 /// types. During typeck, maybe return `None` if the upvar types
2999 /// have not yet been inferred.
3000 fn closure_upvars(&self,
3002 substs
: &Substs
<'tcx
>)
3003 -> Option
<Vec
<ClosureUpvar
<'tcx
>>>;
3006 impl<'tcx
> CommonTypes
<'tcx
> {
3007 fn new(arena
: &'tcx TypedArena
<TyS
<'tcx
>>,
3008 interner
: &mut FnvHashMap
<InternedTy
<'tcx
>, Ty
<'tcx
>>)
3009 -> CommonTypes
<'tcx
>
3012 bool
: intern_ty(arena
, interner
, TyBool
),
3013 char: intern_ty(arena
, interner
, TyChar
),
3014 err
: intern_ty(arena
, interner
, TyError
),
3015 isize: intern_ty(arena
, interner
, TyInt(ast
::TyIs
)),
3016 i8: intern_ty(arena
, interner
, TyInt(ast
::TyI8
)),
3017 i16: intern_ty(arena
, interner
, TyInt(ast
::TyI16
)),
3018 i32: intern_ty(arena
, interner
, TyInt(ast
::TyI32
)),
3019 i64: intern_ty(arena
, interner
, TyInt(ast
::TyI64
)),
3020 usize: intern_ty(arena
, interner
, TyUint(ast
::TyUs
)),
3021 u8: intern_ty(arena
, interner
, TyUint(ast
::TyU8
)),
3022 u16: intern_ty(arena
, interner
, TyUint(ast
::TyU16
)),
3023 u32: intern_ty(arena
, interner
, TyUint(ast
::TyU32
)),
3024 u64: intern_ty(arena
, interner
, TyUint(ast
::TyU64
)),
3025 f32: intern_ty(arena
, interner
, TyFloat(ast
::TyF32
)),
3026 f64: intern_ty(arena
, interner
, TyFloat(ast
::TyF64
)),
3031 /// Create a type context and call the closure with a `&ty::ctxt` reference
3032 /// to the context. The closure enforces that the type context and any interned
3033 /// value (types, substs, etc.) can only be used while `ty::tls` has a valid
3034 /// reference to the context, to allow formatting values that need it.
3035 pub fn with_ctxt
<'tcx
, F
, R
>(s
: Session
,
3036 arenas
: &'tcx CtxtArenas
<'tcx
>,
3038 named_region_map
: resolve_lifetime
::NamedRegionMap
,
3039 map
: ast_map
::Map
<'tcx
>,
3040 freevars
: RefCell
<FreevarMap
>,
3041 region_maps
: RegionMaps
,
3042 lang_items
: middle
::lang_items
::LanguageItems
,
3043 stability
: stability
::Index
<'tcx
>,
3044 f
: F
) -> (Session
, R
)
3045 where F
: FnOnce(&ctxt
<'tcx
>) -> R
3047 let mut interner
= FnvHashMap();
3048 let common_types
= CommonTypes
::new(&arenas
.type_
, &mut interner
);
3052 interner
: RefCell
::new(interner
),
3053 substs_interner
: RefCell
::new(FnvHashMap()),
3054 bare_fn_interner
: RefCell
::new(FnvHashMap()),
3055 region_interner
: RefCell
::new(FnvHashMap()),
3056 stability_interner
: RefCell
::new(FnvHashMap()),
3057 types
: common_types
,
3058 named_region_map
: named_region_map
,
3059 region_maps
: region_maps
,
3060 free_region_maps
: RefCell
::new(FnvHashMap()),
3061 item_variance_map
: RefCell
::new(DefIdMap()),
3062 variance_computed
: Cell
::new(false),
3065 node_types
: RefCell
::new(FnvHashMap()),
3066 item_substs
: RefCell
::new(NodeMap()),
3067 impl_trait_refs
: RefCell
::new(DefIdMap()),
3068 trait_defs
: RefCell
::new(DefIdMap()),
3069 predicates
: RefCell
::new(DefIdMap()),
3070 super_predicates
: RefCell
::new(DefIdMap()),
3071 fulfilled_predicates
: RefCell
::new(traits
::FulfilledPredicates
::new()),
3074 tcache
: RefCell
::new(DefIdMap()),
3075 rcache
: RefCell
::new(FnvHashMap()),
3076 tc_cache
: RefCell
::new(FnvHashMap()),
3077 ast_ty_to_ty_cache
: RefCell
::new(NodeMap()),
3078 enum_var_cache
: RefCell
::new(DefIdMap()),
3079 impl_or_trait_items
: RefCell
::new(DefIdMap()),
3080 trait_item_def_ids
: RefCell
::new(DefIdMap()),
3081 trait_items_cache
: RefCell
::new(DefIdMap()),
3082 ty_param_defs
: RefCell
::new(NodeMap()),
3083 adjustments
: RefCell
::new(NodeMap()),
3084 normalized_cache
: RefCell
::new(FnvHashMap()),
3085 lang_items
: lang_items
,
3086 provided_method_sources
: RefCell
::new(DefIdMap()),
3087 struct_fields
: RefCell
::new(DefIdMap()),
3088 destructor_for_type
: RefCell
::new(DefIdMap()),
3089 destructors
: RefCell
::new(DefIdSet()),
3090 inherent_impls
: RefCell
::new(DefIdMap()),
3091 impl_items
: RefCell
::new(DefIdMap()),
3092 used_unsafe
: RefCell
::new(NodeSet()),
3093 used_mut_nodes
: RefCell
::new(NodeSet()),
3094 populated_external_types
: RefCell
::new(DefIdSet()),
3095 populated_external_primitive_impls
: RefCell
::new(DefIdSet()),
3096 upvar_capture_map
: RefCell
::new(FnvHashMap()),
3097 extern_const_statics
: RefCell
::new(DefIdMap()),
3098 extern_const_variants
: RefCell
::new(DefIdMap()),
3099 extern_const_fns
: RefCell
::new(DefIdMap()),
3100 method_map
: RefCell
::new(FnvHashMap()),
3101 dependency_formats
: RefCell
::new(FnvHashMap()),
3102 closure_kinds
: RefCell
::new(DefIdMap()),
3103 closure_tys
: RefCell
::new(DefIdMap()),
3104 node_lint_levels
: RefCell
::new(FnvHashMap()),
3105 transmute_restrictions
: RefCell
::new(Vec
::new()),
3106 stability
: RefCell
::new(stability
),
3107 selection_cache
: traits
::SelectionCache
::new(),
3108 repr_hint_cache
: RefCell
::new(DefIdMap()),
3109 const_qualif_map
: RefCell
::new(NodeMap()),
3110 custom_coerce_unsized_kinds
: RefCell
::new(DefIdMap()),
3111 cast_kinds
: RefCell
::new(NodeMap()),
3115 // Type constructors
3117 impl<'tcx
> ctxt
<'tcx
> {
3118 pub fn mk_substs(&self, substs
: Substs
<'tcx
>) -> &'tcx Substs
<'tcx
> {
3119 if let Some(substs
) = self.substs_interner
.borrow().get(&substs
) {
3123 let substs
= self.arenas
.substs
.alloc(substs
);
3124 self.substs_interner
.borrow_mut().insert(substs
, substs
);
3128 /// Create an unsafe fn ty based on a safe fn ty.
3129 pub fn safe_to_unsafe_fn_ty(&self, bare_fn
: &BareFnTy
<'tcx
>) -> Ty
<'tcx
> {
3130 assert_eq
!(bare_fn
.unsafety
, ast
::Unsafety
::Normal
);
3131 let unsafe_fn_ty_a
= self.mk_bare_fn(ty
::BareFnTy
{
3132 unsafety
: ast
::Unsafety
::Unsafe
,
3134 sig
: bare_fn
.sig
.clone()
3136 ty
::mk_bare_fn(self, None
, unsafe_fn_ty_a
)
3139 pub fn mk_bare_fn(&self, bare_fn
: BareFnTy
<'tcx
>) -> &'tcx BareFnTy
<'tcx
> {
3140 if let Some(bare_fn
) = self.bare_fn_interner
.borrow().get(&bare_fn
) {
3144 let bare_fn
= self.arenas
.bare_fn
.alloc(bare_fn
);
3145 self.bare_fn_interner
.borrow_mut().insert(bare_fn
, bare_fn
);
3149 pub fn mk_region(&self, region
: Region
) -> &'tcx Region
{
3150 if let Some(region
) = self.region_interner
.borrow().get(®ion
) {
3154 let region
= self.arenas
.region
.alloc(region
);
3155 self.region_interner
.borrow_mut().insert(region
, region
);
3159 pub fn closure_kind(&self, def_id
: ast
::DefId
) -> ty
::ClosureKind
{
3160 *self.closure_kinds
.borrow().get(&def_id
).unwrap()
3163 pub fn closure_type(&self,
3165 substs
: &subst
::Substs
<'tcx
>)
3166 -> ty
::ClosureTy
<'tcx
>
3168 self.closure_tys
.borrow().get(&def_id
).unwrap().subst(self, substs
)
3171 pub fn type_parameter_def(&self,
3172 node_id
: ast
::NodeId
)
3173 -> TypeParameterDef
<'tcx
>
3175 self.ty_param_defs
.borrow().get(&node_id
).unwrap().clone()
3178 pub fn pat_contains_ref_binding(&self, pat
: &ast
::Pat
) -> Option
<ast
::Mutability
> {
3179 pat_util
::pat_contains_ref_binding(&self.def_map
, pat
)
3182 pub fn arm_contains_ref_binding(&self, arm
: &ast
::Arm
) -> Option
<ast
::Mutability
> {
3183 pat_util
::arm_contains_ref_binding(&self.def_map
, arm
)
3187 // Interns a type/name combination, stores the resulting box in cx.interner,
3188 // and returns the box as cast to an unsafe ptr (see comments for Ty above).
3189 pub fn mk_t
<'tcx
>(cx
: &ctxt
<'tcx
>, st
: TypeVariants
<'tcx
>) -> Ty
<'tcx
> {
3190 let mut interner
= cx
.interner
.borrow_mut();
3191 intern_ty(&cx
.arenas
.type_
, &mut *interner
, st
)
3194 fn intern_ty
<'tcx
>(type_arena
: &'tcx TypedArena
<TyS
<'tcx
>>,
3195 interner
: &mut FnvHashMap
<InternedTy
<'tcx
>, Ty
<'tcx
>>,
3196 st
: TypeVariants
<'tcx
>)
3199 match interner
.get(&st
) {
3200 Some(ty
) => return *ty
,
3204 let flags
= FlagComputation
::for_sty(&st
);
3207 () => type_arena
.alloc(TyS
{ sty
: st
,
3208 flags
: Cell
::new(flags
.flags
),
3209 region_depth
: flags
.depth
, }),
3212 debug
!("Interned type: {:?} Pointer: {:?}",
3213 ty
, ty
as *const TyS
);
3215 interner
.insert(InternedTy { ty: ty }
, ty
);
3220 struct FlagComputation
{
3223 // maximum depth of any bound region that we have seen thus far
3227 impl FlagComputation
{
3228 fn new() -> FlagComputation
{
3229 FlagComputation { flags: TypeFlags::empty(), depth: 0 }
3232 fn for_sty(st
: &TypeVariants
) -> FlagComputation
{
3233 let mut result
= FlagComputation
::new();
3238 fn add_flags(&mut self, flags
: TypeFlags
) {
3239 self.flags
= self.flags
| (flags
& TypeFlags
::NOMINAL_FLAGS
);
3242 fn add_depth(&mut self, depth
: u32) {
3243 if depth
> self.depth
{
3248 /// Adds the flags/depth from a set of types that appear within the current type, but within a
3250 fn add_bound_computation(&mut self, computation
: &FlagComputation
) {
3251 self.add_flags(computation
.flags
);
3253 // The types that contributed to `computation` occurred within
3254 // a region binder, so subtract one from the region depth
3255 // within when adding the depth to `self`.
3256 let depth
= computation
.depth
;
3258 self.add_depth(depth
- 1);
3262 fn add_sty(&mut self, st
: &TypeVariants
) {
3272 // You might think that we could just return TyError for
3273 // any type containing TyError as a component, and get
3274 // rid of the TypeFlags::HAS_TY_ERR flag -- likewise for ty_bot (with
3275 // the exception of function types that return bot).
3276 // But doing so caused sporadic memory corruption, and
3277 // neither I (tjc) nor nmatsakis could figure out why,
3278 // so we're doing it this way.
3280 self.add_flags(TypeFlags
::HAS_TY_ERR
)
3283 &TyParam(ref p
) => {
3284 self.add_flags(TypeFlags
::HAS_LOCAL_NAMES
);
3285 if p
.space
== subst
::SelfSpace
{
3286 self.add_flags(TypeFlags
::HAS_SELF
);
3288 self.add_flags(TypeFlags
::HAS_PARAMS
);
3292 &TyClosure(_
, substs
) => {
3293 self.add_flags(TypeFlags
::HAS_TY_CLOSURE
);
3294 self.add_flags(TypeFlags
::HAS_LOCAL_NAMES
);
3295 self.add_substs(substs
);
3299 self.add_flags(TypeFlags
::HAS_LOCAL_NAMES
); // it might, right?
3300 self.add_flags(TypeFlags
::HAS_TY_INFER
)
3303 &TyEnum(_
, substs
) | &TyStruct(_
, substs
) => {
3304 self.add_substs(substs
);
3307 &TyProjection(ref data
) => {
3308 self.add_flags(TypeFlags
::HAS_PROJECTION
);
3309 self.add_projection_ty(data
);
3312 &TyTrait(box TraitTy { ref principal, ref bounds }
) => {
3313 let mut computation
= FlagComputation
::new();
3314 computation
.add_substs(principal
.0.substs
);
3315 for projection_bound
in &bounds
.projection_bounds
{
3316 let mut proj_computation
= FlagComputation
::new();
3317 proj_computation
.add_projection_predicate(&projection_bound
.0);
3318 self.add_bound_computation(&proj_computation
);
3320 self.add_bound_computation(&computation
);
3322 self.add_bounds(bounds
);
3325 &TyBox(tt
) | &TyArray(tt
, _
) | &TySlice(tt
) => {
3329 &TyRawPtr(ref m
) => {
3333 &TyRef(r
, ref m
) => {
3334 self.add_region(*r
);
3338 &TyTuple(ref ts
) => {
3339 self.add_tys(&ts
[..]);
3342 &TyBareFn(_
, ref f
) => {
3343 self.add_fn_sig(&f
.sig
);
3348 fn add_ty(&mut self, ty
: Ty
) {
3349 self.add_flags(ty
.flags
.get());
3350 self.add_depth(ty
.region_depth
);
3353 fn add_tys(&mut self, tys
: &[Ty
]) {
3359 fn add_fn_sig(&mut self, fn_sig
: &PolyFnSig
) {
3360 let mut computation
= FlagComputation
::new();
3362 computation
.add_tys(&fn_sig
.0.inputs
);
3364 if let ty
::FnConverging(output
) = fn_sig
.0.output
{
3365 computation
.add_ty(output
);
3368 self.add_bound_computation(&computation
);
3371 fn add_region(&mut self, r
: Region
) {
3373 ty
::ReInfer(_
) => { self.add_flags(TypeFlags::HAS_RE_INFER); }
3374 ty
::ReLateBound(debruijn
, _
) => { self.add_depth(debruijn.depth); }
3375 ty
::ReEarlyBound(..) => { self.add_flags(TypeFlags::HAS_RE_EARLY_BOUND); }
3377 _
=> { self.add_flags(TypeFlags::HAS_FREE_REGIONS); }
3381 self.add_flags(TypeFlags
::HAS_LOCAL_NAMES
);
3385 fn add_projection_predicate(&mut self, projection_predicate
: &ProjectionPredicate
) {
3386 self.add_projection_ty(&projection_predicate
.projection_ty
);
3387 self.add_ty(projection_predicate
.ty
);
3390 fn add_projection_ty(&mut self, projection_ty
: &ProjectionTy
) {
3391 self.add_substs(projection_ty
.trait_ref
.substs
);
3394 fn add_substs(&mut self, substs
: &Substs
) {
3395 self.add_tys(substs
.types
.as_slice());
3396 match substs
.regions
{
3397 subst
::ErasedRegions
=> {}
3398 subst
::NonerasedRegions(ref regions
) => {
3406 fn add_bounds(&mut self, bounds
: &ExistentialBounds
) {
3407 self.add_region(bounds
.region_bound
);
3411 pub fn mk_mach_int
<'tcx
>(tcx
: &ctxt
<'tcx
>, tm
: ast
::IntTy
) -> Ty
<'tcx
> {
3413 ast
::TyIs
=> tcx
.types
.isize,
3414 ast
::TyI8
=> tcx
.types
.i8,
3415 ast
::TyI16
=> tcx
.types
.i16,
3416 ast
::TyI32
=> tcx
.types
.i32,
3417 ast
::TyI64
=> tcx
.types
.i64,
3421 pub fn mk_mach_uint
<'tcx
>(tcx
: &ctxt
<'tcx
>, tm
: ast
::UintTy
) -> Ty
<'tcx
> {
3423 ast
::TyUs
=> tcx
.types
.usize,
3424 ast
::TyU8
=> tcx
.types
.u8,
3425 ast
::TyU16
=> tcx
.types
.u16,
3426 ast
::TyU32
=> tcx
.types
.u32,
3427 ast
::TyU64
=> tcx
.types
.u64,
3431 pub fn mk_mach_float
<'tcx
>(tcx
: &ctxt
<'tcx
>, tm
: ast
::FloatTy
) -> Ty
<'tcx
> {
3433 ast
::TyF32
=> tcx
.types
.f32,
3434 ast
::TyF64
=> tcx
.types
.f64,
3438 pub fn mk_str
<'tcx
>(cx
: &ctxt
<'tcx
>) -> Ty
<'tcx
> {
3442 pub fn mk_str_slice
<'tcx
>(cx
: &ctxt
<'tcx
>, r
: &'tcx Region
, m
: ast
::Mutability
) -> Ty
<'tcx
> {
3445 ty
: mk_t(cx
, TyStr
),
3450 pub fn mk_enum
<'tcx
>(cx
: &ctxt
<'tcx
>, did
: ast
::DefId
, substs
: &'tcx Substs
<'tcx
>) -> Ty
<'tcx
> {
3451 // take a copy of substs so that we own the vectors inside
3452 mk_t(cx
, TyEnum(did
, substs
))
3455 pub fn mk_uniq
<'tcx
>(cx
: &ctxt
<'tcx
>, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> { mk_t(cx, TyBox(ty)) }
3457 pub fn mk_ptr
<'tcx
>(cx
: &ctxt
<'tcx
>, tm
: mt
<'tcx
>) -> Ty
<'tcx
> { mk_t(cx, TyRawPtr(tm)) }
3459 pub fn mk_rptr
<'tcx
>(cx
: &ctxt
<'tcx
>, r
: &'tcx Region
, tm
: mt
<'tcx
>) -> Ty
<'tcx
> {
3460 mk_t(cx
, TyRef(r
, tm
))
3463 pub fn mk_mut_rptr
<'tcx
>(cx
: &ctxt
<'tcx
>, r
: &'tcx Region
, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
3464 mk_rptr(cx
, r
, mt {ty: ty, mutbl: ast::MutMutable}
)
3466 pub fn mk_imm_rptr
<'tcx
>(cx
: &ctxt
<'tcx
>, r
: &'tcx Region
, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
3467 mk_rptr(cx
, r
, mt {ty: ty, mutbl: ast::MutImmutable}
)
3470 pub fn mk_mut_ptr
<'tcx
>(cx
: &ctxt
<'tcx
>, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
3471 mk_ptr(cx
, mt {ty: ty, mutbl: ast::MutMutable}
)
3474 pub fn mk_imm_ptr
<'tcx
>(cx
: &ctxt
<'tcx
>, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
3475 mk_ptr(cx
, mt {ty: ty, mutbl: ast::MutImmutable}
)
3478 pub fn mk_nil_ptr
<'tcx
>(cx
: &ctxt
<'tcx
>) -> Ty
<'tcx
> {
3479 mk_ptr(cx
, mt {ty: mk_nil(cx), mutbl: ast::MutImmutable}
)
3482 pub fn mk_vec
<'tcx
>(cx
: &ctxt
<'tcx
>, ty
: Ty
<'tcx
>, sz
: Option
<usize>) -> Ty
<'tcx
> {
3484 Some(n
) => mk_t(cx
, TyArray(ty
, n
)),
3485 None
=> mk_t(cx
, TySlice(ty
))
3489 pub fn mk_slice
<'tcx
>(cx
: &ctxt
<'tcx
>, r
: &'tcx Region
, tm
: mt
<'tcx
>) -> Ty
<'tcx
> {
3492 ty
: mk_vec(cx
, tm
.ty
, None
),
3497 pub fn mk_tup
<'tcx
>(cx
: &ctxt
<'tcx
>, ts
: Vec
<Ty
<'tcx
>>) -> Ty
<'tcx
> {
3498 mk_t(cx
, TyTuple(ts
))
3501 pub fn mk_nil
<'tcx
>(cx
: &ctxt
<'tcx
>) -> Ty
<'tcx
> {
3502 mk_tup(cx
, Vec
::new())
3505 pub fn mk_bool
<'tcx
>(cx
: &ctxt
<'tcx
>) -> Ty
<'tcx
> {
3509 pub fn mk_bare_fn
<'tcx
>(cx
: &ctxt
<'tcx
>,
3510 opt_def_id
: Option
<ast
::DefId
>,
3511 fty
: &'tcx BareFnTy
<'tcx
>) -> Ty
<'tcx
> {
3512 mk_t(cx
, TyBareFn(opt_def_id
, fty
))
3515 pub fn mk_ctor_fn
<'tcx
>(cx
: &ctxt
<'tcx
>,
3517 input_tys
: &[Ty
<'tcx
>],
3518 output
: Ty
<'tcx
>) -> Ty
<'tcx
> {
3519 let input_args
= input_tys
.iter().cloned().collect();
3522 cx
.mk_bare_fn(BareFnTy
{
3523 unsafety
: ast
::Unsafety
::Normal
,
3525 sig
: ty
::Binder(FnSig
{
3527 output
: ty
::FnConverging(output
),
3533 pub fn mk_trait
<'tcx
>(cx
: &ctxt
<'tcx
>,
3534 principal
: ty
::PolyTraitRef
<'tcx
>,
3535 bounds
: ExistentialBounds
<'tcx
>)
3538 assert
!(bound_list_is_sorted(&bounds
.projection_bounds
));
3540 let inner
= box TraitTy
{
3541 principal
: principal
,
3544 mk_t(cx
, TyTrait(inner
))
3547 fn bound_list_is_sorted(bounds
: &[ty
::PolyProjectionPredicate
]) -> bool
{
3548 bounds
.is_empty() ||
3549 bounds
[1..].iter().enumerate().all(
3550 |(index
, bound
)| bounds
[index
].sort_key() <= bound
.sort_key())
3553 pub fn sort_bounds_list(bounds
: &mut [ty
::PolyProjectionPredicate
]) {
3554 bounds
.sort_by(|a
, b
| a
.sort_key().cmp(&b
.sort_key()))
3557 pub fn mk_projection
<'tcx
>(cx
: &ctxt
<'tcx
>,
3558 trait_ref
: TraitRef
<'tcx
>,
3559 item_name
: ast
::Name
)
3561 // take a copy of substs so that we own the vectors inside
3562 let inner
= ProjectionTy { trait_ref: trait_ref, item_name: item_name }
;
3563 mk_t(cx
, TyProjection(inner
))
3566 pub fn mk_struct
<'tcx
>(cx
: &ctxt
<'tcx
>, struct_id
: ast
::DefId
,
3567 substs
: &'tcx Substs
<'tcx
>) -> Ty
<'tcx
> {
3568 // take a copy of substs so that we own the vectors inside
3569 mk_t(cx
, TyStruct(struct_id
, substs
))
3572 pub fn mk_closure
<'tcx
>(cx
: &ctxt
<'tcx
>, closure_id
: ast
::DefId
, substs
: &'tcx Substs
<'tcx
>)
3574 mk_t(cx
, TyClosure(closure_id
, substs
))
3577 pub fn mk_var
<'tcx
>(cx
: &ctxt
<'tcx
>, v
: TyVid
) -> Ty
<'tcx
> {
3578 mk_infer(cx
, TyVar(v
))
3581 pub fn mk_int_var
<'tcx
>(cx
: &ctxt
<'tcx
>, v
: IntVid
) -> Ty
<'tcx
> {
3582 mk_infer(cx
, IntVar(v
))
3585 pub fn mk_float_var
<'tcx
>(cx
: &ctxt
<'tcx
>, v
: FloatVid
) -> Ty
<'tcx
> {
3586 mk_infer(cx
, FloatVar(v
))
3589 pub fn mk_infer
<'tcx
>(cx
: &ctxt
<'tcx
>, it
: InferTy
) -> Ty
<'tcx
> {
3590 mk_t(cx
, TyInfer(it
))
3593 pub fn mk_param
<'tcx
>(cx
: &ctxt
<'tcx
>,
3594 space
: subst
::ParamSpace
,
3596 name
: ast
::Name
) -> Ty
<'tcx
> {
3597 mk_t(cx
, TyParam(ParamTy { space: space, idx: index, name: name }
))
3600 pub fn mk_self_type
<'tcx
>(cx
: &ctxt
<'tcx
>) -> Ty
<'tcx
> {
3601 mk_param(cx
, subst
::SelfSpace
, 0, special_idents
::type_self
.name
)
3604 pub fn mk_param_from_def
<'tcx
>(cx
: &ctxt
<'tcx
>, def
: &TypeParameterDef
) -> Ty
<'tcx
> {
3605 mk_param(cx
, def
.space
, def
.index
, def
.name
)
3608 impl<'tcx
> TyS
<'tcx
> {
3609 /// Iterator that walks `self` and any types reachable from
3610 /// `self`, in depth-first order. Note that just walks the types
3611 /// that appear in `self`, it does not descend into the fields of
3612 /// structs or variants. For example:
3615 /// isize => { isize }
3616 /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
3617 /// [isize] => { [isize], isize }
3619 pub fn walk(&'tcx
self) -> TypeWalker
<'tcx
> {
3620 TypeWalker
::new(self)
3623 /// Iterator that walks the immediate children of `self`. Hence
3624 /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
3625 /// (but not `i32`, like `walk`).
3626 pub fn walk_shallow(&'tcx
self) -> IntoIter
<Ty
<'tcx
>> {
3627 ty_walk
::walk_shallow(self)
3630 pub fn as_opt_param_ty(&self) -> Option
<ty
::ParamTy
> {
3632 ty
::TyParam(ref d
) => Some(d
.clone()),
3637 pub fn is_param(&self, space
: ParamSpace
, index
: u32) -> bool
{
3639 ty
::TyParam(ref data
) => data
.space
== space
&& data
.idx
== index
,
3645 pub fn walk_ty
<'tcx
, F
>(ty_root
: Ty
<'tcx
>, mut f
: F
)
3646 where F
: FnMut(Ty
<'tcx
>),
3648 for ty
in ty_root
.walk() {
3653 /// Walks `ty` and any types appearing within `ty`, invoking the
3654 /// callback `f` on each type. If the callback returns false, then the
3655 /// children of the current type are ignored.
3657 /// Note: prefer `ty.walk()` where possible.
3658 pub fn maybe_walk_ty
<'tcx
,F
>(ty_root
: Ty
<'tcx
>, mut f
: F
)
3659 where F
: FnMut(Ty
<'tcx
>) -> bool
3661 let mut walker
= ty_root
.walk();
3662 while let Some(ty
) = walker
.next() {
3664 walker
.skip_current_subtree();
3669 // Folds types from the bottom up.
3670 pub fn fold_ty
<'tcx
, F
>(cx
: &ctxt
<'tcx
>, t0
: Ty
<'tcx
>,
3673 F
: FnMut(Ty
<'tcx
>) -> Ty
<'tcx
>,
3675 let mut f
= ty_fold
::BottomUpFolder {tcx: cx, fldop: fldop}
;
3680 pub fn new(space
: subst
::ParamSpace
,
3684 ParamTy { space: space, idx: index, name: name }
3687 pub fn for_self() -> ParamTy
{
3688 ParamTy
::new(subst
::SelfSpace
, 0, special_idents
::type_self
.name
)
3691 pub fn for_def(def
: &TypeParameterDef
) -> ParamTy
{
3692 ParamTy
::new(def
.space
, def
.index
, def
.name
)
3695 pub fn to_ty
<'tcx
>(self, tcx
: &ty
::ctxt
<'tcx
>) -> Ty
<'tcx
> {
3696 ty
::mk_param(tcx
, self.space
, self.idx
, self.name
)
3699 pub fn is_self(&self) -> bool
{
3700 self.space
== subst
::SelfSpace
&& self.idx
== 0
3704 impl<'tcx
> ItemSubsts
<'tcx
> {
3705 pub fn empty() -> ItemSubsts
<'tcx
> {
3706 ItemSubsts { substs: Substs::empty() }
3709 pub fn is_noop(&self) -> bool
{
3710 self.substs
.is_noop()
3716 pub fn type_is_nil(ty
: Ty
) -> bool
{
3718 TyTuple(ref tys
) => tys
.is_empty(),
3723 pub fn type_is_error(ty
: Ty
) -> bool
{
3724 ty
.flags
.get().intersects(TypeFlags
::HAS_TY_ERR
)
3727 pub fn type_needs_subst(ty
: Ty
) -> bool
{
3728 ty
.flags
.get().intersects(TypeFlags
::NEEDS_SUBST
)
3731 pub fn trait_ref_contains_error(tref
: &ty
::TraitRef
) -> bool
{
3732 tref
.substs
.types
.any(|&ty
| type_is_error(ty
))
3735 pub fn type_is_ty_var(ty
: Ty
) -> bool
{
3737 TyInfer(TyVar(_
)) => true,
3742 pub fn type_is_bool(ty
: Ty
) -> bool { ty.sty == TyBool }
3744 pub fn type_is_self(ty
: Ty
) -> bool
{
3746 TyParam(ref p
) => p
.space
== subst
::SelfSpace
,
3751 fn type_is_slice(ty
: Ty
) -> bool
{
3753 TyRawPtr(mt
) | TyRef(_
, mt
) => match mt
.ty
.sty
{
3754 TySlice(_
) | TyStr
=> true,
3761 pub fn type_is_structural(ty
: Ty
) -> bool
{
3763 TyStruct(..) | TyTuple(_
) | TyEnum(..) |
3764 TyArray(..) | TyClosure(..) => true,
3765 _
=> type_is_slice(ty
) | type_is_trait(ty
)
3769 pub fn type_is_simd(cx
: &ctxt
, ty
: Ty
) -> bool
{
3771 TyStruct(did
, _
) => lookup_simd(cx
, did
),
3776 pub fn sequence_element_type
<'tcx
>(cx
: &ctxt
<'tcx
>, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
3778 TyArray(ty
, _
) | TySlice(ty
) => ty
,
3779 TyStr
=> mk_mach_uint(cx
, ast
::TyU8
),
3780 _
=> cx
.sess
.bug(&format
!("sequence_element_type called on non-sequence value: {}",
3785 pub fn simd_type
<'tcx
>(cx
: &ctxt
<'tcx
>, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
3787 TyStruct(did
, substs
) => {
3788 let fields
= lookup_struct_fields(cx
, did
);
3789 lookup_field_type(cx
, did
, fields
[0].id
, substs
)
3791 _
=> panic
!("simd_type called on invalid type")
3795 pub fn simd_size(cx
: &ctxt
, ty
: Ty
) -> usize {
3797 TyStruct(did
, _
) => {
3798 let fields
= lookup_struct_fields(cx
, did
);
3801 _
=> panic
!("simd_size called on invalid type")
3805 pub fn type_is_region_ptr(ty
: Ty
) -> bool
{
3812 pub fn type_is_unsafe_ptr(ty
: Ty
) -> bool
{
3814 TyRawPtr(_
) => return true,
3819 pub fn type_is_unique(ty
: Ty
) -> bool
{
3827 A scalar type is one that denotes an atomic datum, with no sub-components.
3828 (A TyRawPtr is scalar because it represents a non-managed pointer, so its
3829 contents are abstract to rustc.)
3831 pub fn type_is_scalar(ty
: Ty
) -> bool
{
3833 TyBool
| TyChar
| TyInt(_
) | TyFloat(_
) | TyUint(_
) |
3834 TyInfer(IntVar(_
)) | TyInfer(FloatVar(_
)) |
3835 TyBareFn(..) | TyRawPtr(_
) => true,
3840 /// Returns true if this type is a floating point type and false otherwise.
3841 pub fn type_is_floating_point(ty
: Ty
) -> bool
{
3844 TyInfer(FloatVar(_
)) =>
3852 /// Type contents is how the type checker reasons about kinds.
3853 /// They track what kinds of things are found within a type. You can
3854 /// think of them as kind of an "anti-kind". They track the kinds of values
3855 /// and thinks that are contained in types. Having a larger contents for
3856 /// a type tends to rule that type *out* from various kinds. For example,
3857 /// a type that contains a reference is not sendable.
3859 /// The reason we compute type contents and not kinds is that it is
3860 /// easier for me (nmatsakis) to think about what is contained within
3861 /// a type than to think about what is *not* contained within a type.
3862 #[derive(Clone, Copy)]
3863 pub struct TypeContents
{
3867 macro_rules
! def_type_content_sets
{
3868 (mod $mname
:ident { $($name:ident = $bits:expr),+ }
) => {
3869 #[allow(non_snake_case)]
3871 use middle
::ty
::TypeContents
;
3873 #[allow(non_upper_case_globals)]
3874 pub const $name
: TypeContents
= TypeContents { bits: $bits }
;
3880 def_type_content_sets
! {
3882 None
= 0b0000_0000__0000_0000__0000,
3884 // Things that are interior to the value (first nibble):
3885 InteriorUnsized
= 0b0000_0000__0000_0000__0001,
3886 InteriorUnsafe
= 0b0000_0000__0000_0000__0010,
3887 InteriorParam
= 0b0000_0000__0000_0000__0100,
3888 // InteriorAll = 0b00000000__00000000__1111,
3890 // Things that are owned by the value (second and third nibbles):
3891 OwnsOwned
= 0b0000_0000__0000_0001__0000,
3892 OwnsDtor
= 0b0000_0000__0000_0010__0000,
3893 OwnsAll
= 0b0000_0000__1111_1111__0000,
3895 // Things that are reachable by the value in any way (fourth nibble):
3896 ReachesBorrowed
= 0b0000_0010__0000_0000__0000,
3897 ReachesMutable
= 0b0000_1000__0000_0000__0000,
3898 ReachesFfiUnsafe
= 0b0010_0000__0000_0000__0000,
3899 ReachesAll
= 0b0011_1111__0000_0000__0000,
3901 // Things that mean drop glue is necessary
3902 NeedsDrop
= 0b0000_0000__0000_0111__0000,
3904 // Things that prevent values from being considered sized
3905 Nonsized
= 0b0000_0000__0000_0000__0001,
3908 All
= 0b1111_1111__1111_1111__1111
3913 pub fn when(&self, cond
: bool
) -> TypeContents
{
3914 if cond {*self}
else {TC::None}
3917 pub fn intersects(&self, tc
: TypeContents
) -> bool
{
3918 (self.bits
& tc
.bits
) != 0
3921 pub fn owns_owned(&self) -> bool
{
3922 self.intersects(TC
::OwnsOwned
)
3925 pub fn is_sized(&self, _
: &ctxt
) -> bool
{
3926 !self.intersects(TC
::Nonsized
)
3929 pub fn interior_param(&self) -> bool
{
3930 self.intersects(TC
::InteriorParam
)
3933 pub fn interior_unsafe(&self) -> bool
{
3934 self.intersects(TC
::InteriorUnsafe
)
3937 pub fn interior_unsized(&self) -> bool
{
3938 self.intersects(TC
::InteriorUnsized
)
3941 pub fn needs_drop(&self, _
: &ctxt
) -> bool
{
3942 self.intersects(TC
::NeedsDrop
)
3945 /// Includes only those bits that still apply when indirected through a `Box` pointer
3946 pub fn owned_pointer(&self) -> TypeContents
{
3948 *self & (TC
::OwnsAll
| TC
::ReachesAll
))
3951 /// Includes only those bits that still apply when indirected through a reference (`&`)
3952 pub fn reference(&self, bits
: TypeContents
) -> TypeContents
{
3954 *self & TC
::ReachesAll
)
3957 /// Includes only those bits that still apply when indirected through a raw pointer (`*`)
3958 pub fn unsafe_pointer(&self) -> TypeContents
{
3959 *self & TC
::ReachesAll
3962 pub fn union<T
, F
>(v
: &[T
], mut f
: F
) -> TypeContents
where
3963 F
: FnMut(&T
) -> TypeContents
,
3965 v
.iter().fold(TC
::None
, |tc
, ty
| tc
| f(ty
))
3968 pub fn has_dtor(&self) -> bool
{
3969 self.intersects(TC
::OwnsDtor
)
3973 impl ops
::BitOr
for TypeContents
{
3974 type Output
= TypeContents
;
3976 fn bitor(self, other
: TypeContents
) -> TypeContents
{
3977 TypeContents {bits: self.bits | other.bits}
3981 impl ops
::BitAnd
for TypeContents
{
3982 type Output
= TypeContents
;
3984 fn bitand(self, other
: TypeContents
) -> TypeContents
{
3985 TypeContents {bits: self.bits & other.bits}
3989 impl ops
::Sub
for TypeContents
{
3990 type Output
= TypeContents
;
3992 fn sub(self, other
: TypeContents
) -> TypeContents
{
3993 TypeContents {bits: self.bits & !other.bits}
3997 impl fmt
::Debug
for TypeContents
{
3998 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
3999 write
!(f
, "TypeContents({:b})", self.bits
)
4003 pub fn type_contents
<'tcx
>(cx
: &ctxt
<'tcx
>, ty
: Ty
<'tcx
>) -> TypeContents
{
4004 return memoized(&cx
.tc_cache
, ty
, |ty
| {
4005 tc_ty(cx
, ty
, &mut FnvHashMap())
4008 fn tc_ty
<'tcx
>(cx
: &ctxt
<'tcx
>,
4010 cache
: &mut FnvHashMap
<Ty
<'tcx
>, TypeContents
>) -> TypeContents
4012 // Subtle: Note that we are *not* using cx.tc_cache here but rather a
4013 // private cache for this walk. This is needed in the case of cyclic
4016 // struct List { next: Box<Option<List>>, ... }
4018 // When computing the type contents of such a type, we wind up deeply
4019 // recursing as we go. So when we encounter the recursive reference
4020 // to List, we temporarily use TC::None as its contents. Later we'll
4021 // patch up the cache with the correct value, once we've computed it
4022 // (this is basically a co-inductive process, if that helps). So in
4023 // the end we'll compute TC::OwnsOwned, in this case.
4025 // The problem is, as we are doing the computation, we will also
4026 // compute an *intermediate* contents for, e.g., Option<List> of
4027 // TC::None. This is ok during the computation of List itself, but if
4028 // we stored this intermediate value into cx.tc_cache, then later
4029 // requests for the contents of Option<List> would also yield TC::None
4030 // which is incorrect. This value was computed based on the crutch
4031 // value for the type contents of list. The correct value is
4032 // TC::OwnsOwned. This manifested as issue #4821.
4033 match cache
.get(&ty
) {
4034 Some(tc
) => { return *tc; }
4037 match cx
.tc_cache
.borrow().get(&ty
) { // Must check both caches!
4038 Some(tc
) => { return *tc; }
4041 cache
.insert(ty
, TC
::None
);
4043 let result
= match ty
.sty
{
4044 // usize and isize are ffi-unsafe
4045 TyUint(ast
::TyUs
) | TyInt(ast
::TyIs
) => {
4046 TC
::ReachesFfiUnsafe
4049 // Scalar and unique types are sendable, and durable
4050 TyInfer(ty
::FreshIntTy(_
)) | TyInfer(ty
::FreshFloatTy(_
)) |
4051 TyBool
| TyInt(_
) | TyUint(_
) | TyFloat(_
) |
4052 TyBareFn(..) | ty
::TyChar
=> {
4057 TC
::ReachesFfiUnsafe
| match typ
.sty
{
4058 TyStr
=> TC
::OwnsOwned
,
4059 _
=> tc_ty(cx
, typ
, cache
).owned_pointer(),
4063 TyTrait(box TraitTy { ref bounds, .. }
) => {
4064 object_contents(bounds
) | TC
::ReachesFfiUnsafe
| TC
::Nonsized
4067 TyRawPtr(ref mt
) => {
4068 tc_ty(cx
, mt
.ty
, cache
).unsafe_pointer()
4071 TyRef(r
, ref mt
) => {
4072 TC
::ReachesFfiUnsafe
| match mt
.ty
.sty
{
4073 TyStr
=> borrowed_contents(*r
, ast
::MutImmutable
),
4075 TySlice(_
) => tc_ty(cx
, mt
.ty
, cache
).reference(borrowed_contents(*r
,
4077 _
=> tc_ty(cx
, mt
.ty
, cache
).reference(borrowed_contents(*r
, mt
.mutbl
)),
4082 tc_ty(cx
, ty
, cache
)
4086 tc_ty(cx
, ty
, cache
) | TC
::Nonsized
4088 TyStr
=> TC
::Nonsized
,
4090 TyStruct(did
, substs
) => {
4091 let flds
= struct_fields(cx
, did
, substs
);
4093 TypeContents
::union(&flds
[..],
4094 |f
| tc_mt(cx
, f
.mt
, cache
));
4096 if !lookup_repr_hints(cx
, did
).contains(&attr
::ReprExtern
) {
4097 res
= res
| TC
::ReachesFfiUnsafe
;
4100 if ty
::has_dtor(cx
, did
) {
4101 res
= res
| TC
::OwnsDtor
;
4103 apply_lang_items(cx
, did
, res
)
4106 TyClosure(did
, substs
) => {
4107 // FIXME(#14449): `borrowed_contents` below assumes `&mut` closure.
4108 let param_env
= ty
::empty_parameter_environment(cx
);
4109 let upvars
= closure_upvars(¶m_env
, did
, substs
).unwrap();
4110 TypeContents
::union(&upvars
, |f
| tc_ty(cx
, &f
.ty
, cache
))
4113 TyTuple(ref tys
) => {
4114 TypeContents
::union(&tys
[..],
4115 |ty
| tc_ty(cx
, *ty
, cache
))
4118 TyEnum(did
, substs
) => {
4119 let variants
= substd_enum_variants(cx
, did
, substs
);
4121 TypeContents
::union(&variants
[..], |variant
| {
4122 TypeContents
::union(&variant
.args
,
4124 tc_ty(cx
, *arg_ty
, cache
)
4128 if ty
::has_dtor(cx
, did
) {
4129 res
= res
| TC
::OwnsDtor
;
4132 if !variants
.is_empty() {
4133 let repr_hints
= lookup_repr_hints(cx
, did
);
4134 if repr_hints
.len() > 1 {
4135 // this is an error later on, but this type isn't safe
4136 res
= res
| TC
::ReachesFfiUnsafe
;
4139 match repr_hints
.get(0) {
4140 Some(h
) => if !h
.is_ffi_safe() {
4141 res
= res
| TC
::ReachesFfiUnsafe
;
4145 res
= res
| TC
::ReachesFfiUnsafe
;
4147 // We allow ReprAny enums if they are eligible for
4148 // the nullable pointer optimization and the
4149 // contained type is an `extern fn`
4151 if variants
.len() == 2 {
4152 let mut data_idx
= 0;
4154 if variants
[0].args
.is_empty() {
4158 if variants
[data_idx
].args
.len() == 1 {
4159 match variants
[data_idx
].args
[0].sty
{
4160 TyBareFn(..) => { res = res - TC::ReachesFfiUnsafe; }
4170 apply_lang_items(cx
, did
, res
)
4180 cx
.sess
.bug("asked to compute contents of error type");
4184 cache
.insert(ty
, result
);
4188 fn tc_mt
<'tcx
>(cx
: &ctxt
<'tcx
>,
4190 cache
: &mut FnvHashMap
<Ty
<'tcx
>, TypeContents
>) -> TypeContents
4192 let mc
= TC
::ReachesMutable
.when(mt
.mutbl
== MutMutable
);
4193 mc
| tc_ty(cx
, mt
.ty
, cache
)
4196 fn apply_lang_items(cx
: &ctxt
, did
: ast
::DefId
, tc
: TypeContents
)
4198 if Some(did
) == cx
.lang_items
.unsafe_cell_type() {
4199 tc
| TC
::InteriorUnsafe
4205 /// Type contents due to containing a reference with the region `region` and borrow kind `bk`
4206 fn borrowed_contents(region
: ty
::Region
,
4207 mutbl
: ast
::Mutability
)
4209 let b
= match mutbl
{
4210 ast
::MutMutable
=> TC
::ReachesMutable
,
4211 ast
::MutImmutable
=> TC
::None
,
4213 b
| (TC
::ReachesBorrowed
).when(region
!= ty
::ReStatic
)
4216 fn object_contents(bounds
: &ExistentialBounds
) -> TypeContents
{
4217 // These are the type contents of the (opaque) interior. We
4218 // make no assumptions (other than that it cannot have an
4219 // in-scope type parameter within, which makes no sense).
4220 let mut tc
= TC
::All
- TC
::InteriorParam
;
4221 for bound
in &bounds
.builtin_bounds
{
4222 tc
= tc
- match bound
{
4223 BoundSync
| BoundSend
| BoundCopy
=> TC
::None
,
4224 BoundSized
=> TC
::Nonsized
,
4231 fn type_impls_bound
<'a
,'tcx
>(param_env
: Option
<&ParameterEnvironment
<'a
,'tcx
>>,
4232 tcx
: &ty
::ctxt
<'tcx
>,
4234 bound
: ty
::BuiltinBound
,
4239 let param_env
= match param_env
{
4242 pe
= empty_parameter_environment(tcx
);
4246 let infcx
= infer
::new_infer_ctxt(tcx
);
4248 let is_impld
= traits
::type_known_to_meet_builtin_bound(&infcx
, param_env
, ty
, bound
, span
);
4250 debug
!("type_impls_bound({:?}, {:?}) = {:?}",
4258 pub fn type_moves_by_default
<'a
,'tcx
>(param_env
: &ParameterEnvironment
<'a
,'tcx
>,
4263 if ty
.flags
.get().intersects(TypeFlags
::MOVENESS_CACHED
) {
4264 return ty
.flags
.get().intersects(TypeFlags
::MOVES_BY_DEFAULT
);
4267 assert
!(!ty
::type_needs_infer(ty
));
4269 // Fast-path for primitive types
4270 let result
= match ty
.sty
{
4271 TyBool
| TyChar
| TyInt(..) | TyUint(..) | TyFloat(..) |
4272 TyRawPtr(..) | TyBareFn(..) | TyRef(_
, mt
{
4273 mutbl
: ast
::MutImmutable
, ..
4276 TyStr
| TyBox(..) | TyRef(_
, mt
{
4277 mutbl
: ast
::MutMutable
, ..
4280 TyArray(..) | TySlice(_
) | TyTrait(..) | TyTuple(..) |
4281 TyClosure(..) | TyEnum(..) | TyStruct(..) |
4282 TyProjection(..) | TyParam(..) | TyInfer(..) | TyError
=> None
4283 }.unwrap_or_else(|| !type_impls_bound(Some(param_env
),
4289 if !type_has_params(ty
) && !type_has_self(ty
) {
4290 ty
.flags
.set(ty
.flags
.get() | if result
{
4291 TypeFlags
::MOVENESS_CACHED
| TypeFlags
::MOVES_BY_DEFAULT
4293 TypeFlags
::MOVENESS_CACHED
4301 pub fn type_is_sized
<'a
,'tcx
>(param_env
: Option
<&ParameterEnvironment
<'a
,'tcx
>>,
4302 tcx
: &ty
::ctxt
<'tcx
>,
4307 if ty
.flags
.get().intersects(TypeFlags
::SIZEDNESS_CACHED
) {
4308 let result
= ty
.flags
.get().intersects(TypeFlags
::IS_SIZED
);
4312 type_is_sized_uncached(param_env
, tcx
, span
, ty
)
4315 fn type_is_sized_uncached
<'a
,'tcx
>(param_env
: Option
<&ParameterEnvironment
<'a
,'tcx
>>,
4316 tcx
: &ty
::ctxt
<'tcx
>,
4318 ty
: Ty
<'tcx
>) -> bool
{
4319 assert
!(!ty
::type_needs_infer(ty
));
4321 // Fast-path for primitive types
4322 let result
= match ty
.sty
{
4323 TyBool
| TyChar
| TyInt(..) | TyUint(..) | TyFloat(..) |
4324 TyBox(..) | TyRawPtr(..) | TyRef(..) | TyBareFn(..) |
4325 TyArray(..) | TyTuple(..) | TyClosure(..) => Some(true),
4327 TyStr
| TyTrait(..) | TySlice(_
) => Some(false),
4329 TyEnum(..) | TyStruct(..) | TyProjection(..) | TyParam(..) |
4330 TyInfer(..) | TyError
=> None
4331 }.unwrap_or_else(|| type_impls_bound(param_env
, tcx
, ty
, ty
::BoundSized
, span
));
4333 if !type_has_params(ty
) && !type_has_self(ty
) {
4334 ty
.flags
.set(ty
.flags
.get() | if result
{
4335 TypeFlags
::SIZEDNESS_CACHED
| TypeFlags
::IS_SIZED
4337 TypeFlags
::SIZEDNESS_CACHED
4344 pub fn is_ffi_safe
<'tcx
>(cx
: &ctxt
<'tcx
>, ty
: Ty
<'tcx
>) -> bool
{
4345 !type_contents(cx
, ty
).intersects(TC
::ReachesFfiUnsafe
)
4348 // True if instantiating an instance of `r_ty` requires an instance of `r_ty`.
4349 pub fn is_instantiable
<'tcx
>(cx
: &ctxt
<'tcx
>, r_ty
: Ty
<'tcx
>) -> bool
{
4350 fn type_requires
<'tcx
>(cx
: &ctxt
<'tcx
>, seen
: &mut Vec
<DefId
>,
4351 r_ty
: Ty
<'tcx
>, ty
: Ty
<'tcx
>) -> bool
{
4352 debug
!("type_requires({:?}, {:?})?",
4355 let r
= r_ty
== ty
|| subtypes_require(cx
, seen
, r_ty
, ty
);
4357 debug
!("type_requires({:?}, {:?})? {:?}",
4362 fn subtypes_require
<'tcx
>(cx
: &ctxt
<'tcx
>, seen
: &mut Vec
<DefId
>,
4363 r_ty
: Ty
<'tcx
>, ty
: Ty
<'tcx
>) -> bool
{
4364 debug
!("subtypes_require({:?}, {:?})?",
4367 let r
= match ty
.sty
{
4368 // fixed length vectors need special treatment compared to
4369 // normal vectors, since they don't necessarily have the
4370 // possibility to have length zero.
4371 TyArray(_
, 0) => false, // don't need no contents
4372 TyArray(ty
, _
) => type_requires(cx
, seen
, r_ty
, ty
),
4387 type_requires(cx
, seen
, r_ty
, typ
)
4389 TyRef(_
, ref mt
) => {
4390 type_requires(cx
, seen
, r_ty
, mt
.ty
)
4394 false // unsafe ptrs can always be NULL
4401 TyStruct(ref did
, _
) if seen
.contains(did
) => {
4405 TyStruct(did
, substs
) => {
4407 let fields
= struct_fields(cx
, did
, substs
);
4408 let r
= fields
.iter().any(|f
| type_requires(cx
, seen
, r_ty
, f
.mt
.ty
));
4409 seen
.pop().unwrap();
4416 // this check is run on type definitions, so we don't expect to see
4417 // inference by-products or closure types
4418 cx
.sess
.bug(&format
!("requires check invoked on inapplicable type: {:?}", ty
))
4421 TyTuple(ref ts
) => {
4422 ts
.iter().any(|ty
| type_requires(cx
, seen
, r_ty
, *ty
))
4425 TyEnum(ref did
, _
) if seen
.contains(did
) => {
4429 TyEnum(did
, substs
) => {
4431 let vs
= enum_variants(cx
, did
);
4432 let r
= !vs
.is_empty() && vs
.iter().all(|variant
| {
4433 variant
.args
.iter().any(|aty
| {
4434 let sty
= aty
.subst(cx
, substs
);
4435 type_requires(cx
, seen
, r_ty
, sty
)
4438 seen
.pop().unwrap();
4443 debug
!("subtypes_require({:?}, {:?})? {:?}",
4449 let mut seen
= Vec
::new();
4450 !subtypes_require(cx
, &mut seen
, r_ty
, r_ty
)
4453 /// Describes whether a type is representable. For types that are not
4454 /// representable, 'SelfRecursive' and 'ContainsRecursive' are used to
4455 /// distinguish between types that are recursive with themselves and types that
4456 /// contain a different recursive type. These cases can therefore be treated
4457 /// differently when reporting errors.
4459 /// The ordering of the cases is significant. They are sorted so that cmp::max
4460 /// will keep the "more erroneous" of two values.
4461 #[derive(Copy, Clone, PartialOrd, Ord, Eq, PartialEq, Debug)]
4462 pub enum Representability
{
4468 /// Check whether a type is representable. This means it cannot contain unboxed
4469 /// structural recursion. This check is needed for structs and enums.
4470 pub fn is_type_representable
<'tcx
>(cx
: &ctxt
<'tcx
>, sp
: Span
, ty
: Ty
<'tcx
>)
4471 -> Representability
{
4473 // Iterate until something non-representable is found
4474 fn find_nonrepresentable
<'tcx
, It
: Iterator
<Item
=Ty
<'tcx
>>>(cx
: &ctxt
<'tcx
>, sp
: Span
,
4475 seen
: &mut Vec
<Ty
<'tcx
>>,
4477 -> Representability
{
4478 iter
.fold(Representable
,
4479 |r
, ty
| cmp
::max(r
, is_type_structurally_recursive(cx
, sp
, seen
, ty
)))
4482 fn are_inner_types_recursive
<'tcx
>(cx
: &ctxt
<'tcx
>, sp
: Span
,
4483 seen
: &mut Vec
<Ty
<'tcx
>>, ty
: Ty
<'tcx
>)
4484 -> Representability
{
4486 TyTuple(ref ts
) => {
4487 find_nonrepresentable(cx
, sp
, seen
, ts
.iter().cloned())
4489 // Fixed-length vectors.
4490 // FIXME(#11924) Behavior undecided for zero-length vectors.
4492 is_type_structurally_recursive(cx
, sp
, seen
, ty
)
4494 TyStruct(did
, substs
) => {
4495 let fields
= struct_fields(cx
, did
, substs
);
4496 find_nonrepresentable(cx
, sp
, seen
, fields
.iter().map(|f
| f
.mt
.ty
))
4498 TyEnum(did
, substs
) => {
4499 let vs
= enum_variants(cx
, did
);
4500 let iter
= vs
.iter()
4501 .flat_map(|variant
| &variant
.args
)
4502 .map(|aty
| { aty.subst_spanned(cx, substs, Some(sp)) }
);
4504 find_nonrepresentable(cx
, sp
, seen
, iter
)
4507 // this check is run on type definitions, so we don't expect
4508 // to see closure types
4509 cx
.sess
.bug(&format
!("requires check invoked on inapplicable type: {:?}", ty
))
4515 fn same_struct_or_enum_def_id(ty
: Ty
, did
: DefId
) -> bool
{
4517 TyStruct(ty_did
, _
) | TyEnum(ty_did
, _
) => {
4524 fn same_type
<'tcx
>(a
: Ty
<'tcx
>, b
: Ty
<'tcx
>) -> bool
{
4525 match (&a
.sty
, &b
.sty
) {
4526 (&TyStruct(did_a
, ref substs_a
), &TyStruct(did_b
, ref substs_b
)) |
4527 (&TyEnum(did_a
, ref substs_a
), &TyEnum(did_b
, ref substs_b
)) => {
4532 let types_a
= substs_a
.types
.get_slice(subst
::TypeSpace
);
4533 let types_b
= substs_b
.types
.get_slice(subst
::TypeSpace
);
4535 let mut pairs
= types_a
.iter().zip(types_b
);
4537 pairs
.all(|(&a
, &b
)| same_type(a
, b
))
4545 // Does the type `ty` directly (without indirection through a pointer)
4546 // contain any types on stack `seen`?
4547 fn is_type_structurally_recursive
<'tcx
>(cx
: &ctxt
<'tcx
>, sp
: Span
,
4548 seen
: &mut Vec
<Ty
<'tcx
>>,
4549 ty
: Ty
<'tcx
>) -> Representability
{
4550 debug
!("is_type_structurally_recursive: {:?}", ty
);
4553 TyStruct(did
, _
) | TyEnum(did
, _
) => {
4555 // Iterate through stack of previously seen types.
4556 let mut iter
= seen
.iter();
4558 // The first item in `seen` is the type we are actually curious about.
4559 // We want to return SelfRecursive if this type contains itself.
4560 // It is important that we DON'T take generic parameters into account
4561 // for this check, so that Bar<T> in this example counts as SelfRecursive:
4564 // struct Bar<T> { x: Bar<Foo> }
4567 Some(&seen_type
) => {
4568 if same_struct_or_enum_def_id(seen_type
, did
) {
4569 debug
!("SelfRecursive: {:?} contains {:?}",
4572 return SelfRecursive
;
4578 // We also need to know whether the first item contains other types that
4579 // are structurally recursive. If we don't catch this case, we will recurse
4580 // infinitely for some inputs.
4582 // It is important that we DO take generic parameters into account here,
4583 // so that code like this is considered SelfRecursive, not ContainsRecursive:
4585 // struct Foo { Option<Option<Foo>> }
4587 for &seen_type
in iter
{
4588 if same_type(ty
, seen_type
) {
4589 debug
!("ContainsRecursive: {:?} contains {:?}",
4592 return ContainsRecursive
;
4597 // For structs and enums, track all previously seen types by pushing them
4598 // onto the 'seen' stack.
4600 let out
= are_inner_types_recursive(cx
, sp
, seen
, ty
);
4605 // No need to push in other cases.
4606 are_inner_types_recursive(cx
, sp
, seen
, ty
)
4611 debug
!("is_type_representable: {:?}", ty
);
4613 // To avoid a stack overflow when checking an enum variant or struct that
4614 // contains a different, structurally recursive type, maintain a stack
4615 // of seen types and check recursion for each of them (issues #3008, #3779).
4616 let mut seen
: Vec
<Ty
> = Vec
::new();
4617 let r
= is_type_structurally_recursive(cx
, sp
, &mut seen
, ty
);
4618 debug
!("is_type_representable: {:?} is {:?}", ty
, r
);
4622 pub fn type_is_trait(ty
: Ty
) -> bool
{
4624 TyTrait(..) => true,
4629 pub fn type_is_integral(ty
: Ty
) -> bool
{
4631 TyInfer(IntVar(_
)) | TyInt(_
) | TyUint(_
) => true,
4636 pub fn type_is_fresh(ty
: Ty
) -> bool
{
4638 TyInfer(FreshTy(_
)) => true,
4639 TyInfer(FreshIntTy(_
)) => true,
4640 TyInfer(FreshFloatTy(_
)) => true,
4645 pub fn type_is_uint(ty
: Ty
) -> bool
{
4647 TyInfer(IntVar(_
)) | TyUint(ast
::TyUs
) => true,
4652 pub fn type_is_char(ty
: Ty
) -> bool
{
4659 pub fn type_is_bare_fn(ty
: Ty
) -> bool
{
4661 TyBareFn(..) => true,
4666 pub fn type_is_bare_fn_item(ty
: Ty
) -> bool
{
4668 TyBareFn(Some(_
), _
) => true,
4673 pub fn type_is_fp(ty
: Ty
) -> bool
{
4675 TyInfer(FloatVar(_
)) | TyFloat(_
) => true,
4680 pub fn type_is_numeric(ty
: Ty
) -> bool
{
4681 return type_is_integral(ty
) || type_is_fp(ty
);
4684 pub fn type_is_signed(ty
: Ty
) -> bool
{
4691 pub fn type_is_machine(ty
: Ty
) -> bool
{
4693 TyInt(ast
::TyIs
) | TyUint(ast
::TyUs
) => false,
4694 TyInt(..) | TyUint(..) | TyFloat(..) => true,
4699 // Whether a type is enum like, that is an enum type with only nullary
4701 pub fn type_is_c_like_enum(cx
: &ctxt
, ty
: Ty
) -> bool
{
4704 let variants
= enum_variants(cx
, did
);
4705 if variants
.is_empty() {
4708 variants
.iter().all(|v
| v
.args
.is_empty())
4715 // Returns the type and mutability of *ty.
4717 // The parameter `explicit` indicates if this is an *explicit* dereference.
4718 // Some types---notably unsafe ptrs---can only be dereferenced explicitly.
4719 pub fn deref
<'tcx
>(ty
: Ty
<'tcx
>, explicit
: bool
) -> Option
<mt
<'tcx
>> {
4724 mutbl
: ast
::MutImmutable
,
4727 TyRef(_
, mt
) => Some(mt
),
4728 TyRawPtr(mt
) if explicit
=> Some(mt
),
4733 pub fn type_content
<'tcx
>(ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
4736 TyRef(_
, mt
) | TyRawPtr(mt
) => mt
.ty
,
4741 // Returns the type of ty[i]
4742 pub fn index
<'tcx
>(ty
: Ty
<'tcx
>) -> Option
<Ty
<'tcx
>> {
4744 TyArray(ty
, _
) | TySlice(ty
) => Some(ty
),
4749 // Returns the type of elements contained within an 'array-like' type.
4750 // This is exactly the same as the above, except it supports strings,
4751 // which can't actually be indexed.
4752 pub fn array_element_ty
<'tcx
>(tcx
: &ctxt
<'tcx
>, ty
: Ty
<'tcx
>) -> Option
<Ty
<'tcx
>> {
4754 TyArray(ty
, _
) | TySlice(ty
) => Some(ty
),
4755 TyStr
=> Some(tcx
.types
.u8),
4760 /// Returns the type of element at index `i` in tuple or tuple-like type `t`.
4761 /// For an enum `t`, `variant` is None only if `t` is a univariant enum.
4762 pub fn positional_element_ty
<'tcx
>(cx
: &ctxt
<'tcx
>,
4765 variant
: Option
<ast
::DefId
>) -> Option
<Ty
<'tcx
>> {
4767 match (&ty
.sty
, variant
) {
4768 (&TyTuple(ref v
), None
) => v
.get(i
).cloned(),
4771 (&TyStruct(def_id
, substs
), None
) => lookup_struct_fields(cx
, def_id
)
4773 .map(|&t
|lookup_item_type(cx
, t
.id
).ty
.subst(cx
, substs
)),
4775 (&TyEnum(def_id
, substs
), Some(variant_def_id
)) => {
4776 let variant_info
= enum_variant_with_id(cx
, def_id
, variant_def_id
);
4777 variant_info
.args
.get(i
).map(|t
|t
.subst(cx
, substs
))
4780 (&TyEnum(def_id
, substs
), None
) => {
4781 assert
!(enum_is_univariant(cx
, def_id
));
4782 let enum_variants
= enum_variants(cx
, def_id
);
4783 let variant_info
= &(*enum_variants
)[0];
4784 variant_info
.args
.get(i
).map(|t
|t
.subst(cx
, substs
))
4791 /// Returns the type of element at field `n` in struct or struct-like type `t`.
4792 /// For an enum `t`, `variant` must be some def id.
4793 pub fn named_element_ty
<'tcx
>(cx
: &ctxt
<'tcx
>,
4796 variant
: Option
<ast
::DefId
>) -> Option
<Ty
<'tcx
>> {
4798 match (&ty
.sty
, variant
) {
4799 (&TyStruct(def_id
, substs
), None
) => {
4800 let r
= lookup_struct_fields(cx
, def_id
);
4801 r
.iter().find(|f
| f
.name
== n
)
4802 .map(|&f
| lookup_field_type(cx
, def_id
, f
.id
, substs
))
4804 (&TyEnum(def_id
, substs
), Some(variant_def_id
)) => {
4805 let variant_info
= enum_variant_with_id(cx
, def_id
, variant_def_id
);
4806 variant_info
.arg_names
.as_ref()
4807 .expect("must have struct enum variant if accessing a named fields")
4808 .iter().zip(&variant_info
.args
)
4809 .find(|&(&name
, _
)| name
== n
)
4810 .map(|(_name
, arg_t
)| arg_t
.subst(cx
, substs
))
4816 pub fn node_id_to_type
<'tcx
>(cx
: &ctxt
<'tcx
>, id
: ast
::NodeId
) -> Ty
<'tcx
> {
4817 match node_id_to_type_opt(cx
, id
) {
4819 None
=> cx
.sess
.bug(
4820 &format
!("node_id_to_type: no type for node `{}`",
4821 cx
.map
.node_to_string(id
)))
4825 pub fn node_id_to_type_opt
<'tcx
>(cx
: &ctxt
<'tcx
>, id
: ast
::NodeId
) -> Option
<Ty
<'tcx
>> {
4826 match cx
.node_types
.borrow().get(&id
) {
4827 Some(&ty
) => Some(ty
),
4832 pub fn node_id_item_substs
<'tcx
>(cx
: &ctxt
<'tcx
>, id
: ast
::NodeId
) -> ItemSubsts
<'tcx
> {
4833 match cx
.item_substs
.borrow().get(&id
) {
4834 None
=> ItemSubsts
::empty(),
4835 Some(ts
) => ts
.clone(),
4839 pub fn fn_is_variadic(fty
: Ty
) -> bool
{
4841 TyBareFn(_
, ref f
) => f
.sig
.0.variadic
,
4843 panic
!("fn_is_variadic() called on non-fn type: {:?}", s
)
4848 pub fn ty_fn_sig
<'tcx
>(fty
: Ty
<'tcx
>) -> &'tcx PolyFnSig
<'tcx
> {
4850 TyBareFn(_
, ref f
) => &f
.sig
,
4852 panic
!("ty_fn_sig() called on non-fn type: {:?}", s
)
4857 /// Returns the ABI of the given function.
4858 pub fn ty_fn_abi(fty
: Ty
) -> abi
::Abi
{
4860 TyBareFn(_
, ref f
) => f
.abi
,
4861 _
=> panic
!("ty_fn_abi() called on non-fn type"),
4865 // Type accessors for substructures of types
4866 pub fn ty_fn_args
<'tcx
>(fty
: Ty
<'tcx
>) -> ty
::Binder
<Vec
<Ty
<'tcx
>>> {
4867 ty_fn_sig(fty
).inputs()
4870 pub fn ty_fn_ret
<'tcx
>(fty
: Ty
<'tcx
>) -> Binder
<FnOutput
<'tcx
>> {
4872 TyBareFn(_
, ref f
) => f
.sig
.output(),
4874 panic
!("ty_fn_ret() called on non-fn type: {:?}", s
)
4879 pub fn is_fn_ty(fty
: Ty
) -> bool
{
4881 TyBareFn(..) => true,
4886 pub fn ty_region(tcx
: &ctxt
,
4894 &format
!("ty_region() invoked on an inappropriate ty: {:?}",
4900 pub fn free_region_from_def(outlives_extent
: region
::DestructionScopeData
,
4901 def
: &RegionParameterDef
)
4905 ty
::ReFree(ty
::FreeRegion
{ scope
: outlives_extent
,
4906 bound_region
: ty
::BrNamed(def
.def_id
,
4908 debug
!("free_region_from_def returns {:?}", ret
);
4912 // Returns the type of a pattern as a monotype. Like @expr_ty, this function
4913 // doesn't provide type parameter substitutions.
4914 pub fn pat_ty
<'tcx
>(cx
: &ctxt
<'tcx
>, pat
: &ast
::Pat
) -> Ty
<'tcx
> {
4915 return node_id_to_type(cx
, pat
.id
);
4917 pub fn pat_ty_opt
<'tcx
>(cx
: &ctxt
<'tcx
>, pat
: &ast
::Pat
) -> Option
<Ty
<'tcx
>> {
4918 return node_id_to_type_opt(cx
, pat
.id
);
4922 // Returns the type of an expression as a monotype.
4924 // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in
4925 // some cases, we insert `AutoAdjustment` annotations such as auto-deref or
4926 // auto-ref. The type returned by this function does not consider such
4927 // adjustments. See `expr_ty_adjusted()` instead.
4929 // NB (2): This type doesn't provide type parameter substitutions; e.g. if you
4930 // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
4931 // instead of "fn(ty) -> T with T = isize".
4932 pub fn expr_ty
<'tcx
>(cx
: &ctxt
<'tcx
>, expr
: &ast
::Expr
) -> Ty
<'tcx
> {
4933 return node_id_to_type(cx
, expr
.id
);
4936 pub fn expr_ty_opt
<'tcx
>(cx
: &ctxt
<'tcx
>, expr
: &ast
::Expr
) -> Option
<Ty
<'tcx
>> {
4937 return node_id_to_type_opt(cx
, expr
.id
);
4940 /// Returns the type of `expr`, considering any `AutoAdjustment`
4941 /// entry recorded for that expression.
4943 /// It would almost certainly be better to store the adjusted ty in with
4944 /// the `AutoAdjustment`, but I opted not to do this because it would
4945 /// require serializing and deserializing the type and, although that's not
4946 /// hard to do, I just hate that code so much I didn't want to touch it
4947 /// unless it was to fix it properly, which seemed a distraction from the
4948 /// thread at hand! -nmatsakis
4949 pub fn expr_ty_adjusted
<'tcx
>(cx
: &ctxt
<'tcx
>, expr
: &ast
::Expr
) -> Ty
<'tcx
> {
4950 adjust_ty(cx
, expr
.span
, expr
.id
, expr_ty(cx
, expr
),
4951 cx
.adjustments
.borrow().get(&expr
.id
),
4952 |method_call
| cx
.method_map
.borrow().get(&method_call
).map(|method
| method
.ty
))
4955 pub fn expr_span(cx
: &ctxt
, id
: NodeId
) -> Span
{
4956 match cx
.map
.find(id
) {
4957 Some(ast_map
::NodeExpr(e
)) => {
4961 cx
.sess
.bug(&format
!("Node id {} is not an expr: {:?}",
4966 cx
.sess
.bug(&format
!("Node id {} is not present \
4967 in the node map", id
));
4972 pub fn local_var_name_str(cx
: &ctxt
, id
: NodeId
) -> InternedString
{
4973 match cx
.map
.find(id
) {
4974 Some(ast_map
::NodeLocal(pat
)) => {
4976 ast
::PatIdent(_
, ref path1
, _
) => {
4977 token
::get_ident(path1
.node
)
4981 &format
!("Variable id {} maps to {:?}, not local",
4988 cx
.sess
.bug(&format
!("Variable id {} maps to {:?}, not local",
4995 /// See `expr_ty_adjusted`
4996 pub fn adjust_ty
<'tcx
, F
>(cx
: &ctxt
<'tcx
>,
4998 expr_id
: ast
::NodeId
,
4999 unadjusted_ty
: Ty
<'tcx
>,
5000 adjustment
: Option
<&AutoAdjustment
<'tcx
>>,
5003 F
: FnMut(MethodCall
) -> Option
<Ty
<'tcx
>>,
5005 if let TyError
= unadjusted_ty
.sty
{
5006 return unadjusted_ty
;
5009 return match adjustment
{
5010 Some(adjustment
) => {
5012 AdjustReifyFnPointer
=> {
5013 match unadjusted_ty
.sty
{
5014 ty
::TyBareFn(Some(_
), b
) => {
5015 ty
::mk_bare_fn(cx
, None
, b
)
5019 &format
!("AdjustReifyFnPointer adjustment on non-fn-item: \
5020 {:?}", unadjusted_ty
));
5025 AdjustUnsafeFnPointer
=> {
5026 match unadjusted_ty
.sty
{
5027 ty
::TyBareFn(None
, b
) => cx
.safe_to_unsafe_fn_ty(b
),
5030 &format
!("AdjustReifyFnPointer adjustment on non-fn-item: \
5037 AdjustDerefRef(ref adj
) => {
5038 let mut adjusted_ty
= unadjusted_ty
;
5040 if !ty
::type_is_error(adjusted_ty
) {
5041 for i
in 0..adj
.autoderefs
{
5042 let method_call
= MethodCall
::autoderef(expr_id
, i
as u32);
5043 match method_type(method_call
) {
5044 Some(method_ty
) => {
5045 // Overloaded deref operators have all late-bound
5046 // regions fully instantiated and coverge.
5048 ty
::no_late_bound_regions(cx
,
5049 &ty_fn_ret(method_ty
)).unwrap();
5050 adjusted_ty
= fn_ret
.unwrap();
5054 match deref(adjusted_ty
, true) {
5055 Some(mt
) => { adjusted_ty = mt.ty; }
5059 &format
!("the {}th autoderef failed: {}",
5068 if let Some(target
) = adj
.unsize
{
5071 adjust_ty_for_autoref(cx
, adjusted_ty
, adj
.autoref
)
5076 None
=> unadjusted_ty
5080 pub fn adjust_ty_for_autoref
<'tcx
>(cx
: &ctxt
<'tcx
>,
5082 autoref
: Option
<AutoRef
<'tcx
>>)
5086 Some(AutoPtr(r
, m
)) => {
5087 mk_rptr(cx
, r
, mt { ty: ty, mutbl: m }
)
5089 Some(AutoUnsafe(m
)) => {
5090 mk_ptr(cx
, mt { ty: ty, mutbl: m }
)
5095 pub fn resolve_expr(tcx
: &ctxt
, expr
: &ast
::Expr
) -> def
::Def
{
5096 match tcx
.def_map
.borrow().get(&expr
.id
) {
5097 Some(def
) => def
.full_def(),
5099 tcx
.sess
.span_bug(expr
.span
, &format
!(
5100 "no def-map entry for expr {}", expr
.id
));
5105 pub fn expr_is_lval(tcx
: &ctxt
, expr
: &ast
::Expr
) -> bool
{
5107 ast
::ExprPath(..) => {
5108 // We can't use resolve_expr here, as this needs to run on broken
5109 // programs. We don't need to through - associated items are all
5111 match tcx
.def_map
.borrow().get(&expr
.id
) {
5112 Some(&def
::PathResolution
{
5113 base_def
: def
::DefStatic(..), ..
5114 }) | Some(&def
::PathResolution
{
5115 base_def
: def
::DefUpvar(..), ..
5116 }) | Some(&def
::PathResolution
{
5117 base_def
: def
::DefLocal(..), ..
5124 None
=> tcx
.sess
.span_bug(expr
.span
, &format
!(
5125 "no def for path {}", expr
.id
))
5129 ast
::ExprUnary(ast
::UnDeref
, _
) |
5130 ast
::ExprField(..) |
5131 ast
::ExprTupField(..) |
5132 ast
::ExprIndex(..) => {
5137 ast
::ExprMethodCall(..) |
5138 ast
::ExprStruct(..) |
5139 ast
::ExprRange(..) |
5142 ast
::ExprMatch(..) |
5143 ast
::ExprClosure(..) |
5144 ast
::ExprBlock(..) |
5145 ast
::ExprRepeat(..) |
5147 ast
::ExprBreak(..) |
5148 ast
::ExprAgain(..) |
5150 ast
::ExprWhile(..) |
5152 ast
::ExprAssign(..) |
5153 ast
::ExprInlineAsm(..) |
5154 ast
::ExprAssignOp(..) |
5156 ast
::ExprUnary(..) |
5158 ast
::ExprAddrOf(..) |
5159 ast
::ExprBinary(..) |
5160 ast
::ExprCast(..) => {
5164 ast
::ExprParen(ref e
) => expr_is_lval(tcx
, e
),
5166 ast
::ExprIfLet(..) |
5167 ast
::ExprWhileLet(..) |
5168 ast
::ExprForLoop(..) |
5169 ast
::ExprMac(..) => {
5172 "macro expression remains after expansion");
5177 pub fn stmt_node_id(s
: &ast
::Stmt
) -> ast
::NodeId
{
5179 ast
::StmtDecl(_
, id
) | StmtExpr(_
, id
) | StmtSemi(_
, id
) => {
5182 ast
::StmtMac(..) => panic
!("unexpanded macro in trans")
5186 pub fn field_idx_strict(tcx
: &ctxt
, name
: ast
::Name
, fields
: &[field
])
5189 for f
in fields { if f.name == name { return i; } i
+= 1; }
5190 tcx
.sess
.bug(&format
!(
5191 "no field named `{}` found in the list of fields `{:?}`",
5192 token
::get_name(name
),
5194 .map(|f
| token
::get_name(f
.name
).to_string())
5195 .collect
::<Vec
<String
>>()));
5198 pub fn impl_or_trait_item_idx(id
: ast
::Name
, trait_items
: &[ImplOrTraitItem
])
5200 trait_items
.iter().position(|m
| m
.name() == id
)
5203 pub fn ty_sort_string(cx
: &ctxt
, ty
: Ty
) -> String
{
5205 TyBool
| TyChar
| TyInt(_
) |
5206 TyUint(_
) | TyFloat(_
) | TyStr
=> ty
.to_string(),
5207 TyTuple(ref tys
) if tys
.is_empty() => ty
.to_string(),
5209 TyEnum(id
, _
) => format
!("enum `{}`", item_path_str(cx
, id
)),
5210 TyBox(_
) => "box".to_string(),
5211 TyArray(_
, n
) => format
!("array of {} elements", n
),
5212 TySlice(_
) => "slice".to_string(),
5213 TyRawPtr(_
) => "*-ptr".to_string(),
5214 TyRef(_
, _
) => "&-ptr".to_string(),
5215 TyBareFn(Some(_
), _
) => format
!("fn item"),
5216 TyBareFn(None
, _
) => "fn pointer".to_string(),
5217 TyTrait(ref inner
) => {
5218 format
!("trait {}", item_path_str(cx
, inner
.principal_def_id()))
5220 TyStruct(id
, _
) => {
5221 format
!("struct `{}`", item_path_str(cx
, id
))
5223 TyClosure(..) => "closure".to_string(),
5224 TyTuple(_
) => "tuple".to_string(),
5225 TyInfer(TyVar(_
)) => "inferred type".to_string(),
5226 TyInfer(IntVar(_
)) => "integral variable".to_string(),
5227 TyInfer(FloatVar(_
)) => "floating-point variable".to_string(),
5228 TyInfer(FreshTy(_
)) => "skolemized type".to_string(),
5229 TyInfer(FreshIntTy(_
)) => "skolemized integral type".to_string(),
5230 TyInfer(FreshFloatTy(_
)) => "skolemized floating-point type".to_string(),
5231 TyProjection(_
) => "associated type".to_string(),
5233 if p
.space
== subst
::SelfSpace
{
5236 "type parameter".to_string()
5239 TyError
=> "type error".to_string(),
5243 /// Explains the source of a type err in a short, human readable way. This is meant to be placed
5244 /// in parentheses after some larger message. You should also invoke `note_and_explain_type_err()`
5245 /// afterwards to present additional details, particularly when it comes to lifetime-related
5247 impl<'tcx
> fmt
::Display
for type_err
<'tcx
> {
5248 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
5250 terr_cyclic_ty
=> write
!(f
, "cyclic type of infinite size"),
5251 terr_mismatch
=> write
!(f
, "types differ"),
5252 terr_unsafety_mismatch(values
) => {
5253 write
!(f
, "expected {} fn, found {} fn",
5257 terr_abi_mismatch(values
) => {
5258 write
!(f
, "expected {} fn, found {} fn",
5262 terr_mutability
=> write
!(f
, "values differ in mutability"),
5263 terr_box_mutability
=> {
5264 write
!(f
, "boxed values differ in mutability")
5266 terr_vec_mutability
=> write
!(f
, "vectors differ in mutability"),
5267 terr_ptr_mutability
=> write
!(f
, "pointers differ in mutability"),
5268 terr_ref_mutability
=> write
!(f
, "references differ in mutability"),
5269 terr_ty_param_size(values
) => {
5270 write
!(f
, "expected a type with {} type params, \
5271 found one with {} type params",
5275 terr_fixed_array_size(values
) => {
5276 write
!(f
, "expected an array with a fixed size of {} elements, \
5277 found one with {} elements",
5281 terr_tuple_size(values
) => {
5282 write
!(f
, "expected a tuple with {} elements, \
5283 found one with {} elements",
5288 write
!(f
, "incorrect number of function parameters")
5290 terr_regions_does_not_outlive(..) => {
5291 write
!(f
, "lifetime mismatch")
5293 terr_regions_not_same(..) => {
5294 write
!(f
, "lifetimes are not the same")
5296 terr_regions_no_overlap(..) => {
5297 write
!(f
, "lifetimes do not intersect")
5299 terr_regions_insufficiently_polymorphic(br
, _
) => {
5300 write
!(f
, "expected bound lifetime parameter {}, \
5301 found concrete lifetime", br
)
5303 terr_regions_overly_polymorphic(br
, _
) => {
5304 write
!(f
, "expected concrete lifetime, \
5305 found bound lifetime parameter {}", br
)
5307 terr_sorts(values
) => tls
::with(|tcx
| {
5308 // A naive approach to making sure that we're not reporting silly errors such as:
5309 // (expected closure, found closure).
5310 let expected_str
= ty_sort_string(tcx
, values
.expected
);
5311 let found_str
= ty_sort_string(tcx
, values
.found
);
5312 if expected_str
== found_str
{
5313 write
!(f
, "expected {}, found a different {}", expected_str
, found_str
)
5315 write
!(f
, "expected {}, found {}", expected_str
, found_str
)
5318 terr_traits(values
) => tls
::with(|tcx
| {
5319 write
!(f
, "expected trait `{}`, found trait `{}`",
5320 item_path_str(tcx
, values
.expected
),
5321 item_path_str(tcx
, values
.found
))
5323 terr_builtin_bounds(values
) => {
5324 if values
.expected
.is_empty() {
5325 write
!(f
, "expected no bounds, found `{}`",
5327 } else if values
.found
.is_empty() {
5328 write
!(f
, "expected bounds `{}`, found no bounds",
5331 write
!(f
, "expected bounds `{}`, found bounds `{}`",
5336 terr_integer_as_char
=> {
5337 write
!(f
, "expected an integral type, found `char`")
5339 terr_int_mismatch(ref values
) => {
5340 write
!(f
, "expected `{:?}`, found `{:?}`",
5344 terr_float_mismatch(ref values
) => {
5345 write
!(f
, "expected `{:?}`, found `{:?}`",
5349 terr_variadic_mismatch(ref values
) => {
5350 write
!(f
, "expected {} fn, found {} function",
5351 if values
.expected { "variadic" }
else { "non-variadic" }
,
5352 if values
.found { "variadic" }
else { "non-variadic" }
)
5354 terr_convergence_mismatch(ref values
) => {
5355 write
!(f
, "expected {} fn, found {} function",
5356 if values
.expected { "converging" }
else { "diverging" }
,
5357 if values
.found { "converging" }
else { "diverging" }
)
5359 terr_projection_name_mismatched(ref values
) => {
5360 write
!(f
, "expected {}, found {}",
5364 terr_projection_bounds_length(ref values
) => {
5365 write
!(f
, "expected {} associated type bindings, found {}",
5373 pub fn note_and_explain_type_err
<'tcx
>(cx
: &ctxt
<'tcx
>, err
: &type_err
<'tcx
>, sp
: Span
) {
5375 terr_regions_does_not_outlive(subregion
, superregion
) => {
5376 note_and_explain_region(cx
, "", subregion
, "...");
5377 note_and_explain_region(cx
, "...does not necessarily outlive ",
5380 terr_regions_not_same(region1
, region2
) => {
5381 note_and_explain_region(cx
, "", region1
, "...");
5382 note_and_explain_region(cx
, "...is not the same lifetime as ",
5385 terr_regions_no_overlap(region1
, region2
) => {
5386 note_and_explain_region(cx
, "", region1
, "...");
5387 note_and_explain_region(cx
, "...does not overlap ",
5390 terr_regions_insufficiently_polymorphic(_
, conc_region
) => {
5391 note_and_explain_region(cx
,
5392 "concrete lifetime that was found is ",
5395 terr_regions_overly_polymorphic(_
, ty
::ReInfer(ty
::ReVar(_
))) => {
5396 // don't bother to print out the message below for
5397 // inference variables, it's not very illuminating.
5399 terr_regions_overly_polymorphic(_
, conc_region
) => {
5400 note_and_explain_region(cx
,
5401 "expected concrete lifetime is ",
5404 terr_sorts(values
) => {
5405 let expected_str
= ty_sort_string(cx
, values
.expected
);
5406 let found_str
= ty_sort_string(cx
, values
.found
);
5407 if expected_str
== found_str
&& expected_str
== "closure" {
5408 cx
.sess
.span_note(sp
, &format
!("no two closures, even if identical, have the same \
5410 cx
.sess
.span_help(sp
, &format
!("consider boxing your closure and/or \
5411 using it as a trait object"));
5418 pub fn provided_source(cx
: &ctxt
, id
: ast
::DefId
) -> Option
<ast
::DefId
> {
5419 cx
.provided_method_sources
.borrow().get(&id
).cloned()
5422 pub fn provided_trait_methods
<'tcx
>(cx
: &ctxt
<'tcx
>, id
: ast
::DefId
)
5423 -> Vec
<Rc
<Method
<'tcx
>>> {
5425 if let ItemTrait(_
, _
, _
, ref ms
) = cx
.map
.expect_item(id
.node
).node
{
5426 ms
.iter().filter_map(|ti
| {
5427 if let ast
::MethodTraitItem(_
, Some(_
)) = ti
.node
{
5428 match impl_or_trait_item(cx
, ast_util
::local_def(ti
.id
)) {
5429 MethodTraitItem(m
) => Some(m
),
5431 cx
.sess
.bug("provided_trait_methods(): \
5432 non-method item found from \
5433 looking up provided method?!")
5441 cx
.sess
.bug(&format
!("provided_trait_methods: `{:?}` is not a trait", id
))
5444 csearch
::get_provided_trait_methods(cx
, id
)
5448 pub fn associated_consts
<'tcx
>(cx
: &ctxt
<'tcx
>, id
: ast
::DefId
)
5449 -> Vec
<Rc
<AssociatedConst
<'tcx
>>> {
5451 match cx
.map
.expect_item(id
.node
).node
{
5452 ItemTrait(_
, _
, _
, ref tis
) => {
5453 tis
.iter().filter_map(|ti
| {
5454 if let ast
::ConstTraitItem(_
, _
) = ti
.node
{
5455 match impl_or_trait_item(cx
, ast_util
::local_def(ti
.id
)) {
5456 ConstTraitItem(ac
) => Some(ac
),
5458 cx
.sess
.bug("associated_consts(): \
5459 non-const item found from \
5460 looking up a constant?!")
5468 ItemImpl(_
, _
, _
, _
, _
, ref iis
) => {
5469 iis
.iter().filter_map(|ii
| {
5470 if let ast
::ConstImplItem(_
, _
) = ii
.node
{
5471 match impl_or_trait_item(cx
, ast_util
::local_def(ii
.id
)) {
5472 ConstTraitItem(ac
) => Some(ac
),
5474 cx
.sess
.bug("associated_consts(): \
5475 non-const item found from \
5476 looking up a constant?!")
5485 cx
.sess
.bug(&format
!("associated_consts: `{:?}` is not a trait \
5490 csearch
::get_associated_consts(cx
, id
)
5494 /// Helper for looking things up in the various maps that are populated during
5495 /// typeck::collect (e.g., `cx.impl_or_trait_items`, `cx.tcache`, etc). All of
5496 /// these share the pattern that if the id is local, it should have been loaded
5497 /// into the map by the `typeck::collect` phase. If the def-id is external,
5498 /// then we have to go consult the crate loading code (and cache the result for
5500 fn lookup_locally_or_in_crate_store
<V
, F
>(descr
: &str,
5502 map
: &RefCell
<DefIdMap
<V
>>,
5503 load_external
: F
) -> V
where
5507 match map
.borrow().get(&def_id
).cloned() {
5508 Some(v
) => { return v; }
5512 if def_id
.krate
== ast
::LOCAL_CRATE
{
5513 panic
!("No def'n found for {:?} in tcx.{}", def_id
, descr
);
5515 let v
= load_external();
5516 map
.borrow_mut().insert(def_id
, v
.clone());
5520 pub fn trait_item
<'tcx
>(cx
: &ctxt
<'tcx
>, trait_did
: ast
::DefId
, idx
: usize)
5521 -> ImplOrTraitItem
<'tcx
> {
5522 let method_def_id
= (*ty
::trait_item_def_ids(cx
, trait_did
))[idx
].def_id();
5523 impl_or_trait_item(cx
, method_def_id
)
5526 pub fn trait_items
<'tcx
>(cx
: &ctxt
<'tcx
>, trait_did
: ast
::DefId
)
5527 -> Rc
<Vec
<ImplOrTraitItem
<'tcx
>>> {
5528 let mut trait_items
= cx
.trait_items_cache
.borrow_mut();
5529 match trait_items
.get(&trait_did
).cloned() {
5530 Some(trait_items
) => trait_items
,
5532 let def_ids
= ty
::trait_item_def_ids(cx
, trait_did
);
5533 let items
: Rc
<Vec
<ImplOrTraitItem
>> =
5534 Rc
::new(def_ids
.iter()
5535 .map(|d
| impl_or_trait_item(cx
, d
.def_id()))
5537 trait_items
.insert(trait_did
, items
.clone());
5543 pub fn trait_impl_polarity
<'tcx
>(cx
: &ctxt
<'tcx
>, id
: ast
::DefId
)
5544 -> Option
<ast
::ImplPolarity
> {
5545 if id
.krate
== ast
::LOCAL_CRATE
{
5546 match cx
.map
.find(id
.node
) {
5547 Some(ast_map
::NodeItem(item
)) => {
5549 ast
::ItemImpl(_
, polarity
, _
, _
, _
, _
) => Some(polarity
),
5556 csearch
::get_impl_polarity(cx
, id
)
5560 pub fn custom_coerce_unsized_kind
<'tcx
>(cx
: &ctxt
<'tcx
>, did
: ast
::DefId
)
5561 -> CustomCoerceUnsized
{
5562 memoized(&cx
.custom_coerce_unsized_kinds
, did
, |did
: DefId
| {
5563 let (kind
, src
) = if did
.krate
!= ast
::LOCAL_CRATE
{
5564 (csearch
::get_custom_coerce_unsized_kind(cx
, did
), "external")
5572 cx
.sess
.bug(&format
!("custom_coerce_unsized_kind: \
5573 {} impl `{}` is missing its kind",
5574 src
, item_path_str(cx
, did
)));
5580 pub fn impl_or_trait_item
<'tcx
>(cx
: &ctxt
<'tcx
>, id
: ast
::DefId
)
5581 -> ImplOrTraitItem
<'tcx
> {
5582 lookup_locally_or_in_crate_store(
5583 "impl_or_trait_items", id
, &cx
.impl_or_trait_items
,
5584 || csearch
::get_impl_or_trait_item(cx
, id
))
5587 /// Returns the parameter index that the given associated type corresponds to.
5588 pub fn associated_type_parameter_index(cx
: &ctxt
,
5589 trait_def
: &TraitDef
,
5590 associated_type_id
: ast
::DefId
)
5592 for type_parameter_def
in &trait_def
.generics
.types
{
5593 if type_parameter_def
.def_id
== associated_type_id
{
5594 return type_parameter_def
.index
as usize
5597 cx
.sess
.bug("couldn't find associated type parameter index")
5600 pub fn trait_item_def_ids(cx
: &ctxt
, id
: ast
::DefId
)
5601 -> Rc
<Vec
<ImplOrTraitItemId
>> {
5602 lookup_locally_or_in_crate_store(
5603 "trait_item_def_ids", id
, &cx
.trait_item_def_ids
,
5604 || Rc
::new(csearch
::get_trait_item_def_ids(&cx
.sess
.cstore
, id
)))
5607 /// Returns the trait-ref corresponding to a given impl, or None if it is
5608 /// an inherent impl.
5609 pub fn impl_trait_ref
<'tcx
>(cx
: &ctxt
<'tcx
>, id
: ast
::DefId
)
5610 -> Option
<TraitRef
<'tcx
>>
5612 lookup_locally_or_in_crate_store(
5613 "impl_trait_refs", id
, &cx
.impl_trait_refs
,
5614 || csearch
::get_impl_trait(cx
, id
))
5617 /// Returns whether this DefId refers to an impl
5618 pub fn is_impl
<'tcx
>(cx
: &ctxt
<'tcx
>, id
: ast
::DefId
) -> bool
{
5619 if id
.krate
== ast
::LOCAL_CRATE
{
5620 if let Some(ast_map
::NodeItem(
5621 &ast
::Item { node: ast::ItemImpl(..), .. }
)) = cx
.map
.find(id
.node
) {
5627 csearch
::is_impl(&cx
.sess
.cstore
, id
)
5631 pub fn trait_ref_to_def_id(tcx
: &ctxt
, tr
: &ast
::TraitRef
) -> ast
::DefId
{
5632 tcx
.def_map
.borrow().get(&tr
.ref_id
).expect("no def-map entry for trait").def_id()
5635 pub fn try_add_builtin_trait(
5637 trait_def_id
: ast
::DefId
,
5638 builtin_bounds
: &mut EnumSet
<BuiltinBound
>)
5641 //! Checks whether `trait_ref` refers to one of the builtin
5642 //! traits, like `Send`, and adds the corresponding
5643 //! bound to the set `builtin_bounds` if so. Returns true if `trait_ref`
5644 //! is a builtin trait.
5646 match tcx
.lang_items
.to_builtin_kind(trait_def_id
) {
5647 Some(bound
) => { builtin_bounds.insert(bound); true }
5652 pub fn ty_to_def_id(ty
: Ty
) -> Option
<ast
::DefId
> {
5655 Some(tt
.principal_def_id()),
5667 pub struct VariantInfo
<'tcx
> {
5668 pub args
: Vec
<Ty
<'tcx
>>,
5669 pub arg_names
: Option
<Vec
<ast
::Name
>>,
5670 pub ctor_ty
: Option
<Ty
<'tcx
>>,
5671 pub name
: ast
::Name
,
5677 impl<'tcx
> VariantInfo
<'tcx
> {
5679 /// Creates a new VariantInfo from the corresponding ast representation.
5681 /// Does not do any caching of the value in the type context.
5682 pub fn from_ast_variant(cx
: &ctxt
<'tcx
>,
5683 ast_variant
: &ast
::Variant
,
5684 discriminant
: Disr
) -> VariantInfo
<'tcx
> {
5685 let ctor_ty
= node_id_to_type(cx
, ast_variant
.node
.id
);
5687 match ast_variant
.node
.kind
{
5688 ast
::TupleVariantKind(ref args
) => {
5689 let arg_tys
= if !args
.is_empty() {
5690 // the regions in the argument types come from the
5691 // enum def'n, and hence will all be early bound
5692 ty
::no_late_bound_regions(cx
, &ty_fn_args(ctor_ty
)).unwrap()
5697 return VariantInfo
{
5700 ctor_ty
: Some(ctor_ty
),
5701 name
: ast_variant
.node
.name
.name
,
5702 id
: ast_util
::local_def(ast_variant
.node
.id
),
5703 disr_val
: discriminant
,
5704 vis
: ast_variant
.node
.vis
5707 ast
::StructVariantKind(ref struct_def
) => {
5708 let fields
: &[StructField
] = &struct_def
.fields
;
5710 assert
!(!fields
.is_empty());
5712 let arg_tys
= struct_def
.fields
.iter()
5713 .map(|field
| node_id_to_type(cx
, field
.node
.id
)).collect();
5714 let arg_names
= fields
.iter().map(|field
| {
5715 match field
.node
.kind
{
5716 NamedField(ident
, _
) => ident
.name
,
5717 UnnamedField(..) => cx
.sess
.bug(
5718 "enum_variants: all fields in struct must have a name")
5722 return VariantInfo
{
5724 arg_names
: Some(arg_names
),
5726 name
: ast_variant
.node
.name
.name
,
5727 id
: ast_util
::local_def(ast_variant
.node
.id
),
5728 disr_val
: discriminant
,
5729 vis
: ast_variant
.node
.vis
5736 pub fn substd_enum_variants
<'tcx
>(cx
: &ctxt
<'tcx
>,
5738 substs
: &Substs
<'tcx
>)
5739 -> Vec
<Rc
<VariantInfo
<'tcx
>>> {
5740 enum_variants(cx
, id
).iter().map(|variant_info
| {
5741 let substd_args
= variant_info
.args
.iter()
5742 .map(|aty
| aty
.subst(cx
, substs
)).collect
::<Vec
<_
>>();
5744 let substd_ctor_ty
= variant_info
.ctor_ty
.subst(cx
, substs
);
5746 Rc
::new(VariantInfo
{
5748 ctor_ty
: substd_ctor_ty
,
5749 ..(**variant_info
).clone()
5754 pub fn item_path_str(cx
: &ctxt
, id
: ast
::DefId
) -> String
{
5755 with_path(cx
, id
, |path
| ast_map
::path_to_string(path
)).to_string()
5758 #[derive(Copy, Clone)]
5761 TraitDtor(DefId
, bool
)
5765 pub fn is_present(&self) -> bool
{
5767 TraitDtor(..) => true,
5772 pub fn has_drop_flag(&self) -> bool
{
5775 &TraitDtor(_
, flag
) => flag
5780 /* If struct_id names a struct with a dtor. */
5781 pub fn ty_dtor(cx
: &ctxt
, struct_id
: DefId
) -> DtorKind
{
5782 match cx
.destructor_for_type
.borrow().get(&struct_id
) {
5783 Some(&method_def_id
) => {
5784 let flag
= !has_attr(cx
, struct_id
, "unsafe_no_drop_flag");
5786 TraitDtor(method_def_id
, flag
)
5792 pub fn has_dtor(cx
: &ctxt
, struct_id
: DefId
) -> bool
{
5793 cx
.destructor_for_type
.borrow().contains_key(&struct_id
)
5796 pub fn with_path
<T
, F
>(cx
: &ctxt
, id
: ast
::DefId
, f
: F
) -> T
where
5797 F
: FnOnce(ast_map
::PathElems
) -> T
,
5799 if id
.krate
== ast
::LOCAL_CRATE
{
5800 cx
.map
.with_path(id
.node
, f
)
5802 f(csearch
::get_item_path(cx
, id
).iter().cloned().chain(LinkedPath
::empty()))
5806 pub fn enum_is_univariant(cx
: &ctxt
, id
: ast
::DefId
) -> bool
{
5807 enum_variants(cx
, id
).len() == 1
5810 pub fn type_is_empty(cx
: &ctxt
, ty
: Ty
) -> bool
{
5812 TyEnum(did
, _
) => (*enum_variants(cx
, did
)).is_empty(),
5818 fn to_ty
<'tcx
>(&self, cx
: &ctxt
<'tcx
>) -> Ty
<'tcx
>;
5819 fn i64_to_disr(&self, val
: i64) -> Option
<Disr
>;
5820 fn u64_to_disr(&self, val
: u64) -> Option
<Disr
>;
5821 fn disr_incr(&self, val
: Disr
) -> Option
<Disr
>;
5822 fn disr_string(&self, val
: Disr
) -> String
;
5823 fn disr_wrap_incr(&self, val
: Option
<Disr
>) -> Disr
;
5826 impl IntTypeExt
for attr
::IntType
{
5827 fn to_ty
<'tcx
>(&self, cx
: &ctxt
<'tcx
>) -> Ty
<'tcx
> {
5829 SignedInt(ast
::TyI8
) => cx
.types
.i8,
5830 SignedInt(ast
::TyI16
) => cx
.types
.i16,
5831 SignedInt(ast
::TyI32
) => cx
.types
.i32,
5832 SignedInt(ast
::TyI64
) => cx
.types
.i64,
5833 SignedInt(ast
::TyIs
) => cx
.types
.isize,
5834 UnsignedInt(ast
::TyU8
) => cx
.types
.u8,
5835 UnsignedInt(ast
::TyU16
) => cx
.types
.u16,
5836 UnsignedInt(ast
::TyU32
) => cx
.types
.u32,
5837 UnsignedInt(ast
::TyU64
) => cx
.types
.u64,
5838 UnsignedInt(ast
::TyUs
) => cx
.types
.usize,
5842 fn i64_to_disr(&self, val
: i64) -> Option
<Disr
> {
5844 SignedInt(ast
::TyI8
) => val
.to_i8() .map(|v
| v
as Disr
),
5845 SignedInt(ast
::TyI16
) => val
.to_i16() .map(|v
| v
as Disr
),
5846 SignedInt(ast
::TyI32
) => val
.to_i32() .map(|v
| v
as Disr
),
5847 SignedInt(ast
::TyI64
) => val
.to_i64() .map(|v
| v
as Disr
),
5848 UnsignedInt(ast
::TyU8
) => val
.to_u8() .map(|v
| v
as Disr
),
5849 UnsignedInt(ast
::TyU16
) => val
.to_u16() .map(|v
| v
as Disr
),
5850 UnsignedInt(ast
::TyU32
) => val
.to_u32() .map(|v
| v
as Disr
),
5851 UnsignedInt(ast
::TyU64
) => val
.to_u64() .map(|v
| v
as Disr
),
5853 UnsignedInt(ast
::TyUs
) |
5854 SignedInt(ast
::TyIs
) => unreachable
!(),
5858 fn u64_to_disr(&self, val
: u64) -> Option
<Disr
> {
5860 SignedInt(ast
::TyI8
) => val
.to_i8() .map(|v
| v
as Disr
),
5861 SignedInt(ast
::TyI16
) => val
.to_i16() .map(|v
| v
as Disr
),
5862 SignedInt(ast
::TyI32
) => val
.to_i32() .map(|v
| v
as Disr
),
5863 SignedInt(ast
::TyI64
) => val
.to_i64() .map(|v
| v
as Disr
),
5864 UnsignedInt(ast
::TyU8
) => val
.to_u8() .map(|v
| v
as Disr
),
5865 UnsignedInt(ast
::TyU16
) => val
.to_u16() .map(|v
| v
as Disr
),
5866 UnsignedInt(ast
::TyU32
) => val
.to_u32() .map(|v
| v
as Disr
),
5867 UnsignedInt(ast
::TyU64
) => val
.to_u64() .map(|v
| v
as Disr
),
5869 UnsignedInt(ast
::TyUs
) |
5870 SignedInt(ast
::TyIs
) => unreachable
!(),
5874 fn disr_incr(&self, val
: Disr
) -> Option
<Disr
> {
5876 ($e
:expr
) => { $e.and_then(|v|v.checked_add(1)).map(|v| v as Disr) }
5879 // SignedInt repr means we *want* to reinterpret the bits
5880 // treating the highest bit of Disr as a sign-bit, so
5881 // cast to i64 before range-checking.
5882 SignedInt(ast
::TyI8
) => add1
!((val
as i64).to_i8()),
5883 SignedInt(ast
::TyI16
) => add1
!((val
as i64).to_i16()),
5884 SignedInt(ast
::TyI32
) => add1
!((val
as i64).to_i32()),
5885 SignedInt(ast
::TyI64
) => add1
!(Some(val
as i64)),
5887 UnsignedInt(ast
::TyU8
) => add1
!(val
.to_u8()),
5888 UnsignedInt(ast
::TyU16
) => add1
!(val
.to_u16()),
5889 UnsignedInt(ast
::TyU32
) => add1
!(val
.to_u32()),
5890 UnsignedInt(ast
::TyU64
) => add1
!(Some(val
)),
5892 UnsignedInt(ast
::TyUs
) |
5893 SignedInt(ast
::TyIs
) => unreachable
!(),
5897 // This returns a String because (1.) it is only used for
5898 // rendering an error message and (2.) a string can represent the
5899 // full range from `i64::MIN` through `u64::MAX`.
5900 fn disr_string(&self, val
: Disr
) -> String
{
5902 SignedInt(ast
::TyI8
) => format
!("{}", val
as i8 ),
5903 SignedInt(ast
::TyI16
) => format
!("{}", val
as i16),
5904 SignedInt(ast
::TyI32
) => format
!("{}", val
as i32),
5905 SignedInt(ast
::TyI64
) => format
!("{}", val
as i64),
5906 UnsignedInt(ast
::TyU8
) => format
!("{}", val
as u8 ),
5907 UnsignedInt(ast
::TyU16
) => format
!("{}", val
as u16),
5908 UnsignedInt(ast
::TyU32
) => format
!("{}", val
as u32),
5909 UnsignedInt(ast
::TyU64
) => format
!("{}", val
as u64),
5911 UnsignedInt(ast
::TyUs
) |
5912 SignedInt(ast
::TyIs
) => unreachable
!(),
5916 fn disr_wrap_incr(&self, val
: Option
<Disr
>) -> Disr
{
5918 ($e
:expr
) => { ($e).wrapping_add(1) as Disr }
5920 let val
= val
.unwrap_or(ty
::INITIAL_DISCRIMINANT_VALUE
);
5922 SignedInt(ast
::TyI8
) => add1
!(val
as i8 ),
5923 SignedInt(ast
::TyI16
) => add1
!(val
as i16),
5924 SignedInt(ast
::TyI32
) => add1
!(val
as i32),
5925 SignedInt(ast
::TyI64
) => add1
!(val
as i64),
5926 UnsignedInt(ast
::TyU8
) => add1
!(val
as u8 ),
5927 UnsignedInt(ast
::TyU16
) => add1
!(val
as u16),
5928 UnsignedInt(ast
::TyU32
) => add1
!(val
as u32),
5929 UnsignedInt(ast
::TyU64
) => add1
!(val
as u64),
5931 UnsignedInt(ast
::TyUs
) |
5932 SignedInt(ast
::TyIs
) => unreachable
!(),
5937 /// Returns `(normalized_type, ty)`, where `normalized_type` is the
5938 /// IntType representation of one of {i64,i32,i16,i8,u64,u32,u16,u8},
5939 /// and `ty` is the original type (i.e. may include `isize` or
5941 pub fn enum_repr_type
<'tcx
>(cx
: &ctxt
<'tcx
>,
5942 opt_hint
: Option
<&attr
::ReprAttr
>)
5943 -> (attr
::IntType
, Ty
<'tcx
>)
5945 let repr_type
= match opt_hint
{
5946 // Feed in the given type
5947 Some(&attr
::ReprInt(_
, int_t
)) => int_t
,
5948 // ... but provide sensible default if none provided
5950 // NB. Historically `fn enum_variants` generate i64 here, while
5951 // rustc_typeck::check would generate isize.
5952 _
=> SignedInt(ast
::TyIs
),
5955 let repr_type_ty
= repr_type
.to_ty(cx
);
5956 let repr_type
= match repr_type
{
5957 SignedInt(ast
::TyIs
) =>
5958 SignedInt(cx
.sess
.target
.int_type
),
5959 UnsignedInt(ast
::TyUs
) =>
5960 UnsignedInt(cx
.sess
.target
.uint_type
),
5964 (repr_type
, repr_type_ty
)
5967 fn report_discrim_overflow(cx
: &ctxt
,
5970 repr_type
: attr
::IntType
,
5972 let computed_value
= repr_type
.disr_wrap_incr(Some(prev_val
));
5973 let computed_value
= repr_type
.disr_string(computed_value
);
5974 let prev_val
= repr_type
.disr_string(prev_val
);
5975 let repr_type
= repr_type
.to_ty(cx
);
5976 span_err
!(cx
.sess
, variant_span
, E0370
,
5977 "enum discriminant overflowed on value after {}: {}; \
5978 set explicitly via {} = {} if that is desired outcome",
5979 prev_val
, repr_type
, variant_name
, computed_value
);
5982 // This computes the discriminant values for the sequence of Variants
5983 // attached to a particular enum, taking into account the #[repr] (if
5984 // any) provided via the `opt_hint`.
5985 fn compute_enum_variants
<'tcx
>(cx
: &ctxt
<'tcx
>,
5986 vs
: &'tcx
[P
<ast
::Variant
>],
5987 opt_hint
: Option
<&attr
::ReprAttr
>)
5988 -> Vec
<Rc
<ty
::VariantInfo
<'tcx
>>> {
5989 let mut variants
: Vec
<Rc
<ty
::VariantInfo
>> = Vec
::new();
5990 let mut prev_disr_val
: Option
<ty
::Disr
> = None
;
5992 let (repr_type
, repr_type_ty
) = ty
::enum_repr_type(cx
, opt_hint
);
5995 // If the discriminant value is specified explicitly in the
5996 // enum, check whether the initialization expression is valid,
5997 // otherwise use the last value plus one.
5998 let current_disr_val
;
6000 // This closure marks cases where, when an error occurs during
6001 // the computation, attempt to assign a (hopefully) fresh
6002 // value to avoid spurious error reports downstream.
6003 let attempt_fresh_value
= move || -> Disr
{
6004 repr_type
.disr_wrap_incr(prev_disr_val
)
6007 match v
.node
.disr_expr
{
6009 debug
!("disr expr, checking {}", pprust
::expr_to_string(&**e
));
6011 // check_expr (from check_const pass) doesn't guarantee
6012 // that the expression is in a form that eval_const_expr can
6013 // handle, so we may still get an internal compiler error
6015 // pnkfelix: The above comment was transcribed from
6016 // the version of this code taken from rustc_typeck.
6017 // Presumably the implication is that we need to deal
6018 // with such ICE's as they arise.
6020 // Since this can be called from `ty::enum_variants`
6021 // anyway, best thing is to make `eval_const_expr`
6022 // more robust (on case-by-case basis).
6024 match const_eval
::eval_const_expr_partial(cx
, &**e
, Some(repr_type_ty
)) {
6025 Ok(ConstVal
::Int(val
)) => current_disr_val
= val
as Disr
,
6026 Ok(ConstVal
::Uint(val
)) => current_disr_val
= val
as Disr
,
6028 let sign_desc
= if repr_type
.is_signed() { "signed" }
else { "unsigned" }
;
6029 span_err
!(cx
.sess
, e
.span
, E0079
,
6030 "expected {} integer constant",
6032 current_disr_val
= attempt_fresh_value();
6035 span_err
!(cx
.sess
, err
.span
, E0080
,
6036 "constant evaluation error: {}",
6038 current_disr_val
= attempt_fresh_value();
6043 current_disr_val
= match prev_disr_val
{
6044 Some(prev_disr_val
) => {
6045 if let Some(v
) = repr_type
.disr_incr(prev_disr_val
) {
6048 report_discrim_overflow(cx
, v
.span
, v
.node
.name
.as_str(),
6049 repr_type
, prev_disr_val
);
6050 attempt_fresh_value()
6053 None
=> ty
::INITIAL_DISCRIMINANT_VALUE
6058 let variant_info
= Rc
::new(VariantInfo
::from_ast_variant(cx
, &**v
, current_disr_val
));
6059 prev_disr_val
= Some(current_disr_val
);
6061 variants
.push(variant_info
);
6067 pub fn enum_variants
<'tcx
>(cx
: &ctxt
<'tcx
>, id
: ast
::DefId
)
6068 -> Rc
<Vec
<Rc
<VariantInfo
<'tcx
>>>> {
6069 memoized(&cx
.enum_var_cache
, id
, |id
: ast
::DefId
| {
6070 if ast
::LOCAL_CRATE
!= id
.krate
{
6071 Rc
::new(csearch
::get_enum_variants(cx
, id
))
6073 match cx
.map
.get(id
.node
) {
6074 ast_map
::NodeItem(ref item
) => {
6076 ast
::ItemEnum(ref enum_definition
, _
) => {
6077 Rc
::new(compute_enum_variants(
6079 &enum_definition
.variants
,
6080 lookup_repr_hints(cx
, id
).get(0)))
6083 cx
.sess
.bug("enum_variants: id not bound to an enum")
6087 _
=> cx
.sess
.bug("enum_variants: id not bound to an enum")
6093 // Returns information about the enum variant with the given ID:
6094 pub fn enum_variant_with_id
<'tcx
>(cx
: &ctxt
<'tcx
>,
6095 enum_id
: ast
::DefId
,
6096 variant_id
: ast
::DefId
)
6097 -> Rc
<VariantInfo
<'tcx
>> {
6098 enum_variants(cx
, enum_id
).iter()
6099 .find(|variant
| variant
.id
== variant_id
)
6100 .expect("enum_variant_with_id(): no variant exists with that ID")
6105 // If the given item is in an external crate, looks up its type and adds it to
6106 // the type cache. Returns the type parameters and type.
6107 pub fn lookup_item_type
<'tcx
>(cx
: &ctxt
<'tcx
>,
6109 -> TypeScheme
<'tcx
> {
6110 lookup_locally_or_in_crate_store(
6111 "tcache", did
, &cx
.tcache
,
6112 || csearch
::get_type(cx
, did
))
6115 /// Given the did of a trait, returns its canonical trait ref.
6116 pub fn lookup_trait_def
<'tcx
>(cx
: &ctxt
<'tcx
>, did
: ast
::DefId
)
6117 -> &'tcx TraitDef
<'tcx
> {
6118 lookup_locally_or_in_crate_store(
6119 "trait_defs", did
, &cx
.trait_defs
,
6120 || cx
.arenas
.trait_defs
.alloc(csearch
::get_trait_def(cx
, did
))
6124 /// Given the did of an item, returns its full set of predicates.
6125 pub fn lookup_predicates
<'tcx
>(cx
: &ctxt
<'tcx
>, did
: ast
::DefId
)
6126 -> GenericPredicates
<'tcx
>
6128 lookup_locally_or_in_crate_store(
6129 "predicates", did
, &cx
.predicates
,
6130 || csearch
::get_predicates(cx
, did
))
6133 /// Given the did of a trait, returns its superpredicates.
6134 pub fn lookup_super_predicates
<'tcx
>(cx
: &ctxt
<'tcx
>, did
: ast
::DefId
)
6135 -> GenericPredicates
<'tcx
>
6137 lookup_locally_or_in_crate_store(
6138 "super_predicates", did
, &cx
.super_predicates
,
6139 || csearch
::get_super_predicates(cx
, did
))
6142 /// Get the attributes of a definition.
6143 pub fn get_attrs
<'tcx
>(tcx
: &'tcx ctxt
, did
: DefId
)
6144 -> Cow
<'tcx
, [ast
::Attribute
]> {
6146 Cow
::Borrowed(tcx
.map
.attrs(did
.node
))
6148 Cow
::Owned(csearch
::get_item_attrs(&tcx
.sess
.cstore
, did
))
6152 /// Determine whether an item is annotated with an attribute
6153 pub fn has_attr(tcx
: &ctxt
, did
: DefId
, attr
: &str) -> bool
{
6154 get_attrs(tcx
, did
).iter().any(|item
| item
.check_name(attr
))
6157 /// Determine whether an item is annotated with `#[repr(packed)]`
6158 pub fn lookup_packed(tcx
: &ctxt
, did
: DefId
) -> bool
{
6159 lookup_repr_hints(tcx
, did
).contains(&attr
::ReprPacked
)
6162 /// Determine whether an item is annotated with `#[simd]`
6163 pub fn lookup_simd(tcx
: &ctxt
, did
: DefId
) -> bool
{
6164 has_attr(tcx
, did
, "simd")
6167 /// Obtain the representation annotation for a struct definition.
6168 pub fn lookup_repr_hints(tcx
: &ctxt
, did
: DefId
) -> Rc
<Vec
<attr
::ReprAttr
>> {
6169 memoized(&tcx
.repr_hint_cache
, did
, |did
: DefId
| {
6170 Rc
::new(if did
.krate
== LOCAL_CRATE
{
6171 get_attrs(tcx
, did
).iter().flat_map(|meta
| {
6172 attr
::find_repr_attrs(tcx
.sess
.diagnostic(), meta
).into_iter()
6175 csearch
::get_repr_attrs(&tcx
.sess
.cstore
, did
)
6180 // Look up a field ID, whether or not it's local
6181 pub fn lookup_field_type_unsubstituted
<'tcx
>(tcx
: &ctxt
<'tcx
>,
6185 if id
.krate
== ast
::LOCAL_CRATE
{
6186 node_id_to_type(tcx
, id
.node
)
6188 let mut tcache
= tcx
.tcache
.borrow_mut();
6189 tcache
.entry(id
).or_insert_with(|| csearch
::get_field_type(tcx
, struct_id
, id
)).ty
6194 // Look up a field ID, whether or not it's local
6195 // Takes a list of type substs in case the struct is generic
6196 pub fn lookup_field_type
<'tcx
>(tcx
: &ctxt
<'tcx
>,
6199 substs
: &Substs
<'tcx
>)
6201 lookup_field_type_unsubstituted(tcx
, struct_id
, id
).subst(tcx
, substs
)
6204 // Look up the list of field names and IDs for a given struct.
6205 // Panics if the id is not bound to a struct.
6206 pub fn lookup_struct_fields(cx
: &ctxt
, did
: ast
::DefId
) -> Vec
<field_ty
> {
6207 if did
.krate
== ast
::LOCAL_CRATE
{
6208 let struct_fields
= cx
.struct_fields
.borrow();
6209 match struct_fields
.get(&did
) {
6210 Some(fields
) => (**fields
).clone(),
6213 &format
!("ID not mapped to struct fields: {}",
6214 cx
.map
.node_to_string(did
.node
)));
6218 csearch
::get_struct_fields(&cx
.sess
.cstore
, did
)
6222 pub fn is_tuple_struct(cx
: &ctxt
, did
: ast
::DefId
) -> bool
{
6223 let fields
= lookup_struct_fields(cx
, did
);
6224 !fields
.is_empty() && fields
.iter().all(|f
| f
.name
== token
::special_names
::unnamed_field
)
6227 // Returns a list of fields corresponding to the struct's items. trans uses
6228 // this. Takes a list of substs with which to instantiate field types.
6229 pub fn struct_fields
<'tcx
>(cx
: &ctxt
<'tcx
>, did
: ast
::DefId
, substs
: &Substs
<'tcx
>)
6230 -> Vec
<field
<'tcx
>> {
6231 lookup_struct_fields(cx
, did
).iter().map(|f
| {
6235 ty
: lookup_field_type(cx
, did
, f
.id
, substs
),
6242 // Returns a list of fields corresponding to the tuple's items. trans uses
6244 pub fn tup_fields
<'tcx
>(v
: &[Ty
<'tcx
>]) -> Vec
<field
<'tcx
>> {
6245 v
.iter().enumerate().map(|(i
, &f
)| {
6247 name
: token
::intern(&i
.to_string()),
6256 /// Returns the deeply last field of nested structures, or the same type,
6257 /// if not a structure at all. Corresponds to the only possible unsized
6258 /// field, and its type can be used to determine unsizing strategy.
6259 pub fn struct_tail
<'tcx
>(cx
: &ctxt
<'tcx
>, mut ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
6260 while let TyStruct(def_id
, substs
) = ty
.sty
{
6261 match struct_fields(cx
, def_id
, substs
).last() {
6262 Some(f
) => ty
= f
.mt
.ty
,
6269 /// Same as applying struct_tail on `source` and `target`, but only
6270 /// keeps going as long as the two types are instances of the same
6271 /// structure definitions.
6272 /// For `(Foo<Foo<T>>, Foo<Trait>)`, the result will be `(Foo<T>, Trait)`,
6273 /// whereas struct_tail produces `T`, and `Trait`, respectively.
6274 pub fn struct_lockstep_tails
<'tcx
>(cx
: &ctxt
<'tcx
>,
6277 -> (Ty
<'tcx
>, Ty
<'tcx
>) {
6278 let (mut a
, mut b
) = (source
, target
);
6279 while let (&TyStruct(a_did
, a_substs
), &TyStruct(b_did
, b_substs
)) = (&a
.sty
, &b
.sty
) {
6283 if let Some(a_f
) = struct_fields(cx
, a_did
, a_substs
).last() {
6284 if let Some(b_f
) = struct_fields(cx
, b_did
, b_substs
).last() {
6297 #[derive(Copy, Clone)]
6298 pub struct ClosureUpvar
<'tcx
> {
6304 // Returns a list of `ClosureUpvar`s for each upvar.
6305 pub fn closure_upvars
<'tcx
>(typer
: &mc
::Typer
<'tcx
>,
6306 closure_id
: ast
::DefId
,
6307 substs
: &Substs
<'tcx
>)
6308 -> Option
<Vec
<ClosureUpvar
<'tcx
>>>
6310 // Presently an unboxed closure type cannot "escape" out of a
6311 // function, so we will only encounter ones that originated in the
6312 // local crate or were inlined into it along with some function.
6313 // This may change if abstract return types of some sort are
6315 assert
!(closure_id
.krate
== ast
::LOCAL_CRATE
);
6316 let tcx
= typer
.tcx();
6317 match tcx
.freevars
.borrow().get(&closure_id
.node
) {
6318 None
=> Some(vec
![]),
6319 Some(ref freevars
) => {
6322 let freevar_def_id
= freevar
.def
.def_id();
6323 let freevar_ty
= match typer
.node_ty(freevar_def_id
.node
) {
6325 Err(()) => { return None; }
6327 let freevar_ty
= freevar_ty
.subst(tcx
, substs
);
6329 let upvar_id
= ty
::UpvarId
{
6330 var_id
: freevar_def_id
.node
,
6331 closure_expr_id
: closure_id
.node
6334 typer
.upvar_capture(upvar_id
).map(|capture
| {
6335 let freevar_ref_ty
= match capture
{
6336 UpvarCapture
::ByValue
=> {
6339 UpvarCapture
::ByRef(borrow
) => {
6341 tcx
.mk_region(borrow
.region
),
6344 mutbl
: borrow
.kind
.to_mutbl_lossy(),
6361 // Returns the repeat count for a repeating vector expression.
6362 pub fn eval_repeat_count(tcx
: &ctxt
, count_expr
: &ast
::Expr
) -> usize {
6363 match const_eval
::eval_const_expr_partial(tcx
, count_expr
, Some(tcx
.types
.usize)) {
6365 let found
= match val
{
6366 ConstVal
::Uint(count
) => return count
as usize,
6367 ConstVal
::Int(count
) if count
>= 0 => return count
as usize,
6368 ConstVal
::Int(_
) => "negative integer",
6369 ConstVal
::Float(_
) => "float",
6370 ConstVal
::Str(_
) => "string",
6371 ConstVal
::Bool(_
) => "boolean",
6372 ConstVal
::Binary(_
) => "binary array",
6373 ConstVal
::Struct(..) => "struct",
6374 ConstVal
::Tuple(_
) => "tuple"
6376 span_err
!(tcx
.sess
, count_expr
.span
, E0306
,
6377 "expected positive integer for repeat count, found {}",
6381 let err_description
= err
.description();
6382 let found
= match count_expr
.node
{
6383 ast
::ExprPath(None
, ast
::Path
{
6387 }) if segments
.len() == 1 =>
6388 format
!("{}", "found variable"),
6390 format
!("but {}", err_description
),
6392 span_err
!(tcx
.sess
, count_expr
.span
, E0307
,
6393 "expected constant integer for repeat count, {}",
6400 // Iterate over a type parameter's bounded traits and any supertraits
6401 // of those traits, ignoring kinds.
6402 // Here, the supertraits are the transitive closure of the supertrait
6403 // relation on the supertraits from each bounded trait's constraint
6405 pub fn each_bound_trait_and_supertraits
<'tcx
, F
>(tcx
: &ctxt
<'tcx
>,
6406 bounds
: &[PolyTraitRef
<'tcx
>],
6409 F
: FnMut(PolyTraitRef
<'tcx
>) -> bool
,
6411 for bound_trait_ref
in traits
::transitive_bounds(tcx
, bounds
) {
6412 if !f(bound_trait_ref
) {
6419 /// Given a set of predicates that apply to an object type, returns
6420 /// the region bounds that the (erased) `Self` type must
6421 /// outlive. Precisely *because* the `Self` type is erased, the
6422 /// parameter `erased_self_ty` must be supplied to indicate what type
6423 /// has been used to represent `Self` in the predicates
6424 /// themselves. This should really be a unique type; `FreshTy(0)` is a
6427 /// Requires that trait definitions have been processed so that we can
6428 /// elaborate predicates and walk supertraits.
6429 pub fn required_region_bounds
<'tcx
>(tcx
: &ctxt
<'tcx
>,
6430 erased_self_ty
: Ty
<'tcx
>,
6431 predicates
: Vec
<ty
::Predicate
<'tcx
>>)
6434 debug
!("required_region_bounds(erased_self_ty={:?}, predicates={:?})",
6438 assert
!(!erased_self_ty
.has_escaping_regions());
6440 traits
::elaborate_predicates(tcx
, predicates
)
6441 .filter_map(|predicate
| {
6443 ty
::Predicate
::Projection(..) |
6444 ty
::Predicate
::Trait(..) |
6445 ty
::Predicate
::Equate(..) |
6446 ty
::Predicate
::RegionOutlives(..) => {
6449 ty
::Predicate
::TypeOutlives(ty
::Binder(ty
::OutlivesPredicate(t
, r
))) => {
6450 // Search for a bound of the form `erased_self_ty
6451 // : 'a`, but be wary of something like `for<'a>
6452 // erased_self_ty : 'a` (we interpret a
6453 // higher-ranked bound like that as 'static,
6454 // though at present the code in `fulfill.rs`
6455 // considers such bounds to be unsatisfiable, so
6456 // it's kind of a moot point since you could never
6457 // construct such an object, but this seems
6458 // correct even if that code changes).
6459 if t
== erased_self_ty
&& !r
.has_escaping_regions() {
6460 if r
.has_escaping_regions() {
6474 pub fn item_variances(tcx
: &ctxt
, item_id
: ast
::DefId
) -> Rc
<ItemVariances
> {
6475 lookup_locally_or_in_crate_store(
6476 "item_variance_map", item_id
, &tcx
.item_variance_map
,
6477 || Rc
::new(csearch
::get_item_variances(&tcx
.sess
.cstore
, item_id
)))
6480 pub fn trait_has_default_impl(tcx
: &ctxt
, trait_def_id
: DefId
) -> bool
{
6481 populate_implementations_for_trait_if_necessary(tcx
, trait_def_id
);
6483 let def
= lookup_trait_def(tcx
, trait_def_id
);
6484 def
.flags
.get().intersects(TraitFlags
::HAS_DEFAULT_IMPL
)
6487 /// Records a trait-to-implementation mapping.
6488 pub fn record_trait_has_default_impl(tcx
: &ctxt
, trait_def_id
: DefId
) {
6489 let def
= lookup_trait_def(tcx
, trait_def_id
);
6490 def
.flags
.set(def
.flags
.get() | TraitFlags
::HAS_DEFAULT_IMPL
)
6493 /// Load primitive inherent implementations if necessary
6494 pub fn populate_implementations_for_primitive_if_necessary(tcx
: &ctxt
,
6495 primitive_def_id
: ast
::DefId
) {
6496 if primitive_def_id
.krate
== LOCAL_CRATE
{
6500 if tcx
.populated_external_primitive_impls
.borrow().contains(&primitive_def_id
) {
6504 debug
!("populate_implementations_for_primitive_if_necessary: searching for {:?}",
6507 let impl_items
= csearch
::get_impl_items(&tcx
.sess
.cstore
, primitive_def_id
);
6509 // Store the implementation info.
6510 tcx
.impl_items
.borrow_mut().insert(primitive_def_id
, impl_items
);
6511 tcx
.populated_external_primitive_impls
.borrow_mut().insert(primitive_def_id
);
6514 /// Populates the type context with all the inherent implementations for
6515 /// the given type if necessary.
6516 pub fn populate_inherent_implementations_for_type_if_necessary(tcx
: &ctxt
,
6517 type_id
: ast
::DefId
) {
6518 if type_id
.krate
== LOCAL_CRATE
{
6522 if tcx
.populated_external_types
.borrow().contains(&type_id
) {
6526 debug
!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}", type_id
);
6528 let mut inherent_impls
= Vec
::new();
6529 csearch
::each_inherent_implementation_for_type(&tcx
.sess
.cstore
, type_id
, |impl_def_id
| {
6530 // Record the implementation.
6531 inherent_impls
.push(impl_def_id
);
6533 // Store the implementation info.
6534 let impl_items
= csearch
::get_impl_items(&tcx
.sess
.cstore
, impl_def_id
);
6535 tcx
.impl_items
.borrow_mut().insert(impl_def_id
, impl_items
);
6538 tcx
.inherent_impls
.borrow_mut().insert(type_id
, Rc
::new(inherent_impls
));
6539 tcx
.populated_external_types
.borrow_mut().insert(type_id
);
6542 /// Populates the type context with all the implementations for the given
6543 /// trait if necessary.
6544 pub fn populate_implementations_for_trait_if_necessary(tcx
: &ctxt
, trait_id
: ast
::DefId
) {
6545 if trait_id
.krate
== LOCAL_CRATE
{
6549 let def
= lookup_trait_def(tcx
, trait_id
);
6550 if def
.flags
.get().intersects(TraitFlags
::IMPLS_VALID
) {
6554 debug
!("populate_implementations_for_trait_if_necessary: searching for {:?}", def
);
6556 if csearch
::is_defaulted_trait(&tcx
.sess
.cstore
, trait_id
) {
6557 record_trait_has_default_impl(tcx
, trait_id
);
6560 csearch
::each_implementation_for_trait(&tcx
.sess
.cstore
, trait_id
, |implementation_def_id
| {
6561 let impl_items
= csearch
::get_impl_items(&tcx
.sess
.cstore
, implementation_def_id
);
6562 let trait_ref
= impl_trait_ref(tcx
, implementation_def_id
).unwrap();
6563 // Record the trait->implementation mapping.
6564 def
.record_impl(tcx
, implementation_def_id
, trait_ref
);
6566 // For any methods that use a default implementation, add them to
6567 // the map. This is a bit unfortunate.
6568 for impl_item_def_id
in &impl_items
{
6569 let method_def_id
= impl_item_def_id
.def_id();
6570 match impl_or_trait_item(tcx
, method_def_id
) {
6571 MethodTraitItem(method
) => {
6572 if let Some(source
) = method
.provided_source
{
6573 tcx
.provided_method_sources
6575 .insert(method_def_id
, source
);
6582 // Store the implementation info.
6583 tcx
.impl_items
.borrow_mut().insert(implementation_def_id
, impl_items
);
6586 def
.flags
.set(def
.flags
.get() | TraitFlags
::IMPLS_VALID
);
6589 /// Given the def_id of an impl, return the def_id of the trait it implements.
6590 /// If it implements no trait, return `None`.
6591 pub fn trait_id_of_impl(tcx
: &ctxt
,
6593 -> Option
<ast
::DefId
> {
6594 ty
::impl_trait_ref(tcx
, def_id
).map(|tr
| tr
.def_id
)
6597 /// If the given def ID describes a method belonging to an impl, return the
6598 /// ID of the impl that the method belongs to. Otherwise, return `None`.
6599 pub fn impl_of_method(tcx
: &ctxt
, def_id
: ast
::DefId
)
6600 -> Option
<ast
::DefId
> {
6601 if def_id
.krate
!= LOCAL_CRATE
{
6602 return match csearch
::get_impl_or_trait_item(tcx
,
6603 def_id
).container() {
6604 TraitContainer(_
) => None
,
6605 ImplContainer(def_id
) => Some(def_id
),
6608 match tcx
.impl_or_trait_items
.borrow().get(&def_id
).cloned() {
6609 Some(trait_item
) => {
6610 match trait_item
.container() {
6611 TraitContainer(_
) => None
,
6612 ImplContainer(def_id
) => Some(def_id
),
6619 /// If the given def ID describes an item belonging to a trait (either a
6620 /// default method or an implementation of a trait method), return the ID of
6621 /// the trait that the method belongs to. Otherwise, return `None`.
6622 pub fn trait_of_item(tcx
: &ctxt
, def_id
: ast
::DefId
) -> Option
<ast
::DefId
> {
6623 if def_id
.krate
!= LOCAL_CRATE
{
6624 return csearch
::get_trait_of_item(&tcx
.sess
.cstore
, def_id
, tcx
);
6626 match tcx
.impl_or_trait_items
.borrow().get(&def_id
).cloned() {
6627 Some(impl_or_trait_item
) => {
6628 match impl_or_trait_item
.container() {
6629 TraitContainer(def_id
) => Some(def_id
),
6630 ImplContainer(def_id
) => trait_id_of_impl(tcx
, def_id
),
6637 /// If the given def ID describes an item belonging to a trait, (either a
6638 /// default method or an implementation of a trait method), return the ID of
6639 /// the method inside trait definition (this means that if the given def ID
6640 /// is already that of the original trait method, then the return value is
6642 /// Otherwise, return `None`.
6643 pub fn trait_item_of_item(tcx
: &ctxt
, def_id
: ast
::DefId
)
6644 -> Option
<ImplOrTraitItemId
> {
6645 let impl_item
= match tcx
.impl_or_trait_items
.borrow().get(&def_id
) {
6646 Some(m
) => m
.clone(),
6647 None
=> return None
,
6649 let name
= impl_item
.name();
6650 match trait_of_item(tcx
, def_id
) {
6651 Some(trait_did
) => {
6652 let trait_items
= ty
::trait_items(tcx
, trait_did
);
6654 .position(|m
| m
.name() == name
)
6655 .map(|idx
| ty
::trait_item(tcx
, trait_did
, idx
).id())
6661 /// Creates a hash of the type `Ty` which will be the same no matter what crate
6662 /// context it's calculated within. This is used by the `type_id` intrinsic.
6663 pub fn hash_crate_independent
<'tcx
>(tcx
: &ctxt
<'tcx
>, ty
: Ty
<'tcx
>, svh
: &Svh
) -> u64 {
6664 let mut state
= SipHasher
::new();
6665 helper(tcx
, ty
, svh
, &mut state
);
6666 return state
.finish();
6668 fn helper
<'tcx
>(tcx
: &ctxt
<'tcx
>, ty
: Ty
<'tcx
>, svh
: &Svh
,
6669 state
: &mut SipHasher
) {
6670 macro_rules
! byte { ($b:expr) => { ($b as u8).hash(state) }
}
6671 macro_rules
! hash { ($e:expr) => { $e.hash(state) }
}
6673 let region
= |state
: &mut SipHasher
, r
: Region
| {
6676 ReLateBound(db
, BrAnon(i
)) => {
6686 tcx
.sess
.bug("unexpected region found when hashing a type")
6690 let did
= |state
: &mut SipHasher
, did
: DefId
| {
6691 let h
= if ast_util
::is_local(did
) {
6694 tcx
.sess
.cstore
.get_crate_hash(did
.krate
)
6696 h
.as_str().hash(state
);
6697 did
.node
.hash(state
);
6699 let mt
= |state
: &mut SipHasher
, mt
: mt
| {
6700 mt
.mutbl
.hash(state
);
6702 let fn_sig
= |state
: &mut SipHasher
, sig
: &Binder
<FnSig
<'tcx
>>| {
6703 let sig
= anonymize_late_bound_regions(tcx
, sig
).0;
6704 for a
in &sig
.inputs { helper(tcx, *a, svh, state); }
6705 if let ty
::FnConverging(output
) = sig
.output
{
6706 helper(tcx
, output
, svh
, state
);
6709 maybe_walk_ty(ty
, |ty
| {
6751 TyBareFn(opt_def_id
, ref b
) => {
6756 fn_sig(state
, &b
.sig
);
6759 TyTrait(ref data
) => {
6761 did(state
, data
.principal_def_id());
6764 let principal
= anonymize_late_bound_regions(tcx
, &data
.principal
).0;
6765 for subty
in &principal
.substs
.types
{
6766 helper(tcx
, subty
, svh
, state
);
6775 TyTuple(ref inner
) => {
6783 hash
!(token
::get_name(p
.name
));
6785 TyInfer(_
) => unreachable
!(),
6786 TyError
=> byte
!(21),
6787 TyClosure(d
, _
) => {
6791 TyProjection(ref data
) => {
6793 did(state
, data
.trait_ref
.def_id
);
6794 hash
!(token
::get_name(data
.item_name
));
6802 impl fmt
::Debug
for Variance
{
6803 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
6804 f
.write_str(match *self {
6806 Contravariant
=> "-",
6813 /// Construct a parameter environment suitable for static contexts or other contexts where there
6814 /// are no free type/lifetime parameters in scope.
6815 pub fn empty_parameter_environment
<'a
,'tcx
>(cx
: &'a ctxt
<'tcx
>) -> ParameterEnvironment
<'a
,'tcx
> {
6816 ty
::ParameterEnvironment
{ tcx
: cx
,
6817 free_substs
: Substs
::empty(),
6818 caller_bounds
: Vec
::new(),
6819 implicit_region_bound
: ty
::ReEmpty
,
6820 selection_cache
: traits
::SelectionCache
::new(), }
6823 /// Constructs and returns a substitution that can be applied to move from
6824 /// the "outer" view of a type or method to the "inner" view.
6825 /// In general, this means converting from bound parameters to
6826 /// free parameters. Since we currently represent bound/free type
6827 /// parameters in the same way, this only has an effect on regions.
6828 pub fn construct_free_substs
<'a
,'tcx
>(
6829 tcx
: &'a ctxt
<'tcx
>,
6830 generics
: &Generics
<'tcx
>,
6831 free_id
: ast
::NodeId
)
6835 let mut types
= VecPerParamSpace
::empty();
6836 push_types_from_defs(tcx
, &mut types
, generics
.types
.as_slice());
6838 let free_id_outlive
= region
::DestructionScopeData
::new(free_id
);
6840 // map bound 'a => free 'a
6841 let mut regions
= VecPerParamSpace
::empty();
6842 push_region_params(&mut regions
, free_id_outlive
, generics
.regions
.as_slice());
6846 regions
: subst
::NonerasedRegions(regions
)
6849 fn push_region_params(regions
: &mut VecPerParamSpace
<ty
::Region
>,
6850 all_outlive_extent
: region
::DestructionScopeData
,
6851 region_params
: &[RegionParameterDef
])
6853 for r
in region_params
{
6854 regions
.push(r
.space
, ty
::free_region_from_def(all_outlive_extent
, r
));
6858 fn push_types_from_defs
<'tcx
>(tcx
: &ty
::ctxt
<'tcx
>,
6859 types
: &mut VecPerParamSpace
<Ty
<'tcx
>>,
6860 defs
: &[TypeParameterDef
<'tcx
>]) {
6862 debug
!("construct_parameter_environment(): push_types_from_defs: def={:?}",
6864 let ty
= ty
::mk_param_from_def(tcx
, def
);
6865 types
.push(def
.space
, ty
);
6870 /// See `ParameterEnvironment` struct def'n for details
6871 pub fn construct_parameter_environment
<'a
,'tcx
>(
6872 tcx
: &'a ctxt
<'tcx
>,
6874 generics
: &ty
::Generics
<'tcx
>,
6875 generic_predicates
: &ty
::GenericPredicates
<'tcx
>,
6876 free_id
: ast
::NodeId
)
6877 -> ParameterEnvironment
<'a
, 'tcx
>
6880 // Construct the free substs.
6883 let free_substs
= construct_free_substs(tcx
, generics
, free_id
);
6884 let free_id_outlive
= region
::DestructionScopeData
::new(free_id
);
6887 // Compute the bounds on Self and the type parameters.
6890 let bounds
= generic_predicates
.instantiate(tcx
, &free_substs
);
6891 let bounds
= liberate_late_bound_regions(tcx
, free_id_outlive
, &ty
::Binder(bounds
));
6892 let predicates
= bounds
.predicates
.into_vec();
6894 debug
!("construct_parameter_environment: free_id={:?} free_subst={:?} predicates={:?}",
6900 // Finally, we have to normalize the bounds in the environment, in
6901 // case they contain any associated type projections. This process
6902 // can yield errors if the put in illegal associated types, like
6903 // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
6904 // report these errors right here; this doesn't actually feel
6905 // right to me, because constructing the environment feels like a
6906 // kind of a "idempotent" action, but I'm not sure where would be
6907 // a better place. In practice, we construct environments for
6908 // every fn once during type checking, and we'll abort if there
6909 // are any errors at that point, so after type checking you can be
6910 // sure that this will succeed without errors anyway.
6913 let unnormalized_env
= ty
::ParameterEnvironment
{
6915 free_substs
: free_substs
,
6916 implicit_region_bound
: ty
::ReScope(free_id_outlive
.to_code_extent()),
6917 caller_bounds
: predicates
,
6918 selection_cache
: traits
::SelectionCache
::new(),
6921 let cause
= traits
::ObligationCause
::misc(span
, free_id
);
6922 traits
::normalize_param_env_or_error(unnormalized_env
, cause
)
6926 pub fn from_mutbl(m
: ast
::Mutability
) -> BorrowKind
{
6928 ast
::MutMutable
=> MutBorrow
,
6929 ast
::MutImmutable
=> ImmBorrow
,
6933 /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow
6934 /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a
6935 /// mutability that is stronger than necessary so that it at least *would permit* the borrow in
6937 pub fn to_mutbl_lossy(self) -> ast
::Mutability
{
6939 MutBorrow
=> ast
::MutMutable
,
6940 ImmBorrow
=> ast
::MutImmutable
,
6942 // We have no type corresponding to a unique imm borrow, so
6943 // use `&mut`. It gives all the capabilities of an `&uniq`
6944 // and hence is a safe "over approximation".
6945 UniqueImmBorrow
=> ast
::MutMutable
,
6949 pub fn to_user_str(&self) -> &'
static str {
6951 MutBorrow
=> "mutable",
6952 ImmBorrow
=> "immutable",
6953 UniqueImmBorrow
=> "uniquely immutable",
6958 impl<'tcx
> ctxt
<'tcx
> {
6959 pub fn is_method_call(&self, expr_id
: ast
::NodeId
) -> bool
{
6960 self.method_map
.borrow().contains_key(&MethodCall
::expr(expr_id
))
6963 pub fn upvar_capture(&self, upvar_id
: ty
::UpvarId
) -> Option
<ty
::UpvarCapture
> {
6964 Some(self.upvar_capture_map
.borrow().get(&upvar_id
).unwrap().clone())
6968 impl<'a
,'tcx
> mc
::Typer
<'tcx
> for ParameterEnvironment
<'a
,'tcx
> {
6969 fn node_ty(&self, id
: ast
::NodeId
) -> mc
::McResult
<Ty
<'tcx
>> {
6970 Ok(ty
::node_id_to_type(self.tcx
, id
))
6973 fn expr_ty_adjusted(&self, expr
: &ast
::Expr
) -> mc
::McResult
<Ty
<'tcx
>> {
6974 Ok(ty
::expr_ty_adjusted(self.tcx
, expr
))
6977 fn node_method_ty(&self, method_call
: ty
::MethodCall
) -> Option
<Ty
<'tcx
>> {
6978 self.tcx
.method_map
.borrow().get(&method_call
).map(|method
| method
.ty
)
6981 fn node_method_origin(&self, method_call
: ty
::MethodCall
)
6982 -> Option
<ty
::MethodOrigin
<'tcx
>>
6984 self.tcx
.method_map
.borrow().get(&method_call
).map(|method
| method
.origin
.clone())
6987 fn adjustments(&self) -> &RefCell
<NodeMap
<ty
::AutoAdjustment
<'tcx
>>> {
6988 &self.tcx
.adjustments
6991 fn is_method_call(&self, id
: ast
::NodeId
) -> bool
{
6992 self.tcx
.is_method_call(id
)
6995 fn temporary_scope(&self, rvalue_id
: ast
::NodeId
) -> Option
<region
::CodeExtent
> {
6996 self.tcx
.region_maps
.temporary_scope(rvalue_id
)
6999 fn upvar_capture(&self, upvar_id
: ty
::UpvarId
) -> Option
<ty
::UpvarCapture
> {
7000 self.tcx
.upvar_capture(upvar_id
)
7003 fn type_moves_by_default(&self, span
: Span
, ty
: Ty
<'tcx
>) -> bool
{
7004 type_moves_by_default(self, span
, ty
)
7008 impl<'a
,'tcx
> ClosureTyper
<'tcx
> for ty
::ParameterEnvironment
<'a
,'tcx
> {
7009 fn param_env
<'b
>(&'b
self) -> &'b ty
::ParameterEnvironment
<'b
,'tcx
> {
7013 fn closure_kind(&self,
7015 -> Option
<ty
::ClosureKind
>
7017 Some(self.tcx
.closure_kind(def_id
))
7020 fn closure_type(&self,
7022 substs
: &subst
::Substs
<'tcx
>)
7023 -> ty
::ClosureTy
<'tcx
>
7025 self.tcx
.closure_type(def_id
, substs
)
7028 fn closure_upvars(&self,
7030 substs
: &Substs
<'tcx
>)
7031 -> Option
<Vec
<ClosureUpvar
<'tcx
>>>
7033 closure_upvars(self, def_id
, substs
)
7038 /// The category of explicit self.
7039 #[derive(Clone, Copy, Eq, PartialEq, Debug)]
7040 pub enum ExplicitSelfCategory
{
7041 StaticExplicitSelfCategory
,
7042 ByValueExplicitSelfCategory
,
7043 ByReferenceExplicitSelfCategory(Region
, ast
::Mutability
),
7044 ByBoxExplicitSelfCategory
,
7047 /// Pushes all the lifetimes in the given type onto the given list. A
7048 /// "lifetime in a type" is a lifetime specified by a reference or a lifetime
7049 /// in a list of type substitutions. This does *not* traverse into nominal
7050 /// types, nor does it resolve fictitious types.
7051 pub fn accumulate_lifetimes_in_type(accumulator
: &mut Vec
<ty
::Region
>,
7055 TyRef(region
, _
) => {
7056 accumulator
.push(*region
)
7059 accumulator
.push_all(t
.principal
.0.substs
.regions().as_slice());
7062 TyStruct(_
, substs
) => {
7063 accum_substs(accumulator
, substs
);
7065 TyClosure(_
, substs
) => {
7066 accum_substs(accumulator
, substs
);
7088 fn accum_substs(accumulator
: &mut Vec
<Region
>, substs
: &Substs
) {
7089 match substs
.regions
{
7090 subst
::ErasedRegions
=> {}
7091 subst
::NonerasedRegions(ref regions
) => {
7092 for region
in regions
{
7093 accumulator
.push(*region
)
7100 /// A free variable referred to in a function.
7101 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
7102 pub struct Freevar
{
7103 /// The variable being accessed free.
7106 // First span where it is accessed (there can be multiple).
7110 pub type FreevarMap
= NodeMap
<Vec
<Freevar
>>;
7112 pub type CaptureModeMap
= NodeMap
<ast
::CaptureClause
>;
7114 // Trait method resolution
7115 pub type TraitMap
= NodeMap
<Vec
<DefId
>>;
7117 // Map from the NodeId of a glob import to a list of items which are actually
7119 pub type GlobMap
= HashMap
<NodeId
, HashSet
<Name
>>;
7121 pub fn with_freevars
<T
, F
>(tcx
: &ty
::ctxt
, fid
: ast
::NodeId
, f
: F
) -> T
where
7122 F
: FnOnce(&[Freevar
]) -> T
,
7124 match tcx
.freevars
.borrow().get(&fid
) {
7126 Some(d
) => f(&d
[..])
7130 impl<'tcx
> AutoAdjustment
<'tcx
> {
7131 pub fn is_identity(&self) -> bool
{
7133 AdjustReifyFnPointer
|
7134 AdjustUnsafeFnPointer
=> false,
7135 AdjustDerefRef(ref r
) => r
.is_identity(),
7140 impl<'tcx
> AutoDerefRef
<'tcx
> {
7141 pub fn is_identity(&self) -> bool
{
7142 self.autoderefs
== 0 && self.unsize
.is_none() && self.autoref
.is_none()
7146 /// Replace any late-bound regions bound in `value` with free variants attached to scope-id
7148 pub fn liberate_late_bound_regions
<'tcx
, T
>(
7149 tcx
: &ty
::ctxt
<'tcx
>,
7150 all_outlive_scope
: region
::DestructionScopeData
,
7153 where T
: TypeFoldable
<'tcx
>
7155 ty_fold
::replace_late_bound_regions(
7157 |br
| ty
::ReFree(ty
::FreeRegion{scope: all_outlive_scope, bound_region: br}
)).0
7160 pub fn count_late_bound_regions
<'tcx
, T
>(
7161 tcx
: &ty
::ctxt
<'tcx
>,
7164 where T
: TypeFoldable
<'tcx
>
7166 let (_
, skol_map
) = ty_fold
::replace_late_bound_regions(tcx
, value
, |_
| ty
::ReStatic
);
7170 pub fn binds_late_bound_regions
<'tcx
, T
>(
7171 tcx
: &ty
::ctxt
<'tcx
>,
7174 where T
: TypeFoldable
<'tcx
>
7176 count_late_bound_regions(tcx
, value
) > 0
7179 /// Flattens two binding levels into one. So `for<'a> for<'b> Foo`
7180 /// becomes `for<'a,'b> Foo`.
7181 pub fn flatten_late_bound_regions
<'tcx
, T
>(
7182 tcx
: &ty
::ctxt
<'tcx
>,
7183 bound2_value
: &Binder
<Binder
<T
>>)
7185 where T
: TypeFoldable
<'tcx
>
7187 let bound0_value
= bound2_value
.skip_binder().skip_binder();
7188 let value
= ty_fold
::fold_regions(tcx
, bound0_value
, |region
, current_depth
| {
7190 ty
::ReLateBound(debruijn
, br
) if debruijn
.depth
>= current_depth
=> {
7191 // should be true if no escaping regions from bound2_value
7192 assert
!(debruijn
.depth
- current_depth
<= 1);
7193 ty
::ReLateBound(DebruijnIndex
::new(current_depth
), br
)
7203 pub fn no_late_bound_regions
<'tcx
, T
>(
7204 tcx
: &ty
::ctxt
<'tcx
>,
7207 where T
: TypeFoldable
<'tcx
>
7209 if binds_late_bound_regions(tcx
, value
) {
7212 Some(value
.0.clone())
7216 /// Replace any late-bound regions bound in `value` with `'static`. Useful in trans but also
7217 /// method lookup and a few other places where precise region relationships are not required.
7218 pub fn erase_late_bound_regions
<'tcx
, T
>(
7219 tcx
: &ty
::ctxt
<'tcx
>,
7222 where T
: TypeFoldable
<'tcx
>
7224 ty_fold
::replace_late_bound_regions(tcx
, value
, |_
| ty
::ReStatic
).0
7227 /// Rewrite any late-bound regions so that they are anonymous. Region numbers are
7228 /// assigned starting at 1 and increasing monotonically in the order traversed
7229 /// by the fold operation.
7231 /// The chief purpose of this function is to canonicalize regions so that two
7232 /// `FnSig`s or `TraitRef`s which are equivalent up to region naming will become
7233 /// structurally identical. For example, `for<'a, 'b> fn(&'a isize, &'b isize)` and
7234 /// `for<'a, 'b> fn(&'b isize, &'a isize)` will become identical after anonymization.
7235 pub fn anonymize_late_bound_regions
<'tcx
, T
>(
7239 where T
: TypeFoldable
<'tcx
>,
7241 let mut counter
= 0;
7242 ty
::Binder(ty_fold
::replace_late_bound_regions(tcx
, sig
, |_
| {
7244 ReLateBound(ty
::DebruijnIndex
::new(1), BrAnon(counter
))
7248 impl DebruijnIndex
{
7249 pub fn new(depth
: u32) -> DebruijnIndex
{
7251 DebruijnIndex { depth: depth }
7254 pub fn shifted(&self, amount
: u32) -> DebruijnIndex
{
7255 DebruijnIndex { depth: self.depth + amount }
7259 impl<'tcx
> fmt
::Debug
for AutoAdjustment
<'tcx
> {
7260 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
7262 AdjustReifyFnPointer
=> {
7263 write
!(f
, "AdjustReifyFnPointer")
7265 AdjustUnsafeFnPointer
=> {
7266 write
!(f
, "AdjustUnsafeFnPointer")
7268 AdjustDerefRef(ref data
) => {
7269 write
!(f
, "{:?}", data
)
7275 impl<'tcx
> fmt
::Debug
for AutoDerefRef
<'tcx
> {
7276 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
7277 write
!(f
, "AutoDerefRef({}, unsize={:?}, {:?})",
7278 self.autoderefs
, self.unsize
, self.autoref
)
7282 impl<'tcx
> fmt
::Debug
for TraitTy
<'tcx
> {
7283 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
7284 write
!(f
, "TraitTy({:?},{:?})",
7290 impl<'tcx
> fmt
::Debug
for ty
::Predicate
<'tcx
> {
7291 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
7293 Predicate
::Trait(ref a
) => write
!(f
, "{:?}", a
),
7294 Predicate
::Equate(ref pair
) => write
!(f
, "{:?}", pair
),
7295 Predicate
::RegionOutlives(ref pair
) => write
!(f
, "{:?}", pair
),
7296 Predicate
::TypeOutlives(ref pair
) => write
!(f
, "{:?}", pair
),
7297 Predicate
::Projection(ref pair
) => write
!(f
, "{:?}", pair
),
7302 pub fn make_substs_for_receiver_types
<'tcx
>(tcx
: &ty
::ctxt
<'tcx
>,
7303 trait_ref
: &ty
::TraitRef
<'tcx
>,
7304 method
: &ty
::Method
<'tcx
>)
7305 -> subst
::Substs
<'tcx
>
7308 * Substitutes the values for the receiver's type parameters
7309 * that are found in method, leaving the method's type parameters
7313 let meth_tps
: Vec
<Ty
> =
7314 method
.generics
.types
.get_slice(subst
::FnSpace
)
7316 .map(|def
| ty
::mk_param_from_def(tcx
, def
))
7318 let meth_regions
: Vec
<ty
::Region
> =
7319 method
.generics
.regions
.get_slice(subst
::FnSpace
)
7321 .map(|def
| def
.to_early_bound_region())
7323 trait_ref
.substs
.clone().with_method(meth_tps
, meth_regions
)
7326 #[derive(Copy, Clone)]
7327 pub enum CopyImplementationError
{
7328 FieldDoesNotImplementCopy(ast
::Name
),
7329 VariantDoesNotImplementCopy(ast
::Name
),
7334 pub fn can_type_implement_copy
<'a
,'tcx
>(param_env
: &ParameterEnvironment
<'a
, 'tcx
>,
7336 self_type
: Ty
<'tcx
>)
7337 -> Result
<(),CopyImplementationError
>
7339 let tcx
= param_env
.tcx
;
7341 let did
= match self_type
.sty
{
7342 ty
::TyStruct(struct_did
, substs
) => {
7343 let fields
= ty
::struct_fields(tcx
, struct_did
, substs
);
7344 for field
in &fields
{
7345 if type_moves_by_default(param_env
, span
, field
.mt
.ty
) {
7346 return Err(FieldDoesNotImplementCopy(field
.name
))
7351 ty
::TyEnum(enum_did
, substs
) => {
7352 let enum_variants
= ty
::enum_variants(tcx
, enum_did
);
7353 for variant
in enum_variants
.iter() {
7354 for variant_arg_type
in &variant
.args
{
7355 let substd_arg_type
=
7356 variant_arg_type
.subst(tcx
, substs
);
7357 if type_moves_by_default(param_env
, span
, substd_arg_type
) {
7358 return Err(VariantDoesNotImplementCopy(variant
.name
))
7364 _
=> return Err(TypeIsStructural
),
7367 if ty
::has_dtor(tcx
, did
) {
7368 return Err(TypeHasDestructor
)
7374 // FIXME(#20298) -- all of these types basically walk various
7375 // structures to test whether types/regions are reachable with various
7376 // properties. It should be possible to express them in terms of one
7377 // common "walker" trait or something.
7379 pub trait RegionEscape
{
7380 fn has_escaping_regions(&self) -> bool
{
7381 self.has_regions_escaping_depth(0)
7384 fn has_regions_escaping_depth(&self, depth
: u32) -> bool
;
7387 impl<'tcx
> RegionEscape
for Ty
<'tcx
> {
7388 fn has_regions_escaping_depth(&self, depth
: u32) -> bool
{
7389 ty
::type_escapes_depth(*self, depth
)
7393 impl<'tcx
> RegionEscape
for Substs
<'tcx
> {
7394 fn has_regions_escaping_depth(&self, depth
: u32) -> bool
{
7395 self.types
.has_regions_escaping_depth(depth
) ||
7396 self.regions
.has_regions_escaping_depth(depth
)
7400 impl<'tcx
,T
:RegionEscape
> RegionEscape
for VecPerParamSpace
<T
> {
7401 fn has_regions_escaping_depth(&self, depth
: u32) -> bool
{
7402 self.iter_enumerated().any(|(space
, _
, t
)| {
7403 if space
== subst
::FnSpace
{
7404 t
.has_regions_escaping_depth(depth
+1)
7406 t
.has_regions_escaping_depth(depth
)
7412 impl<'tcx
> RegionEscape
for TypeScheme
<'tcx
> {
7413 fn has_regions_escaping_depth(&self, depth
: u32) -> bool
{
7414 self.ty
.has_regions_escaping_depth(depth
)
7418 impl RegionEscape
for Region
{
7419 fn has_regions_escaping_depth(&self, depth
: u32) -> bool
{
7420 self.escapes_depth(depth
)
7424 impl<'tcx
> RegionEscape
for GenericPredicates
<'tcx
> {
7425 fn has_regions_escaping_depth(&self, depth
: u32) -> bool
{
7426 self.predicates
.has_regions_escaping_depth(depth
)
7430 impl<'tcx
> RegionEscape
for Predicate
<'tcx
> {
7431 fn has_regions_escaping_depth(&self, depth
: u32) -> bool
{
7433 Predicate
::Trait(ref data
) => data
.has_regions_escaping_depth(depth
),
7434 Predicate
::Equate(ref data
) => data
.has_regions_escaping_depth(depth
),
7435 Predicate
::RegionOutlives(ref data
) => data
.has_regions_escaping_depth(depth
),
7436 Predicate
::TypeOutlives(ref data
) => data
.has_regions_escaping_depth(depth
),
7437 Predicate
::Projection(ref data
) => data
.has_regions_escaping_depth(depth
),
7442 impl<'tcx
,P
:RegionEscape
> RegionEscape
for traits
::Obligation
<'tcx
,P
> {
7443 fn has_regions_escaping_depth(&self, depth
: u32) -> bool
{
7444 self.predicate
.has_regions_escaping_depth(depth
)
7448 impl<'tcx
> RegionEscape
for TraitRef
<'tcx
> {
7449 fn has_regions_escaping_depth(&self, depth
: u32) -> bool
{
7450 self.substs
.types
.iter().any(|t
| t
.has_regions_escaping_depth(depth
)) ||
7451 self.substs
.regions
.has_regions_escaping_depth(depth
)
7455 impl<'tcx
> RegionEscape
for subst
::RegionSubsts
{
7456 fn has_regions_escaping_depth(&self, depth
: u32) -> bool
{
7458 subst
::ErasedRegions
=> false,
7459 subst
::NonerasedRegions(ref r
) => {
7460 r
.iter().any(|t
| t
.has_regions_escaping_depth(depth
))
7466 impl<'tcx
,T
:RegionEscape
> RegionEscape
for Binder
<T
> {
7467 fn has_regions_escaping_depth(&self, depth
: u32) -> bool
{
7468 self.0.has_regions_escaping_depth(depth
+ 1)
7472 impl<'tcx
> RegionEscape
for EquatePredicate
<'tcx
> {
7473 fn has_regions_escaping_depth(&self, depth
: u32) -> bool
{
7474 self.0.has_regions_escaping_depth(depth
) || self.1.has_regions_escaping_depth(depth
)
7478 impl<'tcx
> RegionEscape
for TraitPredicate
<'tcx
> {
7479 fn has_regions_escaping_depth(&self, depth
: u32) -> bool
{
7480 self.trait_ref
.has_regions_escaping_depth(depth
)
7484 impl<T
:RegionEscape
,U
:RegionEscape
> RegionEscape
for OutlivesPredicate
<T
,U
> {
7485 fn has_regions_escaping_depth(&self, depth
: u32) -> bool
{
7486 self.0.has_regions_escaping_depth(depth
) || self.1.has_regions_escaping_depth(depth
)
7490 impl<'tcx
> RegionEscape
for ProjectionPredicate
<'tcx
> {
7491 fn has_regions_escaping_depth(&self, depth
: u32) -> bool
{
7492 self.projection_ty
.has_regions_escaping_depth(depth
) ||
7493 self.ty
.has_regions_escaping_depth(depth
)
7497 impl<'tcx
> RegionEscape
for ProjectionTy
<'tcx
> {
7498 fn has_regions_escaping_depth(&self, depth
: u32) -> bool
{
7499 self.trait_ref
.has_regions_escaping_depth(depth
)
7503 pub trait HasProjectionTypes
{
7504 fn has_projection_types(&self) -> bool
;
7507 impl<'tcx
,T
:HasProjectionTypes
> HasProjectionTypes
for Vec
<T
> {
7508 fn has_projection_types(&self) -> bool
{
7509 self.iter().any(|p
| p
.has_projection_types())
7513 impl<'tcx
,T
:HasProjectionTypes
> HasProjectionTypes
for VecPerParamSpace
<T
> {
7514 fn has_projection_types(&self) -> bool
{
7515 self.iter().any(|p
| p
.has_projection_types())
7519 impl<'tcx
> HasProjectionTypes
for ClosureTy
<'tcx
> {
7520 fn has_projection_types(&self) -> bool
{
7521 self.sig
.has_projection_types()
7525 impl<'tcx
> HasProjectionTypes
for ClosureUpvar
<'tcx
> {
7526 fn has_projection_types(&self) -> bool
{
7527 self.ty
.has_projection_types()
7531 impl<'tcx
> HasProjectionTypes
for ty
::InstantiatedPredicates
<'tcx
> {
7532 fn has_projection_types(&self) -> bool
{
7533 self.predicates
.has_projection_types()
7537 impl<'tcx
> HasProjectionTypes
for Predicate
<'tcx
> {
7538 fn has_projection_types(&self) -> bool
{
7540 Predicate
::Trait(ref data
) => data
.has_projection_types(),
7541 Predicate
::Equate(ref data
) => data
.has_projection_types(),
7542 Predicate
::RegionOutlives(ref data
) => data
.has_projection_types(),
7543 Predicate
::TypeOutlives(ref data
) => data
.has_projection_types(),
7544 Predicate
::Projection(ref data
) => data
.has_projection_types(),
7549 impl<'tcx
> HasProjectionTypes
for TraitPredicate
<'tcx
> {
7550 fn has_projection_types(&self) -> bool
{
7551 self.trait_ref
.has_projection_types()
7555 impl<'tcx
> HasProjectionTypes
for EquatePredicate
<'tcx
> {
7556 fn has_projection_types(&self) -> bool
{
7557 self.0.has_projection_types() || self.1.has_projection_types()
7561 impl HasProjectionTypes
for Region
{
7562 fn has_projection_types(&self) -> bool
{
7567 impl<T
:HasProjectionTypes
,U
:HasProjectionTypes
> HasProjectionTypes
for OutlivesPredicate
<T
,U
> {
7568 fn has_projection_types(&self) -> bool
{
7569 self.0.has_projection_types() || self.1.has_projection_types()
7573 impl<'tcx
> HasProjectionTypes
for ProjectionPredicate
<'tcx
> {
7574 fn has_projection_types(&self) -> bool
{
7575 self.projection_ty
.has_projection_types() || self.ty
.has_projection_types()
7579 impl<'tcx
> HasProjectionTypes
for ProjectionTy
<'tcx
> {
7580 fn has_projection_types(&self) -> bool
{
7581 self.trait_ref
.has_projection_types()
7585 impl<'tcx
> HasProjectionTypes
for Ty
<'tcx
> {
7586 fn has_projection_types(&self) -> bool
{
7587 ty
::type_has_projection(*self)
7591 impl<'tcx
> HasProjectionTypes
for TraitRef
<'tcx
> {
7592 fn has_projection_types(&self) -> bool
{
7593 self.substs
.has_projection_types()
7597 impl<'tcx
> HasProjectionTypes
for subst
::Substs
<'tcx
> {
7598 fn has_projection_types(&self) -> bool
{
7599 self.types
.iter().any(|t
| t
.has_projection_types())
7603 impl<'tcx
,T
> HasProjectionTypes
for Option
<T
>
7604 where T
: HasProjectionTypes
7606 fn has_projection_types(&self) -> bool
{
7607 self.iter().any(|t
| t
.has_projection_types())
7611 impl<'tcx
,T
> HasProjectionTypes
for Rc
<T
>
7612 where T
: HasProjectionTypes
7614 fn has_projection_types(&self) -> bool
{
7615 (**self).has_projection_types()
7619 impl<'tcx
,T
> HasProjectionTypes
for Box
<T
>
7620 where T
: HasProjectionTypes
7622 fn has_projection_types(&self) -> bool
{
7623 (**self).has_projection_types()
7627 impl<T
> HasProjectionTypes
for Binder
<T
>
7628 where T
: HasProjectionTypes
7630 fn has_projection_types(&self) -> bool
{
7631 self.0.has_projection_types()
7635 impl<'tcx
> HasProjectionTypes
for FnOutput
<'tcx
> {
7636 fn has_projection_types(&self) -> bool
{
7638 FnConverging(t
) => t
.has_projection_types(),
7639 FnDiverging
=> false,
7644 impl<'tcx
> HasProjectionTypes
for FnSig
<'tcx
> {
7645 fn has_projection_types(&self) -> bool
{
7646 self.inputs
.iter().any(|t
| t
.has_projection_types()) ||
7647 self.output
.has_projection_types()
7651 impl<'tcx
> HasProjectionTypes
for field
<'tcx
> {
7652 fn has_projection_types(&self) -> bool
{
7653 self.mt
.ty
.has_projection_types()
7657 impl<'tcx
> HasProjectionTypes
for BareFnTy
<'tcx
> {
7658 fn has_projection_types(&self) -> bool
{
7659 self.sig
.has_projection_types()
7663 pub trait ReferencesError
{
7664 fn references_error(&self) -> bool
;
7667 impl<T
:ReferencesError
> ReferencesError
for Binder
<T
> {
7668 fn references_error(&self) -> bool
{
7669 self.0.references_error()
7673 impl<T
:ReferencesError
> ReferencesError
for Rc
<T
> {
7674 fn references_error(&self) -> bool
{
7675 (&**self).references_error()
7679 impl<'tcx
> ReferencesError
for TraitPredicate
<'tcx
> {
7680 fn references_error(&self) -> bool
{
7681 self.trait_ref
.references_error()
7685 impl<'tcx
> ReferencesError
for ProjectionPredicate
<'tcx
> {
7686 fn references_error(&self) -> bool
{
7687 self.projection_ty
.trait_ref
.references_error() || self.ty
.references_error()
7691 impl<'tcx
> ReferencesError
for TraitRef
<'tcx
> {
7692 fn references_error(&self) -> bool
{
7693 self.input_types().iter().any(|t
| t
.references_error())
7697 impl<'tcx
> ReferencesError
for Ty
<'tcx
> {
7698 fn references_error(&self) -> bool
{
7699 type_is_error(*self)
7703 impl<'tcx
> ReferencesError
for Predicate
<'tcx
> {
7704 fn references_error(&self) -> bool
{
7706 Predicate
::Trait(ref data
) => data
.references_error(),
7707 Predicate
::Equate(ref data
) => data
.references_error(),
7708 Predicate
::RegionOutlives(ref data
) => data
.references_error(),
7709 Predicate
::TypeOutlives(ref data
) => data
.references_error(),
7710 Predicate
::Projection(ref data
) => data
.references_error(),
7715 impl<A
,B
> ReferencesError
for OutlivesPredicate
<A
,B
>
7716 where A
: ReferencesError
, B
: ReferencesError
7718 fn references_error(&self) -> bool
{
7719 self.0.references_error() || self.1.references_error()
7723 impl<'tcx
> ReferencesError
for EquatePredicate
<'tcx
>
7725 fn references_error(&self) -> bool
{
7726 self.0.references_error() || self.1.references_error()
7730 impl ReferencesError
for Region
7732 fn references_error(&self) -> bool
{
7737 impl<'tcx
> fmt
::Debug
for ClosureTy
<'tcx
> {
7738 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
7739 write
!(f
, "ClosureTy({},{:?},{})",
7746 impl<'tcx
> fmt
::Debug
for ClosureUpvar
<'tcx
> {
7747 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
7748 write
!(f
, "ClosureUpvar({:?},{:?})",
7754 impl<'tcx
> fmt
::Debug
for field
<'tcx
> {
7755 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
7756 write
!(f
, "field({},{})", self.name
, self.mt
)
7760 impl<'a
, 'tcx
> fmt
::Debug
for ParameterEnvironment
<'a
, 'tcx
> {
7761 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
7762 write
!(f
, "ParameterEnvironment(\
7764 implicit_region_bound={:?}, \
7765 caller_bounds={:?})",
7767 self.implicit_region_bound
,
7772 impl<'tcx
> fmt
::Debug
for ObjectLifetimeDefault
{
7773 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
7775 ObjectLifetimeDefault
::Ambiguous
=> write
!(f
, "Ambiguous"),
7776 ObjectLifetimeDefault
::BaseDefault
=> write
!(f
, "BaseDefault"),
7777 ObjectLifetimeDefault
::Specific(ref r
) => write
!(f
, "{:?}", r
),