1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 pub use self::Variance
::*;
12 pub use self::AssociatedItemContainer
::*;
13 pub use self::BorrowKind
::*;
14 pub use self::IntVarValue
::*;
15 pub use self::LvaluePreference
::*;
16 pub use self::fold
::TypeFoldable
;
18 use dep_graph
::{self, DepNode}
;
19 use hir
::{map as hir_map, FreevarMap, TraitMap}
;
21 use hir
::def
::{Def, CtorKind, ExportMap}
;
22 use hir
::def_id
::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}
;
23 use middle
::lang_items
::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}
;
24 use middle
::region
::{CodeExtent, ROOT_CODE_EXTENT}
;
28 use ty
::subst
::{Subst, Substs}
;
29 use ty
::walk
::TypeWalker
;
30 use util
::common
::MemoizationMap
;
31 use util
::nodemap
::{NodeSet, NodeMap, FxHashMap}
;
33 use serialize
::{self, Encodable, Encoder}
;
35 use std
::cell
::{Cell, RefCell, Ref}
;
36 use std
::hash
::{Hash, Hasher}
;
41 use std
::vec
::IntoIter
;
43 use syntax
::ast
::{self, Name, NodeId}
;
45 use syntax
::symbol
::{Symbol, InternedString}
;
46 use syntax_pos
::{DUMMY_SP, Span}
;
48 use rustc_const_math
::ConstInt
;
49 use rustc_data_structures
::accumulate_vec
::IntoIter
as AccIntoIter
;
52 use hir
::itemlikevisit
::ItemLikeVisitor
;
54 pub use self::sty
::{Binder, DebruijnIndex}
;
55 pub use self::sty
::{BareFnTy, FnSig, PolyFnSig}
;
56 pub use self::sty
::{ClosureTy, InferTy, ParamTy, ProjectionTy, ExistentialPredicate}
;
57 pub use self::sty
::{ClosureSubsts, TypeAndMut}
;
58 pub use self::sty
::{TraitRef, TypeVariants, PolyTraitRef}
;
59 pub use self::sty
::{ExistentialTraitRef, PolyExistentialTraitRef}
;
60 pub use self::sty
::{ExistentialProjection, PolyExistentialProjection}
;
61 pub use self::sty
::{BoundRegion, EarlyBoundRegion, FreeRegion, Region}
;
62 pub use self::sty
::Issue32330
;
63 pub use self::sty
::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid}
;
64 pub use self::sty
::BoundRegion
::*;
65 pub use self::sty
::InferTy
::*;
66 pub use self::sty
::Region
::*;
67 pub use self::sty
::TypeVariants
::*;
69 pub use self::contents
::TypeContents
;
70 pub use self::context
::{TyCtxt, GlobalArenas, tls}
;
71 pub use self::context
::{Lift, TypeckTables}
;
73 pub use self::trait_def
::{TraitDef, TraitFlags}
;
80 pub mod inhabitedness
;
99 pub type Disr
= ConstInt
;
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.
106 pub struct CrateAnalysis
<'tcx
> {
107 pub export_map
: ExportMap
,
108 pub access_levels
: middle
::privacy
::AccessLevels
,
109 pub reachable
: NodeSet
,
111 pub glob_map
: Option
<hir
::GlobMap
>,
112 pub hir_ty_to_ty
: NodeMap
<Ty
<'tcx
>>,
116 pub struct Resolutions
{
117 pub freevars
: FreevarMap
,
118 pub trait_map
: TraitMap
,
119 pub maybe_unused_trait_imports
: NodeSet
,
122 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
123 pub enum AssociatedItemContainer
{
124 TraitContainer(DefId
),
125 ImplContainer(DefId
),
128 impl AssociatedItemContainer
{
129 pub fn id(&self) -> DefId
{
131 TraitContainer(id
) => id
,
132 ImplContainer(id
) => id
,
137 /// The "header" of an impl is everything outside the body: a Self type, a trait
138 /// ref (in the case of a trait impl), and a set of predicates (from the
139 /// bounds/where clauses).
140 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
141 pub struct ImplHeader
<'tcx
> {
142 pub impl_def_id
: DefId
,
143 pub self_ty
: Ty
<'tcx
>,
144 pub trait_ref
: Option
<TraitRef
<'tcx
>>,
145 pub predicates
: Vec
<Predicate
<'tcx
>>,
148 impl<'a
, 'gcx
, 'tcx
> ImplHeader
<'tcx
> {
149 pub fn with_fresh_ty_vars(selcx
: &mut traits
::SelectionContext
<'a
, 'gcx
, 'tcx
>,
153 let tcx
= selcx
.tcx();
154 let impl_substs
= selcx
.infcx().fresh_substs_for_item(DUMMY_SP
, impl_def_id
);
156 let header
= ImplHeader
{
157 impl_def_id
: impl_def_id
,
158 self_ty
: tcx
.item_type(impl_def_id
),
159 trait_ref
: tcx
.impl_trait_ref(impl_def_id
),
160 predicates
: tcx
.item_predicates(impl_def_id
).predicates
161 }.subst(tcx
, impl_substs
);
163 let traits
::Normalized { value: mut header, obligations }
=
164 traits
::normalize(selcx
, traits
::ObligationCause
::dummy(), &header
);
166 header
.predicates
.extend(obligations
.into_iter().map(|o
| o
.predicate
));
171 #[derive(Copy, Clone, Debug)]
172 pub struct AssociatedItem
{
175 pub kind
: AssociatedKind
,
177 pub defaultness
: hir
::Defaultness
,
178 pub container
: AssociatedItemContainer
,
180 /// Whether this is a method with an explicit self
181 /// as its first argument, allowing method calls.
182 pub method_has_self_argument
: bool
,
185 #[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
186 pub enum AssociatedKind
{
192 impl AssociatedItem
{
193 pub fn def(&self) -> Def
{
195 AssociatedKind
::Const
=> Def
::AssociatedConst(self.def_id
),
196 AssociatedKind
::Method
=> Def
::Method(self.def_id
),
197 AssociatedKind
::Type
=> Def
::AssociatedTy(self.def_id
),
202 #[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable)]
203 pub enum Visibility
{
204 /// Visible everywhere (including in other crates).
206 /// Visible only in the given crate-local module.
208 /// Not visible anywhere in the local crate. This is the visibility of private external items.
212 pub trait DefIdTree
: Copy
{
213 fn parent(self, id
: DefId
) -> Option
<DefId
>;
215 fn is_descendant_of(self, mut descendant
: DefId
, ancestor
: DefId
) -> bool
{
216 if descendant
.krate
!= ancestor
.krate
{
220 while descendant
!= ancestor
{
221 match self.parent(descendant
) {
222 Some(parent
) => descendant
= parent
,
223 None
=> return false,
230 impl<'a
, 'gcx
, 'tcx
> DefIdTree
for TyCtxt
<'a
, 'gcx
, 'tcx
> {
231 fn parent(self, id
: DefId
) -> Option
<DefId
> {
232 self.def_key(id
).parent
.map(|index
| DefId { index: index, ..id }
)
237 pub fn from_hir(visibility
: &hir
::Visibility
, id
: NodeId
, tcx
: TyCtxt
) -> Self {
239 hir
::Public
=> Visibility
::Public
,
240 hir
::Visibility
::Crate
=> Visibility
::Restricted(DefId
::local(CRATE_DEF_INDEX
)),
241 hir
::Visibility
::Restricted { ref path, .. }
=> match path
.def
{
242 // If there is no resolution, `resolve` will have already reported an error, so
243 // assume that the visibility is public to avoid reporting more privacy errors.
244 Def
::Err
=> Visibility
::Public
,
245 def
=> Visibility
::Restricted(def
.def_id()),
248 Visibility
::Restricted(tcx
.hir
.local_def_id(tcx
.hir
.get_module_parent(id
)))
253 /// Returns true if an item with this visibility is accessible from the given block.
254 pub fn is_accessible_from
<T
: DefIdTree
>(self, module
: DefId
, tree
: T
) -> bool
{
255 let restriction
= match self {
256 // Public items are visible everywhere.
257 Visibility
::Public
=> return true,
258 // Private items from other crates are visible nowhere.
259 Visibility
::Invisible
=> return false,
260 // Restricted items are visible in an arbitrary local module.
261 Visibility
::Restricted(other
) if other
.krate
!= module
.krate
=> return false,
262 Visibility
::Restricted(module
) => module
,
265 tree
.is_descendant_of(module
, restriction
)
268 /// Returns true if this visibility is at least as accessible as the given visibility
269 pub fn is_at_least
<T
: DefIdTree
>(self, vis
: Visibility
, tree
: T
) -> bool
{
270 let vis_restriction
= match vis
{
271 Visibility
::Public
=> return self == Visibility
::Public
,
272 Visibility
::Invisible
=> return true,
273 Visibility
::Restricted(module
) => module
,
276 self.is_accessible_from(vis_restriction
, tree
)
280 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Copy)]
282 Covariant
, // T<A> <: T<B> iff A <: B -- e.g., function return type
283 Invariant
, // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
284 Contravariant
, // T<A> <: T<B> iff B <: A -- e.g., function param type
285 Bivariant
, // T<A> <: T<B> -- e.g., unused type parameter
288 #[derive(Clone, Copy, Debug, RustcDecodable, RustcEncodable)]
289 pub struct MethodCallee
<'tcx
> {
290 /// Impl method ID, for inherent methods, or trait method ID, otherwise.
293 pub substs
: &'tcx Substs
<'tcx
>
296 /// With method calls, we store some extra information in
297 /// side tables (i.e method_map). We use
298 /// MethodCall as a key to index into these tables instead of
299 /// just directly using the expression's NodeId. The reason
300 /// for this being that we may apply adjustments (coercions)
301 /// with the resulting expression also needing to use the
302 /// side tables. The problem with this is that we don't
303 /// assign a separate NodeId to this new expression
304 /// and so it would clash with the base expression if both
305 /// needed to add to the side tables. Thus to disambiguate
306 /// we also keep track of whether there's an adjustment in
308 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
309 pub struct MethodCall
{
315 pub fn expr(id
: NodeId
) -> MethodCall
{
322 pub fn autoderef(expr_id
: NodeId
, autoderef
: u32) -> MethodCall
{
325 autoderef
: 1 + autoderef
330 // maps from an expression id that corresponds to a method call to the details
331 // of the method to be invoked
332 pub type MethodMap
<'tcx
> = FxHashMap
<MethodCall
, MethodCallee
<'tcx
>>;
334 // Contains information needed to resolve types and (in the future) look up
335 // the types of AST nodes.
336 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
337 pub struct CReaderCacheKey
{
342 /// Describes the fragment-state associated with a NodeId.
344 /// Currently only unfragmented paths have entries in the table,
345 /// but longer-term this enum is expected to expand to also
346 /// include data for fragmented paths.
347 #[derive(Copy, Clone, Debug)]
348 pub enum FragmentInfo
{
349 Moved { var: NodeId, move_expr: NodeId }
,
350 Assigned { var: NodeId, assign_expr: NodeId, assignee_id: NodeId }
,
353 // Flags that we track on types. These flags are propagated upwards
354 // through the type during type construction, so that we can quickly
355 // check whether the type has various kinds of types in it without
356 // recursing over the type itself.
358 flags TypeFlags
: u32 {
359 const HAS_PARAMS
= 1 << 0,
360 const HAS_SELF
= 1 << 1,
361 const HAS_TY_INFER
= 1 << 2,
362 const HAS_RE_INFER
= 1 << 3,
363 const HAS_RE_SKOL
= 1 << 4,
364 const HAS_RE_EARLY_BOUND
= 1 << 5,
365 const HAS_FREE_REGIONS
= 1 << 6,
366 const HAS_TY_ERR
= 1 << 7,
367 const HAS_PROJECTION
= 1 << 8,
368 const HAS_TY_CLOSURE
= 1 << 9,
370 // true if there are "names" of types and regions and so forth
371 // that are local to a particular fn
372 const HAS_LOCAL_NAMES
= 1 << 10,
374 // Present if the type belongs in a local type context.
375 // Only set for TyInfer other than Fresh.
376 const KEEP_IN_LOCAL_TCX
= 1 << 11,
378 // Is there a projection that does not involve a bound region?
379 // Currently we can't normalize projections w/ bound regions.
380 const HAS_NORMALIZABLE_PROJECTION
= 1 << 12,
382 const NEEDS_SUBST
= TypeFlags
::HAS_PARAMS
.bits
|
383 TypeFlags
::HAS_SELF
.bits
|
384 TypeFlags
::HAS_RE_EARLY_BOUND
.bits
,
386 // Flags representing the nominal content of a type,
387 // computed by FlagsComputation. If you add a new nominal
388 // flag, it should be added here too.
389 const NOMINAL_FLAGS
= TypeFlags
::HAS_PARAMS
.bits
|
390 TypeFlags
::HAS_SELF
.bits
|
391 TypeFlags
::HAS_TY_INFER
.bits
|
392 TypeFlags
::HAS_RE_INFER
.bits
|
393 TypeFlags
::HAS_RE_SKOL
.bits
|
394 TypeFlags
::HAS_RE_EARLY_BOUND
.bits
|
395 TypeFlags
::HAS_FREE_REGIONS
.bits
|
396 TypeFlags
::HAS_TY_ERR
.bits
|
397 TypeFlags
::HAS_PROJECTION
.bits
|
398 TypeFlags
::HAS_TY_CLOSURE
.bits
|
399 TypeFlags
::HAS_LOCAL_NAMES
.bits
|
400 TypeFlags
::KEEP_IN_LOCAL_TCX
.bits
,
402 // Caches for type_is_sized, type_moves_by_default
403 const SIZEDNESS_CACHED
= 1 << 16,
404 const IS_SIZED
= 1 << 17,
405 const MOVENESS_CACHED
= 1 << 18,
406 const MOVES_BY_DEFAULT
= 1 << 19,
410 pub struct TyS
<'tcx
> {
411 pub sty
: TypeVariants
<'tcx
>,
412 pub flags
: Cell
<TypeFlags
>,
414 // the maximal depth of any bound regions appearing in this type.
418 impl<'tcx
> PartialEq
for TyS
<'tcx
> {
420 fn eq(&self, other
: &TyS
<'tcx
>) -> bool
{
421 // (self as *const _) == (other as *const _)
422 (self as *const TyS
<'tcx
>) == (other
as *const TyS
<'tcx
>)
425 impl<'tcx
> Eq
for TyS
<'tcx
> {}
427 impl<'tcx
> Hash
for TyS
<'tcx
> {
428 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
429 (self as *const TyS
).hash(s
)
433 pub type Ty
<'tcx
> = &'tcx TyS
<'tcx
>;
435 impl<'tcx
> serialize
::UseSpecializedEncodable
for Ty
<'tcx
> {}
436 impl<'tcx
> serialize
::UseSpecializedDecodable
for Ty
<'tcx
> {}
438 /// A wrapper for slices with the additional invariant
439 /// that the slice is interned and no other slice with
440 /// the same contents can exist in the same context.
441 /// This means we can use pointer + length for both
442 /// equality comparisons and hashing.
443 #[derive(Debug, RustcEncodable)]
444 pub struct Slice
<T
>([T
]);
446 impl<T
> PartialEq
for Slice
<T
> {
448 fn eq(&self, other
: &Slice
<T
>) -> bool
{
449 (&self.0 as *const [T
]) == (&other
.0 as *const [T
])
452 impl<T
> Eq
for Slice
<T
> {}
454 impl<T
> Hash
for Slice
<T
> {
455 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
456 (self.as_ptr(), self.len()).hash(s
)
460 impl<T
> Deref
for Slice
<T
> {
462 fn deref(&self) -> &[T
] {
467 impl<'a
, T
> IntoIterator
for &'a Slice
<T
> {
469 type IntoIter
= <&'a
[T
] as IntoIterator
>::IntoIter
;
470 fn into_iter(self) -> Self::IntoIter
{
475 impl<'tcx
> serialize
::UseSpecializedDecodable
for &'tcx Slice
<Ty
<'tcx
>> {}
478 pub fn empty
<'a
>() -> &'a Slice
<T
> {
480 mem
::transmute(slice
::from_raw_parts(0x1 as *const T
, 0))
485 /// Upvars do not get their own node-id. Instead, we use the pair of
486 /// the original var id (that is, the root variable that is referenced
487 /// by the upvar) and the id of the closure expression.
488 #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
491 pub closure_expr_id
: NodeId
,
494 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)]
495 pub enum BorrowKind
{
496 /// Data must be immutable and is aliasable.
499 /// Data must be immutable but not aliasable. This kind of borrow
500 /// cannot currently be expressed by the user and is used only in
501 /// implicit closure bindings. It is needed when the closure
502 /// is borrowing or mutating a mutable referent, e.g.:
504 /// let x: &mut isize = ...;
505 /// let y = || *x += 5;
507 /// If we were to try to translate this closure into a more explicit
508 /// form, we'd encounter an error with the code as written:
510 /// struct Env { x: & &mut isize }
511 /// let x: &mut isize = ...;
512 /// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn
513 /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
515 /// This is then illegal because you cannot mutate a `&mut` found
516 /// in an aliasable location. To solve, you'd have to translate with
517 /// an `&mut` borrow:
519 /// struct Env { x: & &mut isize }
520 /// let x: &mut isize = ...;
521 /// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
522 /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
524 /// Now the assignment to `**env.x` is legal, but creating a
525 /// mutable pointer to `x` is not because `x` is not mutable. We
526 /// could fix this by declaring `x` as `let mut x`. This is ok in
527 /// user code, if awkward, but extra weird for closures, since the
528 /// borrow is hidden.
530 /// So we introduce a "unique imm" borrow -- the referent is
531 /// immutable, but not aliasable. This solves the problem. For
532 /// simplicity, we don't give users the way to express this
533 /// borrow, it's just used when translating closures.
536 /// Data is mutable and not aliasable.
540 /// Information describing the capture of an upvar. This is computed
541 /// during `typeck`, specifically by `regionck`.
542 #[derive(PartialEq, Clone, Debug, Copy, RustcEncodable, RustcDecodable)]
543 pub enum UpvarCapture
<'tcx
> {
544 /// Upvar is captured by value. This is always true when the
545 /// closure is labeled `move`, but can also be true in other cases
546 /// depending on inference.
549 /// Upvar is captured by reference.
550 ByRef(UpvarBorrow
<'tcx
>),
553 #[derive(PartialEq, Clone, Copy, RustcEncodable, RustcDecodable)]
554 pub struct UpvarBorrow
<'tcx
> {
555 /// The kind of borrow: by-ref upvars have access to shared
556 /// immutable borrows, which are not part of the normal language
558 pub kind
: BorrowKind
,
560 /// Region of the resulting reference.
561 pub region
: &'tcx ty
::Region
,
564 pub type UpvarCaptureMap
<'tcx
> = FxHashMap
<UpvarId
, UpvarCapture
<'tcx
>>;
566 #[derive(Copy, Clone)]
567 pub struct ClosureUpvar
<'tcx
> {
573 #[derive(Clone, Copy, PartialEq)]
574 pub enum IntVarValue
{
576 UintType(ast
::UintTy
),
579 #[derive(Clone, RustcEncodable, RustcDecodable)]
580 pub struct TypeParameterDef
<'tcx
> {
584 pub default_def_id
: DefId
, // for use in error reporing about defaults
585 pub default: Option
<Ty
<'tcx
>>,
587 /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute
588 /// on generic parameter `T`, asserts data behind the parameter
589 /// `T` won't be accessed during the parent type's `Drop` impl.
590 pub pure_wrt_drop
: bool
,
593 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
594 pub struct RegionParameterDef
{
599 /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute
600 /// on generic parameter `'a`, asserts data of lifetime `'a`
601 /// won't be accessed during the parent type's `Drop` impl.
602 pub pure_wrt_drop
: bool
,
605 impl RegionParameterDef
{
606 pub fn to_early_bound_region_data(&self) -> ty
::EarlyBoundRegion
{
607 ty
::EarlyBoundRegion
{
613 pub fn to_bound_region(&self) -> ty
::BoundRegion
{
614 // this is an early bound region, so unaffected by #32330
615 ty
::BoundRegion
::BrNamed(self.def_id
, self.name
, Issue32330
::WontChange
)
619 /// Information about the formal type/lifetime parameters associated
620 /// with an item or method. Analogous to hir::Generics.
621 #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
622 pub struct Generics
<'tcx
> {
623 pub parent
: Option
<DefId
>,
624 pub parent_regions
: u32,
625 pub parent_types
: u32,
626 pub regions
: Vec
<RegionParameterDef
>,
627 pub types
: Vec
<TypeParameterDef
<'tcx
>>,
631 impl<'tcx
> Generics
<'tcx
> {
632 pub fn parent_count(&self) -> usize {
633 self.parent_regions
as usize + self.parent_types
as usize
636 pub fn own_count(&self) -> usize {
637 self.regions
.len() + self.types
.len()
640 pub fn count(&self) -> usize {
641 self.parent_count() + self.own_count()
644 pub fn region_param(&self, param
: &EarlyBoundRegion
) -> &RegionParameterDef
{
645 &self.regions
[param
.index
as usize - self.has_self
as usize]
648 pub fn type_param(&self, param
: &ParamTy
) -> &TypeParameterDef
<'tcx
> {
649 &self.types
[param
.idx
as usize - self.has_self
as usize - self.regions
.len()]
653 /// Bounds on generics.
655 pub struct GenericPredicates
<'tcx
> {
656 pub parent
: Option
<DefId
>,
657 pub predicates
: Vec
<Predicate
<'tcx
>>,
660 impl<'tcx
> serialize
::UseSpecializedEncodable
for GenericPredicates
<'tcx
> {}
661 impl<'tcx
> serialize
::UseSpecializedDecodable
for GenericPredicates
<'tcx
> {}
663 impl<'a
, 'gcx
, 'tcx
> GenericPredicates
<'tcx
> {
664 pub fn instantiate(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>, substs
: &Substs
<'tcx
>)
665 -> InstantiatedPredicates
<'tcx
> {
666 let mut instantiated
= InstantiatedPredicates
::empty();
667 self.instantiate_into(tcx
, &mut instantiated
, substs
);
670 pub fn instantiate_own(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>, substs
: &Substs
<'tcx
>)
671 -> InstantiatedPredicates
<'tcx
> {
672 InstantiatedPredicates
{
673 predicates
: self.predicates
.subst(tcx
, substs
)
677 fn instantiate_into(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
678 instantiated
: &mut InstantiatedPredicates
<'tcx
>,
679 substs
: &Substs
<'tcx
>) {
680 if let Some(def_id
) = self.parent
{
681 tcx
.item_predicates(def_id
).instantiate_into(tcx
, instantiated
, substs
);
683 instantiated
.predicates
.extend(self.predicates
.iter().map(|p
| p
.subst(tcx
, substs
)))
686 pub fn instantiate_supertrait(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
687 poly_trait_ref
: &ty
::PolyTraitRef
<'tcx
>)
688 -> InstantiatedPredicates
<'tcx
>
690 assert_eq
!(self.parent
, None
);
691 InstantiatedPredicates
{
692 predicates
: self.predicates
.iter().map(|pred
| {
693 pred
.subst_supertrait(tcx
, poly_trait_ref
)
699 #[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
700 pub enum Predicate
<'tcx
> {
701 /// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
702 /// the `Self` type of the trait reference and `A`, `B`, and `C`
703 /// would be the type parameters.
704 Trait(PolyTraitPredicate
<'tcx
>),
706 /// where `T1 == T2`.
707 Equate(PolyEquatePredicate
<'tcx
>),
710 RegionOutlives(PolyRegionOutlivesPredicate
<'tcx
>),
713 TypeOutlives(PolyTypeOutlivesPredicate
<'tcx
>),
715 /// where <T as TraitRef>::Name == X, approximately.
716 /// See `ProjectionPredicate` struct for details.
717 Projection(PolyProjectionPredicate
<'tcx
>),
720 WellFormed(Ty
<'tcx
>),
722 /// trait must be object-safe
725 /// No direct syntax. May be thought of as `where T : FnFoo<...>`
726 /// for some substitutions `...` and T being a closure type.
727 /// Satisfied (or refuted) once we know the closure's kind.
728 ClosureKind(DefId
, ClosureKind
),
731 impl<'a
, 'gcx
, 'tcx
> Predicate
<'tcx
> {
732 /// Performs a substitution suitable for going from a
733 /// poly-trait-ref to supertraits that must hold if that
734 /// poly-trait-ref holds. This is slightly different from a normal
735 /// substitution in terms of what happens with bound regions. See
736 /// lengthy comment below for details.
737 pub fn subst_supertrait(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
738 trait_ref
: &ty
::PolyTraitRef
<'tcx
>)
739 -> ty
::Predicate
<'tcx
>
741 // The interaction between HRTB and supertraits is not entirely
742 // obvious. Let me walk you (and myself) through an example.
744 // Let's start with an easy case. Consider two traits:
746 // trait Foo<'a> : Bar<'a,'a> { }
747 // trait Bar<'b,'c> { }
749 // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
750 // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
751 // knew that `Foo<'x>` (for any 'x) then we also know that
752 // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
753 // normal substitution.
755 // In terms of why this is sound, the idea is that whenever there
756 // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
757 // holds. So if there is an impl of `T:Foo<'a>` that applies to
758 // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
761 // Another example to be careful of is this:
763 // trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
764 // trait Bar1<'b,'c> { }
766 // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
767 // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
768 // reason is similar to the previous example: any impl of
769 // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`. So
770 // basically we would want to collapse the bound lifetimes from
771 // the input (`trait_ref`) and the supertraits.
773 // To achieve this in practice is fairly straightforward. Let's
774 // consider the more complicated scenario:
776 // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
777 // has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
778 // where both `'x` and `'b` would have a DB index of 1.
779 // The substitution from the input trait-ref is therefore going to be
780 // `'a => 'x` (where `'x` has a DB index of 1).
781 // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
782 // early-bound parameter and `'b' is a late-bound parameter with a
784 // - If we replace `'a` with `'x` from the input, it too will have
785 // a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
786 // just as we wanted.
788 // There is only one catch. If we just apply the substitution `'a
789 // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
790 // adjust the DB index because we substituting into a binder (it
791 // tries to be so smart...) resulting in `for<'x> for<'b>
792 // Bar1<'x,'b>` (we have no syntax for this, so use your
793 // imagination). Basically the 'x will have DB index of 2 and 'b
794 // will have DB index of 1. Not quite what we want. So we apply
795 // the substitution to the *contents* of the trait reference,
796 // rather than the trait reference itself (put another way, the
797 // substitution code expects equal binding levels in the values
798 // from the substitution and the value being substituted into, and
799 // this trick achieves that).
801 let substs
= &trait_ref
.0.substs
;
803 Predicate
::Trait(ty
::Binder(ref data
)) =>
804 Predicate
::Trait(ty
::Binder(data
.subst(tcx
, substs
))),
805 Predicate
::Equate(ty
::Binder(ref data
)) =>
806 Predicate
::Equate(ty
::Binder(data
.subst(tcx
, substs
))),
807 Predicate
::RegionOutlives(ty
::Binder(ref data
)) =>
808 Predicate
::RegionOutlives(ty
::Binder(data
.subst(tcx
, substs
))),
809 Predicate
::TypeOutlives(ty
::Binder(ref data
)) =>
810 Predicate
::TypeOutlives(ty
::Binder(data
.subst(tcx
, substs
))),
811 Predicate
::Projection(ty
::Binder(ref data
)) =>
812 Predicate
::Projection(ty
::Binder(data
.subst(tcx
, substs
))),
813 Predicate
::WellFormed(data
) =>
814 Predicate
::WellFormed(data
.subst(tcx
, substs
)),
815 Predicate
::ObjectSafe(trait_def_id
) =>
816 Predicate
::ObjectSafe(trait_def_id
),
817 Predicate
::ClosureKind(closure_def_id
, kind
) =>
818 Predicate
::ClosureKind(closure_def_id
, kind
),
823 #[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
824 pub struct TraitPredicate
<'tcx
> {
825 pub trait_ref
: TraitRef
<'tcx
>
827 pub type PolyTraitPredicate
<'tcx
> = ty
::Binder
<TraitPredicate
<'tcx
>>;
829 impl<'tcx
> TraitPredicate
<'tcx
> {
830 pub fn def_id(&self) -> DefId
{
831 self.trait_ref
.def_id
834 /// Creates the dep-node for selecting/evaluating this trait reference.
835 fn dep_node(&self) -> DepNode
<DefId
> {
836 // Ideally, the dep-node would just have all the input types
837 // in it. But they are limited to including def-ids. So as an
838 // approximation we include the def-ids for all nominal types
839 // found somewhere. This means that we will e.g. conflate the
840 // dep-nodes for `u32: SomeTrait` and `u64: SomeTrait`, but we
841 // would have distinct dep-nodes for `Vec<u32>: SomeTrait`,
842 // `Rc<u32>: SomeTrait`, and `(Vec<u32>, Rc<u32>): SomeTrait`.
843 // Note that it's always sound to conflate dep-nodes, it just
844 // leads to more recompilation.
845 let def_ids
: Vec
<_
> =
847 .flat_map(|t
| t
.walk())
848 .filter_map(|t
| match t
.sty
{
849 ty
::TyAdt(adt_def
, _
) =>
854 .chain(iter
::once(self.def_id()))
856 DepNode
::TraitSelect(def_ids
)
859 pub fn input_types
<'a
>(&'a
self) -> impl DoubleEndedIterator
<Item
=Ty
<'tcx
>> + 'a
{
860 self.trait_ref
.input_types()
863 pub fn self_ty(&self) -> Ty
<'tcx
> {
864 self.trait_ref
.self_ty()
868 impl<'tcx
> PolyTraitPredicate
<'tcx
> {
869 pub fn def_id(&self) -> DefId
{
870 // ok to skip binder since trait def-id does not care about regions
874 pub fn dep_node(&self) -> DepNode
<DefId
> {
875 // ok to skip binder since depnode does not care about regions
880 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
881 pub struct EquatePredicate
<'tcx
>(pub Ty
<'tcx
>, pub Ty
<'tcx
>); // `0 == 1`
882 pub type PolyEquatePredicate
<'tcx
> = ty
::Binder
<EquatePredicate
<'tcx
>>;
884 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
885 pub struct OutlivesPredicate
<A
,B
>(pub A
, pub B
); // `A : B`
886 pub type PolyOutlivesPredicate
<A
,B
> = ty
::Binder
<OutlivesPredicate
<A
,B
>>;
887 pub type PolyRegionOutlivesPredicate
<'tcx
> = PolyOutlivesPredicate
<&'tcx ty
::Region
,
889 pub type PolyTypeOutlivesPredicate
<'tcx
> = PolyOutlivesPredicate
<Ty
<'tcx
>, &'tcx ty
::Region
>;
891 /// This kind of predicate has no *direct* correspondent in the
892 /// syntax, but it roughly corresponds to the syntactic forms:
894 /// 1. `T : TraitRef<..., Item=Type>`
895 /// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
897 /// In particular, form #1 is "desugared" to the combination of a
898 /// normal trait predicate (`T : TraitRef<...>`) and one of these
899 /// predicates. Form #2 is a broader form in that it also permits
900 /// equality between arbitrary types. Processing an instance of Form
901 /// #2 eventually yields one of these `ProjectionPredicate`
902 /// instances to normalize the LHS.
903 #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
904 pub struct ProjectionPredicate
<'tcx
> {
905 pub projection_ty
: ProjectionTy
<'tcx
>,
909 pub type PolyProjectionPredicate
<'tcx
> = Binder
<ProjectionPredicate
<'tcx
>>;
911 impl<'tcx
> PolyProjectionPredicate
<'tcx
> {
912 pub fn item_name(&self) -> Name
{
913 self.0.projection_ty
.item_name
// safe to skip the binder to access a name
917 pub trait ToPolyTraitRef
<'tcx
> {
918 fn to_poly_trait_ref(&self) -> PolyTraitRef
<'tcx
>;
921 impl<'tcx
> ToPolyTraitRef
<'tcx
> for TraitRef
<'tcx
> {
922 fn to_poly_trait_ref(&self) -> PolyTraitRef
<'tcx
> {
923 assert
!(!self.has_escaping_regions());
924 ty
::Binder(self.clone())
928 impl<'tcx
> ToPolyTraitRef
<'tcx
> for PolyTraitPredicate
<'tcx
> {
929 fn to_poly_trait_ref(&self) -> PolyTraitRef
<'tcx
> {
930 self.map_bound_ref(|trait_pred
| trait_pred
.trait_ref
)
934 impl<'tcx
> ToPolyTraitRef
<'tcx
> for PolyProjectionPredicate
<'tcx
> {
935 fn to_poly_trait_ref(&self) -> PolyTraitRef
<'tcx
> {
936 // Note: unlike with TraitRef::to_poly_trait_ref(),
937 // self.0.trait_ref is permitted to have escaping regions.
938 // This is because here `self` has a `Binder` and so does our
939 // return value, so we are preserving the number of binding
941 ty
::Binder(self.0.projection_ty
.trait_ref
)
945 pub trait ToPredicate
<'tcx
> {
946 fn to_predicate(&self) -> Predicate
<'tcx
>;
949 impl<'tcx
> ToPredicate
<'tcx
> for TraitRef
<'tcx
> {
950 fn to_predicate(&self) -> Predicate
<'tcx
> {
951 // we're about to add a binder, so let's check that we don't
952 // accidentally capture anything, or else that might be some
953 // weird debruijn accounting.
954 assert
!(!self.has_escaping_regions());
956 ty
::Predicate
::Trait(ty
::Binder(ty
::TraitPredicate
{
957 trait_ref
: self.clone()
962 impl<'tcx
> ToPredicate
<'tcx
> for PolyTraitRef
<'tcx
> {
963 fn to_predicate(&self) -> Predicate
<'tcx
> {
964 ty
::Predicate
::Trait(self.to_poly_trait_predicate())
968 impl<'tcx
> ToPredicate
<'tcx
> for PolyEquatePredicate
<'tcx
> {
969 fn to_predicate(&self) -> Predicate
<'tcx
> {
970 Predicate
::Equate(self.clone())
974 impl<'tcx
> ToPredicate
<'tcx
> for PolyRegionOutlivesPredicate
<'tcx
> {
975 fn to_predicate(&self) -> Predicate
<'tcx
> {
976 Predicate
::RegionOutlives(self.clone())
980 impl<'tcx
> ToPredicate
<'tcx
> for PolyTypeOutlivesPredicate
<'tcx
> {
981 fn to_predicate(&self) -> Predicate
<'tcx
> {
982 Predicate
::TypeOutlives(self.clone())
986 impl<'tcx
> ToPredicate
<'tcx
> for PolyProjectionPredicate
<'tcx
> {
987 fn to_predicate(&self) -> Predicate
<'tcx
> {
988 Predicate
::Projection(self.clone())
992 impl<'tcx
> Predicate
<'tcx
> {
993 /// Iterates over the types in this predicate. Note that in all
994 /// cases this is skipping over a binder, so late-bound regions
995 /// with depth 0 are bound by the predicate.
996 pub fn walk_tys(&self) -> IntoIter
<Ty
<'tcx
>> {
997 let vec
: Vec
<_
> = match *self {
998 ty
::Predicate
::Trait(ref data
) => {
999 data
.skip_binder().input_types().collect()
1001 ty
::Predicate
::Equate(ty
::Binder(ref data
)) => {
1002 vec
![data
.0, data
.1]
1004 ty
::Predicate
::TypeOutlives(ty
::Binder(ref data
)) => {
1007 ty
::Predicate
::RegionOutlives(..) => {
1010 ty
::Predicate
::Projection(ref data
) => {
1011 let trait_inputs
= data
.0.projection_ty
.trait_ref
.input_types();
1012 trait_inputs
.chain(Some(data
.0.ty
)).collect()
1014 ty
::Predicate
::WellFormed(data
) => {
1017 ty
::Predicate
::ObjectSafe(_trait_def_id
) => {
1020 ty
::Predicate
::ClosureKind(_closure_def_id
, _kind
) => {
1025 // The only reason to collect into a vector here is that I was
1026 // too lazy to make the full (somewhat complicated) iterator
1027 // type that would be needed here. But I wanted this fn to
1028 // return an iterator conceptually, rather than a `Vec`, so as
1029 // to be closer to `Ty::walk`.
1033 pub fn to_opt_poly_trait_ref(&self) -> Option
<PolyTraitRef
<'tcx
>> {
1035 Predicate
::Trait(ref t
) => {
1036 Some(t
.to_poly_trait_ref())
1038 Predicate
::Projection(..) |
1039 Predicate
::Equate(..) |
1040 Predicate
::RegionOutlives(..) |
1041 Predicate
::WellFormed(..) |
1042 Predicate
::ObjectSafe(..) |
1043 Predicate
::ClosureKind(..) |
1044 Predicate
::TypeOutlives(..) => {
1051 /// Represents the bounds declared on a particular set of type
1052 /// parameters. Should eventually be generalized into a flag list of
1053 /// where clauses. You can obtain a `InstantiatedPredicates` list from a
1054 /// `GenericPredicates` by using the `instantiate` method. Note that this method
1055 /// reflects an important semantic invariant of `InstantiatedPredicates`: while
1056 /// the `GenericPredicates` are expressed in terms of the bound type
1057 /// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance
1058 /// represented a set of bounds for some particular instantiation,
1059 /// meaning that the generic parameters have been substituted with
1064 /// struct Foo<T,U:Bar<T>> { ... }
1066 /// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
1067 /// `[[], [U:Bar<T>]]`. Now if there were some particular reference
1068 /// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
1069 /// [usize:Bar<isize>]]`.
1071 pub struct InstantiatedPredicates
<'tcx
> {
1072 pub predicates
: Vec
<Predicate
<'tcx
>>,
1075 impl<'tcx
> InstantiatedPredicates
<'tcx
> {
1076 pub fn empty() -> InstantiatedPredicates
<'tcx
> {
1077 InstantiatedPredicates { predicates: vec![] }
1080 pub fn is_empty(&self) -> bool
{
1081 self.predicates
.is_empty()
1085 impl<'tcx
> TraitRef
<'tcx
> {
1086 pub fn new(def_id
: DefId
, substs
: &'tcx Substs
<'tcx
>) -> TraitRef
<'tcx
> {
1087 TraitRef { def_id: def_id, substs: substs }
1090 pub fn self_ty(&self) -> Ty
<'tcx
> {
1091 self.substs
.type_at(0)
1094 pub fn input_types
<'a
>(&'a
self) -> impl DoubleEndedIterator
<Item
=Ty
<'tcx
>> + 'a
{
1095 // Select only the "input types" from a trait-reference. For
1096 // now this is all the types that appear in the
1097 // trait-reference, but it should eventually exclude
1098 // associated types.
1103 /// When type checking, we use the `ParameterEnvironment` to track
1104 /// details about the type/lifetime parameters that are in scope.
1105 /// It primarily stores the bounds information.
1107 /// Note: This information might seem to be redundant with the data in
1108 /// `tcx.ty_param_defs`, but it is not. That table contains the
1109 /// parameter definitions from an "outside" perspective, but this
1110 /// struct will contain the bounds for a parameter as seen from inside
1111 /// the function body. Currently the only real distinction is that
1112 /// bound lifetime parameters are replaced with free ones, but in the
1113 /// future I hope to refine the representation of types so as to make
1114 /// more distinctions clearer.
1116 pub struct ParameterEnvironment
<'tcx
> {
1117 /// See `construct_free_substs` for details.
1118 pub free_substs
: &'tcx Substs
<'tcx
>,
1120 /// Each type parameter has an implicit region bound that
1121 /// indicates it must outlive at least the function body (the user
1122 /// may specify stronger requirements). This field indicates the
1123 /// region of the callee.
1124 pub implicit_region_bound
: &'tcx ty
::Region
,
1126 /// Obligations that the caller must satisfy. This is basically
1127 /// the set of bounds on the in-scope type parameters, translated
1128 /// into Obligations, and elaborated and normalized.
1129 pub caller_bounds
: Vec
<ty
::Predicate
<'tcx
>>,
1131 /// Scope that is attached to free regions for this scope. This
1132 /// is usually the id of the fn body, but for more abstract scopes
1133 /// like structs we often use the node-id of the struct.
1135 /// FIXME(#3696). It would be nice to refactor so that free
1136 /// regions don't have this implicit scope and instead introduce
1137 /// relationships in the environment.
1138 pub free_id_outlive
: CodeExtent
,
1140 /// A cache for `moves_by_default`.
1141 pub is_copy_cache
: RefCell
<FxHashMap
<Ty
<'tcx
>, bool
>>,
1143 /// A cache for `type_is_sized`
1144 pub is_sized_cache
: RefCell
<FxHashMap
<Ty
<'tcx
>, bool
>>,
1147 impl<'a
, 'tcx
> ParameterEnvironment
<'tcx
> {
1148 pub fn with_caller_bounds(&self,
1149 caller_bounds
: Vec
<ty
::Predicate
<'tcx
>>)
1150 -> ParameterEnvironment
<'tcx
>
1152 ParameterEnvironment
{
1153 free_substs
: self.free_substs
,
1154 implicit_region_bound
: self.implicit_region_bound
,
1155 caller_bounds
: caller_bounds
,
1156 free_id_outlive
: self.free_id_outlive
,
1157 is_copy_cache
: RefCell
::new(FxHashMap()),
1158 is_sized_cache
: RefCell
::new(FxHashMap()),
1162 /// Construct a parameter environment given an item, impl item, or trait item
1163 pub fn for_item(tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>, id
: NodeId
)
1164 -> ParameterEnvironment
<'tcx
> {
1165 match tcx
.hir
.find(id
) {
1166 Some(hir_map
::NodeImplItem(ref impl_item
)) => {
1167 match impl_item
.node
{
1168 hir
::ImplItemKind
::Type(_
) | hir
::ImplItemKind
::Const(..) => {
1169 // associated types don't have their own entry (for some reason),
1170 // so for now just grab environment for the impl
1171 let impl_id
= tcx
.hir
.get_parent(id
);
1172 let impl_def_id
= tcx
.hir
.local_def_id(impl_id
);
1173 tcx
.construct_parameter_environment(impl_item
.span
,
1175 tcx
.region_maps
.item_extent(id
))
1177 hir
::ImplItemKind
::Method(_
, ref body
) => {
1178 tcx
.construct_parameter_environment(
1180 tcx
.hir
.local_def_id(id
),
1181 tcx
.region_maps
.call_site_extent(id
, body
.node_id
))
1185 Some(hir_map
::NodeTraitItem(trait_item
)) => {
1186 match trait_item
.node
{
1187 hir
::TraitItemKind
::Type(..) | hir
::TraitItemKind
::Const(..) => {
1188 // associated types don't have their own entry (for some reason),
1189 // so for now just grab environment for the trait
1190 let trait_id
= tcx
.hir
.get_parent(id
);
1191 let trait_def_id
= tcx
.hir
.local_def_id(trait_id
);
1192 tcx
.construct_parameter_environment(trait_item
.span
,
1194 tcx
.region_maps
.item_extent(id
))
1196 hir
::TraitItemKind
::Method(_
, ref body
) => {
1197 // Use call-site for extent (unless this is a
1198 // trait method with no default; then fallback
1199 // to the method id).
1200 let extent
= if let hir
::TraitMethod
::Provided(body_id
) = *body
{
1201 // default impl: use call_site extent as free_id_outlive bound.
1202 tcx
.region_maps
.call_site_extent(id
, body_id
.node_id
)
1204 // no default impl: use item extent as free_id_outlive bound.
1205 tcx
.region_maps
.item_extent(id
)
1207 tcx
.construct_parameter_environment(
1209 tcx
.hir
.local_def_id(id
),
1214 Some(hir_map
::NodeItem(item
)) => {
1216 hir
::ItemFn(.., body_id
) => {
1217 // We assume this is a function.
1218 let fn_def_id
= tcx
.hir
.local_def_id(id
);
1220 tcx
.construct_parameter_environment(
1223 tcx
.region_maps
.call_site_extent(id
, body_id
.node_id
))
1226 hir
::ItemStruct(..) |
1227 hir
::ItemUnion(..) |
1230 hir
::ItemConst(..) |
1231 hir
::ItemStatic(..) => {
1232 let def_id
= tcx
.hir
.local_def_id(id
);
1233 tcx
.construct_parameter_environment(item
.span
,
1235 tcx
.region_maps
.item_extent(id
))
1237 hir
::ItemTrait(..) => {
1238 let def_id
= tcx
.hir
.local_def_id(id
);
1239 tcx
.construct_parameter_environment(item
.span
,
1241 tcx
.region_maps
.item_extent(id
))
1244 span_bug
!(item
.span
,
1245 "ParameterEnvironment::for_item():
1246 can't create a parameter \
1247 environment for this kind of item")
1251 Some(hir_map
::NodeExpr(expr
)) => {
1252 // This is a convenience to allow closures to work.
1253 if let hir
::ExprClosure(.., body
, _
) = expr
.node
{
1254 let def_id
= tcx
.hir
.local_def_id(id
);
1255 let base_def_id
= tcx
.closure_base_def_id(def_id
);
1256 tcx
.construct_parameter_environment(
1259 tcx
.region_maps
.call_site_extent(id
, body
.node_id
))
1261 tcx
.empty_parameter_environment()
1264 Some(hir_map
::NodeForeignItem(item
)) => {
1265 let def_id
= tcx
.hir
.local_def_id(id
);
1266 tcx
.construct_parameter_environment(item
.span
,
1271 bug
!("ParameterEnvironment::from_item(): \
1272 `{}` is not an item",
1273 tcx
.hir
.node_to_string(id
))
1280 flags AdtFlags
: u32 {
1281 const NO_ADT_FLAGS
= 0,
1282 const IS_ENUM
= 1 << 0,
1283 const IS_DTORCK
= 1 << 1, // is this a dtorck type?
1284 const IS_DTORCK_VALID
= 1 << 2,
1285 const IS_PHANTOM_DATA
= 1 << 3,
1286 const IS_SIMD
= 1 << 4,
1287 const IS_FUNDAMENTAL
= 1 << 5,
1288 const IS_UNION
= 1 << 6,
1289 const IS_BOX
= 1 << 7,
1294 pub struct VariantDef
{
1295 /// The variant's DefId. If this is a tuple-like struct,
1296 /// this is the DefId of the struct's ctor.
1298 pub name
: Name
, // struct's name if this is a struct
1300 pub fields
: Vec
<FieldDef
>,
1301 pub ctor_kind
: CtorKind
,
1305 pub struct FieldDef
{
1308 pub vis
: Visibility
,
1311 /// The definition of an abstract data type - a struct or enum.
1313 /// These are all interned (by intern_adt_def) into the adt_defs
1317 pub variants
: Vec
<VariantDef
>,
1318 destructor
: Cell
<Option
<DefId
>>,
1319 flags
: Cell
<AdtFlags
>
1322 impl PartialEq
for AdtDef
{
1323 // AdtDef are always interned and this is part of TyS equality
1325 fn eq(&self, other
: &Self) -> bool { self as *const _ == other as *const _ }
1328 impl Eq
for AdtDef {}
1330 impl Hash
for AdtDef
{
1332 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
1333 (self as *const AdtDef
).hash(s
)
1337 impl<'tcx
> serialize
::UseSpecializedEncodable
for &'tcx AdtDef
{
1338 fn default_encode
<S
: Encoder
>(&self, s
: &mut S
) -> Result
<(), S
::Error
> {
1343 impl<'tcx
> serialize
::UseSpecializedDecodable
for &'tcx AdtDef {}
1345 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
1346 pub enum AdtKind { Struct, Union, Enum }
1348 impl<'a
, 'gcx
, 'tcx
> AdtDef
{
1349 fn new(tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
1352 variants
: Vec
<VariantDef
>) -> Self {
1353 let mut flags
= AdtFlags
::NO_ADT_FLAGS
;
1354 let attrs
= tcx
.get_attrs(did
);
1355 if attr
::contains_name(&attrs
, "fundamental") {
1356 flags
= flags
| AdtFlags
::IS_FUNDAMENTAL
;
1358 if tcx
.lookup_simd(did
) {
1359 flags
= flags
| AdtFlags
::IS_SIMD
;
1361 if Some(did
) == tcx
.lang_items
.phantom_data() {
1362 flags
= flags
| AdtFlags
::IS_PHANTOM_DATA
;
1364 if Some(did
) == tcx
.lang_items
.owned_box() {
1365 flags
= flags
| AdtFlags
::IS_BOX
;
1368 AdtKind
::Enum
=> flags
= flags
| AdtFlags
::IS_ENUM
,
1369 AdtKind
::Union
=> flags
= flags
| AdtFlags
::IS_UNION
,
1370 AdtKind
::Struct
=> {}
1375 flags
: Cell
::new(flags
),
1376 destructor
: Cell
::new(None
),
1380 fn calculate_dtorck(&'gcx
self, tcx
: TyCtxt
) {
1381 if tcx
.is_adt_dtorck(self) {
1382 self.flags
.set(self.flags
.get() | AdtFlags
::IS_DTORCK
);
1384 self.flags
.set(self.flags
.get() | AdtFlags
::IS_DTORCK_VALID
)
1388 pub fn is_struct(&self) -> bool
{
1389 !self.is_union() && !self.is_enum()
1393 pub fn is_union(&self) -> bool
{
1394 self.flags
.get().intersects(AdtFlags
::IS_UNION
)
1398 pub fn is_enum(&self) -> bool
{
1399 self.flags
.get().intersects(AdtFlags
::IS_ENUM
)
1402 /// Returns the kind of the ADT - Struct or Enum.
1404 pub fn adt_kind(&self) -> AdtKind
{
1407 } else if self.is_union() {
1414 pub fn descr(&self) -> &'
static str {
1415 match self.adt_kind() {
1416 AdtKind
::Struct
=> "struct",
1417 AdtKind
::Union
=> "union",
1418 AdtKind
::Enum
=> "enum",
1422 pub fn variant_descr(&self) -> &'
static str {
1423 match self.adt_kind() {
1424 AdtKind
::Struct
=> "struct",
1425 AdtKind
::Union
=> "union",
1426 AdtKind
::Enum
=> "variant",
1430 /// Returns whether this is a dtorck type. If this returns
1431 /// true, this type being safe for destruction requires it to be
1432 /// alive; Otherwise, only the contents are required to be.
1434 pub fn is_dtorck(&'gcx
self, tcx
: TyCtxt
) -> bool
{
1435 if !self.flags
.get().intersects(AdtFlags
::IS_DTORCK_VALID
) {
1436 self.calculate_dtorck(tcx
)
1438 self.flags
.get().intersects(AdtFlags
::IS_DTORCK
)
1441 /// Returns whether this type is #[fundamental] for the purposes
1442 /// of coherence checking.
1444 pub fn is_fundamental(&self) -> bool
{
1445 self.flags
.get().intersects(AdtFlags
::IS_FUNDAMENTAL
)
1449 pub fn is_simd(&self) -> bool
{
1450 self.flags
.get().intersects(AdtFlags
::IS_SIMD
)
1453 /// Returns true if this is PhantomData<T>.
1455 pub fn is_phantom_data(&self) -> bool
{
1456 self.flags
.get().intersects(AdtFlags
::IS_PHANTOM_DATA
)
1459 /// Returns true if this is Box<T>.
1461 pub fn is_box(&self) -> bool
{
1462 self.flags
.get().intersects(AdtFlags
::IS_BOX
)
1465 /// Returns whether this type has a destructor.
1466 pub fn has_dtor(&self) -> bool
{
1467 self.destructor
.get().is_some()
1470 /// Asserts this is a struct and returns the struct's unique
1472 pub fn struct_variant(&self) -> &VariantDef
{
1473 assert
!(!self.is_enum());
1478 pub fn predicates(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>) -> GenericPredicates
<'gcx
> {
1479 tcx
.item_predicates(self.did
)
1482 /// Returns an iterator over all fields contained
1485 pub fn all_fields
<'s
>(&'s
self) -> impl Iterator
<Item
= &'s FieldDef
> {
1486 self.variants
.iter().flat_map(|v
| v
.fields
.iter())
1490 pub fn is_univariant(&self) -> bool
{
1491 self.variants
.len() == 1
1494 pub fn is_payloadfree(&self) -> bool
{
1495 !self.variants
.is_empty() &&
1496 self.variants
.iter().all(|v
| v
.fields
.is_empty())
1499 pub fn variant_with_id(&self, vid
: DefId
) -> &VariantDef
{
1502 .find(|v
| v
.did
== vid
)
1503 .expect("variant_with_id: unknown variant")
1506 pub fn variant_index_with_id(&self, vid
: DefId
) -> usize {
1509 .position(|v
| v
.did
== vid
)
1510 .expect("variant_index_with_id: unknown variant")
1513 pub fn variant_of_def(&self, def
: Def
) -> &VariantDef
{
1515 Def
::Variant(vid
) | Def
::VariantCtor(vid
, ..) => self.variant_with_id(vid
),
1516 Def
::Struct(..) | Def
::StructCtor(..) | Def
::Union(..) |
1517 Def
::TyAlias(..) | Def
::AssociatedTy(..) | Def
::SelfTy(..) => self.struct_variant(),
1518 _
=> bug
!("unexpected def {:?} in variant_of_def", def
)
1522 pub fn destructor(&self) -> Option
<DefId
> {
1523 self.destructor
.get()
1526 pub fn set_destructor(&self, dtor
: DefId
) {
1527 self.destructor
.set(Some(dtor
));
1530 /// Returns a simpler type such that `Self: Sized` if and only
1531 /// if that type is Sized, or `TyErr` if this type is recursive.
1533 /// HACK: instead of returning a list of types, this function can
1534 /// return a tuple. In that case, the result is Sized only if
1535 /// all elements of the tuple are Sized.
1537 /// This is generally the `struct_tail` if this is a struct, or a
1538 /// tuple of them if this is an enum.
1540 /// Oddly enough, checking that the sized-constraint is Sized is
1541 /// actually more expressive than checking all members:
1542 /// the Sized trait is inductive, so an associated type that references
1543 /// Self would prevent its containing ADT from being Sized.
1545 /// Due to normalization being eager, this applies even if
1546 /// the associated type is behind a pointer, e.g. issue #31299.
1547 pub fn sized_constraint(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>) -> Ty
<'tcx
> {
1548 self.calculate_sized_constraint_inner(tcx
.global_tcx(), &mut Vec
::new())
1551 /// Calculates the Sized-constraint.
1553 /// As the Sized-constraint of enums can be a *set* of types,
1554 /// the Sized-constraint may need to be a set also. Because introducing
1555 /// a new type of IVar is currently a complex affair, the Sized-constraint
1558 /// In fact, there are only a few options for the constraint:
1559 /// - `bool`, if the type is always Sized
1560 /// - an obviously-unsized type
1561 /// - a type parameter or projection whose Sizedness can't be known
1562 /// - a tuple of type parameters or projections, if there are multiple
1564 /// - a TyError, if a type contained itself. The representability
1565 /// check should catch this case.
1566 fn calculate_sized_constraint_inner(&self,
1567 tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
1568 stack
: &mut Vec
<DefId
>)
1571 if let Some(ty
) = tcx
.adt_sized_constraint
.borrow().get(&self.did
) {
1575 // Follow the memoization pattern: push the computation of
1576 // DepNode::SizedConstraint as our current task.
1577 let _task
= tcx
.dep_graph
.in_task(DepNode
::SizedConstraint(self.did
));
1579 if stack
.contains(&self.did
) {
1580 debug
!("calculate_sized_constraint: {:?} is recursive", self);
1581 // This should be reported as an error by `check_representable`.
1583 // Consider the type as Sized in the meanwhile to avoid
1585 tcx
.adt_sized_constraint
.borrow_mut().insert(self.did
, tcx
.types
.err
);
1586 return tcx
.types
.err
;
1589 stack
.push(self.did
);
1592 self.variants
.iter().flat_map(|v
| {
1595 let ty
= tcx
.item_type(f
.did
);
1596 self.sized_constraint_for_ty(tcx
, stack
, ty
)
1599 let self_
= stack
.pop().unwrap();
1600 assert_eq
!(self_
, self.did
);
1602 let ty
= match tys
.len() {
1603 _
if tys
.references_error() => tcx
.types
.err
,
1604 0 => tcx
.types
.bool
,
1606 _
=> tcx
.intern_tup(&tys
[..])
1609 let old
= tcx
.adt_sized_constraint
.borrow().get(&self.did
).cloned();
1612 debug
!("calculate_sized_constraint: {:?} recurred", self);
1613 assert_eq
!(old_ty
, tcx
.types
.err
);
1617 debug
!("calculate_sized_constraint: {:?} => {:?}", self, ty
);
1618 tcx
.adt_sized_constraint
.borrow_mut().insert(self.did
, ty
);
1624 fn sized_constraint_for_ty(&self,
1625 tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
1626 stack
: &mut Vec
<DefId
>,
1629 let result
= match ty
.sty
{
1630 TyBool
| TyChar
| TyInt(..) | TyUint(..) | TyFloat(..) |
1631 TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_
) |
1632 TyArray(..) | TyClosure(..) | TyNever
=> {
1636 TyStr
| TyDynamic(..) | TySlice(_
) | TyError
=> {
1637 // these are never sized - return the target type
1641 TyTuple(ref tys
) => {
1644 Some(ty
) => self.sized_constraint_for_ty(tcx
, stack
, ty
)
1648 TyAdt(adt
, substs
) => {
1651 adt
.calculate_sized_constraint_inner(tcx
, stack
)
1652 .subst(tcx
, substs
);
1653 debug
!("sized_constraint_for_ty({:?}) intermediate = {:?}",
1655 if let ty
::TyTuple(ref tys
) = adt_ty
.sty
{
1656 tys
.iter().flat_map(|ty
| {
1657 self.sized_constraint_for_ty(tcx
, stack
, ty
)
1660 self.sized_constraint_for_ty(tcx
, stack
, adt_ty
)
1664 TyProjection(..) | TyAnon(..) => {
1665 // must calculate explicitly.
1666 // FIXME: consider special-casing always-Sized projections
1671 // perf hack: if there is a `T: Sized` bound, then
1672 // we know that `T` is Sized and do not need to check
1675 let sized_trait
= match tcx
.lang_items
.sized_trait() {
1677 _
=> return vec
![ty
]
1679 let sized_predicate
= Binder(TraitRef
{
1680 def_id
: sized_trait
,
1681 substs
: tcx
.mk_substs_trait(ty
, &[])
1683 let predicates
= tcx
.item_predicates(self.did
).predicates
;
1684 if predicates
.into_iter().any(|p
| p
== sized_predicate
) {
1692 bug
!("unexpected type `{:?}` in sized_constraint_for_ty",
1696 debug
!("sized_constraint_for_ty({:?}) = {:?}", ty
, result
);
1701 impl<'a
, 'gcx
, 'tcx
> VariantDef
{
1703 pub fn find_field_named(&self,
1705 -> Option
<&FieldDef
> {
1706 self.fields
.iter().find(|f
| f
.name
== name
)
1710 pub fn index_of_field_named(&self,
1713 self.fields
.iter().position(|f
| f
.name
== name
)
1717 pub fn field_named(&self, name
: ast
::Name
) -> &FieldDef
{
1718 self.find_field_named(name
).unwrap()
1722 impl<'a
, 'gcx
, 'tcx
> FieldDef
{
1723 pub fn ty(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>, subst
: &Substs
<'tcx
>) -> Ty
<'tcx
> {
1724 tcx
.item_type(self.did
).subst(tcx
, subst
)
1728 /// Records the substitutions used to translate the polytype for an
1729 /// item into the monotype of an item reference.
1730 #[derive(Clone, RustcEncodable, RustcDecodable)]
1731 pub struct ItemSubsts
<'tcx
> {
1732 pub substs
: &'tcx Substs
<'tcx
>,
1735 #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
1736 pub enum ClosureKind
{
1737 // Warning: Ordering is significant here! The ordering is chosen
1738 // because the trait Fn is a subtrait of FnMut and so in turn, and
1739 // hence we order it so that Fn < FnMut < FnOnce.
1745 impl<'a
, 'tcx
> ClosureKind
{
1746 pub fn trait_did(&self, tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>) -> DefId
{
1748 ClosureKind
::Fn
=> tcx
.require_lang_item(FnTraitLangItem
),
1749 ClosureKind
::FnMut
=> {
1750 tcx
.require_lang_item(FnMutTraitLangItem
)
1752 ClosureKind
::FnOnce
=> {
1753 tcx
.require_lang_item(FnOnceTraitLangItem
)
1758 /// True if this a type that impls this closure kind
1759 /// must also implement `other`.
1760 pub fn extends(self, other
: ty
::ClosureKind
) -> bool
{
1761 match (self, other
) {
1762 (ClosureKind
::Fn
, ClosureKind
::Fn
) => true,
1763 (ClosureKind
::Fn
, ClosureKind
::FnMut
) => true,
1764 (ClosureKind
::Fn
, ClosureKind
::FnOnce
) => true,
1765 (ClosureKind
::FnMut
, ClosureKind
::FnMut
) => true,
1766 (ClosureKind
::FnMut
, ClosureKind
::FnOnce
) => true,
1767 (ClosureKind
::FnOnce
, ClosureKind
::FnOnce
) => true,
1773 impl<'tcx
> TyS
<'tcx
> {
1774 /// Iterator that walks `self` and any types reachable from
1775 /// `self`, in depth-first order. Note that just walks the types
1776 /// that appear in `self`, it does not descend into the fields of
1777 /// structs or variants. For example:
1780 /// isize => { isize }
1781 /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
1782 /// [isize] => { [isize], isize }
1784 pub fn walk(&'tcx
self) -> TypeWalker
<'tcx
> {
1785 TypeWalker
::new(self)
1788 /// Iterator that walks the immediate children of `self`. Hence
1789 /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
1790 /// (but not `i32`, like `walk`).
1791 pub fn walk_shallow(&'tcx
self) -> AccIntoIter
<walk
::TypeWalkerArray
<'tcx
>> {
1792 walk
::walk_shallow(self)
1795 /// Walks `ty` and any types appearing within `ty`, invoking the
1796 /// callback `f` on each type. If the callback returns false, then the
1797 /// children of the current type are ignored.
1799 /// Note: prefer `ty.walk()` where possible.
1800 pub fn maybe_walk
<F
>(&'tcx
self, mut f
: F
)
1801 where F
: FnMut(Ty
<'tcx
>) -> bool
1803 let mut walker
= self.walk();
1804 while let Some(ty
) = walker
.next() {
1806 walker
.skip_current_subtree();
1812 impl<'tcx
> ItemSubsts
<'tcx
> {
1813 pub fn is_noop(&self) -> bool
{
1814 self.substs
.is_noop()
1818 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1819 pub enum LvaluePreference
{
1824 impl LvaluePreference
{
1825 pub fn from_mutbl(m
: hir
::Mutability
) -> Self {
1827 hir
::MutMutable
=> PreferMutLvalue
,
1828 hir
::MutImmutable
=> NoPreference
,
1833 /// Helper for looking things up in the various maps that are populated during
1834 /// typeck::collect (e.g., `tcx.associated_items`, `tcx.types`, etc). All of
1835 /// these share the pattern that if the id is local, it should have been loaded
1836 /// into the map by the `typeck::collect` phase. If the def-id is external,
1837 /// then we have to go consult the crate loading code (and cache the result for
1839 fn lookup_locally_or_in_crate_store
<M
, F
>(descr
: &str,
1844 M
: MemoizationMap
<Key
=DefId
>,
1845 F
: FnOnce() -> M
::Value
,
1847 map
.memoize(def_id
, || {
1848 if def_id
.is_local() {
1849 bug
!("No def'n found for {:?} in tcx.{}", def_id
, descr
);
1856 pub fn from_mutbl(m
: hir
::Mutability
) -> BorrowKind
{
1858 hir
::MutMutable
=> MutBorrow
,
1859 hir
::MutImmutable
=> ImmBorrow
,
1863 /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow
1864 /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a
1865 /// mutability that is stronger than necessary so that it at least *would permit* the borrow in
1867 pub fn to_mutbl_lossy(self) -> hir
::Mutability
{
1869 MutBorrow
=> hir
::MutMutable
,
1870 ImmBorrow
=> hir
::MutImmutable
,
1872 // We have no type corresponding to a unique imm borrow, so
1873 // use `&mut`. It gives all the capabilities of an `&uniq`
1874 // and hence is a safe "over approximation".
1875 UniqueImmBorrow
=> hir
::MutMutable
,
1879 pub fn to_user_str(&self) -> &'
static str {
1881 MutBorrow
=> "mutable",
1882 ImmBorrow
=> "immutable",
1883 UniqueImmBorrow
=> "uniquely immutable",
1888 impl<'a
, 'gcx
, 'tcx
> TyCtxt
<'a
, 'gcx
, 'tcx
> {
1889 pub fn body_tables(self, body
: hir
::BodyId
) -> &'gcx TypeckTables
<'gcx
> {
1890 self.item_tables(self.hir
.body_owner_def_id(body
))
1893 pub fn item_tables(self, def_id
: DefId
) -> &'gcx TypeckTables
<'gcx
> {
1894 self.tables
.memoize(def_id
, || {
1895 if def_id
.is_local() {
1896 // Closures' tables come from their outermost function,
1897 // as they are part of the same "inference environment".
1898 let outer_def_id
= self.closure_base_def_id(def_id
);
1899 if outer_def_id
!= def_id
{
1900 return self.item_tables(outer_def_id
);
1903 bug
!("No def'n found for {:?} in tcx.tables", def_id
);
1906 // Cross-crate side-tables only exist alongside serialized HIR.
1907 self.sess
.cstore
.maybe_get_item_body(self.global_tcx(), def_id
).map(|_
| {
1908 self.tables
.borrow()[&def_id
]
1909 }).unwrap_or_else(|| {
1910 bug
!("tcx.item_tables({:?}): missing from metadata", def_id
)
1915 pub fn expr_span(self, id
: NodeId
) -> Span
{
1916 match self.hir
.find(id
) {
1917 Some(hir_map
::NodeExpr(e
)) => {
1921 bug
!("Node id {} is not an expr: {:?}", id
, f
);
1924 bug
!("Node id {} is not present in the node map", id
);
1929 pub fn local_var_name_str(self, id
: NodeId
) -> InternedString
{
1930 match self.hir
.find(id
) {
1931 Some(hir_map
::NodeLocal(pat
)) => {
1933 hir
::PatKind
::Binding(_
, _
, ref path1
, _
) => path1
.node
.as_str(),
1935 bug
!("Variable id {} maps to {:?}, not local", id
, pat
);
1939 r
=> bug
!("Variable id {} maps to {:?}, not local", id
, r
),
1943 pub fn expr_is_lval(self, expr
: &hir
::Expr
) -> bool
{
1945 hir
::ExprPath(hir
::QPath
::Resolved(_
, ref path
)) => {
1947 Def
::Local(..) | Def
::Upvar(..) | Def
::Static(..) | Def
::Err
=> true,
1952 hir
::ExprType(ref e
, _
) => {
1953 self.expr_is_lval(e
)
1956 hir
::ExprUnary(hir
::UnDeref
, _
) |
1957 hir
::ExprField(..) |
1958 hir
::ExprTupField(..) |
1959 hir
::ExprIndex(..) => {
1963 // Partially qualified paths in expressions can only legally
1964 // refer to associated items which are always rvalues.
1965 hir
::ExprPath(hir
::QPath
::TypeRelative(..)) |
1968 hir
::ExprMethodCall(..) |
1969 hir
::ExprStruct(..) |
1972 hir
::ExprMatch(..) |
1973 hir
::ExprClosure(..) |
1974 hir
::ExprBlock(..) |
1975 hir
::ExprRepeat(..) |
1976 hir
::ExprArray(..) |
1977 hir
::ExprBreak(..) |
1978 hir
::ExprAgain(..) |
1980 hir
::ExprWhile(..) |
1982 hir
::ExprAssign(..) |
1983 hir
::ExprInlineAsm(..) |
1984 hir
::ExprAssignOp(..) |
1986 hir
::ExprUnary(..) |
1988 hir
::ExprAddrOf(..) |
1989 hir
::ExprBinary(..) |
1990 hir
::ExprCast(..) => {
1996 pub fn provided_trait_methods(self, id
: DefId
) -> Vec
<AssociatedItem
> {
1997 self.associated_items(id
)
1998 .filter(|item
| item
.kind
== AssociatedKind
::Method
&& item
.defaultness
.has_value())
2002 pub fn trait_impl_polarity(self, id
: DefId
) -> hir
::ImplPolarity
{
2003 if let Some(id
) = self.hir
.as_local_node_id(id
) {
2004 match self.hir
.expect_item(id
).node
{
2005 hir
::ItemImpl(_
, polarity
, ..) => polarity
,
2006 ref item
=> bug
!("trait_impl_polarity: {:?} not an impl", item
)
2009 self.sess
.cstore
.impl_polarity(id
)
2013 pub fn custom_coerce_unsized_kind(self, did
: DefId
) -> adjustment
::CustomCoerceUnsized
{
2014 self.custom_coerce_unsized_kinds
.memoize(did
, || {
2015 let (kind
, src
) = if did
.krate
!= LOCAL_CRATE
{
2016 (self.sess
.cstore
.custom_coerce_unsized_kind(did
), "external")
2024 bug
!("custom_coerce_unsized_kind: \
2025 {} impl `{}` is missing its kind",
2026 src
, self.item_path_str(did
));
2032 pub fn associated_item(self, def_id
: DefId
) -> AssociatedItem
{
2033 self.associated_items
.memoize(def_id
, || {
2034 if !def_id
.is_local() {
2035 return self.sess
.cstore
.associated_item(def_id
)
2036 .expect("missing AssociatedItem in metadata");
2039 // When the user asks for a given associated item, we
2040 // always go ahead and convert all the associated items in
2041 // the container. Note that we are also careful only to
2042 // ever register a read on the *container* of the assoc
2043 // item, not the assoc item itself. This prevents changes
2044 // in the details of an item (for example, the type to
2045 // which an associated type is bound) from contaminating
2046 // those tasks that just need to scan the names of items
2049 let id
= self.hir
.as_local_node_id(def_id
).unwrap();
2050 let parent_id
= self.hir
.get_parent(id
);
2051 let parent_def_id
= self.hir
.local_def_id(parent_id
);
2052 let parent_item
= self.hir
.expect_item(parent_id
);
2053 match parent_item
.node
{
2054 hir
::ItemImpl(.., ref impl_trait_ref
, _
, ref impl_item_refs
) => {
2055 for impl_item_ref
in impl_item_refs
{
2057 self.associated_item_from_impl_item_ref(parent_def_id
,
2058 impl_trait_ref
.is_some(),
2060 self.associated_items
.borrow_mut().insert(assoc_item
.def_id
, assoc_item
);
2064 hir
::ItemTrait(.., ref trait_item_refs
) => {
2065 for trait_item_ref
in trait_item_refs
{
2067 self.associated_item_from_trait_item_ref(parent_def_id
, trait_item_ref
);
2068 self.associated_items
.borrow_mut().insert(assoc_item
.def_id
, assoc_item
);
2073 panic
!("unexpected container of associated items: {:?}", r
)
2077 // memoize wants us to return something, so return
2078 // the one we generated for this def-id
2079 *self.associated_items
.borrow().get(&def_id
).unwrap()
2083 fn associated_item_from_trait_item_ref(self,
2084 parent_def_id
: DefId
,
2085 trait_item_ref
: &hir
::TraitItemRef
)
2087 let def_id
= self.hir
.local_def_id(trait_item_ref
.id
.node_id
);
2088 let (kind
, has_self
) = match trait_item_ref
.kind
{
2089 hir
::AssociatedItemKind
::Const
=> (ty
::AssociatedKind
::Const
, false),
2090 hir
::AssociatedItemKind
::Method { has_self }
=> {
2091 (ty
::AssociatedKind
::Method
, has_self
)
2093 hir
::AssociatedItemKind
::Type
=> (ty
::AssociatedKind
::Type
, false),
2097 name
: trait_item_ref
.name
,
2099 vis
: Visibility
::from_hir(&hir
::Inherited
, trait_item_ref
.id
.node_id
, self),
2100 defaultness
: trait_item_ref
.defaultness
,
2102 container
: TraitContainer(parent_def_id
),
2103 method_has_self_argument
: has_self
2107 fn associated_item_from_impl_item_ref(self,
2108 parent_def_id
: DefId
,
2109 from_trait_impl
: bool
,
2110 impl_item_ref
: &hir
::ImplItemRef
)
2112 let def_id
= self.hir
.local_def_id(impl_item_ref
.id
.node_id
);
2113 let (kind
, has_self
) = match impl_item_ref
.kind
{
2114 hir
::AssociatedItemKind
::Const
=> (ty
::AssociatedKind
::Const
, false),
2115 hir
::AssociatedItemKind
::Method { has_self }
=> {
2116 (ty
::AssociatedKind
::Method
, has_self
)
2118 hir
::AssociatedItemKind
::Type
=> (ty
::AssociatedKind
::Type
, false),
2121 // Trait impl items are always public.
2122 let public
= hir
::Public
;
2123 let vis
= if from_trait_impl { &public }
else { &impl_item_ref.vis }
;
2125 ty
::AssociatedItem
{
2126 name
: impl_item_ref
.name
,
2128 vis
: ty
::Visibility
::from_hir(vis
, impl_item_ref
.id
.node_id
, self),
2129 defaultness
: impl_item_ref
.defaultness
,
2131 container
: ImplContainer(parent_def_id
),
2132 method_has_self_argument
: has_self
2136 pub fn associated_item_def_ids(self, def_id
: DefId
) -> Rc
<Vec
<DefId
>> {
2137 self.associated_item_def_ids
.memoize(def_id
, || {
2138 if !def_id
.is_local() {
2139 return Rc
::new(self.sess
.cstore
.associated_item_def_ids(def_id
));
2142 let id
= self.hir
.as_local_node_id(def_id
).unwrap();
2143 let item
= self.hir
.expect_item(id
);
2144 let vec
: Vec
<_
> = match item
.node
{
2145 hir
::ItemTrait(.., ref trait_item_refs
) => {
2146 trait_item_refs
.iter()
2147 .map(|trait_item_ref
| trait_item_ref
.id
)
2148 .map(|id
| self.hir
.local_def_id(id
.node_id
))
2151 hir
::ItemImpl(.., ref impl_item_refs
) => {
2152 impl_item_refs
.iter()
2153 .map(|impl_item_ref
| impl_item_ref
.id
)
2154 .map(|id
| self.hir
.local_def_id(id
.node_id
))
2157 _
=> span_bug
!(item
.span
, "associated_item_def_ids: not impl or trait")
2163 #[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait.
2164 pub fn associated_items(self, def_id
: DefId
)
2165 -> impl Iterator
<Item
= ty
::AssociatedItem
> + 'a
{
2166 let def_ids
= self.associated_item_def_ids(def_id
);
2167 (0..def_ids
.len()).map(move |i
| self.associated_item(def_ids
[i
]))
2170 /// Returns the trait-ref corresponding to a given impl, or None if it is
2171 /// an inherent impl.
2172 pub fn impl_trait_ref(self, id
: DefId
) -> Option
<TraitRef
<'gcx
>> {
2173 lookup_locally_or_in_crate_store(
2174 "impl_trait_refs", id
, &self.impl_trait_refs
,
2175 || self.sess
.cstore
.impl_trait_ref(self.global_tcx(), id
))
2178 // Returns `ty::VariantDef` if `def` refers to a struct,
2179 // or variant or their constructors, panics otherwise.
2180 pub fn expect_variant_def(self, def
: Def
) -> &'tcx VariantDef
{
2182 Def
::Variant(did
) | Def
::VariantCtor(did
, ..) => {
2183 let enum_did
= self.parent_def_id(did
).unwrap();
2184 self.lookup_adt_def(enum_did
).variant_with_id(did
)
2186 Def
::Struct(did
) | Def
::Union(did
) => {
2187 self.lookup_adt_def(did
).struct_variant()
2189 Def
::StructCtor(ctor_did
, ..) => {
2190 let did
= self.parent_def_id(ctor_did
).expect("struct ctor has no parent");
2191 self.lookup_adt_def(did
).struct_variant()
2193 _
=> bug
!("expect_variant_def used with unexpected def {:?}", def
)
2197 pub fn def_key(self, id
: DefId
) -> hir_map
::DefKey
{
2199 self.hir
.def_key(id
)
2201 self.sess
.cstore
.def_key(id
)
2205 /// Convert a `DefId` into its fully expanded `DefPath` (every
2206 /// `DefId` is really just an interned def-path).
2208 /// Note that if `id` is not local to this crate, the result will
2209 // be a non-local `DefPath`.
2210 pub fn def_path(self, id
: DefId
) -> hir_map
::DefPath
{
2212 self.hir
.def_path(id
)
2214 self.sess
.cstore
.def_path(id
)
2218 pub fn def_span(self, def_id
: DefId
) -> Span
{
2219 if let Some(id
) = self.hir
.as_local_node_id(def_id
) {
2222 self.sess
.cstore
.def_span(&self.sess
, def_id
)
2226 pub fn vis_is_accessible_from(self, vis
: Visibility
, block
: NodeId
) -> bool
{
2227 vis
.is_accessible_from(self.hir
.local_def_id(self.hir
.get_module_parent(block
)), self)
2230 pub fn item_name(self, id
: DefId
) -> ast
::Name
{
2231 if let Some(id
) = self.hir
.as_local_node_id(id
) {
2233 } else if id
.index
== CRATE_DEF_INDEX
{
2234 self.sess
.cstore
.original_crate_name(id
.krate
)
2236 let def_key
= self.sess
.cstore
.def_key(id
);
2237 // The name of a StructCtor is that of its struct parent.
2238 if let hir_map
::DefPathData
::StructCtor
= def_key
.disambiguated_data
.data
{
2239 self.item_name(DefId
{
2241 index
: def_key
.parent
.unwrap()
2244 def_key
.disambiguated_data
.data
.get_opt_name().unwrap_or_else(|| {
2245 bug
!("item_name: no name for {:?}", self.def_path(id
));
2251 // If the given item is in an external crate, looks up its type and adds it to
2252 // the type cache. Returns the type parameters and type.
2253 pub fn item_type(self, did
: DefId
) -> Ty
<'gcx
> {
2254 lookup_locally_or_in_crate_store(
2255 "item_types", did
, &self.item_types
,
2256 || self.sess
.cstore
.item_type(self.global_tcx(), did
))
2259 /// Given the did of a trait, returns its canonical trait ref.
2260 pub fn lookup_trait_def(self, did
: DefId
) -> &'gcx TraitDef
{
2261 lookup_locally_or_in_crate_store(
2262 "trait_defs", did
, &self.trait_defs
,
2263 || self.alloc_trait_def(self.sess
.cstore
.trait_def(self.global_tcx(), did
))
2267 /// Given the did of an ADT, return a reference to its definition.
2268 pub fn lookup_adt_def(self, did
: DefId
) -> &'gcx AdtDef
{
2269 lookup_locally_or_in_crate_store(
2270 "adt_defs", did
, &self.adt_defs
,
2271 || self.sess
.cstore
.adt_def(self.global_tcx(), did
))
2274 /// Given the did of an item, returns its generics.
2275 pub fn item_generics(self, did
: DefId
) -> &'gcx Generics
<'gcx
> {
2276 lookup_locally_or_in_crate_store(
2277 "generics", did
, &self.generics
,
2278 || self.alloc_generics(self.sess
.cstore
.item_generics(self.global_tcx(), did
)))
2281 /// Given the did of an item, returns its full set of predicates.
2282 pub fn item_predicates(self, did
: DefId
) -> GenericPredicates
<'gcx
> {
2283 lookup_locally_or_in_crate_store(
2284 "predicates", did
, &self.predicates
,
2285 || self.sess
.cstore
.item_predicates(self.global_tcx(), did
))
2288 /// Given the did of a trait, returns its superpredicates.
2289 pub fn item_super_predicates(self, did
: DefId
) -> GenericPredicates
<'gcx
> {
2290 lookup_locally_or_in_crate_store(
2291 "super_predicates", did
, &self.super_predicates
,
2292 || self.sess
.cstore
.item_super_predicates(self.global_tcx(), did
))
2295 /// Given the did of an item, returns its MIR, borrowed immutably.
2296 pub fn item_mir(self, did
: DefId
) -> Ref
<'gcx
, Mir
<'gcx
>> {
2297 lookup_locally_or_in_crate_store("mir_map", did
, &self.mir_map
, || {
2298 let mir
= self.sess
.cstore
.get_item_mir(self.global_tcx(), did
);
2299 let mir
= self.alloc_mir(mir
);
2301 // Perma-borrow MIR from extern crates to prevent mutation.
2302 mem
::forget(mir
.borrow());
2308 /// If `type_needs_drop` returns true, then `ty` is definitely
2309 /// non-copy and *might* have a destructor attached; if it returns
2310 /// false, then `ty` definitely has no destructor (i.e. no drop glue).
2312 /// (Note that this implies that if `ty` has a destructor attached,
2313 /// then `type_needs_drop` will definitely return `true` for `ty`.)
2314 pub fn type_needs_drop_given_env(self,
2316 param_env
: &ty
::ParameterEnvironment
<'gcx
>) -> bool
{
2317 // Issue #22536: We first query type_moves_by_default. It sees a
2318 // normalized version of the type, and therefore will definitely
2319 // know whether the type implements Copy (and thus needs no
2320 // cleanup/drop/zeroing) ...
2321 let tcx
= self.global_tcx();
2322 let implements_copy
= !ty
.moves_by_default(tcx
, param_env
, DUMMY_SP
);
2324 if implements_copy { return false; }
2326 // ... (issue #22536 continued) but as an optimization, still use
2327 // prior logic of asking if the `needs_drop` bit is set; we need
2328 // not zero non-Copy types if they have no destructor.
2330 // FIXME(#22815): Note that calling `ty::type_contents` is a
2331 // conservative heuristic; it may report that `needs_drop` is set
2332 // when actual type does not actually have a destructor associated
2333 // with it. But since `ty` absolutely did not have the `Copy`
2334 // bound attached (see above), it is sound to treat it as having a
2335 // destructor (e.g. zero its memory on move).
2337 let contents
= ty
.type_contents(tcx
);
2338 debug
!("type_needs_drop ty={:?} contents={:?}", ty
, contents
);
2339 contents
.needs_drop(tcx
)
2342 /// Get the attributes of a definition.
2343 pub fn get_attrs(self, did
: DefId
) -> Cow
<'gcx
, [ast
::Attribute
]> {
2344 if let Some(id
) = self.hir
.as_local_node_id(did
) {
2345 Cow
::Borrowed(self.hir
.attrs(id
))
2347 Cow
::Owned(self.sess
.cstore
.item_attrs(did
))
2351 /// Determine whether an item is annotated with an attribute
2352 pub fn has_attr(self, did
: DefId
, attr
: &str) -> bool
{
2353 self.get_attrs(did
).iter().any(|item
| item
.check_name(attr
))
2356 /// Determine whether an item is annotated with `#[repr(packed)]`
2357 pub fn lookup_packed(self, did
: DefId
) -> bool
{
2358 self.lookup_repr_hints(did
).contains(&attr
::ReprPacked
)
2361 /// Determine whether an item is annotated with `#[simd]`
2362 pub fn lookup_simd(self, did
: DefId
) -> bool
{
2363 self.has_attr(did
, "simd")
2364 || self.lookup_repr_hints(did
).contains(&attr
::ReprSimd
)
2367 pub fn item_variances(self, item_id
: DefId
) -> Rc
<Vec
<ty
::Variance
>> {
2368 lookup_locally_or_in_crate_store(
2369 "item_variance_map", item_id
, &self.item_variance_map
,
2370 || Rc
::new(self.sess
.cstore
.item_variances(item_id
)))
2373 pub fn trait_has_default_impl(self, trait_def_id
: DefId
) -> bool
{
2374 self.populate_implementations_for_trait_if_necessary(trait_def_id
);
2376 let def
= self.lookup_trait_def(trait_def_id
);
2377 def
.flags
.get().intersects(TraitFlags
::HAS_DEFAULT_IMPL
)
2380 /// Records a trait-to-implementation mapping.
2381 pub fn record_trait_has_default_impl(self, trait_def_id
: DefId
) {
2382 let def
= self.lookup_trait_def(trait_def_id
);
2383 def
.flags
.set(def
.flags
.get() | TraitFlags
::HAS_DEFAULT_IMPL
)
2386 /// Populates the type context with all the inherent implementations for
2387 /// the given type if necessary.
2388 pub fn populate_inherent_implementations_for_type_if_necessary(self,
2390 if type_id
.is_local() {
2394 // The type is not local, hence we are reading this out of
2395 // metadata and don't need to track edges.
2396 let _ignore
= self.dep_graph
.in_ignore();
2398 if self.populated_external_types
.borrow().contains(&type_id
) {
2402 debug
!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}",
2405 let inherent_impls
= self.sess
.cstore
.inherent_implementations_for_type(type_id
);
2407 self.inherent_impls
.borrow_mut().insert(type_id
, inherent_impls
);
2408 self.populated_external_types
.borrow_mut().insert(type_id
);
2411 /// Populates the type context with all the implementations for the given
2412 /// trait if necessary.
2413 pub fn populate_implementations_for_trait_if_necessary(self, trait_id
: DefId
) {
2414 if trait_id
.is_local() {
2418 // The type is not local, hence we are reading this out of
2419 // metadata and don't need to track edges.
2420 let _ignore
= self.dep_graph
.in_ignore();
2422 let def
= self.lookup_trait_def(trait_id
);
2423 if def
.flags
.get().intersects(TraitFlags
::IMPLS_VALID
) {
2427 debug
!("populate_implementations_for_trait_if_necessary: searching for {:?}", def
);
2429 if self.sess
.cstore
.is_defaulted_trait(trait_id
) {
2430 self.record_trait_has_default_impl(trait_id
);
2433 for impl_def_id
in self.sess
.cstore
.implementations_of_trait(Some(trait_id
)) {
2434 let trait_ref
= self.impl_trait_ref(impl_def_id
).unwrap();
2436 // Record the trait->implementation mapping.
2437 let parent
= self.sess
.cstore
.impl_parent(impl_def_id
).unwrap_or(trait_id
);
2438 def
.record_remote_impl(self, impl_def_id
, trait_ref
, parent
);
2441 def
.flags
.set(def
.flags
.get() | TraitFlags
::IMPLS_VALID
);
2444 pub fn closure_kind(self, def_id
: DefId
) -> ty
::ClosureKind
{
2445 // If this is a local def-id, it should be inserted into the
2446 // tables by typeck; else, it will be retreived from
2447 // the external crate metadata.
2448 if let Some(&kind
) = self.closure_kinds
.borrow().get(&def_id
) {
2452 let kind
= self.sess
.cstore
.closure_kind(def_id
);
2453 self.closure_kinds
.borrow_mut().insert(def_id
, kind
);
2457 pub fn closure_type(self,
2459 substs
: ClosureSubsts
<'tcx
>)
2460 -> ty
::ClosureTy
<'tcx
>
2462 // If this is a local def-id, it should be inserted into the
2463 // tables by typeck; else, it will be retreived from
2464 // the external crate metadata.
2465 if let Some(ty
) = self.closure_tys
.borrow().get(&def_id
) {
2466 return ty
.subst(self, substs
.substs
);
2469 let ty
= self.sess
.cstore
.closure_ty(self.global_tcx(), def_id
);
2470 self.closure_tys
.borrow_mut().insert(def_id
, ty
.clone());
2471 ty
.subst(self, substs
.substs
)
2474 /// Given the def_id of an impl, return the def_id of the trait it implements.
2475 /// If it implements no trait, return `None`.
2476 pub fn trait_id_of_impl(self, def_id
: DefId
) -> Option
<DefId
> {
2477 self.impl_trait_ref(def_id
).map(|tr
| tr
.def_id
)
2480 /// If the given def ID describes a method belonging to an impl, return the
2481 /// ID of the impl that the method belongs to. Otherwise, return `None`.
2482 pub fn impl_of_method(self, def_id
: DefId
) -> Option
<DefId
> {
2483 if def_id
.krate
!= LOCAL_CRATE
{
2484 return self.sess
.cstore
.associated_item(def_id
).and_then(|item
| {
2485 match item
.container
{
2486 TraitContainer(_
) => None
,
2487 ImplContainer(def_id
) => Some(def_id
),
2491 match self.associated_items
.borrow().get(&def_id
).cloned() {
2492 Some(trait_item
) => {
2493 match trait_item
.container
{
2494 TraitContainer(_
) => None
,
2495 ImplContainer(def_id
) => Some(def_id
),
2502 /// If the given def ID describes an item belonging to a trait,
2503 /// return the ID of the trait that the trait item belongs to.
2504 /// Otherwise, return `None`.
2505 pub fn trait_of_item(self, def_id
: DefId
) -> Option
<DefId
> {
2506 if def_id
.krate
!= LOCAL_CRATE
{
2507 return self.sess
.cstore
.trait_of_item(def_id
);
2509 match self.associated_items
.borrow().get(&def_id
) {
2510 Some(associated_item
) => {
2511 match associated_item
.container
{
2512 TraitContainer(def_id
) => Some(def_id
),
2513 ImplContainer(_
) => None
2520 /// Construct a parameter environment suitable for static contexts or other contexts where there
2521 /// are no free type/lifetime parameters in scope.
2522 pub fn empty_parameter_environment(self) -> ParameterEnvironment
<'tcx
> {
2524 // for an empty parameter environment, there ARE no free
2525 // regions, so it shouldn't matter what we use for the free id
2526 let free_id_outlive
= self.region_maps
.node_extent(ast
::DUMMY_NODE_ID
);
2527 ty
::ParameterEnvironment
{
2528 free_substs
: self.intern_substs(&[]),
2529 caller_bounds
: Vec
::new(),
2530 implicit_region_bound
: self.mk_region(ty
::ReEmpty
),
2531 free_id_outlive
: free_id_outlive
,
2532 is_copy_cache
: RefCell
::new(FxHashMap()),
2533 is_sized_cache
: RefCell
::new(FxHashMap()),
2537 /// Constructs and returns a substitution that can be applied to move from
2538 /// the "outer" view of a type or method to the "inner" view.
2539 /// In general, this means converting from bound parameters to
2540 /// free parameters. Since we currently represent bound/free type
2541 /// parameters in the same way, this only has an effect on regions.
2542 pub fn construct_free_substs(self, def_id
: DefId
,
2543 free_id_outlive
: CodeExtent
)
2544 -> &'gcx Substs
<'gcx
> {
2546 let substs
= Substs
::for_item(self.global_tcx(), def_id
, |def
, _
| {
2547 // map bound 'a => free 'a
2548 self.global_tcx().mk_region(ReFree(FreeRegion
{
2549 scope
: free_id_outlive
,
2550 bound_region
: def
.to_bound_region()
2554 self.global_tcx().mk_param_from_def(def
)
2557 debug
!("construct_parameter_environment: {:?}", substs
);
2561 /// See `ParameterEnvironment` struct def'n for details.
2562 /// If you were using `free_id: NodeId`, you might try `self.region_maps.item_extent(free_id)`
2563 /// for the `free_id_outlive` parameter. (But note that this is not always quite right.)
2564 pub fn construct_parameter_environment(self,
2567 free_id_outlive
: CodeExtent
)
2568 -> ParameterEnvironment
<'gcx
>
2571 // Construct the free substs.
2574 let free_substs
= self.construct_free_substs(def_id
, free_id_outlive
);
2577 // Compute the bounds on Self and the type parameters.
2580 let tcx
= self.global_tcx();
2581 let generic_predicates
= tcx
.item_predicates(def_id
);
2582 let bounds
= generic_predicates
.instantiate(tcx
, free_substs
);
2583 let bounds
= tcx
.liberate_late_bound_regions(free_id_outlive
, &ty
::Binder(bounds
));
2584 let predicates
= bounds
.predicates
;
2586 // Finally, we have to normalize the bounds in the environment, in
2587 // case they contain any associated type projections. This process
2588 // can yield errors if the put in illegal associated types, like
2589 // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
2590 // report these errors right here; this doesn't actually feel
2591 // right to me, because constructing the environment feels like a
2592 // kind of a "idempotent" action, but I'm not sure where would be
2593 // a better place. In practice, we construct environments for
2594 // every fn once during type checking, and we'll abort if there
2595 // are any errors at that point, so after type checking you can be
2596 // sure that this will succeed without errors anyway.
2599 let unnormalized_env
= ty
::ParameterEnvironment
{
2600 free_substs
: free_substs
,
2601 implicit_region_bound
: tcx
.mk_region(ty
::ReScope(free_id_outlive
)),
2602 caller_bounds
: predicates
,
2603 free_id_outlive
: free_id_outlive
,
2604 is_copy_cache
: RefCell
::new(FxHashMap()),
2605 is_sized_cache
: RefCell
::new(FxHashMap()),
2608 let cause
= traits
::ObligationCause
::misc(span
, free_id_outlive
.node_id(&self.region_maps
));
2609 traits
::normalize_param_env_or_error(tcx
, unnormalized_env
, cause
)
2612 pub fn node_scope_region(self, id
: NodeId
) -> &'tcx Region
{
2613 self.mk_region(ty
::ReScope(self.region_maps
.node_extent(id
)))
2616 pub fn visit_all_item_likes_in_krate
<V
,F
>(self,
2619 where F
: FnMut(DefId
) -> DepNode
<DefId
>, V
: ItemLikeVisitor
<'gcx
>
2621 dep_graph
::visit_all_item_likes_in_krate(self.global_tcx(), dep_node_fn
, visitor
);
2624 /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
2625 /// with the name of the crate containing the impl.
2626 pub fn span_of_impl(self, impl_did
: DefId
) -> Result
<Span
, Symbol
> {
2627 if impl_did
.is_local() {
2628 let node_id
= self.hir
.as_local_node_id(impl_did
).unwrap();
2629 Ok(self.hir
.span(node_id
))
2631 Err(self.sess
.cstore
.crate_name(impl_did
.krate
))
2636 impl<'a
, 'gcx
, 'tcx
> TyCtxt
<'a
, 'gcx
, 'tcx
> {
2637 pub fn with_freevars
<T
, F
>(self, fid
: NodeId
, f
: F
) -> T
where
2638 F
: FnOnce(&[hir
::Freevar
]) -> T
,
2640 match self.freevars
.borrow().get(&fid
) {
2642 Some(d
) => f(&d
[..])