1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 pub use self::Variance
::*;
12 pub use self::DtorKind
::*;
13 pub use self::AssociatedItemContainer
::*;
14 pub use self::BorrowKind
::*;
15 pub use self::IntVarValue
::*;
16 pub use self::LvaluePreference
::*;
17 pub use self::fold
::TypeFoldable
;
19 use dep_graph
::{self, DepNode}
;
20 use hir
::map
as ast_map
;
22 use hir
::def
::{Def, CtorKind, ExportMap}
;
23 use hir
::def_id
::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}
;
24 use middle
::lang_items
::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}
;
25 use middle
::region
::{CodeExtent, ROOT_CODE_EXTENT}
;
29 use ty
::subst
::{Subst, Substs}
;
30 use ty
::walk
::TypeWalker
;
31 use util
::common
::MemoizationMap
;
32 use util
::nodemap
::{NodeSet, NodeMap, FxHashMap, FxHashSet}
;
34 use serialize
::{self, Encodable, Encoder}
;
36 use std
::cell
::{Cell, RefCell, Ref}
;
37 use std
::hash
::{Hash, Hasher}
;
42 use std
::vec
::IntoIter
;
44 use syntax
::ast
::{self, Name, NodeId}
;
46 use syntax
::symbol
::{Symbol, InternedString}
;
47 use syntax_pos
::{DUMMY_SP, Span}
;
49 use rustc_const_math
::ConstInt
;
50 use rustc_data_structures
::accumulate_vec
::IntoIter
as AccIntoIter
;
53 use hir
::itemlikevisit
::ItemLikeVisitor
;
55 pub use self::sty
::{Binder, DebruijnIndex}
;
56 pub use self::sty
::{BareFnTy, FnSig, PolyFnSig}
;
57 pub use self::sty
::{ClosureTy, InferTy, ParamTy, ProjectionTy, ExistentialPredicate}
;
58 pub use self::sty
::{ClosureSubsts, TypeAndMut}
;
59 pub use self::sty
::{TraitRef, TypeVariants, PolyTraitRef}
;
60 pub use self::sty
::{ExistentialTraitRef, PolyExistentialTraitRef}
;
61 pub use self::sty
::{ExistentialProjection, PolyExistentialProjection}
;
62 pub use self::sty
::{BoundRegion, EarlyBoundRegion, FreeRegion, Region}
;
63 pub use self::sty
::Issue32330
;
64 pub use self::sty
::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid}
;
65 pub use self::sty
::BoundRegion
::*;
66 pub use self::sty
::InferTy
::*;
67 pub use self::sty
::Region
::*;
68 pub use self::sty
::TypeVariants
::*;
70 pub use self::contents
::TypeContents
;
71 pub use self::context
::{TyCtxt, tls}
;
72 pub use self::context
::{CtxtArenas, Lift, Tables}
;
74 pub use self::trait_def
::{TraitDef, TraitFlags}
;
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
>>,
115 #[derive(Copy, Clone)]
122 pub fn is_present(&self) -> bool
{
130 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
131 pub enum AssociatedItemContainer
{
132 TraitContainer(DefId
),
133 ImplContainer(DefId
),
136 impl AssociatedItemContainer
{
137 pub fn id(&self) -> DefId
{
139 TraitContainer(id
) => id
,
140 ImplContainer(id
) => id
,
145 /// The "header" of an impl is everything outside the body: a Self type, a trait
146 /// ref (in the case of a trait impl), and a set of predicates (from the
147 /// bounds/where clauses).
148 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
149 pub struct ImplHeader
<'tcx
> {
150 pub impl_def_id
: DefId
,
151 pub self_ty
: Ty
<'tcx
>,
152 pub trait_ref
: Option
<TraitRef
<'tcx
>>,
153 pub predicates
: Vec
<Predicate
<'tcx
>>,
156 impl<'a
, 'gcx
, 'tcx
> ImplHeader
<'tcx
> {
157 pub fn with_fresh_ty_vars(selcx
: &mut traits
::SelectionContext
<'a
, 'gcx
, 'tcx
>,
161 let tcx
= selcx
.tcx();
162 let impl_substs
= selcx
.infcx().fresh_substs_for_item(DUMMY_SP
, impl_def_id
);
164 let header
= ImplHeader
{
165 impl_def_id
: impl_def_id
,
166 self_ty
: tcx
.item_type(impl_def_id
),
167 trait_ref
: tcx
.impl_trait_ref(impl_def_id
),
168 predicates
: tcx
.item_predicates(impl_def_id
).predicates
169 }.subst(tcx
, impl_substs
);
171 let traits
::Normalized { value: mut header, obligations }
=
172 traits
::normalize(selcx
, traits
::ObligationCause
::dummy(), &header
);
174 header
.predicates
.extend(obligations
.into_iter().map(|o
| o
.predicate
));
179 #[derive(Copy, Clone, Debug)]
180 pub struct AssociatedItem
{
183 pub kind
: AssociatedKind
,
185 pub defaultness
: hir
::Defaultness
,
186 pub container
: AssociatedItemContainer
,
188 /// Whether this is a method with an explicit self
189 /// as its first argument, allowing method calls.
190 pub method_has_self_argument
: bool
,
193 #[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
194 pub enum AssociatedKind
{
200 impl AssociatedItem
{
201 pub fn def(&self) -> Def
{
203 AssociatedKind
::Const
=> Def
::AssociatedConst(self.def_id
),
204 AssociatedKind
::Method
=> Def
::Method(self.def_id
),
205 AssociatedKind
::Type
=> Def
::AssociatedTy(self.def_id
),
210 #[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable)]
211 pub enum Visibility
{
212 /// Visible everywhere (including in other crates).
214 /// Visible only in the given crate-local module.
216 /// Not visible anywhere in the local crate. This is the visibility of private external items.
220 pub trait NodeIdTree
{
221 fn is_descendant_of(&self, node
: NodeId
, ancestor
: NodeId
) -> bool
;
224 impl<'a
> NodeIdTree
for ast_map
::Map
<'a
> {
225 fn is_descendant_of(&self, node
: NodeId
, ancestor
: NodeId
) -> bool
{
226 let mut node_ancestor
= node
;
227 while node_ancestor
!= ancestor
{
228 let node_ancestor_parent
= self.get_module_parent(node_ancestor
);
229 if node_ancestor_parent
== node_ancestor
{
232 node_ancestor
= node_ancestor_parent
;
239 pub fn from_hir(visibility
: &hir
::Visibility
, id
: NodeId
, tcx
: TyCtxt
) -> Self {
241 hir
::Public
=> Visibility
::Public
,
242 hir
::Visibility
::Crate
=> Visibility
::Restricted(ast
::CRATE_NODE_ID
),
243 hir
::Visibility
::Restricted { ref path, .. }
=> match path
.def
{
244 // If there is no resolution, `resolve` will have already reported an error, so
245 // assume that the visibility is public to avoid reporting more privacy errors.
246 Def
::Err
=> Visibility
::Public
,
247 def
=> Visibility
::Restricted(tcx
.map
.as_local_node_id(def
.def_id()).unwrap()),
249 hir
::Inherited
=> Visibility
::Restricted(tcx
.map
.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
: NodeIdTree
>(self, block
: NodeId
, 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
::PrivateExternal
=> return false,
260 // Restricted items are visible in an arbitrary local module.
261 Visibility
::Restricted(module
) => module
,
264 tree
.is_descendant_of(block
, restriction
)
267 /// Returns true if this visibility is at least as accessible as the given visibility
268 pub fn is_at_least
<T
: NodeIdTree
>(self, vis
: Visibility
, tree
: &T
) -> bool
{
269 let vis_restriction
= match vis
{
270 Visibility
::Public
=> return self == Visibility
::Public
,
271 Visibility
::PrivateExternal
=> return true,
272 Visibility
::Restricted(module
) => module
,
275 self.is_accessible_from(vis_restriction
, tree
)
279 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Copy)]
281 Covariant
, // T<A> <: T<B> iff A <: B -- e.g., function return type
282 Invariant
, // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
283 Contravariant
, // T<A> <: T<B> iff B <: A -- e.g., function param type
284 Bivariant
, // T<A> <: T<B> -- e.g., unused type parameter
287 #[derive(Clone, Copy, Debug, RustcDecodable, RustcEncodable)]
288 pub struct MethodCallee
<'tcx
> {
289 /// Impl method ID, for inherent methods, or trait method ID, otherwise.
292 pub substs
: &'tcx Substs
<'tcx
>
295 /// With method calls, we store some extra information in
296 /// side tables (i.e method_map). We use
297 /// MethodCall as a key to index into these tables instead of
298 /// just directly using the expression's NodeId. The reason
299 /// for this being that we may apply adjustments (coercions)
300 /// with the resulting expression also needing to use the
301 /// side tables. The problem with this is that we don't
302 /// assign a separate NodeId to this new expression
303 /// and so it would clash with the base expression if both
304 /// needed to add to the side tables. Thus to disambiguate
305 /// we also keep track of whether there's an adjustment in
307 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
308 pub struct MethodCall
{
314 pub fn expr(id
: NodeId
) -> MethodCall
{
321 pub fn autoderef(expr_id
: NodeId
, autoderef
: u32) -> MethodCall
{
324 autoderef
: 1 + autoderef
329 // maps from an expression id that corresponds to a method call to the details
330 // of the method to be invoked
331 pub type MethodMap
<'tcx
> = FxHashMap
<MethodCall
, MethodCallee
<'tcx
>>;
333 // Contains information needed to resolve types and (in the future) look up
334 // the types of AST nodes.
335 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
336 pub struct CReaderCacheKey
{
341 /// Describes the fragment-state associated with a NodeId.
343 /// Currently only unfragmented paths have entries in the table,
344 /// but longer-term this enum is expected to expand to also
345 /// include data for fragmented paths.
346 #[derive(Copy, Clone, Debug)]
347 pub enum FragmentInfo
{
348 Moved { var: NodeId, move_expr: NodeId }
,
349 Assigned { var: NodeId, assign_expr: NodeId, assignee_id: NodeId }
,
352 // Flags that we track on types. These flags are propagated upwards
353 // through the type during type construction, so that we can quickly
354 // check whether the type has various kinds of types in it without
355 // recursing over the type itself.
357 flags TypeFlags
: u32 {
358 const HAS_PARAMS
= 1 << 0,
359 const HAS_SELF
= 1 << 1,
360 const HAS_TY_INFER
= 1 << 2,
361 const HAS_RE_INFER
= 1 << 3,
362 const HAS_RE_SKOL
= 1 << 4,
363 const HAS_RE_EARLY_BOUND
= 1 << 5,
364 const HAS_FREE_REGIONS
= 1 << 6,
365 const HAS_TY_ERR
= 1 << 7,
366 const HAS_PROJECTION
= 1 << 8,
367 const HAS_TY_CLOSURE
= 1 << 9,
369 // true if there are "names" of types and regions and so forth
370 // that are local to a particular fn
371 const HAS_LOCAL_NAMES
= 1 << 10,
373 // Present if the type belongs in a local type context.
374 // Only set for TyInfer other than Fresh.
375 const KEEP_IN_LOCAL_TCX
= 1 << 11,
377 // Is there a projection that does not involve a bound region?
378 // Currently we can't normalize projections w/ bound regions.
379 const HAS_NORMALIZABLE_PROJECTION
= 1 << 12,
381 const NEEDS_SUBST
= TypeFlags
::HAS_PARAMS
.bits
|
382 TypeFlags
::HAS_SELF
.bits
|
383 TypeFlags
::HAS_RE_EARLY_BOUND
.bits
,
385 // Flags representing the nominal content of a type,
386 // computed by FlagsComputation. If you add a new nominal
387 // flag, it should be added here too.
388 const NOMINAL_FLAGS
= TypeFlags
::HAS_PARAMS
.bits
|
389 TypeFlags
::HAS_SELF
.bits
|
390 TypeFlags
::HAS_TY_INFER
.bits
|
391 TypeFlags
::HAS_RE_INFER
.bits
|
392 TypeFlags
::HAS_RE_SKOL
.bits
|
393 TypeFlags
::HAS_RE_EARLY_BOUND
.bits
|
394 TypeFlags
::HAS_FREE_REGIONS
.bits
|
395 TypeFlags
::HAS_TY_ERR
.bits
|
396 TypeFlags
::HAS_PROJECTION
.bits
|
397 TypeFlags
::HAS_TY_CLOSURE
.bits
|
398 TypeFlags
::HAS_LOCAL_NAMES
.bits
|
399 TypeFlags
::KEEP_IN_LOCAL_TCX
.bits
,
401 // Caches for type_is_sized, type_moves_by_default
402 const SIZEDNESS_CACHED
= 1 << 16,
403 const IS_SIZED
= 1 << 17,
404 const MOVENESS_CACHED
= 1 << 18,
405 const MOVES_BY_DEFAULT
= 1 << 19,
409 pub struct TyS
<'tcx
> {
410 pub sty
: TypeVariants
<'tcx
>,
411 pub flags
: Cell
<TypeFlags
>,
413 // the maximal depth of any bound regions appearing in this type.
417 impl<'tcx
> PartialEq
for TyS
<'tcx
> {
419 fn eq(&self, other
: &TyS
<'tcx
>) -> bool
{
420 // (self as *const _) == (other as *const _)
421 (self as *const TyS
<'tcx
>) == (other
as *const TyS
<'tcx
>)
424 impl<'tcx
> Eq
for TyS
<'tcx
> {}
426 impl<'tcx
> Hash
for TyS
<'tcx
> {
427 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
428 (self as *const TyS
).hash(s
)
432 pub type Ty
<'tcx
> = &'tcx TyS
<'tcx
>;
434 impl<'tcx
> serialize
::UseSpecializedEncodable
for Ty
<'tcx
> {}
435 impl<'tcx
> serialize
::UseSpecializedDecodable
for Ty
<'tcx
> {}
437 /// A wrapper for slices with the additional invariant
438 /// that the slice is interned and no other slice with
439 /// the same contents can exist in the same context.
440 /// This means we can use pointer + length for both
441 /// equality comparisons and hashing.
442 #[derive(Debug, RustcEncodable)]
443 pub struct Slice
<T
>([T
]);
445 impl<T
> PartialEq
for Slice
<T
> {
447 fn eq(&self, other
: &Slice
<T
>) -> bool
{
448 (&self.0 as *const [T
]) == (&other
.0 as *const [T
])
451 impl<T
> Eq
for Slice
<T
> {}
453 impl<T
> Hash
for Slice
<T
> {
454 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
455 (self.as_ptr(), self.len()).hash(s
)
459 impl<T
> Deref
for Slice
<T
> {
461 fn deref(&self) -> &[T
] {
466 impl<'a
, T
> IntoIterator
for &'a Slice
<T
> {
468 type IntoIter
= <&'a
[T
] as IntoIterator
>::IntoIter
;
469 fn into_iter(self) -> Self::IntoIter
{
474 impl<'tcx
> serialize
::UseSpecializedDecodable
for &'tcx Slice
<Ty
<'tcx
>> {}
477 pub fn empty
<'a
>() -> &'a Slice
<T
> {
479 mem
::transmute(slice
::from_raw_parts(0x1 as *const T
, 0))
484 /// Upvars do not get their own node-id. Instead, we use the pair of
485 /// the original var id (that is, the root variable that is referenced
486 /// by the upvar) and the id of the closure expression.
487 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
490 pub closure_expr_id
: NodeId
,
493 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)]
494 pub enum BorrowKind
{
495 /// Data must be immutable and is aliasable.
498 /// Data must be immutable but not aliasable. This kind of borrow
499 /// cannot currently be expressed by the user and is used only in
500 /// implicit closure bindings. It is needed when you the closure
501 /// is borrowing or mutating a mutable referent, e.g.:
503 /// let x: &mut isize = ...;
504 /// let y = || *x += 5;
506 /// If we were to try to translate this closure into a more explicit
507 /// form, we'd encounter an error with the code as written:
509 /// struct Env { x: & &mut isize }
510 /// let x: &mut isize = ...;
511 /// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn
512 /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
514 /// This is then illegal because you cannot mutate a `&mut` found
515 /// in an aliasable location. To solve, you'd have to translate with
516 /// an `&mut` borrow:
518 /// struct Env { x: & &mut isize }
519 /// let x: &mut isize = ...;
520 /// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
521 /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
523 /// Now the assignment to `**env.x` is legal, but creating a
524 /// mutable pointer to `x` is not because `x` is not mutable. We
525 /// could fix this by declaring `x` as `let mut x`. This is ok in
526 /// user code, if awkward, but extra weird for closures, since the
527 /// borrow is hidden.
529 /// So we introduce a "unique imm" borrow -- the referent is
530 /// immutable, but not aliasable. This solves the problem. For
531 /// simplicity, we don't give users the way to express this
532 /// borrow, it's just used when translating closures.
535 /// Data is mutable and not aliasable.
539 /// Information describing the capture of an upvar. This is computed
540 /// during `typeck`, specifically by `regionck`.
541 #[derive(PartialEq, Clone, Debug, Copy, RustcEncodable, RustcDecodable)]
542 pub enum UpvarCapture
<'tcx
> {
543 /// Upvar is captured by value. This is always true when the
544 /// closure is labeled `move`, but can also be true in other cases
545 /// depending on inference.
548 /// Upvar is captured by reference.
549 ByRef(UpvarBorrow
<'tcx
>),
552 #[derive(PartialEq, Clone, Copy, RustcEncodable, RustcDecodable)]
553 pub struct UpvarBorrow
<'tcx
> {
554 /// The kind of borrow: by-ref upvars have access to shared
555 /// immutable borrows, which are not part of the normal language
557 pub kind
: BorrowKind
,
559 /// Region of the resulting reference.
560 pub region
: &'tcx ty
::Region
,
563 pub type UpvarCaptureMap
<'tcx
> = FxHashMap
<UpvarId
, UpvarCapture
<'tcx
>>;
565 #[derive(Copy, Clone)]
566 pub struct ClosureUpvar
<'tcx
> {
572 #[derive(Clone, Copy, PartialEq)]
573 pub enum IntVarValue
{
575 UintType(ast
::UintTy
),
578 /// Default region to use for the bound of objects that are
579 /// supplied as the value for this type parameter. This is derived
580 /// from `T:'a` annotations appearing in the type definition. If
581 /// this is `None`, then the default is inherited from the
582 /// surrounding context. See RFC #599 for details.
583 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
584 pub enum ObjectLifetimeDefault
<'tcx
> {
585 /// Require an explicit annotation. Occurs when multiple
586 /// `T:'a` constraints are found.
589 /// Use the base default, typically 'static, but in a fn body it is a fresh variable
592 /// Use the given region as the default.
593 Specific(&'tcx Region
),
596 #[derive(Clone, RustcEncodable, RustcDecodable)]
597 pub struct TypeParameterDef
<'tcx
> {
601 pub default_def_id
: DefId
, // for use in error reporing about defaults
602 pub default: Option
<Ty
<'tcx
>>,
603 pub object_lifetime_default
: ObjectLifetimeDefault
<'tcx
>,
605 /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute
606 /// on generic parameter `T`, asserts data behind the parameter
607 /// `T` won't be accessed during the parent type's `Drop` impl.
608 pub pure_wrt_drop
: bool
,
611 #[derive(Clone, RustcEncodable, RustcDecodable)]
612 pub struct RegionParameterDef
<'tcx
> {
616 pub bounds
: Vec
<&'tcx ty
::Region
>,
618 /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute
619 /// on generic parameter `'a`, asserts data of lifetime `'a`
620 /// won't be accessed during the parent type's `Drop` impl.
621 pub pure_wrt_drop
: bool
,
624 impl<'tcx
> RegionParameterDef
<'tcx
> {
625 pub fn to_early_bound_region_data(&self) -> ty
::EarlyBoundRegion
{
626 ty
::EarlyBoundRegion
{
632 pub fn to_bound_region(&self) -> ty
::BoundRegion
{
633 // this is an early bound region, so unaffected by #32330
634 ty
::BoundRegion
::BrNamed(self.def_id
, self.name
, Issue32330
::WontChange
)
638 /// Information about the formal type/lifetime parameters associated
639 /// with an item or method. Analogous to hir::Generics.
640 #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
641 pub struct Generics
<'tcx
> {
642 pub parent
: Option
<DefId
>,
643 pub parent_regions
: u32,
644 pub parent_types
: u32,
645 pub regions
: Vec
<RegionParameterDef
<'tcx
>>,
646 pub types
: Vec
<TypeParameterDef
<'tcx
>>,
650 impl<'tcx
> Generics
<'tcx
> {
651 pub fn parent_count(&self) -> usize {
652 self.parent_regions
as usize + self.parent_types
as usize
655 pub fn own_count(&self) -> usize {
656 self.regions
.len() + self.types
.len()
659 pub fn count(&self) -> usize {
660 self.parent_count() + self.own_count()
663 pub fn region_param(&self, param
: &EarlyBoundRegion
) -> &RegionParameterDef
<'tcx
> {
664 &self.regions
[param
.index
as usize - self.has_self
as usize]
667 pub fn type_param(&self, param
: &ParamTy
) -> &TypeParameterDef
<'tcx
> {
668 &self.types
[param
.idx
as usize - self.has_self
as usize - self.regions
.len()]
672 /// Bounds on generics.
674 pub struct GenericPredicates
<'tcx
> {
675 pub parent
: Option
<DefId
>,
676 pub predicates
: Vec
<Predicate
<'tcx
>>,
679 impl<'tcx
> serialize
::UseSpecializedEncodable
for GenericPredicates
<'tcx
> {}
680 impl<'tcx
> serialize
::UseSpecializedDecodable
for GenericPredicates
<'tcx
> {}
682 impl<'a
, 'gcx
, 'tcx
> GenericPredicates
<'tcx
> {
683 pub fn instantiate(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>, substs
: &Substs
<'tcx
>)
684 -> InstantiatedPredicates
<'tcx
> {
685 let mut instantiated
= InstantiatedPredicates
::empty();
686 self.instantiate_into(tcx
, &mut instantiated
, substs
);
689 pub fn instantiate_own(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>, substs
: &Substs
<'tcx
>)
690 -> InstantiatedPredicates
<'tcx
> {
691 InstantiatedPredicates
{
692 predicates
: self.predicates
.subst(tcx
, substs
)
696 fn instantiate_into(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
697 instantiated
: &mut InstantiatedPredicates
<'tcx
>,
698 substs
: &Substs
<'tcx
>) {
699 if let Some(def_id
) = self.parent
{
700 tcx
.item_predicates(def_id
).instantiate_into(tcx
, instantiated
, substs
);
702 instantiated
.predicates
.extend(self.predicates
.iter().map(|p
| p
.subst(tcx
, substs
)))
705 pub fn instantiate_supertrait(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
706 poly_trait_ref
: &ty
::PolyTraitRef
<'tcx
>)
707 -> InstantiatedPredicates
<'tcx
>
709 assert_eq
!(self.parent
, None
);
710 InstantiatedPredicates
{
711 predicates
: self.predicates
.iter().map(|pred
| {
712 pred
.subst_supertrait(tcx
, poly_trait_ref
)
718 #[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
719 pub enum Predicate
<'tcx
> {
720 /// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
721 /// the `Self` type of the trait reference and `A`, `B`, and `C`
722 /// would be the type parameters.
723 Trait(PolyTraitPredicate
<'tcx
>),
725 /// where `T1 == T2`.
726 Equate(PolyEquatePredicate
<'tcx
>),
729 RegionOutlives(PolyRegionOutlivesPredicate
<'tcx
>),
732 TypeOutlives(PolyTypeOutlivesPredicate
<'tcx
>),
734 /// where <T as TraitRef>::Name == X, approximately.
735 /// See `ProjectionPredicate` struct for details.
736 Projection(PolyProjectionPredicate
<'tcx
>),
739 WellFormed(Ty
<'tcx
>),
741 /// trait must be object-safe
744 /// No direct syntax. May be thought of as `where T : FnFoo<...>`
745 /// for some substitutions `...` and T being a closure type.
746 /// Satisfied (or refuted) once we know the closure's kind.
747 ClosureKind(DefId
, ClosureKind
),
750 impl<'a
, 'gcx
, 'tcx
> Predicate
<'tcx
> {
751 /// Performs a substitution suitable for going from a
752 /// poly-trait-ref to supertraits that must hold if that
753 /// poly-trait-ref holds. This is slightly different from a normal
754 /// substitution in terms of what happens with bound regions. See
755 /// lengthy comment below for details.
756 pub fn subst_supertrait(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
757 trait_ref
: &ty
::PolyTraitRef
<'tcx
>)
758 -> ty
::Predicate
<'tcx
>
760 // The interaction between HRTB and supertraits is not entirely
761 // obvious. Let me walk you (and myself) through an example.
763 // Let's start with an easy case. Consider two traits:
765 // trait Foo<'a> : Bar<'a,'a> { }
766 // trait Bar<'b,'c> { }
768 // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
769 // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
770 // knew that `Foo<'x>` (for any 'x) then we also know that
771 // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
772 // normal substitution.
774 // In terms of why this is sound, the idea is that whenever there
775 // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
776 // holds. So if there is an impl of `T:Foo<'a>` that applies to
777 // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
780 // Another example to be careful of is this:
782 // trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
783 // trait Bar1<'b,'c> { }
785 // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
786 // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
787 // reason is similar to the previous example: any impl of
788 // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`. So
789 // basically we would want to collapse the bound lifetimes from
790 // the input (`trait_ref`) and the supertraits.
792 // To achieve this in practice is fairly straightforward. Let's
793 // consider the more complicated scenario:
795 // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
796 // has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
797 // where both `'x` and `'b` would have a DB index of 1.
798 // The substitution from the input trait-ref is therefore going to be
799 // `'a => 'x` (where `'x` has a DB index of 1).
800 // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
801 // early-bound parameter and `'b' is a late-bound parameter with a
803 // - If we replace `'a` with `'x` from the input, it too will have
804 // a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
805 // just as we wanted.
807 // There is only one catch. If we just apply the substitution `'a
808 // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
809 // adjust the DB index because we substituting into a binder (it
810 // tries to be so smart...) resulting in `for<'x> for<'b>
811 // Bar1<'x,'b>` (we have no syntax for this, so use your
812 // imagination). Basically the 'x will have DB index of 2 and 'b
813 // will have DB index of 1. Not quite what we want. So we apply
814 // the substitution to the *contents* of the trait reference,
815 // rather than the trait reference itself (put another way, the
816 // substitution code expects equal binding levels in the values
817 // from the substitution and the value being substituted into, and
818 // this trick achieves that).
820 let substs
= &trait_ref
.0.substs
;
822 Predicate
::Trait(ty
::Binder(ref data
)) =>
823 Predicate
::Trait(ty
::Binder(data
.subst(tcx
, substs
))),
824 Predicate
::Equate(ty
::Binder(ref data
)) =>
825 Predicate
::Equate(ty
::Binder(data
.subst(tcx
, substs
))),
826 Predicate
::RegionOutlives(ty
::Binder(ref data
)) =>
827 Predicate
::RegionOutlives(ty
::Binder(data
.subst(tcx
, substs
))),
828 Predicate
::TypeOutlives(ty
::Binder(ref data
)) =>
829 Predicate
::TypeOutlives(ty
::Binder(data
.subst(tcx
, substs
))),
830 Predicate
::Projection(ty
::Binder(ref data
)) =>
831 Predicate
::Projection(ty
::Binder(data
.subst(tcx
, substs
))),
832 Predicate
::WellFormed(data
) =>
833 Predicate
::WellFormed(data
.subst(tcx
, substs
)),
834 Predicate
::ObjectSafe(trait_def_id
) =>
835 Predicate
::ObjectSafe(trait_def_id
),
836 Predicate
::ClosureKind(closure_def_id
, kind
) =>
837 Predicate
::ClosureKind(closure_def_id
, kind
),
842 #[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
843 pub struct TraitPredicate
<'tcx
> {
844 pub trait_ref
: TraitRef
<'tcx
>
846 pub type PolyTraitPredicate
<'tcx
> = ty
::Binder
<TraitPredicate
<'tcx
>>;
848 impl<'tcx
> TraitPredicate
<'tcx
> {
849 pub fn def_id(&self) -> DefId
{
850 self.trait_ref
.def_id
853 /// Creates the dep-node for selecting/evaluating this trait reference.
854 fn dep_node(&self) -> DepNode
<DefId
> {
855 // Ideally, the dep-node would just have all the input types
856 // in it. But they are limited to including def-ids. So as an
857 // approximation we include the def-ids for all nominal types
858 // found somewhere. This means that we will e.g. conflate the
859 // dep-nodes for `u32: SomeTrait` and `u64: SomeTrait`, but we
860 // would have distinct dep-nodes for `Vec<u32>: SomeTrait`,
861 // `Rc<u32>: SomeTrait`, and `(Vec<u32>, Rc<u32>): SomeTrait`.
862 // Note that it's always sound to conflate dep-nodes, it just
863 // leads to more recompilation.
864 let def_ids
: Vec
<_
> =
866 .flat_map(|t
| t
.walk())
867 .filter_map(|t
| match t
.sty
{
868 ty
::TyAdt(adt_def
, _
) =>
873 .chain(iter
::once(self.def_id()))
875 DepNode
::TraitSelect(def_ids
)
878 pub fn input_types
<'a
>(&'a
self) -> impl DoubleEndedIterator
<Item
=Ty
<'tcx
>> + 'a
{
879 self.trait_ref
.input_types()
882 pub fn self_ty(&self) -> Ty
<'tcx
> {
883 self.trait_ref
.self_ty()
887 impl<'tcx
> PolyTraitPredicate
<'tcx
> {
888 pub fn def_id(&self) -> DefId
{
889 // ok to skip binder since trait def-id does not care about regions
893 pub fn dep_node(&self) -> DepNode
<DefId
> {
894 // ok to skip binder since depnode does not care about regions
899 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
900 pub struct EquatePredicate
<'tcx
>(pub Ty
<'tcx
>, pub Ty
<'tcx
>); // `0 == 1`
901 pub type PolyEquatePredicate
<'tcx
> = ty
::Binder
<EquatePredicate
<'tcx
>>;
903 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
904 pub struct OutlivesPredicate
<A
,B
>(pub A
, pub B
); // `A : B`
905 pub type PolyOutlivesPredicate
<A
,B
> = ty
::Binder
<OutlivesPredicate
<A
,B
>>;
906 pub type PolyRegionOutlivesPredicate
<'tcx
> = PolyOutlivesPredicate
<&'tcx ty
::Region
,
908 pub type PolyTypeOutlivesPredicate
<'tcx
> = PolyOutlivesPredicate
<Ty
<'tcx
>, &'tcx ty
::Region
>;
910 /// This kind of predicate has no *direct* correspondent in the
911 /// syntax, but it roughly corresponds to the syntactic forms:
913 /// 1. `T : TraitRef<..., Item=Type>`
914 /// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
916 /// In particular, form #1 is "desugared" to the combination of a
917 /// normal trait predicate (`T : TraitRef<...>`) and one of these
918 /// predicates. Form #2 is a broader form in that it also permits
919 /// equality between arbitrary types. Processing an instance of Form
920 /// #2 eventually yields one of these `ProjectionPredicate`
921 /// instances to normalize the LHS.
922 #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
923 pub struct ProjectionPredicate
<'tcx
> {
924 pub projection_ty
: ProjectionTy
<'tcx
>,
928 pub type PolyProjectionPredicate
<'tcx
> = Binder
<ProjectionPredicate
<'tcx
>>;
930 impl<'tcx
> PolyProjectionPredicate
<'tcx
> {
931 pub fn item_name(&self) -> Name
{
932 self.0.projection_ty
.item_name
// safe to skip the binder to access a name
936 pub trait ToPolyTraitRef
<'tcx
> {
937 fn to_poly_trait_ref(&self) -> PolyTraitRef
<'tcx
>;
940 impl<'tcx
> ToPolyTraitRef
<'tcx
> for TraitRef
<'tcx
> {
941 fn to_poly_trait_ref(&self) -> PolyTraitRef
<'tcx
> {
942 assert
!(!self.has_escaping_regions());
943 ty
::Binder(self.clone())
947 impl<'tcx
> ToPolyTraitRef
<'tcx
> for PolyTraitPredicate
<'tcx
> {
948 fn to_poly_trait_ref(&self) -> PolyTraitRef
<'tcx
> {
949 self.map_bound_ref(|trait_pred
| trait_pred
.trait_ref
)
953 impl<'tcx
> ToPolyTraitRef
<'tcx
> for PolyProjectionPredicate
<'tcx
> {
954 fn to_poly_trait_ref(&self) -> PolyTraitRef
<'tcx
> {
955 // Note: unlike with TraitRef::to_poly_trait_ref(),
956 // self.0.trait_ref is permitted to have escaping regions.
957 // This is because here `self` has a `Binder` and so does our
958 // return value, so we are preserving the number of binding
960 ty
::Binder(self.0.projection_ty
.trait_ref
)
964 pub trait ToPredicate
<'tcx
> {
965 fn to_predicate(&self) -> Predicate
<'tcx
>;
968 impl<'tcx
> ToPredicate
<'tcx
> for TraitRef
<'tcx
> {
969 fn to_predicate(&self) -> Predicate
<'tcx
> {
970 // we're about to add a binder, so let's check that we don't
971 // accidentally capture anything, or else that might be some
972 // weird debruijn accounting.
973 assert
!(!self.has_escaping_regions());
975 ty
::Predicate
::Trait(ty
::Binder(ty
::TraitPredicate
{
976 trait_ref
: self.clone()
981 impl<'tcx
> ToPredicate
<'tcx
> for PolyTraitRef
<'tcx
> {
982 fn to_predicate(&self) -> Predicate
<'tcx
> {
983 ty
::Predicate
::Trait(self.to_poly_trait_predicate())
987 impl<'tcx
> ToPredicate
<'tcx
> for PolyEquatePredicate
<'tcx
> {
988 fn to_predicate(&self) -> Predicate
<'tcx
> {
989 Predicate
::Equate(self.clone())
993 impl<'tcx
> ToPredicate
<'tcx
> for PolyRegionOutlivesPredicate
<'tcx
> {
994 fn to_predicate(&self) -> Predicate
<'tcx
> {
995 Predicate
::RegionOutlives(self.clone())
999 impl<'tcx
> ToPredicate
<'tcx
> for PolyTypeOutlivesPredicate
<'tcx
> {
1000 fn to_predicate(&self) -> Predicate
<'tcx
> {
1001 Predicate
::TypeOutlives(self.clone())
1005 impl<'tcx
> ToPredicate
<'tcx
> for PolyProjectionPredicate
<'tcx
> {
1006 fn to_predicate(&self) -> Predicate
<'tcx
> {
1007 Predicate
::Projection(self.clone())
1011 impl<'tcx
> Predicate
<'tcx
> {
1012 /// Iterates over the types in this predicate. Note that in all
1013 /// cases this is skipping over a binder, so late-bound regions
1014 /// with depth 0 are bound by the predicate.
1015 pub fn walk_tys(&self) -> IntoIter
<Ty
<'tcx
>> {
1016 let vec
: Vec
<_
> = match *self {
1017 ty
::Predicate
::Trait(ref data
) => {
1018 data
.skip_binder().input_types().collect()
1020 ty
::Predicate
::Equate(ty
::Binder(ref data
)) => {
1021 vec
![data
.0, data
.1]
1023 ty
::Predicate
::TypeOutlives(ty
::Binder(ref data
)) => {
1026 ty
::Predicate
::RegionOutlives(..) => {
1029 ty
::Predicate
::Projection(ref data
) => {
1030 let trait_inputs
= data
.0.projection_ty
.trait_ref
.input_types();
1031 trait_inputs
.chain(Some(data
.0.ty
)).collect()
1033 ty
::Predicate
::WellFormed(data
) => {
1036 ty
::Predicate
::ObjectSafe(_trait_def_id
) => {
1039 ty
::Predicate
::ClosureKind(_closure_def_id
, _kind
) => {
1044 // The only reason to collect into a vector here is that I was
1045 // too lazy to make the full (somewhat complicated) iterator
1046 // type that would be needed here. But I wanted this fn to
1047 // return an iterator conceptually, rather than a `Vec`, so as
1048 // to be closer to `Ty::walk`.
1052 pub fn to_opt_poly_trait_ref(&self) -> Option
<PolyTraitRef
<'tcx
>> {
1054 Predicate
::Trait(ref t
) => {
1055 Some(t
.to_poly_trait_ref())
1057 Predicate
::Projection(..) |
1058 Predicate
::Equate(..) |
1059 Predicate
::RegionOutlives(..) |
1060 Predicate
::WellFormed(..) |
1061 Predicate
::ObjectSafe(..) |
1062 Predicate
::ClosureKind(..) |
1063 Predicate
::TypeOutlives(..) => {
1070 /// Represents the bounds declared on a particular set of type
1071 /// parameters. Should eventually be generalized into a flag list of
1072 /// where clauses. You can obtain a `InstantiatedPredicates` list from a
1073 /// `GenericPredicates` by using the `instantiate` method. Note that this method
1074 /// reflects an important semantic invariant of `InstantiatedPredicates`: while
1075 /// the `GenericPredicates` are expressed in terms of the bound type
1076 /// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance
1077 /// represented a set of bounds for some particular instantiation,
1078 /// meaning that the generic parameters have been substituted with
1083 /// struct Foo<T,U:Bar<T>> { ... }
1085 /// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
1086 /// `[[], [U:Bar<T>]]`. Now if there were some particular reference
1087 /// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
1088 /// [usize:Bar<isize>]]`.
1090 pub struct InstantiatedPredicates
<'tcx
> {
1091 pub predicates
: Vec
<Predicate
<'tcx
>>,
1094 impl<'tcx
> InstantiatedPredicates
<'tcx
> {
1095 pub fn empty() -> InstantiatedPredicates
<'tcx
> {
1096 InstantiatedPredicates { predicates: vec![] }
1099 pub fn is_empty(&self) -> bool
{
1100 self.predicates
.is_empty()
1104 impl<'tcx
> TraitRef
<'tcx
> {
1105 pub fn new(def_id
: DefId
, substs
: &'tcx Substs
<'tcx
>) -> TraitRef
<'tcx
> {
1106 TraitRef { def_id: def_id, substs: substs }
1109 pub fn self_ty(&self) -> Ty
<'tcx
> {
1110 self.substs
.type_at(0)
1113 pub fn input_types
<'a
>(&'a
self) -> impl DoubleEndedIterator
<Item
=Ty
<'tcx
>> + 'a
{
1114 // Select only the "input types" from a trait-reference. For
1115 // now this is all the types that appear in the
1116 // trait-reference, but it should eventually exclude
1117 // associated types.
1122 /// When type checking, we use the `ParameterEnvironment` to track
1123 /// details about the type/lifetime parameters that are in scope.
1124 /// It primarily stores the bounds information.
1126 /// Note: This information might seem to be redundant with the data in
1127 /// `tcx.ty_param_defs`, but it is not. That table contains the
1128 /// parameter definitions from an "outside" perspective, but this
1129 /// struct will contain the bounds for a parameter as seen from inside
1130 /// the function body. Currently the only real distinction is that
1131 /// bound lifetime parameters are replaced with free ones, but in the
1132 /// future I hope to refine the representation of types so as to make
1133 /// more distinctions clearer.
1135 pub struct ParameterEnvironment
<'tcx
> {
1136 /// See `construct_free_substs` for details.
1137 pub free_substs
: &'tcx Substs
<'tcx
>,
1139 /// Each type parameter has an implicit region bound that
1140 /// indicates it must outlive at least the function body (the user
1141 /// may specify stronger requirements). This field indicates the
1142 /// region of the callee.
1143 pub implicit_region_bound
: &'tcx ty
::Region
,
1145 /// Obligations that the caller must satisfy. This is basically
1146 /// the set of bounds on the in-scope type parameters, translated
1147 /// into Obligations, and elaborated and normalized.
1148 pub caller_bounds
: Vec
<ty
::Predicate
<'tcx
>>,
1150 /// Scope that is attached to free regions for this scope. This
1151 /// is usually the id of the fn body, but for more abstract scopes
1152 /// like structs we often use the node-id of the struct.
1154 /// FIXME(#3696). It would be nice to refactor so that free
1155 /// regions don't have this implicit scope and instead introduce
1156 /// relationships in the environment.
1157 pub free_id_outlive
: CodeExtent
,
1159 /// A cache for `moves_by_default`.
1160 pub is_copy_cache
: RefCell
<FxHashMap
<Ty
<'tcx
>, bool
>>,
1162 /// A cache for `type_is_sized`
1163 pub is_sized_cache
: RefCell
<FxHashMap
<Ty
<'tcx
>, bool
>>,
1166 impl<'a
, 'tcx
> ParameterEnvironment
<'tcx
> {
1167 pub fn with_caller_bounds(&self,
1168 caller_bounds
: Vec
<ty
::Predicate
<'tcx
>>)
1169 -> ParameterEnvironment
<'tcx
>
1171 ParameterEnvironment
{
1172 free_substs
: self.free_substs
,
1173 implicit_region_bound
: self.implicit_region_bound
,
1174 caller_bounds
: caller_bounds
,
1175 free_id_outlive
: self.free_id_outlive
,
1176 is_copy_cache
: RefCell
::new(FxHashMap()),
1177 is_sized_cache
: RefCell
::new(FxHashMap()),
1181 /// Construct a parameter environment given an item, impl item, or trait item
1182 pub fn for_item(tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>, id
: NodeId
)
1183 -> ParameterEnvironment
<'tcx
> {
1184 match tcx
.map
.find(id
) {
1185 Some(ast_map
::NodeImplItem(ref impl_item
)) => {
1186 match impl_item
.node
{
1187 hir
::ImplItemKind
::Type(_
) | hir
::ImplItemKind
::Const(..) => {
1188 // associated types don't have their own entry (for some reason),
1189 // so for now just grab environment for the impl
1190 let impl_id
= tcx
.map
.get_parent(id
);
1191 let impl_def_id
= tcx
.map
.local_def_id(impl_id
);
1192 tcx
.construct_parameter_environment(impl_item
.span
,
1194 tcx
.region_maps
.item_extent(id
))
1196 hir
::ImplItemKind
::Method(_
, ref body
) => {
1197 tcx
.construct_parameter_environment(
1199 tcx
.map
.local_def_id(id
),
1200 tcx
.region_maps
.call_site_extent(id
, body
.node_id()))
1204 Some(ast_map
::NodeTraitItem(trait_item
)) => {
1205 match trait_item
.node
{
1206 hir
::TypeTraitItem(..) | hir
::ConstTraitItem(..) => {
1207 // associated types don't have their own entry (for some reason),
1208 // so for now just grab environment for the trait
1209 let trait_id
= tcx
.map
.get_parent(id
);
1210 let trait_def_id
= tcx
.map
.local_def_id(trait_id
);
1211 tcx
.construct_parameter_environment(trait_item
.span
,
1213 tcx
.region_maps
.item_extent(id
))
1215 hir
::MethodTraitItem(_
, ref body
) => {
1216 // Use call-site for extent (unless this is a
1217 // trait method with no default; then fallback
1218 // to the method id).
1219 let extent
= if let Some(body_id
) = *body
{
1220 // default impl: use call_site extent as free_id_outlive bound.
1221 tcx
.region_maps
.call_site_extent(id
, body_id
.node_id())
1223 // no default impl: use item extent as free_id_outlive bound.
1224 tcx
.region_maps
.item_extent(id
)
1226 tcx
.construct_parameter_environment(
1228 tcx
.map
.local_def_id(id
),
1233 Some(ast_map
::NodeItem(item
)) => {
1235 hir
::ItemFn(.., body_id
) => {
1236 // We assume this is a function.
1237 let fn_def_id
= tcx
.map
.local_def_id(id
);
1239 tcx
.construct_parameter_environment(
1242 tcx
.region_maps
.call_site_extent(id
, body_id
.node_id()))
1245 hir
::ItemStruct(..) |
1246 hir
::ItemUnion(..) |
1249 hir
::ItemConst(..) |
1250 hir
::ItemStatic(..) => {
1251 let def_id
= tcx
.map
.local_def_id(id
);
1252 tcx
.construct_parameter_environment(item
.span
,
1254 tcx
.region_maps
.item_extent(id
))
1256 hir
::ItemTrait(..) => {
1257 let def_id
= tcx
.map
.local_def_id(id
);
1258 tcx
.construct_parameter_environment(item
.span
,
1260 tcx
.region_maps
.item_extent(id
))
1263 span_bug
!(item
.span
,
1264 "ParameterEnvironment::for_item():
1265 can't create a parameter \
1266 environment for this kind of item")
1270 Some(ast_map
::NodeExpr(expr
)) => {
1271 // This is a convenience to allow closures to work.
1272 if let hir
::ExprClosure(.., body
, _
) = expr
.node
{
1273 let def_id
= tcx
.map
.local_def_id(id
);
1274 let base_def_id
= tcx
.closure_base_def_id(def_id
);
1275 tcx
.construct_parameter_environment(
1278 tcx
.region_maps
.call_site_extent(id
, body
.node_id()))
1280 tcx
.empty_parameter_environment()
1283 Some(ast_map
::NodeForeignItem(item
)) => {
1284 let def_id
= tcx
.map
.local_def_id(id
);
1285 tcx
.construct_parameter_environment(item
.span
,
1290 bug
!("ParameterEnvironment::from_item(): \
1291 `{}` is not an item",
1292 tcx
.map
.node_to_string(id
))
1299 flags AdtFlags
: u32 {
1300 const NO_ADT_FLAGS
= 0,
1301 const IS_ENUM
= 1 << 0,
1302 const IS_DTORCK
= 1 << 1, // is this a dtorck type?
1303 const IS_DTORCK_VALID
= 1 << 2,
1304 const IS_PHANTOM_DATA
= 1 << 3,
1305 const IS_SIMD
= 1 << 4,
1306 const IS_FUNDAMENTAL
= 1 << 5,
1307 const IS_UNION
= 1 << 6,
1311 pub struct VariantDef
{
1312 /// The variant's DefId. If this is a tuple-like struct,
1313 /// this is the DefId of the struct's ctor.
1315 pub name
: Name
, // struct's name if this is a struct
1317 pub fields
: Vec
<FieldDef
>,
1318 pub ctor_kind
: CtorKind
,
1321 pub struct FieldDef
{
1324 pub vis
: Visibility
,
1327 /// The definition of an abstract data type - a struct or enum.
1329 /// These are all interned (by intern_adt_def) into the adt_defs
1333 pub variants
: Vec
<VariantDef
>,
1334 destructor
: Cell
<Option
<DefId
>>,
1335 flags
: Cell
<AdtFlags
>
1338 impl PartialEq
for AdtDef
{
1339 // AdtDef are always interned and this is part of TyS equality
1341 fn eq(&self, other
: &Self) -> bool { self as *const _ == other as *const _ }
1344 impl Eq
for AdtDef {}
1346 impl Hash
for AdtDef
{
1348 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
1349 (self as *const AdtDef
).hash(s
)
1353 impl<'tcx
> serialize
::UseSpecializedEncodable
for &'tcx AdtDef
{
1354 fn default_encode
<S
: Encoder
>(&self, s
: &mut S
) -> Result
<(), S
::Error
> {
1359 impl<'tcx
> serialize
::UseSpecializedDecodable
for &'tcx AdtDef {}
1361 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
1362 pub enum AdtKind { Struct, Union, Enum }
1364 impl<'a
, 'gcx
, 'tcx
> AdtDef
{
1365 fn new(tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
1368 variants
: Vec
<VariantDef
>) -> Self {
1369 let mut flags
= AdtFlags
::NO_ADT_FLAGS
;
1370 let attrs
= tcx
.get_attrs(did
);
1371 if attr
::contains_name(&attrs
, "fundamental") {
1372 flags
= flags
| AdtFlags
::IS_FUNDAMENTAL
;
1374 if tcx
.lookup_simd(did
) {
1375 flags
= flags
| AdtFlags
::IS_SIMD
;
1377 if Some(did
) == tcx
.lang_items
.phantom_data() {
1378 flags
= flags
| AdtFlags
::IS_PHANTOM_DATA
;
1381 AdtKind
::Enum
=> flags
= flags
| AdtFlags
::IS_ENUM
,
1382 AdtKind
::Union
=> flags
= flags
| AdtFlags
::IS_UNION
,
1383 AdtKind
::Struct
=> {}
1388 flags
: Cell
::new(flags
),
1389 destructor
: Cell
::new(None
),
1393 fn calculate_dtorck(&'gcx
self, tcx
: TyCtxt
) {
1394 if tcx
.is_adt_dtorck(self) {
1395 self.flags
.set(self.flags
.get() | AdtFlags
::IS_DTORCK
);
1397 self.flags
.set(self.flags
.get() | AdtFlags
::IS_DTORCK_VALID
)
1401 pub fn is_uninhabited_recurse(&self,
1402 visited
: &mut FxHashSet
<(DefId
, &'tcx Substs
<'tcx
>)>,
1403 block
: Option
<NodeId
>,
1404 tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
1405 substs
: &'tcx Substs
<'tcx
>) -> bool
{
1406 if !visited
.insert((self.did
, substs
)) {
1409 self.variants
.iter().all(|v
| {
1410 v
.is_uninhabited_recurse(visited
, block
, tcx
, substs
, self.is_union())
1415 pub fn is_struct(&self) -> bool
{
1416 !self.is_union() && !self.is_enum()
1420 pub fn is_union(&self) -> bool
{
1421 self.flags
.get().intersects(AdtFlags
::IS_UNION
)
1425 pub fn is_enum(&self) -> bool
{
1426 self.flags
.get().intersects(AdtFlags
::IS_ENUM
)
1429 /// Returns the kind of the ADT - Struct or Enum.
1431 pub fn adt_kind(&self) -> AdtKind
{
1434 } else if self.is_union() {
1441 pub fn descr(&self) -> &'
static str {
1442 match self.adt_kind() {
1443 AdtKind
::Struct
=> "struct",
1444 AdtKind
::Union
=> "union",
1445 AdtKind
::Enum
=> "enum",
1449 pub fn variant_descr(&self) -> &'
static str {
1450 match self.adt_kind() {
1451 AdtKind
::Struct
=> "struct",
1452 AdtKind
::Union
=> "union",
1453 AdtKind
::Enum
=> "variant",
1457 /// Returns whether this is a dtorck type. If this returns
1458 /// true, this type being safe for destruction requires it to be
1459 /// alive; Otherwise, only the contents are required to be.
1461 pub fn is_dtorck(&'gcx
self, tcx
: TyCtxt
) -> bool
{
1462 if !self.flags
.get().intersects(AdtFlags
::IS_DTORCK_VALID
) {
1463 self.calculate_dtorck(tcx
)
1465 self.flags
.get().intersects(AdtFlags
::IS_DTORCK
)
1468 /// Returns whether this type is #[fundamental] for the purposes
1469 /// of coherence checking.
1471 pub fn is_fundamental(&self) -> bool
{
1472 self.flags
.get().intersects(AdtFlags
::IS_FUNDAMENTAL
)
1476 pub fn is_simd(&self) -> bool
{
1477 self.flags
.get().intersects(AdtFlags
::IS_SIMD
)
1480 /// Returns true if this is PhantomData<T>.
1482 pub fn is_phantom_data(&self) -> bool
{
1483 self.flags
.get().intersects(AdtFlags
::IS_PHANTOM_DATA
)
1486 /// Returns whether this type has a destructor.
1487 pub fn has_dtor(&self) -> bool
{
1488 self.dtor_kind().is_present()
1491 /// Asserts this is a struct and returns the struct's unique
1493 pub fn struct_variant(&self) -> &VariantDef
{
1494 assert
!(!self.is_enum());
1499 pub fn predicates(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>) -> GenericPredicates
<'gcx
> {
1500 tcx
.item_predicates(self.did
)
1503 /// Returns an iterator over all fields contained
1506 pub fn all_fields
<'s
>(&'s
self) -> impl Iterator
<Item
= &'s FieldDef
> {
1507 self.variants
.iter().flat_map(|v
| v
.fields
.iter())
1511 pub fn is_univariant(&self) -> bool
{
1512 self.variants
.len() == 1
1515 pub fn is_payloadfree(&self) -> bool
{
1516 !self.variants
.is_empty() &&
1517 self.variants
.iter().all(|v
| v
.fields
.is_empty())
1520 pub fn variant_with_id(&self, vid
: DefId
) -> &VariantDef
{
1523 .find(|v
| v
.did
== vid
)
1524 .expect("variant_with_id: unknown variant")
1527 pub fn variant_index_with_id(&self, vid
: DefId
) -> usize {
1530 .position(|v
| v
.did
== vid
)
1531 .expect("variant_index_with_id: unknown variant")
1534 pub fn variant_of_def(&self, def
: Def
) -> &VariantDef
{
1536 Def
::Variant(vid
) | Def
::VariantCtor(vid
, ..) => self.variant_with_id(vid
),
1537 Def
::Struct(..) | Def
::StructCtor(..) | Def
::Union(..) |
1538 Def
::TyAlias(..) | Def
::AssociatedTy(..) | Def
::SelfTy(..) => self.struct_variant(),
1539 _
=> bug
!("unexpected def {:?} in variant_of_def", def
)
1543 pub fn destructor(&self) -> Option
<DefId
> {
1544 self.destructor
.get()
1547 pub fn set_destructor(&self, dtor
: DefId
) {
1548 self.destructor
.set(Some(dtor
));
1551 pub fn dtor_kind(&self) -> DtorKind
{
1552 match self.destructor
.get() {
1553 Some(_
) => TraitDtor
,
1558 /// Returns a simpler type such that `Self: Sized` if and only
1559 /// if that type is Sized, or `TyErr` if this type is recursive.
1561 /// HACK: instead of returning a list of types, this function can
1562 /// return a tuple. In that case, the result is Sized only if
1563 /// all elements of the tuple are Sized.
1565 /// This is generally the `struct_tail` if this is a struct, or a
1566 /// tuple of them if this is an enum.
1568 /// Oddly enough, checking that the sized-constraint is Sized is
1569 /// actually more expressive than checking all members:
1570 /// the Sized trait is inductive, so an associated type that references
1571 /// Self would prevent its containing ADT from being Sized.
1573 /// Due to normalization being eager, this applies even if
1574 /// the associated type is behind a pointer, e.g. issue #31299.
1575 pub fn sized_constraint(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>) -> Ty
<'tcx
> {
1576 self.calculate_sized_constraint_inner(tcx
.global_tcx(), &mut Vec
::new())
1579 /// Calculates the Sized-constraint.
1581 /// As the Sized-constraint of enums can be a *set* of types,
1582 /// the Sized-constraint may need to be a set also. Because introducing
1583 /// a new type of IVar is currently a complex affair, the Sized-constraint
1586 /// In fact, there are only a few options for the constraint:
1587 /// - `bool`, if the type is always Sized
1588 /// - an obviously-unsized type
1589 /// - a type parameter or projection whose Sizedness can't be known
1590 /// - a tuple of type parameters or projections, if there are multiple
1592 /// - a TyError, if a type contained itself. The representability
1593 /// check should catch this case.
1594 fn calculate_sized_constraint_inner(&self,
1595 tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
1596 stack
: &mut Vec
<DefId
>)
1599 if let Some(ty
) = tcx
.adt_sized_constraint
.borrow().get(&self.did
) {
1603 // Follow the memoization pattern: push the computation of
1604 // DepNode::SizedConstraint as our current task.
1605 let _task
= tcx
.dep_graph
.in_task(DepNode
::SizedConstraint(self.did
));
1607 if stack
.contains(&self.did
) {
1608 debug
!("calculate_sized_constraint: {:?} is recursive", self);
1609 // This should be reported as an error by `check_representable`.
1611 // Consider the type as Sized in the meanwhile to avoid
1613 tcx
.adt_sized_constraint
.borrow_mut().insert(self.did
, tcx
.types
.err
);
1614 return tcx
.types
.err
;
1617 stack
.push(self.did
);
1620 self.variants
.iter().flat_map(|v
| {
1623 let ty
= tcx
.item_type(f
.did
);
1624 self.sized_constraint_for_ty(tcx
, stack
, ty
)
1627 let self_
= stack
.pop().unwrap();
1628 assert_eq
!(self_
, self.did
);
1630 let ty
= match tys
.len() {
1631 _
if tys
.references_error() => tcx
.types
.err
,
1632 0 => tcx
.types
.bool
,
1634 _
=> tcx
.intern_tup(&tys
[..])
1637 let old
= tcx
.adt_sized_constraint
.borrow().get(&self.did
).cloned();
1640 debug
!("calculate_sized_constraint: {:?} recurred", self);
1641 assert_eq
!(old_ty
, tcx
.types
.err
);
1645 debug
!("calculate_sized_constraint: {:?} => {:?}", self, ty
);
1646 tcx
.adt_sized_constraint
.borrow_mut().insert(self.did
, ty
);
1652 fn sized_constraint_for_ty(&self,
1653 tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
1654 stack
: &mut Vec
<DefId
>,
1657 let result
= match ty
.sty
{
1658 TyBool
| TyChar
| TyInt(..) | TyUint(..) | TyFloat(..) |
1659 TyBox(..) | TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_
) |
1660 TyArray(..) | TyClosure(..) | TyNever
=> {
1664 TyStr
| TyDynamic(..) | TySlice(_
) | TyError
=> {
1665 // these are never sized - return the target type
1669 TyTuple(ref tys
) => {
1672 Some(ty
) => self.sized_constraint_for_ty(tcx
, stack
, ty
)
1676 TyAdt(adt
, substs
) => {
1679 adt
.calculate_sized_constraint_inner(tcx
, stack
)
1680 .subst(tcx
, substs
);
1681 debug
!("sized_constraint_for_ty({:?}) intermediate = {:?}",
1683 if let ty
::TyTuple(ref tys
) = adt_ty
.sty
{
1684 tys
.iter().flat_map(|ty
| {
1685 self.sized_constraint_for_ty(tcx
, stack
, ty
)
1688 self.sized_constraint_for_ty(tcx
, stack
, adt_ty
)
1692 TyProjection(..) | TyAnon(..) => {
1693 // must calculate explicitly.
1694 // FIXME: consider special-casing always-Sized projections
1699 // perf hack: if there is a `T: Sized` bound, then
1700 // we know that `T` is Sized and do not need to check
1703 let sized_trait
= match tcx
.lang_items
.sized_trait() {
1705 _
=> return vec
![ty
]
1707 let sized_predicate
= Binder(TraitRef
{
1708 def_id
: sized_trait
,
1709 substs
: tcx
.mk_substs_trait(ty
, &[])
1711 let predicates
= tcx
.item_predicates(self.did
).predicates
;
1712 if predicates
.into_iter().any(|p
| p
== sized_predicate
) {
1720 bug
!("unexpected type `{:?}` in sized_constraint_for_ty",
1724 debug
!("sized_constraint_for_ty({:?}) = {:?}", ty
, result
);
1729 impl<'a
, 'gcx
, 'tcx
> VariantDef
{
1731 pub fn find_field_named(&self,
1733 -> Option
<&FieldDef
> {
1734 self.fields
.iter().find(|f
| f
.name
== name
)
1738 pub fn index_of_field_named(&self,
1741 self.fields
.iter().position(|f
| f
.name
== name
)
1745 pub fn field_named(&self, name
: ast
::Name
) -> &FieldDef
{
1746 self.find_field_named(name
).unwrap()
1750 pub fn is_uninhabited_recurse(&self,
1751 visited
: &mut FxHashSet
<(DefId
, &'tcx Substs
<'tcx
>)>,
1752 block
: Option
<NodeId
>,
1753 tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
1754 substs
: &'tcx Substs
<'tcx
>,
1755 is_union
: bool
) -> bool
{
1757 self.fields
.iter().all(|f
| f
.is_uninhabited_recurse(visited
, block
, tcx
, substs
))
1759 self.fields
.iter().any(|f
| f
.is_uninhabited_recurse(visited
, block
, tcx
, substs
))
1764 impl<'a
, 'gcx
, 'tcx
> FieldDef
{
1765 pub fn ty(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>, subst
: &Substs
<'tcx
>) -> Ty
<'tcx
> {
1766 tcx
.item_type(self.did
).subst(tcx
, subst
)
1770 pub fn is_uninhabited_recurse(&self,
1771 visited
: &mut FxHashSet
<(DefId
, &'tcx Substs
<'tcx
>)>,
1772 block
: Option
<NodeId
>,
1773 tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
1774 substs
: &'tcx Substs
<'tcx
>) -> bool
{
1775 block
.map_or(true, |b
| self.vis
.is_accessible_from(b
, &tcx
.map
)) &&
1776 self.ty(tcx
, substs
).is_uninhabited_recurse(visited
, block
, tcx
)
1780 /// Records the substitutions used to translate the polytype for an
1781 /// item into the monotype of an item reference.
1782 #[derive(Clone, RustcEncodable, RustcDecodable)]
1783 pub struct ItemSubsts
<'tcx
> {
1784 pub substs
: &'tcx Substs
<'tcx
>,
1787 #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
1788 pub enum ClosureKind
{
1789 // Warning: Ordering is significant here! The ordering is chosen
1790 // because the trait Fn is a subtrait of FnMut and so in turn, and
1791 // hence we order it so that Fn < FnMut < FnOnce.
1797 impl<'a
, 'tcx
> ClosureKind
{
1798 pub fn trait_did(&self, tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>) -> DefId
{
1800 ClosureKind
::Fn
=> tcx
.require_lang_item(FnTraitLangItem
),
1801 ClosureKind
::FnMut
=> {
1802 tcx
.require_lang_item(FnMutTraitLangItem
)
1804 ClosureKind
::FnOnce
=> {
1805 tcx
.require_lang_item(FnOnceTraitLangItem
)
1810 /// True if this a type that impls this closure kind
1811 /// must also implement `other`.
1812 pub fn extends(self, other
: ty
::ClosureKind
) -> bool
{
1813 match (self, other
) {
1814 (ClosureKind
::Fn
, ClosureKind
::Fn
) => true,
1815 (ClosureKind
::Fn
, ClosureKind
::FnMut
) => true,
1816 (ClosureKind
::Fn
, ClosureKind
::FnOnce
) => true,
1817 (ClosureKind
::FnMut
, ClosureKind
::FnMut
) => true,
1818 (ClosureKind
::FnMut
, ClosureKind
::FnOnce
) => true,
1819 (ClosureKind
::FnOnce
, ClosureKind
::FnOnce
) => true,
1825 impl<'tcx
> TyS
<'tcx
> {
1826 /// Iterator that walks `self` and any types reachable from
1827 /// `self`, in depth-first order. Note that just walks the types
1828 /// that appear in `self`, it does not descend into the fields of
1829 /// structs or variants. For example:
1832 /// isize => { isize }
1833 /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
1834 /// [isize] => { [isize], isize }
1836 pub fn walk(&'tcx
self) -> TypeWalker
<'tcx
> {
1837 TypeWalker
::new(self)
1840 /// Iterator that walks the immediate children of `self`. Hence
1841 /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
1842 /// (but not `i32`, like `walk`).
1843 pub fn walk_shallow(&'tcx
self) -> AccIntoIter
<walk
::TypeWalkerArray
<'tcx
>> {
1844 walk
::walk_shallow(self)
1847 /// Walks `ty` and any types appearing within `ty`, invoking the
1848 /// callback `f` on each type. If the callback returns false, then the
1849 /// children of the current type are ignored.
1851 /// Note: prefer `ty.walk()` where possible.
1852 pub fn maybe_walk
<F
>(&'tcx
self, mut f
: F
)
1853 where F
: FnMut(Ty
<'tcx
>) -> bool
1855 let mut walker
= self.walk();
1856 while let Some(ty
) = walker
.next() {
1858 walker
.skip_current_subtree();
1864 impl<'tcx
> ItemSubsts
<'tcx
> {
1865 pub fn is_noop(&self) -> bool
{
1866 self.substs
.is_noop()
1870 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1871 pub enum LvaluePreference
{
1876 impl LvaluePreference
{
1877 pub fn from_mutbl(m
: hir
::Mutability
) -> Self {
1879 hir
::MutMutable
=> PreferMutLvalue
,
1880 hir
::MutImmutable
=> NoPreference
,
1885 /// Helper for looking things up in the various maps that are populated during
1886 /// typeck::collect (e.g., `tcx.associated_items`, `tcx.types`, etc). All of
1887 /// these share the pattern that if the id is local, it should have been loaded
1888 /// into the map by the `typeck::collect` phase. If the def-id is external,
1889 /// then we have to go consult the crate loading code (and cache the result for
1891 fn lookup_locally_or_in_crate_store
<M
, F
>(descr
: &str,
1896 M
: MemoizationMap
<Key
=DefId
>,
1897 F
: FnOnce() -> M
::Value
,
1899 map
.memoize(def_id
, || {
1900 if def_id
.is_local() {
1901 bug
!("No def'n found for {:?} in tcx.{}", def_id
, descr
);
1908 pub fn from_mutbl(m
: hir
::Mutability
) -> BorrowKind
{
1910 hir
::MutMutable
=> MutBorrow
,
1911 hir
::MutImmutable
=> ImmBorrow
,
1915 /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow
1916 /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a
1917 /// mutability that is stronger than necessary so that it at least *would permit* the borrow in
1919 pub fn to_mutbl_lossy(self) -> hir
::Mutability
{
1921 MutBorrow
=> hir
::MutMutable
,
1922 ImmBorrow
=> hir
::MutImmutable
,
1924 // We have no type corresponding to a unique imm borrow, so
1925 // use `&mut`. It gives all the capabilities of an `&uniq`
1926 // and hence is a safe "over approximation".
1927 UniqueImmBorrow
=> hir
::MutMutable
,
1931 pub fn to_user_str(&self) -> &'
static str {
1933 MutBorrow
=> "mutable",
1934 ImmBorrow
=> "immutable",
1935 UniqueImmBorrow
=> "uniquely immutable",
1940 impl<'a
, 'gcx
, 'tcx
> TyCtxt
<'a
, 'gcx
, 'tcx
> {
1941 pub fn tables(self) -> Ref
<'a
, Tables
<'gcx
>> {
1942 self.tables
.borrow()
1945 pub fn expr_span(self, id
: NodeId
) -> Span
{
1946 match self.map
.find(id
) {
1947 Some(ast_map
::NodeExpr(e
)) => {
1951 bug
!("Node id {} is not an expr: {:?}", id
, f
);
1954 bug
!("Node id {} is not present in the node map", id
);
1959 pub fn local_var_name_str(self, id
: NodeId
) -> InternedString
{
1960 match self.map
.find(id
) {
1961 Some(ast_map
::NodeLocal(pat
)) => {
1963 hir
::PatKind
::Binding(_
, _
, ref path1
, _
) => path1
.node
.as_str(),
1965 bug
!("Variable id {} maps to {:?}, not local", id
, pat
);
1969 r
=> bug
!("Variable id {} maps to {:?}, not local", id
, r
),
1973 pub fn expr_is_lval(self, expr
: &hir
::Expr
) -> bool
{
1975 hir
::ExprPath(hir
::QPath
::Resolved(_
, ref path
)) => {
1977 Def
::Local(..) | Def
::Upvar(..) | Def
::Static(..) | Def
::Err
=> true,
1982 hir
::ExprType(ref e
, _
) => {
1983 self.expr_is_lval(e
)
1986 hir
::ExprUnary(hir
::UnDeref
, _
) |
1987 hir
::ExprField(..) |
1988 hir
::ExprTupField(..) |
1989 hir
::ExprIndex(..) => {
1993 // Partially qualified paths in expressions can only legally
1994 // refer to associated items which are always rvalues.
1995 hir
::ExprPath(hir
::QPath
::TypeRelative(..)) |
1998 hir
::ExprMethodCall(..) |
1999 hir
::ExprStruct(..) |
2002 hir
::ExprMatch(..) |
2003 hir
::ExprClosure(..) |
2004 hir
::ExprBlock(..) |
2005 hir
::ExprRepeat(..) |
2006 hir
::ExprArray(..) |
2007 hir
::ExprBreak(..) |
2008 hir
::ExprAgain(..) |
2010 hir
::ExprWhile(..) |
2012 hir
::ExprAssign(..) |
2013 hir
::ExprInlineAsm(..) |
2014 hir
::ExprAssignOp(..) |
2016 hir
::ExprUnary(..) |
2018 hir
::ExprAddrOf(..) |
2019 hir
::ExprBinary(..) |
2020 hir
::ExprCast(..) => {
2026 pub fn provided_trait_methods(self, id
: DefId
) -> Vec
<AssociatedItem
> {
2027 self.associated_items(id
)
2028 .filter(|item
| item
.kind
== AssociatedKind
::Method
&& item
.defaultness
.has_value())
2032 pub fn trait_impl_polarity(self, id
: DefId
) -> hir
::ImplPolarity
{
2033 if let Some(id
) = self.map
.as_local_node_id(id
) {
2034 match self.map
.expect_item(id
).node
{
2035 hir
::ItemImpl(_
, polarity
, ..) => polarity
,
2036 ref item
=> bug
!("trait_impl_polarity: {:?} not an impl", item
)
2039 self.sess
.cstore
.impl_polarity(id
)
2043 pub fn custom_coerce_unsized_kind(self, did
: DefId
) -> adjustment
::CustomCoerceUnsized
{
2044 self.custom_coerce_unsized_kinds
.memoize(did
, || {
2045 let (kind
, src
) = if did
.krate
!= LOCAL_CRATE
{
2046 (self.sess
.cstore
.custom_coerce_unsized_kind(did
), "external")
2054 bug
!("custom_coerce_unsized_kind: \
2055 {} impl `{}` is missing its kind",
2056 src
, self.item_path_str(did
));
2062 pub fn associated_item(self, def_id
: DefId
) -> AssociatedItem
{
2063 self.associated_items
.memoize(def_id
, || {
2064 if !def_id
.is_local() {
2065 return self.sess
.cstore
.associated_item(def_id
)
2066 .expect("missing AssociatedItem in metadata");
2069 // When the user asks for a given associated item, we
2070 // always go ahead and convert all the associated items in
2071 // the container. Note that we are also careful only to
2072 // ever register a read on the *container* of the assoc
2073 // item, not the assoc item itself. This prevents changes
2074 // in the details of an item (for example, the type to
2075 // which an associated type is bound) from contaminating
2076 // those tasks that just need to scan the names of items
2079 let id
= self.map
.as_local_node_id(def_id
).unwrap();
2080 let parent_id
= self.map
.get_parent(id
);
2081 let parent_def_id
= self.map
.local_def_id(parent_id
);
2082 let parent_item
= self.map
.expect_item(parent_id
);
2083 match parent_item
.node
{
2084 hir
::ItemImpl(.., ref impl_trait_ref
, _
, ref impl_item_refs
) => {
2085 for impl_item_ref
in impl_item_refs
{
2087 self.associated_item_from_impl_item_ref(parent_def_id
,
2088 impl_trait_ref
.is_some(),
2090 self.associated_items
.borrow_mut().insert(assoc_item
.def_id
, assoc_item
);
2094 hir
::ItemTrait(.., ref trait_items
) => {
2095 for trait_item
in trait_items
{
2097 self.associated_item_from_trait_item_ref(parent_def_id
, trait_item
);
2098 self.associated_items
.borrow_mut().insert(assoc_item
.def_id
, assoc_item
);
2103 panic
!("unexpected container of associated items: {:?}", r
)
2107 // memoize wants us to return something, so return
2108 // the one we generated for this def-id
2109 *self.associated_items
.borrow().get(&def_id
).unwrap()
2113 fn associated_item_from_trait_item_ref(self,
2114 parent_def_id
: DefId
,
2115 trait_item
: &hir
::TraitItem
)
2117 let def_id
= self.map
.local_def_id(trait_item
.id
);
2119 let (kind
, has_self
, has_value
) = match trait_item
.node
{
2120 hir
::MethodTraitItem(ref sig
, ref body
) => {
2121 (AssociatedKind
::Method
, sig
.decl
.get_self().is_some(),
2124 hir
::ConstTraitItem(_
, ref value
) => {
2125 (AssociatedKind
::Const
, false, value
.is_some())
2127 hir
::TypeTraitItem(_
, ref ty
) => {
2128 (AssociatedKind
::Type
, false, ty
.is_some())
2133 name
: trait_item
.name
,
2135 vis
: Visibility
::from_hir(&hir
::Inherited
, trait_item
.id
, self),
2136 defaultness
: hir
::Defaultness
::Default { has_value: has_value }
,
2138 container
: TraitContainer(parent_def_id
),
2139 method_has_self_argument
: has_self
2143 fn associated_item_from_impl_item_ref(self,
2144 parent_def_id
: DefId
,
2145 from_trait_impl
: bool
,
2146 impl_item_ref
: &hir
::ImplItemRef
)
2148 let def_id
= self.map
.local_def_id(impl_item_ref
.id
.node_id
);
2149 let (kind
, has_self
) = match impl_item_ref
.kind
{
2150 hir
::AssociatedItemKind
::Const
=> (ty
::AssociatedKind
::Const
, false),
2151 hir
::AssociatedItemKind
::Method { has_self }
=> {
2152 (ty
::AssociatedKind
::Method
, has_self
)
2154 hir
::AssociatedItemKind
::Type
=> (ty
::AssociatedKind
::Type
, false),
2157 // Trait impl items are always public.
2158 let public
= hir
::Public
;
2159 let vis
= if from_trait_impl { &public }
else { &impl_item_ref.vis }
;
2161 ty
::AssociatedItem
{
2162 name
: impl_item_ref
.name
,
2164 vis
: ty
::Visibility
::from_hir(vis
, impl_item_ref
.id
.node_id
, self),
2165 defaultness
: impl_item_ref
.defaultness
,
2167 container
: ImplContainer(parent_def_id
),
2168 method_has_self_argument
: has_self
2172 pub fn associated_item_def_ids(self, def_id
: DefId
) -> Rc
<Vec
<DefId
>> {
2173 self.associated_item_def_ids
.memoize(def_id
, || {
2174 if !def_id
.is_local() {
2175 return Rc
::new(self.sess
.cstore
.associated_item_def_ids(def_id
));
2178 let id
= self.map
.as_local_node_id(def_id
).unwrap();
2179 let item
= self.map
.expect_item(id
);
2180 let vec
: Vec
<_
> = match item
.node
{
2181 hir
::ItemTrait(.., ref trait_items
) => {
2183 .map(|trait_item
| trait_item
.id
)
2184 .map(|id
| self.map
.local_def_id(id
))
2187 hir
::ItemImpl(.., ref impl_item_refs
) => {
2188 impl_item_refs
.iter()
2189 .map(|impl_item_ref
| impl_item_ref
.id
)
2190 .map(|id
| self.map
.local_def_id(id
.node_id
))
2193 _
=> span_bug
!(item
.span
, "associated_item_def_ids: not impl or trait")
2199 #[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait.
2200 pub fn associated_items(self, def_id
: DefId
)
2201 -> impl Iterator
<Item
= ty
::AssociatedItem
> + 'a
{
2202 let def_ids
= self.associated_item_def_ids(def_id
);
2203 (0..def_ids
.len()).map(move |i
| self.associated_item(def_ids
[i
]))
2206 /// Returns the trait-ref corresponding to a given impl, or None if it is
2207 /// an inherent impl.
2208 pub fn impl_trait_ref(self, id
: DefId
) -> Option
<TraitRef
<'gcx
>> {
2209 lookup_locally_or_in_crate_store(
2210 "impl_trait_refs", id
, &self.impl_trait_refs
,
2211 || self.sess
.cstore
.impl_trait_ref(self.global_tcx(), id
))
2214 // Returns `ty::VariantDef` if `def` refers to a struct,
2215 // or variant or their constructors, panics otherwise.
2216 pub fn expect_variant_def(self, def
: Def
) -> &'tcx VariantDef
{
2218 Def
::Variant(did
) | Def
::VariantCtor(did
, ..) => {
2219 let enum_did
= self.parent_def_id(did
).unwrap();
2220 self.lookup_adt_def(enum_did
).variant_with_id(did
)
2222 Def
::Struct(did
) | Def
::Union(did
) => {
2223 self.lookup_adt_def(did
).struct_variant()
2225 Def
::StructCtor(ctor_did
, ..) => {
2226 let did
= self.parent_def_id(ctor_did
).expect("struct ctor has no parent");
2227 self.lookup_adt_def(did
).struct_variant()
2229 _
=> bug
!("expect_variant_def used with unexpected def {:?}", def
)
2233 pub fn def_key(self, id
: DefId
) -> ast_map
::DefKey
{
2235 self.map
.def_key(id
)
2237 self.sess
.cstore
.def_key(id
)
2241 /// Convert a `DefId` into its fully expanded `DefPath` (every
2242 /// `DefId` is really just an interned def-path).
2244 /// Note that if `id` is not local to this crate -- or is
2245 /// inlined into this crate -- the result will be a non-local
2248 /// This function is only safe to use when you are sure that the
2249 /// full def-path is accessible. Examples that are known to be
2250 /// safe are local def-ids or items; see `opt_def_path` for more
2252 pub fn def_path(self, id
: DefId
) -> ast_map
::DefPath
{
2253 self.opt_def_path(id
).unwrap_or_else(|| {
2254 bug
!("could not load def-path for {:?}", id
)
2258 /// Convert a `DefId` into its fully expanded `DefPath` (every
2259 /// `DefId` is really just an interned def-path).
2261 /// When going across crates, we do not save the full info for
2262 /// every cross-crate def-id, and hence we may not always be able
2263 /// to create a def-path. Therefore, this returns
2264 /// `Option<DefPath>` to cover that possibility. It will always
2265 /// return `Some` for local def-ids, however, as well as for
2266 /// items. The problems arise with "minor" def-ids like those
2267 /// associated with a pattern, `impl Trait`, or other internal
2270 /// Note that if `id` is not local to this crate -- or is
2271 /// inlined into this crate -- the result will be a non-local
2273 pub fn opt_def_path(self, id
: DefId
) -> Option
<ast_map
::DefPath
> {
2275 Some(self.map
.def_path(id
))
2277 self.sess
.cstore
.relative_def_path(id
)
2281 pub fn def_span(self, def_id
: DefId
) -> Span
{
2282 if let Some(id
) = self.map
.as_local_node_id(def_id
) {
2285 self.sess
.cstore
.def_span(&self.sess
, def_id
)
2289 pub fn item_name(self, id
: DefId
) -> ast
::Name
{
2290 if let Some(id
) = self.map
.as_local_node_id(id
) {
2292 } else if id
.index
== CRATE_DEF_INDEX
{
2293 self.sess
.cstore
.original_crate_name(id
.krate
)
2295 let def_key
= self.sess
.cstore
.def_key(id
);
2296 // The name of a StructCtor is that of its struct parent.
2297 if let ast_map
::DefPathData
::StructCtor
= def_key
.disambiguated_data
.data
{
2298 self.item_name(DefId
{
2300 index
: def_key
.parent
.unwrap()
2303 def_key
.disambiguated_data
.data
.get_opt_name().unwrap_or_else(|| {
2304 bug
!("item_name: no name for {:?}", self.def_path(id
));
2310 // If the given item is in an external crate, looks up its type and adds it to
2311 // the type cache. Returns the type parameters and type.
2312 pub fn item_type(self, did
: DefId
) -> Ty
<'gcx
> {
2313 lookup_locally_or_in_crate_store(
2314 "item_types", did
, &self.item_types
,
2315 || self.sess
.cstore
.item_type(self.global_tcx(), did
))
2318 /// Given the did of a trait, returns its canonical trait ref.
2319 pub fn lookup_trait_def(self, did
: DefId
) -> &'gcx TraitDef
{
2320 lookup_locally_or_in_crate_store(
2321 "trait_defs", did
, &self.trait_defs
,
2322 || self.alloc_trait_def(self.sess
.cstore
.trait_def(self.global_tcx(), did
))
2326 /// Given the did of an ADT, return a reference to its definition.
2327 pub fn lookup_adt_def(self, did
: DefId
) -> &'gcx AdtDef
{
2328 lookup_locally_or_in_crate_store(
2329 "adt_defs", did
, &self.adt_defs
,
2330 || self.sess
.cstore
.adt_def(self.global_tcx(), did
))
2333 /// Given the did of an item, returns its generics.
2334 pub fn item_generics(self, did
: DefId
) -> &'gcx Generics
<'gcx
> {
2335 lookup_locally_or_in_crate_store(
2336 "generics", did
, &self.generics
,
2337 || self.alloc_generics(self.sess
.cstore
.item_generics(self.global_tcx(), did
)))
2340 /// Given the did of an item, returns its full set of predicates.
2341 pub fn item_predicates(self, did
: DefId
) -> GenericPredicates
<'gcx
> {
2342 lookup_locally_or_in_crate_store(
2343 "predicates", did
, &self.predicates
,
2344 || self.sess
.cstore
.item_predicates(self.global_tcx(), did
))
2347 /// Given the did of a trait, returns its superpredicates.
2348 pub fn item_super_predicates(self, did
: DefId
) -> GenericPredicates
<'gcx
> {
2349 lookup_locally_or_in_crate_store(
2350 "super_predicates", did
, &self.super_predicates
,
2351 || self.sess
.cstore
.item_super_predicates(self.global_tcx(), did
))
2354 /// Given the did of an item, returns its MIR, borrowed immutably.
2355 pub fn item_mir(self, did
: DefId
) -> Ref
<'gcx
, Mir
<'gcx
>> {
2356 lookup_locally_or_in_crate_store("mir_map", did
, &self.mir_map
, || {
2357 let mir
= self.sess
.cstore
.get_item_mir(self.global_tcx(), did
);
2358 let mir
= self.alloc_mir(mir
);
2360 // Perma-borrow MIR from extern crates to prevent mutation.
2361 mem
::forget(mir
.borrow());
2367 /// If `type_needs_drop` returns true, then `ty` is definitely
2368 /// non-copy and *might* have a destructor attached; if it returns
2369 /// false, then `ty` definitely has no destructor (i.e. no drop glue).
2371 /// (Note that this implies that if `ty` has a destructor attached,
2372 /// then `type_needs_drop` will definitely return `true` for `ty`.)
2373 pub fn type_needs_drop_given_env(self,
2375 param_env
: &ty
::ParameterEnvironment
<'gcx
>) -> bool
{
2376 // Issue #22536: We first query type_moves_by_default. It sees a
2377 // normalized version of the type, and therefore will definitely
2378 // know whether the type implements Copy (and thus needs no
2379 // cleanup/drop/zeroing) ...
2380 let tcx
= self.global_tcx();
2381 let implements_copy
= !ty
.moves_by_default(tcx
, param_env
, DUMMY_SP
);
2383 if implements_copy { return false; }
2385 // ... (issue #22536 continued) but as an optimization, still use
2386 // prior logic of asking if the `needs_drop` bit is set; we need
2387 // not zero non-Copy types if they have no destructor.
2389 // FIXME(#22815): Note that calling `ty::type_contents` is a
2390 // conservative heuristic; it may report that `needs_drop` is set
2391 // when actual type does not actually have a destructor associated
2392 // with it. But since `ty` absolutely did not have the `Copy`
2393 // bound attached (see above), it is sound to treat it as having a
2394 // destructor (e.g. zero its memory on move).
2396 let contents
= ty
.type_contents(tcx
);
2397 debug
!("type_needs_drop ty={:?} contents={:?}", ty
, contents
);
2398 contents
.needs_drop(tcx
)
2401 /// Get the attributes of a definition.
2402 pub fn get_attrs(self, did
: DefId
) -> Cow
<'gcx
, [ast
::Attribute
]> {
2403 if let Some(id
) = self.map
.as_local_node_id(did
) {
2404 Cow
::Borrowed(self.map
.attrs(id
))
2406 Cow
::Owned(self.sess
.cstore
.item_attrs(did
))
2410 /// Determine whether an item is annotated with an attribute
2411 pub fn has_attr(self, did
: DefId
, attr
: &str) -> bool
{
2412 self.get_attrs(did
).iter().any(|item
| item
.check_name(attr
))
2415 /// Determine whether an item is annotated with `#[repr(packed)]`
2416 pub fn lookup_packed(self, did
: DefId
) -> bool
{
2417 self.lookup_repr_hints(did
).contains(&attr
::ReprPacked
)
2420 /// Determine whether an item is annotated with `#[simd]`
2421 pub fn lookup_simd(self, did
: DefId
) -> bool
{
2422 self.has_attr(did
, "simd")
2423 || self.lookup_repr_hints(did
).contains(&attr
::ReprSimd
)
2426 pub fn item_variances(self, item_id
: DefId
) -> Rc
<Vec
<ty
::Variance
>> {
2427 lookup_locally_or_in_crate_store(
2428 "item_variance_map", item_id
, &self.item_variance_map
,
2429 || Rc
::new(self.sess
.cstore
.item_variances(item_id
)))
2432 pub fn trait_has_default_impl(self, trait_def_id
: DefId
) -> bool
{
2433 self.populate_implementations_for_trait_if_necessary(trait_def_id
);
2435 let def
= self.lookup_trait_def(trait_def_id
);
2436 def
.flags
.get().intersects(TraitFlags
::HAS_DEFAULT_IMPL
)
2439 /// Records a trait-to-implementation mapping.
2440 pub fn record_trait_has_default_impl(self, trait_def_id
: DefId
) {
2441 let def
= self.lookup_trait_def(trait_def_id
);
2442 def
.flags
.set(def
.flags
.get() | TraitFlags
::HAS_DEFAULT_IMPL
)
2445 /// Populates the type context with all the inherent implementations for
2446 /// the given type if necessary.
2447 pub fn populate_inherent_implementations_for_type_if_necessary(self,
2449 if type_id
.is_local() {
2453 // The type is not local, hence we are reading this out of
2454 // metadata and don't need to track edges.
2455 let _ignore
= self.dep_graph
.in_ignore();
2457 if self.populated_external_types
.borrow().contains(&type_id
) {
2461 debug
!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}",
2464 let inherent_impls
= self.sess
.cstore
.inherent_implementations_for_type(type_id
);
2466 self.inherent_impls
.borrow_mut().insert(type_id
, inherent_impls
);
2467 self.populated_external_types
.borrow_mut().insert(type_id
);
2470 /// Populates the type context with all the implementations for the given
2471 /// trait if necessary.
2472 pub fn populate_implementations_for_trait_if_necessary(self, trait_id
: DefId
) {
2473 if trait_id
.is_local() {
2477 // The type is not local, hence we are reading this out of
2478 // metadata and don't need to track edges.
2479 let _ignore
= self.dep_graph
.in_ignore();
2481 let def
= self.lookup_trait_def(trait_id
);
2482 if def
.flags
.get().intersects(TraitFlags
::IMPLS_VALID
) {
2486 debug
!("populate_implementations_for_trait_if_necessary: searching for {:?}", def
);
2488 if self.sess
.cstore
.is_defaulted_trait(trait_id
) {
2489 self.record_trait_has_default_impl(trait_id
);
2492 for impl_def_id
in self.sess
.cstore
.implementations_of_trait(Some(trait_id
)) {
2493 let trait_ref
= self.impl_trait_ref(impl_def_id
).unwrap();
2495 // Record the trait->implementation mapping.
2496 let parent
= self.sess
.cstore
.impl_parent(impl_def_id
).unwrap_or(trait_id
);
2497 def
.record_remote_impl(self, impl_def_id
, trait_ref
, parent
);
2500 def
.flags
.set(def
.flags
.get() | TraitFlags
::IMPLS_VALID
);
2503 pub fn closure_kind(self, def_id
: DefId
) -> ty
::ClosureKind
{
2504 // If this is a local def-id, it should be inserted into the
2505 // tables by typeck; else, it will be retreived from
2506 // the external crate metadata.
2507 if let Some(&kind
) = self.tables
.borrow().closure_kinds
.get(&def_id
) {
2511 let kind
= self.sess
.cstore
.closure_kind(def_id
);
2512 self.tables
.borrow_mut().closure_kinds
.insert(def_id
, kind
);
2516 pub fn closure_type(self,
2518 substs
: ClosureSubsts
<'tcx
>)
2519 -> ty
::ClosureTy
<'tcx
>
2521 // If this is a local def-id, it should be inserted into the
2522 // tables by typeck; else, it will be retreived from
2523 // the external crate metadata.
2524 if let Some(ty
) = self.tables
.borrow().closure_tys
.get(&def_id
) {
2525 return ty
.subst(self, substs
.substs
);
2528 let ty
= self.sess
.cstore
.closure_ty(self.global_tcx(), def_id
);
2529 self.tables
.borrow_mut().closure_tys
.insert(def_id
, ty
.clone());
2530 ty
.subst(self, substs
.substs
)
2533 /// Given the def_id of an impl, return the def_id of the trait it implements.
2534 /// If it implements no trait, return `None`.
2535 pub fn trait_id_of_impl(self, def_id
: DefId
) -> Option
<DefId
> {
2536 self.impl_trait_ref(def_id
).map(|tr
| tr
.def_id
)
2539 /// If the given def ID describes a method belonging to an impl, return the
2540 /// ID of the impl that the method belongs to. Otherwise, return `None`.
2541 pub fn impl_of_method(self, def_id
: DefId
) -> Option
<DefId
> {
2542 if def_id
.krate
!= LOCAL_CRATE
{
2543 return self.sess
.cstore
.associated_item(def_id
)
2545 match item
.container
{
2546 TraitContainer(_
) => None
,
2547 ImplContainer(def_id
) => Some(def_id
),
2551 match self.associated_items
.borrow().get(&def_id
).cloned() {
2552 Some(trait_item
) => {
2553 match trait_item
.container
{
2554 TraitContainer(_
) => None
,
2555 ImplContainer(def_id
) => Some(def_id
),
2562 /// If the given def ID describes an item belonging to a trait,
2563 /// return the ID of the trait that the trait item belongs to.
2564 /// Otherwise, return `None`.
2565 pub fn trait_of_item(self, def_id
: DefId
) -> Option
<DefId
> {
2566 if def_id
.krate
!= LOCAL_CRATE
{
2567 return self.sess
.cstore
.trait_of_item(def_id
);
2569 match self.associated_items
.borrow().get(&def_id
) {
2570 Some(associated_item
) => {
2571 match associated_item
.container
{
2572 TraitContainer(def_id
) => Some(def_id
),
2573 ImplContainer(_
) => None
2580 /// Construct a parameter environment suitable for static contexts or other contexts where there
2581 /// are no free type/lifetime parameters in scope.
2582 pub fn empty_parameter_environment(self) -> ParameterEnvironment
<'tcx
> {
2584 // for an empty parameter environment, there ARE no free
2585 // regions, so it shouldn't matter what we use for the free id
2586 let free_id_outlive
= self.region_maps
.node_extent(ast
::DUMMY_NODE_ID
);
2587 ty
::ParameterEnvironment
{
2588 free_substs
: self.intern_substs(&[]),
2589 caller_bounds
: Vec
::new(),
2590 implicit_region_bound
: self.mk_region(ty
::ReEmpty
),
2591 free_id_outlive
: free_id_outlive
,
2592 is_copy_cache
: RefCell
::new(FxHashMap()),
2593 is_sized_cache
: RefCell
::new(FxHashMap()),
2597 /// Constructs and returns a substitution that can be applied to move from
2598 /// the "outer" view of a type or method to the "inner" view.
2599 /// In general, this means converting from bound parameters to
2600 /// free parameters. Since we currently represent bound/free type
2601 /// parameters in the same way, this only has an effect on regions.
2602 pub fn construct_free_substs(self, def_id
: DefId
,
2603 free_id_outlive
: CodeExtent
)
2604 -> &'gcx Substs
<'gcx
> {
2606 let substs
= Substs
::for_item(self.global_tcx(), def_id
, |def
, _
| {
2607 // map bound 'a => free 'a
2608 self.global_tcx().mk_region(ReFree(FreeRegion
{
2609 scope
: free_id_outlive
,
2610 bound_region
: def
.to_bound_region()
2614 self.global_tcx().mk_param_from_def(def
)
2617 debug
!("construct_parameter_environment: {:?}", substs
);
2621 /// See `ParameterEnvironment` struct def'n for details.
2622 /// If you were using `free_id: NodeId`, you might try `self.region_maps.item_extent(free_id)`
2623 /// for the `free_id_outlive` parameter. (But note that this is not always quite right.)
2624 pub fn construct_parameter_environment(self,
2627 free_id_outlive
: CodeExtent
)
2628 -> ParameterEnvironment
<'gcx
>
2631 // Construct the free substs.
2634 let free_substs
= self.construct_free_substs(def_id
, free_id_outlive
);
2637 // Compute the bounds on Self and the type parameters.
2640 let tcx
= self.global_tcx();
2641 let generic_predicates
= tcx
.item_predicates(def_id
);
2642 let bounds
= generic_predicates
.instantiate(tcx
, free_substs
);
2643 let bounds
= tcx
.liberate_late_bound_regions(free_id_outlive
, &ty
::Binder(bounds
));
2644 let predicates
= bounds
.predicates
;
2646 // Finally, we have to normalize the bounds in the environment, in
2647 // case they contain any associated type projections. This process
2648 // can yield errors if the put in illegal associated types, like
2649 // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
2650 // report these errors right here; this doesn't actually feel
2651 // right to me, because constructing the environment feels like a
2652 // kind of a "idempotent" action, but I'm not sure where would be
2653 // a better place. In practice, we construct environments for
2654 // every fn once during type checking, and we'll abort if there
2655 // are any errors at that point, so after type checking you can be
2656 // sure that this will succeed without errors anyway.
2659 let unnormalized_env
= ty
::ParameterEnvironment
{
2660 free_substs
: free_substs
,
2661 implicit_region_bound
: tcx
.mk_region(ty
::ReScope(free_id_outlive
)),
2662 caller_bounds
: predicates
,
2663 free_id_outlive
: free_id_outlive
,
2664 is_copy_cache
: RefCell
::new(FxHashMap()),
2665 is_sized_cache
: RefCell
::new(FxHashMap()),
2668 let cause
= traits
::ObligationCause
::misc(span
, free_id_outlive
.node_id(&self.region_maps
));
2669 traits
::normalize_param_env_or_error(tcx
, unnormalized_env
, cause
)
2672 pub fn node_scope_region(self, id
: NodeId
) -> &'tcx Region
{
2673 self.mk_region(ty
::ReScope(self.region_maps
.node_extent(id
)))
2676 pub fn visit_all_item_likes_in_krate
<V
,F
>(self,
2679 where F
: FnMut(DefId
) -> DepNode
<DefId
>, V
: ItemLikeVisitor
<'gcx
>
2681 dep_graph
::visit_all_item_likes_in_krate(self.global_tcx(), dep_node_fn
, visitor
);
2684 /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
2685 /// with the name of the crate containing the impl.
2686 pub fn span_of_impl(self, impl_did
: DefId
) -> Result
<Span
, Symbol
> {
2687 if impl_did
.is_local() {
2688 let node_id
= self.map
.as_local_node_id(impl_did
).unwrap();
2689 Ok(self.map
.span(node_id
))
2691 Err(self.sess
.cstore
.crate_name(impl_did
.krate
))
2696 impl<'a
, 'gcx
, 'tcx
> TyCtxt
<'a
, 'gcx
, 'tcx
> {
2697 pub fn with_freevars
<T
, F
>(self, fid
: NodeId
, f
: F
) -> T
where
2698 F
: FnOnce(&[hir
::Freevar
]) -> T
,
2700 match self.freevars
.borrow().get(&fid
) {
2702 Some(d
) => f(&d
[..])