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::ImplOrTraitItemId::*;
12 pub use self::ClosureKind::*;
13 pub use self::Variance::*;
14 pub use self::AutoAdjustment::*;
15 pub use self::Representability::*;
16 pub use self::AutoRef::*;
17 pub use self::DtorKind::*;
18 pub use self::ExplicitSelfCategory::*;
19 pub use self::ImplOrTraitItemContainer::*;
20 pub use self::BorrowKind::*;
21 pub use self::ImplOrTraitItem::*;
22 pub use self::IntVarValue::*;
23 pub use self::CopyImplementationError::*;
24 pub use self::LvaluePreference::*;
27 use front::map as ast_map;
28 use front::map::LinkedPath;
29 use metadata::csearch;
31 use middle::const_eval::{self, ConstVal, ErrKind};
32 use middle::const_eval::EvalHint::UncheckedExprHint;
33 use middle::def::{self, ExportMap};
34 use middle::def_id::{DefId, LOCAL_CRATE};
35 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
38 use middle::subst::{self, ParamSpace, Subst, Substs, VecPerParamSpace};
41 use middle::ty::fold::TypeFolder;
42 use middle::ty::walk::TypeWalker;
43 use util::common::memoized;
44 use util::nodemap::{NodeMap, NodeSet, DefIdMap};
45 use util::nodemap::FnvHashMap;
46 use util::num::ToPrimitive;
48 use std::borrow::{Borrow, Cow};
49 use std::cell::{Cell, RefCell};
51 use std::hash::{Hash, SipHasher, Hasher};
55 use std::vec::IntoIter;
56 use std::collections::{HashMap, HashSet};
57 use syntax::ast::{self, CrateNum, Name, NodeId};
58 use syntax::codemap::Span;
59 use syntax::parse::token::{InternedString, special_idents};
62 use rustc_front::hir::{ItemImpl, ItemTrait};
63 use rustc_front::hir::{MutImmutable, MutMutable, Visibility};
64 use rustc_front::attr::{self, AttrMetaMethods, SignedInt, UnsignedInt};
66 pub use self::sty::{Binder, DebruijnIndex};
67 pub use self::sty::{BuiltinBound, BuiltinBounds, ExistentialBounds};
68 pub use self::sty::{BareFnTy, FnSig, PolyFnSig, FnOutput, PolyFnOutput};
69 pub use self::sty::{ClosureTy, InferTy, ParamTy, ProjectionTy, TraitTy};
70 pub use self::sty::{ClosureSubsts, TypeAndMut};
71 pub use self::sty::{TraitRef, TypeVariants, PolyTraitRef};
72 pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
73 pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid};
74 pub use self::sty::BoundRegion::*;
75 pub use self::sty::FnOutput::*;
76 pub use self::sty::InferTy::*;
77 pub use self::sty::Region::*;
78 pub use self::sty::TypeVariants::*;
80 pub use self::sty::BuiltinBound::Send as BoundSend;
81 pub use self::sty::BuiltinBound::Sized as BoundSized;
82 pub use self::sty::BuiltinBound::Copy as BoundCopy;
83 pub use self::sty::BuiltinBound::Sync as BoundSync;
85 pub use self::contents::TypeContents;
86 pub use self::context::{ctxt, tls};
87 pub use self::context::{CtxtArenas, Lift, Tables};
103 mod structural_impls;
108 pub const INITIAL_DISCRIMINANT_VALUE: Disr = 0;
112 /// The complete set of all analyses described in this module. This is
113 /// produced by the driver and fed to trans and later passes.
114 pub struct CrateAnalysis {
115 pub export_map: ExportMap,
116 pub exported_items: middle::privacy::ExportedItems,
117 pub public_items: middle::privacy::PublicItems,
118 pub reachable: NodeSet,
120 pub glob_map: Option<GlobMap>,
124 #[derive(Copy, Clone)]
131 pub fn is_present(&self) -> bool {
133 TraitDtor(..) => true,
138 pub fn has_drop_flag(&self) -> bool {
141 &TraitDtor(flag) => flag
146 pub trait IntTypeExt {
147 fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx>;
148 fn i64_to_disr(&self, val: i64) -> Option<Disr>;
149 fn u64_to_disr(&self, val: u64) -> Option<Disr>;
150 fn disr_incr(&self, val: Disr) -> Option<Disr>;
151 fn disr_string(&self, val: Disr) -> String;
152 fn disr_wrap_incr(&self, val: Option<Disr>) -> Disr;
155 impl IntTypeExt for attr::IntType {
156 fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx> {
158 SignedInt(hir::TyI8) => cx.types.i8,
159 SignedInt(hir::TyI16) => cx.types.i16,
160 SignedInt(hir::TyI32) => cx.types.i32,
161 SignedInt(hir::TyI64) => cx.types.i64,
162 SignedInt(hir::TyIs) => cx.types.isize,
163 UnsignedInt(hir::TyU8) => cx.types.u8,
164 UnsignedInt(hir::TyU16) => cx.types.u16,
165 UnsignedInt(hir::TyU32) => cx.types.u32,
166 UnsignedInt(hir::TyU64) => cx.types.u64,
167 UnsignedInt(hir::TyUs) => cx.types.usize,
171 fn i64_to_disr(&self, val: i64) -> Option<Disr> {
173 SignedInt(hir::TyI8) => val.to_i8() .map(|v| v as Disr),
174 SignedInt(hir::TyI16) => val.to_i16() .map(|v| v as Disr),
175 SignedInt(hir::TyI32) => val.to_i32() .map(|v| v as Disr),
176 SignedInt(hir::TyI64) => val.to_i64() .map(|v| v as Disr),
177 UnsignedInt(hir::TyU8) => val.to_u8() .map(|v| v as Disr),
178 UnsignedInt(hir::TyU16) => val.to_u16() .map(|v| v as Disr),
179 UnsignedInt(hir::TyU32) => val.to_u32() .map(|v| v as Disr),
180 UnsignedInt(hir::TyU64) => val.to_u64() .map(|v| v as Disr),
182 UnsignedInt(hir::TyUs) |
183 SignedInt(hir::TyIs) => unreachable!(),
187 fn u64_to_disr(&self, val: u64) -> Option<Disr> {
189 SignedInt(hir::TyI8) => val.to_i8() .map(|v| v as Disr),
190 SignedInt(hir::TyI16) => val.to_i16() .map(|v| v as Disr),
191 SignedInt(hir::TyI32) => val.to_i32() .map(|v| v as Disr),
192 SignedInt(hir::TyI64) => val.to_i64() .map(|v| v as Disr),
193 UnsignedInt(hir::TyU8) => val.to_u8() .map(|v| v as Disr),
194 UnsignedInt(hir::TyU16) => val.to_u16() .map(|v| v as Disr),
195 UnsignedInt(hir::TyU32) => val.to_u32() .map(|v| v as Disr),
196 UnsignedInt(hir::TyU64) => val.to_u64() .map(|v| v as Disr),
198 UnsignedInt(hir::TyUs) |
199 SignedInt(hir::TyIs) => unreachable!(),
203 fn disr_incr(&self, val: Disr) -> Option<Disr> {
205 ($e:expr) => { $e.and_then(|v|v.checked_add(1)).map(|v| v as Disr) }
208 // SignedInt repr means we *want* to reinterpret the bits
209 // treating the highest bit of Disr as a sign-bit, so
210 // cast to i64 before range-checking.
211 SignedInt(hir::TyI8) => add1!((val as i64).to_i8()),
212 SignedInt(hir::TyI16) => add1!((val as i64).to_i16()),
213 SignedInt(hir::TyI32) => add1!((val as i64).to_i32()),
214 SignedInt(hir::TyI64) => add1!(Some(val as i64)),
216 UnsignedInt(hir::TyU8) => add1!(val.to_u8()),
217 UnsignedInt(hir::TyU16) => add1!(val.to_u16()),
218 UnsignedInt(hir::TyU32) => add1!(val.to_u32()),
219 UnsignedInt(hir::TyU64) => add1!(Some(val)),
221 UnsignedInt(hir::TyUs) |
222 SignedInt(hir::TyIs) => unreachable!(),
226 // This returns a String because (1.) it is only used for
227 // rendering an error message and (2.) a string can represent the
228 // full range from `i64::MIN` through `u64::MAX`.
229 fn disr_string(&self, val: Disr) -> String {
231 SignedInt(hir::TyI8) => format!("{}", val as i8 ),
232 SignedInt(hir::TyI16) => format!("{}", val as i16),
233 SignedInt(hir::TyI32) => format!("{}", val as i32),
234 SignedInt(hir::TyI64) => format!("{}", val as i64),
235 UnsignedInt(hir::TyU8) => format!("{}", val as u8 ),
236 UnsignedInt(hir::TyU16) => format!("{}", val as u16),
237 UnsignedInt(hir::TyU32) => format!("{}", val as u32),
238 UnsignedInt(hir::TyU64) => format!("{}", val as u64),
240 UnsignedInt(hir::TyUs) |
241 SignedInt(hir::TyIs) => unreachable!(),
245 fn disr_wrap_incr(&self, val: Option<Disr>) -> Disr {
247 ($e:expr) => { ($e).wrapping_add(1) as Disr }
249 let val = val.unwrap_or(ty::INITIAL_DISCRIMINANT_VALUE);
251 SignedInt(hir::TyI8) => add1!(val as i8 ),
252 SignedInt(hir::TyI16) => add1!(val as i16),
253 SignedInt(hir::TyI32) => add1!(val as i32),
254 SignedInt(hir::TyI64) => add1!(val as i64),
255 UnsignedInt(hir::TyU8) => add1!(val as u8 ),
256 UnsignedInt(hir::TyU16) => add1!(val as u16),
257 UnsignedInt(hir::TyU32) => add1!(val as u32),
258 UnsignedInt(hir::TyU64) => add1!(val as u64),
260 UnsignedInt(hir::TyUs) |
261 SignedInt(hir::TyIs) => unreachable!(),
266 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
267 pub enum ImplOrTraitItemContainer {
268 TraitContainer(DefId),
269 ImplContainer(DefId),
272 impl ImplOrTraitItemContainer {
273 pub fn id(&self) -> DefId {
275 TraitContainer(id) => id,
276 ImplContainer(id) => id,
282 pub enum ImplOrTraitItem<'tcx> {
283 ConstTraitItem(Rc<AssociatedConst<'tcx>>),
284 MethodTraitItem(Rc<Method<'tcx>>),
285 TypeTraitItem(Rc<AssociatedType<'tcx>>),
288 impl<'tcx> ImplOrTraitItem<'tcx> {
289 fn id(&self) -> ImplOrTraitItemId {
291 ConstTraitItem(ref associated_const) => {
292 ConstTraitItemId(associated_const.def_id)
294 MethodTraitItem(ref method) => MethodTraitItemId(method.def_id),
295 TypeTraitItem(ref associated_type) => {
296 TypeTraitItemId(associated_type.def_id)
301 pub fn def_id(&self) -> DefId {
303 ConstTraitItem(ref associated_const) => associated_const.def_id,
304 MethodTraitItem(ref method) => method.def_id,
305 TypeTraitItem(ref associated_type) => associated_type.def_id,
309 pub fn name(&self) -> Name {
311 ConstTraitItem(ref associated_const) => associated_const.name,
312 MethodTraitItem(ref method) => method.name,
313 TypeTraitItem(ref associated_type) => associated_type.name,
317 pub fn vis(&self) -> hir::Visibility {
319 ConstTraitItem(ref associated_const) => associated_const.vis,
320 MethodTraitItem(ref method) => method.vis,
321 TypeTraitItem(ref associated_type) => associated_type.vis,
325 pub fn container(&self) -> ImplOrTraitItemContainer {
327 ConstTraitItem(ref associated_const) => associated_const.container,
328 MethodTraitItem(ref method) => method.container,
329 TypeTraitItem(ref associated_type) => associated_type.container,
333 pub fn as_opt_method(&self) -> Option<Rc<Method<'tcx>>> {
335 MethodTraitItem(ref m) => Some((*m).clone()),
341 #[derive(Clone, Copy, Debug)]
342 pub enum ImplOrTraitItemId {
343 ConstTraitItemId(DefId),
344 MethodTraitItemId(DefId),
345 TypeTraitItemId(DefId),
348 impl ImplOrTraitItemId {
349 pub fn def_id(&self) -> DefId {
351 ConstTraitItemId(def_id) => def_id,
352 MethodTraitItemId(def_id) => def_id,
353 TypeTraitItemId(def_id) => def_id,
358 #[derive(Clone, Debug)]
359 pub struct Method<'tcx> {
361 pub generics: Generics<'tcx>,
362 pub predicates: GenericPredicates<'tcx>,
363 pub fty: BareFnTy<'tcx>,
364 pub explicit_self: ExplicitSelfCategory,
365 pub vis: hir::Visibility,
367 pub container: ImplOrTraitItemContainer,
369 // If this method is provided, we need to know where it came from
370 pub provided_source: Option<DefId>
373 impl<'tcx> Method<'tcx> {
374 pub fn new(name: Name,
375 generics: ty::Generics<'tcx>,
376 predicates: GenericPredicates<'tcx>,
378 explicit_self: ExplicitSelfCategory,
379 vis: hir::Visibility,
381 container: ImplOrTraitItemContainer,
382 provided_source: Option<DefId>)
387 predicates: predicates,
389 explicit_self: explicit_self,
392 container: container,
393 provided_source: provided_source
397 pub fn container_id(&self) -> DefId {
398 match self.container {
399 TraitContainer(id) => id,
400 ImplContainer(id) => id,
405 #[derive(Clone, Copy, Debug)]
406 pub struct AssociatedConst<'tcx> {
409 pub vis: hir::Visibility,
411 pub container: ImplOrTraitItemContainer,
412 pub default: Option<DefId>,
415 #[derive(Clone, Copy, Debug)]
416 pub struct AssociatedType<'tcx> {
418 pub ty: Option<Ty<'tcx>>,
419 pub vis: hir::Visibility,
421 pub container: ImplOrTraitItemContainer,
424 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable)]
425 pub struct ItemVariances {
426 pub types: VecPerParamSpace<Variance>,
427 pub regions: VecPerParamSpace<Variance>,
430 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Copy)]
432 Covariant, // T<A> <: T<B> iff A <: B -- e.g., function return type
433 Invariant, // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
434 Contravariant, // T<A> <: T<B> iff B <: A -- e.g., function param type
435 Bivariant, // T<A> <: T<B> -- e.g., unused type parameter
438 #[derive(Copy, Clone)]
439 pub enum AutoAdjustment<'tcx> {
440 AdjustReifyFnPointer, // go from a fn-item type to a fn-pointer type
441 AdjustUnsafeFnPointer, // go from a safe fn pointer to an unsafe fn pointer
442 AdjustDerefRef(AutoDerefRef<'tcx>),
445 /// Represents coercing a pointer to a different kind of pointer - where 'kind'
446 /// here means either or both of raw vs borrowed vs unique and fat vs thin.
448 /// We transform pointers by following the following steps in order:
449 /// 1. Deref the pointer `self.autoderefs` times (may be 0).
450 /// 2. If `autoref` is `Some(_)`, then take the address and produce either a
451 /// `&` or `*` pointer.
452 /// 3. If `unsize` is `Some(_)`, then apply the unsize transformation,
453 /// which will do things like convert thin pointers to fat
454 /// pointers, or convert structs containing thin pointers to
455 /// structs containing fat pointers, or convert between fat
456 /// pointers. We don't store the details of how the transform is
457 /// done (in fact, we don't know that, because it might depend on
458 /// the precise type parameters). We just store the target
459 /// type. Trans figures out what has to be done at monomorphization
460 /// time based on the precise source/target type at hand.
462 /// To make that more concrete, here are some common scenarios:
464 /// 1. The simplest cases are where the pointer is not adjusted fat vs thin.
465 /// Here the pointer will be dereferenced N times (where a dereference can
466 /// happen to to raw or borrowed pointers or any smart pointer which implements
467 /// Deref, including Box<_>). The number of dereferences is given by
468 /// `autoderefs`. It can then be auto-referenced zero or one times, indicated
469 /// by `autoref`, to either a raw or borrowed pointer. In these cases unsize is
472 /// 2. A thin-to-fat coercon involves unsizing the underlying data. We start
473 /// with a thin pointer, deref a number of times, unsize the underlying data,
474 /// then autoref. The 'unsize' phase may change a fixed length array to a
475 /// dynamically sized one, a concrete object to a trait object, or statically
476 /// sized struct to a dyncamically sized one. E.g., &[i32; 4] -> &[i32] is
481 /// autoderefs: 1, // &[i32; 4] -> [i32; 4]
482 /// autoref: Some(AutoPtr), // [i32] -> &[i32]
483 /// unsize: Some([i32]), // [i32; 4] -> [i32]
487 /// Note that for a struct, the 'deep' unsizing of the struct is not recorded.
488 /// E.g., `struct Foo<T> { x: T }` we can coerce &Foo<[i32; 4]> to &Foo<[i32]>
489 /// The autoderef and -ref are the same as in the above example, but the type
490 /// stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about
491 /// the underlying conversions from `[i32; 4]` to `[i32]`.
493 /// 3. Coercing a `Box<T>` to `Box<Trait>` is an interesting special case. In
494 /// that case, we have the pointer we need coming in, so there are no
495 /// autoderefs, and no autoref. Instead we just do the `Unsize` transformation.
496 /// At some point, of course, `Box` should move out of the compiler, in which
497 /// case this is analogous to transformating a struct. E.g., Box<[i32; 4]> ->
498 /// Box<[i32]> is represented by:
504 /// unsize: Some(Box<[i32]>),
507 #[derive(Copy, Clone)]
508 pub struct AutoDerefRef<'tcx> {
509 /// Step 1. Apply a number of dereferences, producing an lvalue.
510 pub autoderefs: usize,
512 /// Step 2. Optionally produce a pointer/reference from the value.
513 pub autoref: Option<AutoRef<'tcx>>,
515 /// Step 3. Unsize a pointer/reference value, e.g. `&[T; n]` to
516 /// `&[T]`. The stored type is the target pointer type. Note that
517 /// the source could be a thin or fat pointer.
518 pub unsize: Option<Ty<'tcx>>,
521 #[derive(Copy, Clone, PartialEq, Debug)]
522 pub enum AutoRef<'tcx> {
523 /// Convert from T to &T.
524 AutoPtr(&'tcx Region, hir::Mutability),
526 /// Convert from T to *T.
527 /// Value to thin pointer.
528 AutoUnsafe(hir::Mutability),
531 #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
532 pub enum CustomCoerceUnsized {
533 /// Records the index of the field being coerced.
537 #[derive(Clone, Copy, Debug)]
538 pub struct MethodCallee<'tcx> {
539 /// Impl method ID, for inherent methods, or trait method ID, otherwise.
542 pub substs: &'tcx subst::Substs<'tcx>
545 /// With method calls, we store some extra information in
546 /// side tables (i.e method_map). We use
547 /// MethodCall as a key to index into these tables instead of
548 /// just directly using the expression's NodeId. The reason
549 /// for this being that we may apply adjustments (coercions)
550 /// with the resulting expression also needing to use the
551 /// side tables. The problem with this is that we don't
552 /// assign a separate NodeId to this new expression
553 /// and so it would clash with the base expression if both
554 /// needed to add to the side tables. Thus to disambiguate
555 /// we also keep track of whether there's an adjustment in
557 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
558 pub struct MethodCall {
564 pub fn expr(id: NodeId) -> MethodCall {
571 pub fn autoderef(expr_id: NodeId, autoderef: u32) -> MethodCall {
574 autoderef: 1 + autoderef
579 // maps from an expression id that corresponds to a method call to the details
580 // of the method to be invoked
581 pub type MethodMap<'tcx> = FnvHashMap<MethodCall, MethodCallee<'tcx>>;
583 // Contains information needed to resolve types and (in the future) look up
584 // the types of AST nodes.
585 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
586 pub struct CReaderCacheKey {
592 /// A restriction that certain types must be the same size. The use of
593 /// `transmute` gives rise to these restrictions. These generally
594 /// cannot be checked until trans; therefore, each call to `transmute`
595 /// will push one or more such restriction into the
596 /// `transmute_restrictions` vector during `intrinsicck`. They are
597 /// then checked during `trans` by the fn `check_intrinsics`.
598 #[derive(Copy, Clone)]
599 pub struct TransmuteRestriction<'tcx> {
600 /// The span whence the restriction comes.
603 /// The type being transmuted from.
604 pub original_from: Ty<'tcx>,
606 /// The type being transmuted to.
607 pub original_to: Ty<'tcx>,
609 /// The type being transmuted from, with all type parameters
610 /// substituted for an arbitrary representative. Not to be shown
612 pub substituted_from: Ty<'tcx>,
614 /// The type being transmuted to, with all type parameters
615 /// substituted for an arbitrary representative. Not to be shown
617 pub substituted_to: Ty<'tcx>,
619 /// NodeId of the transmute intrinsic.
623 /// Describes the fragment-state associated with a NodeId.
625 /// Currently only unfragmented paths have entries in the table,
626 /// but longer-term this enum is expected to expand to also
627 /// include data for fragmented paths.
628 #[derive(Copy, Clone, Debug)]
629 pub enum FragmentInfo {
630 Moved { var: NodeId, move_expr: NodeId },
631 Assigned { var: NodeId, assign_expr: NodeId, assignee_id: NodeId },
634 // Flags that we track on types. These flags are propagated upwards
635 // through the type during type construction, so that we can quickly
636 // check whether the type has various kinds of types in it without
637 // recursing over the type itself.
639 flags TypeFlags: u32 {
640 const HAS_PARAMS = 1 << 0,
641 const HAS_SELF = 1 << 1,
642 const HAS_TY_INFER = 1 << 2,
643 const HAS_RE_INFER = 1 << 3,
644 const HAS_RE_EARLY_BOUND = 1 << 4,
645 const HAS_FREE_REGIONS = 1 << 5,
646 const HAS_TY_ERR = 1 << 6,
647 const HAS_PROJECTION = 1 << 7,
648 const HAS_TY_CLOSURE = 1 << 8,
650 // true if there are "names" of types and regions and so forth
651 // that are local to a particular fn
652 const HAS_LOCAL_NAMES = 1 << 9,
654 const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits |
655 TypeFlags::HAS_SELF.bits |
656 TypeFlags::HAS_RE_EARLY_BOUND.bits,
658 // Flags representing the nominal content of a type,
659 // computed by FlagsComputation. If you add a new nominal
660 // flag, it should be added here too.
661 const NOMINAL_FLAGS = TypeFlags::HAS_PARAMS.bits |
662 TypeFlags::HAS_SELF.bits |
663 TypeFlags::HAS_TY_INFER.bits |
664 TypeFlags::HAS_RE_INFER.bits |
665 TypeFlags::HAS_RE_EARLY_BOUND.bits |
666 TypeFlags::HAS_FREE_REGIONS.bits |
667 TypeFlags::HAS_TY_ERR.bits |
668 TypeFlags::HAS_PROJECTION.bits |
669 TypeFlags::HAS_TY_CLOSURE.bits |
670 TypeFlags::HAS_LOCAL_NAMES.bits,
672 // Caches for type_is_sized, type_moves_by_default
673 const SIZEDNESS_CACHED = 1 << 16,
674 const IS_SIZED = 1 << 17,
675 const MOVENESS_CACHED = 1 << 18,
676 const MOVES_BY_DEFAULT = 1 << 19,
680 pub struct TyS<'tcx> {
681 pub sty: TypeVariants<'tcx>,
682 pub flags: Cell<TypeFlags>,
684 // the maximal depth of any bound regions appearing in this type.
688 impl<'tcx> PartialEq for TyS<'tcx> {
690 fn eq(&self, other: &TyS<'tcx>) -> bool {
691 // (self as *const _) == (other as *const _)
692 (self as *const TyS<'tcx>) == (other as *const TyS<'tcx>)
695 impl<'tcx> Eq for TyS<'tcx> {}
697 impl<'tcx> Hash for TyS<'tcx> {
698 fn hash<H: Hasher>(&self, s: &mut H) {
699 (self as *const TyS).hash(s)
703 pub type Ty<'tcx> = &'tcx TyS<'tcx>;
705 /// Upvars do not get their own node-id. Instead, we use the pair of
706 /// the original var id (that is, the root variable that is referenced
707 /// by the upvar) and the id of the closure expression.
708 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
711 pub closure_expr_id: NodeId,
714 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)]
715 pub enum BorrowKind {
716 /// Data must be immutable and is aliasable.
719 /// Data must be immutable but not aliasable. This kind of borrow
720 /// cannot currently be expressed by the user and is used only in
721 /// implicit closure bindings. It is needed when you the closure
722 /// is borrowing or mutating a mutable referent, e.g.:
724 /// let x: &mut isize = ...;
725 /// let y = || *x += 5;
727 /// If we were to try to translate this closure into a more explicit
728 /// form, we'd encounter an error with the code as written:
730 /// struct Env { x: & &mut isize }
731 /// let x: &mut isize = ...;
732 /// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn
733 /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
735 /// This is then illegal because you cannot mutate a `&mut` found
736 /// in an aliasable location. To solve, you'd have to translate with
737 /// an `&mut` borrow:
739 /// struct Env { x: & &mut isize }
740 /// let x: &mut isize = ...;
741 /// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
742 /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
744 /// Now the assignment to `**env.x` is legal, but creating a
745 /// mutable pointer to `x` is not because `x` is not mutable. We
746 /// could fix this by declaring `x` as `let mut x`. This is ok in
747 /// user code, if awkward, but extra weird for closures, since the
748 /// borrow is hidden.
750 /// So we introduce a "unique imm" borrow -- the referent is
751 /// immutable, but not aliasable. This solves the problem. For
752 /// simplicity, we don't give users the way to express this
753 /// borrow, it's just used when translating closures.
756 /// Data is mutable and not aliasable.
760 /// Information describing the capture of an upvar. This is computed
761 /// during `typeck`, specifically by `regionck`.
762 #[derive(PartialEq, Clone, Debug, Copy)]
763 pub enum UpvarCapture {
764 /// Upvar is captured by value. This is always true when the
765 /// closure is labeled `move`, but can also be true in other cases
766 /// depending on inference.
769 /// Upvar is captured by reference.
773 #[derive(PartialEq, Clone, Copy)]
774 pub struct UpvarBorrow {
775 /// The kind of borrow: by-ref upvars have access to shared
776 /// immutable borrows, which are not part of the normal language
778 pub kind: BorrowKind,
780 /// Region of the resulting reference.
781 pub region: ty::Region,
784 pub type UpvarCaptureMap = FnvHashMap<UpvarId, UpvarCapture>;
786 #[derive(Copy, Clone)]
787 pub struct ClosureUpvar<'tcx> {
793 #[derive(Clone, Copy, PartialEq)]
794 pub enum IntVarValue {
796 UintType(hir::UintTy),
799 /// Default region to use for the bound of objects that are
800 /// supplied as the value for this type parameter. This is derived
801 /// from `T:'a` annotations appearing in the type definition. If
802 /// this is `None`, then the default is inherited from the
803 /// surrounding context. See RFC #599 for details.
804 #[derive(Copy, Clone)]
805 pub enum ObjectLifetimeDefault {
806 /// Require an explicit annotation. Occurs when multiple
807 /// `T:'a` constraints are found.
810 /// Use the base default, typically 'static, but in a fn body it is a fresh variable
813 /// Use the given region as the default.
818 pub struct TypeParameterDef<'tcx> {
821 pub space: subst::ParamSpace,
823 pub default_def_id: DefId, // for use in error reporing about defaults
824 pub default: Option<Ty<'tcx>>,
825 pub object_lifetime_default: ObjectLifetimeDefault,
829 pub struct RegionParameterDef {
832 pub space: subst::ParamSpace,
834 pub bounds: Vec<ty::Region>,
837 impl RegionParameterDef {
838 pub fn to_early_bound_region(&self) -> ty::Region {
839 ty::ReEarlyBound(ty::EarlyBoundRegion {
840 param_id: self.def_id.node,
846 pub fn to_bound_region(&self) -> ty::BoundRegion {
847 ty::BoundRegion::BrNamed(self.def_id, self.name)
851 /// Information about the formal type/lifetime parameters associated
852 /// with an item or method. Analogous to hir::Generics.
853 #[derive(Clone, Debug)]
854 pub struct Generics<'tcx> {
855 pub types: VecPerParamSpace<TypeParameterDef<'tcx>>,
856 pub regions: VecPerParamSpace<RegionParameterDef>,
859 impl<'tcx> Generics<'tcx> {
860 pub fn empty() -> Generics<'tcx> {
862 types: VecPerParamSpace::empty(),
863 regions: VecPerParamSpace::empty(),
867 pub fn is_empty(&self) -> bool {
868 self.types.is_empty() && self.regions.is_empty()
871 pub fn has_type_params(&self, space: subst::ParamSpace) -> bool {
872 !self.types.is_empty_in(space)
875 pub fn has_region_params(&self, space: subst::ParamSpace) -> bool {
876 !self.regions.is_empty_in(space)
880 /// Bounds on generics.
882 pub struct GenericPredicates<'tcx> {
883 pub predicates: VecPerParamSpace<Predicate<'tcx>>,
886 impl<'tcx> GenericPredicates<'tcx> {
887 pub fn empty() -> GenericPredicates<'tcx> {
889 predicates: VecPerParamSpace::empty(),
893 pub fn instantiate(&self, tcx: &ctxt<'tcx>, substs: &Substs<'tcx>)
894 -> InstantiatedPredicates<'tcx> {
895 InstantiatedPredicates {
896 predicates: self.predicates.subst(tcx, substs),
900 pub fn instantiate_supertrait(&self,
902 poly_trait_ref: &ty::PolyTraitRef<'tcx>)
903 -> InstantiatedPredicates<'tcx>
905 InstantiatedPredicates {
906 predicates: self.predicates.map(|pred| pred.subst_supertrait(tcx, poly_trait_ref))
911 #[derive(Clone, PartialEq, Eq, Hash)]
912 pub enum Predicate<'tcx> {
913 /// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
914 /// the `Self` type of the trait reference and `A`, `B`, and `C`
915 /// would be the parameters in the `TypeSpace`.
916 Trait(PolyTraitPredicate<'tcx>),
918 /// where `T1 == T2`.
919 Equate(PolyEquatePredicate<'tcx>),
922 RegionOutlives(PolyRegionOutlivesPredicate),
925 TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),
927 /// where <T as TraitRef>::Name == X, approximately.
928 /// See `ProjectionPredicate` struct for details.
929 Projection(PolyProjectionPredicate<'tcx>),
932 WellFormed(Ty<'tcx>),
934 /// trait must be object-safe
938 impl<'tcx> Predicate<'tcx> {
939 /// Performs a substitution suitable for going from a
940 /// poly-trait-ref to supertraits that must hold if that
941 /// poly-trait-ref holds. This is slightly different from a normal
942 /// substitution in terms of what happens with bound regions. See
943 /// lengthy comment below for details.
944 pub fn subst_supertrait(&self,
946 trait_ref: &ty::PolyTraitRef<'tcx>)
947 -> ty::Predicate<'tcx>
949 // The interaction between HRTB and supertraits is not entirely
950 // obvious. Let me walk you (and myself) through an example.
952 // Let's start with an easy case. Consider two traits:
954 // trait Foo<'a> : Bar<'a,'a> { }
955 // trait Bar<'b,'c> { }
957 // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
958 // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
959 // knew that `Foo<'x>` (for any 'x) then we also know that
960 // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
961 // normal substitution.
963 // In terms of why this is sound, the idea is that whenever there
964 // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
965 // holds. So if there is an impl of `T:Foo<'a>` that applies to
966 // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
969 // Another example to be careful of is this:
971 // trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
972 // trait Bar1<'b,'c> { }
974 // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
975 // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
976 // reason is similar to the previous example: any impl of
977 // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`. So
978 // basically we would want to collapse the bound lifetimes from
979 // the input (`trait_ref`) and the supertraits.
981 // To achieve this in practice is fairly straightforward. Let's
982 // consider the more complicated scenario:
984 // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
985 // has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
986 // where both `'x` and `'b` would have a DB index of 1.
987 // The substitution from the input trait-ref is therefore going to be
988 // `'a => 'x` (where `'x` has a DB index of 1).
989 // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
990 // early-bound parameter and `'b' is a late-bound parameter with a
992 // - If we replace `'a` with `'x` from the input, it too will have
993 // a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
994 // just as we wanted.
996 // There is only one catch. If we just apply the substitution `'a
997 // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
998 // adjust the DB index because we substituting into a binder (it
999 // tries to be so smart...) resulting in `for<'x> for<'b>
1000 // Bar1<'x,'b>` (we have no syntax for this, so use your
1001 // imagination). Basically the 'x will have DB index of 2 and 'b
1002 // will have DB index of 1. Not quite what we want. So we apply
1003 // the substitution to the *contents* of the trait reference,
1004 // rather than the trait reference itself (put another way, the
1005 // substitution code expects equal binding levels in the values
1006 // from the substitution and the value being substituted into, and
1007 // this trick achieves that).
1009 let substs = &trait_ref.0.substs;
1011 Predicate::Trait(ty::Binder(ref data)) =>
1012 Predicate::Trait(ty::Binder(data.subst(tcx, substs))),
1013 Predicate::Equate(ty::Binder(ref data)) =>
1014 Predicate::Equate(ty::Binder(data.subst(tcx, substs))),
1015 Predicate::RegionOutlives(ty::Binder(ref data)) =>
1016 Predicate::RegionOutlives(ty::Binder(data.subst(tcx, substs))),
1017 Predicate::TypeOutlives(ty::Binder(ref data)) =>
1018 Predicate::TypeOutlives(ty::Binder(data.subst(tcx, substs))),
1019 Predicate::Projection(ty::Binder(ref data)) =>
1020 Predicate::Projection(ty::Binder(data.subst(tcx, substs))),
1021 Predicate::WellFormed(data) =>
1022 Predicate::WellFormed(data.subst(tcx, substs)),
1023 Predicate::ObjectSafe(trait_def_id) =>
1024 Predicate::ObjectSafe(trait_def_id),
1029 #[derive(Clone, PartialEq, Eq, Hash)]
1030 pub struct TraitPredicate<'tcx> {
1031 pub trait_ref: TraitRef<'tcx>
1033 pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;
1035 impl<'tcx> TraitPredicate<'tcx> {
1036 pub fn def_id(&self) -> DefId {
1037 self.trait_ref.def_id
1040 pub fn input_types(&self) -> &[Ty<'tcx>] {
1041 self.trait_ref.substs.types.as_slice()
1044 pub fn self_ty(&self) -> Ty<'tcx> {
1045 self.trait_ref.self_ty()
1049 impl<'tcx> PolyTraitPredicate<'tcx> {
1050 pub fn def_id(&self) -> DefId {
1055 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
1056 pub struct EquatePredicate<'tcx>(pub Ty<'tcx>, pub Ty<'tcx>); // `0 == 1`
1057 pub type PolyEquatePredicate<'tcx> = ty::Binder<EquatePredicate<'tcx>>;
1059 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
1060 pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
1061 pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
1062 pub type PolyRegionOutlivesPredicate = PolyOutlivesPredicate<ty::Region, ty::Region>;
1063 pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate<Ty<'tcx>, ty::Region>;
1065 /// This kind of predicate has no *direct* correspondent in the
1066 /// syntax, but it roughly corresponds to the syntactic forms:
1068 /// 1. `T : TraitRef<..., Item=Type>`
1069 /// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
1071 /// In particular, form #1 is "desugared" to the combination of a
1072 /// normal trait predicate (`T : TraitRef<...>`) and one of these
1073 /// predicates. Form #2 is a broader form in that it also permits
1074 /// equality between arbitrary types. Processing an instance of Form
1075 /// #2 eventually yields one of these `ProjectionPredicate`
1076 /// instances to normalize the LHS.
1077 #[derive(Clone, PartialEq, Eq, Hash)]
1078 pub struct ProjectionPredicate<'tcx> {
1079 pub projection_ty: ProjectionTy<'tcx>,
1083 pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;
1085 impl<'tcx> PolyProjectionPredicate<'tcx> {
1086 pub fn item_name(&self) -> Name {
1087 self.0.projection_ty.item_name // safe to skip the binder to access a name
1090 pub fn sort_key(&self) -> (DefId, Name) {
1091 self.0.projection_ty.sort_key()
1095 pub trait ToPolyTraitRef<'tcx> {
1096 fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
1099 impl<'tcx> ToPolyTraitRef<'tcx> for TraitRef<'tcx> {
1100 fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
1101 assert!(!self.has_escaping_regions());
1102 ty::Binder(self.clone())
1106 impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
1107 fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
1108 self.map_bound_ref(|trait_pred| trait_pred.trait_ref.clone())
1112 impl<'tcx> ToPolyTraitRef<'tcx> for PolyProjectionPredicate<'tcx> {
1113 fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
1114 // Note: unlike with TraitRef::to_poly_trait_ref(),
1115 // self.0.trait_ref is permitted to have escaping regions.
1116 // This is because here `self` has a `Binder` and so does our
1117 // return value, so we are preserving the number of binding
1119 ty::Binder(self.0.projection_ty.trait_ref.clone())
1123 pub trait ToPredicate<'tcx> {
1124 fn to_predicate(&self) -> Predicate<'tcx>;
1127 impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
1128 fn to_predicate(&self) -> Predicate<'tcx> {
1129 // we're about to add a binder, so let's check that we don't
1130 // accidentally capture anything, or else that might be some
1131 // weird debruijn accounting.
1132 assert!(!self.has_escaping_regions());
1134 ty::Predicate::Trait(ty::Binder(ty::TraitPredicate {
1135 trait_ref: self.clone()
1140 impl<'tcx> ToPredicate<'tcx> for PolyTraitRef<'tcx> {
1141 fn to_predicate(&self) -> Predicate<'tcx> {
1142 ty::Predicate::Trait(self.to_poly_trait_predicate())
1146 impl<'tcx> ToPredicate<'tcx> for PolyEquatePredicate<'tcx> {
1147 fn to_predicate(&self) -> Predicate<'tcx> {
1148 Predicate::Equate(self.clone())
1152 impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate {
1153 fn to_predicate(&self) -> Predicate<'tcx> {
1154 Predicate::RegionOutlives(self.clone())
1158 impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
1159 fn to_predicate(&self) -> Predicate<'tcx> {
1160 Predicate::TypeOutlives(self.clone())
1164 impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
1165 fn to_predicate(&self) -> Predicate<'tcx> {
1166 Predicate::Projection(self.clone())
1170 impl<'tcx> Predicate<'tcx> {
1171 /// Iterates over the types in this predicate. Note that in all
1172 /// cases this is skipping over a binder, so late-bound regions
1173 /// with depth 0 are bound by the predicate.
1174 pub fn walk_tys(&self) -> IntoIter<Ty<'tcx>> {
1175 let vec: Vec<_> = match *self {
1176 ty::Predicate::Trait(ref data) => {
1177 data.0.trait_ref.substs.types.as_slice().to_vec()
1179 ty::Predicate::Equate(ty::Binder(ref data)) => {
1180 vec![data.0, data.1]
1182 ty::Predicate::TypeOutlives(ty::Binder(ref data)) => {
1185 ty::Predicate::RegionOutlives(..) => {
1188 ty::Predicate::Projection(ref data) => {
1189 let trait_inputs = data.0.projection_ty.trait_ref.substs.types.as_slice();
1192 .chain(Some(data.0.ty))
1195 ty::Predicate::WellFormed(data) => {
1198 ty::Predicate::ObjectSafe(_trait_def_id) => {
1203 // The only reason to collect into a vector here is that I was
1204 // too lazy to make the full (somewhat complicated) iterator
1205 // type that would be needed here. But I wanted this fn to
1206 // return an iterator conceptually, rather than a `Vec`, so as
1207 // to be closer to `Ty::walk`.
1211 pub fn has_escaping_regions(&self) -> bool {
1213 Predicate::Trait(ref trait_ref) => trait_ref.has_escaping_regions(),
1214 Predicate::Equate(ref p) => p.has_escaping_regions(),
1215 Predicate::RegionOutlives(ref p) => p.has_escaping_regions(),
1216 Predicate::TypeOutlives(ref p) => p.has_escaping_regions(),
1217 Predicate::Projection(ref p) => p.has_escaping_regions(),
1218 Predicate::WellFormed(p) => p.has_escaping_regions(),
1219 Predicate::ObjectSafe(_trait_def_id) => false,
1223 pub fn to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'tcx>> {
1225 Predicate::Trait(ref t) => {
1226 Some(t.to_poly_trait_ref())
1228 Predicate::Projection(..) |
1229 Predicate::Equate(..) |
1230 Predicate::RegionOutlives(..) |
1231 Predicate::WellFormed(..) |
1232 Predicate::ObjectSafe(..) |
1233 Predicate::TypeOutlives(..) => {
1240 /// Represents the bounds declared on a particular set of type
1241 /// parameters. Should eventually be generalized into a flag list of
1242 /// where clauses. You can obtain a `InstantiatedPredicates` list from a
1243 /// `GenericPredicates` by using the `instantiate` method. Note that this method
1244 /// reflects an important semantic invariant of `InstantiatedPredicates`: while
1245 /// the `GenericPredicates` are expressed in terms of the bound type
1246 /// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance
1247 /// represented a set of bounds for some particular instantiation,
1248 /// meaning that the generic parameters have been substituted with
1253 /// struct Foo<T,U:Bar<T>> { ... }
1255 /// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
1256 /// `[[], [U:Bar<T>]]`. Now if there were some particular reference
1257 /// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
1258 /// [usize:Bar<isize>]]`.
1260 pub struct InstantiatedPredicates<'tcx> {
1261 pub predicates: VecPerParamSpace<Predicate<'tcx>>,
1264 impl<'tcx> InstantiatedPredicates<'tcx> {
1265 pub fn empty() -> InstantiatedPredicates<'tcx> {
1266 InstantiatedPredicates { predicates: VecPerParamSpace::empty() }
1269 pub fn has_escaping_regions(&self) -> bool {
1270 self.predicates.any(|p| p.has_escaping_regions())
1273 pub fn is_empty(&self) -> bool {
1274 self.predicates.is_empty()
1278 impl<'tcx> TraitRef<'tcx> {
1279 pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>) -> TraitRef<'tcx> {
1280 TraitRef { def_id: def_id, substs: substs }
1283 pub fn self_ty(&self) -> Ty<'tcx> {
1284 self.substs.self_ty().unwrap()
1287 pub fn input_types(&self) -> &[Ty<'tcx>] {
1288 // Select only the "input types" from a trait-reference. For
1289 // now this is all the types that appear in the
1290 // trait-reference, but it should eventually exclude
1291 // associated types.
1292 self.substs.types.as_slice()
1296 /// When type checking, we use the `ParameterEnvironment` to track
1297 /// details about the type/lifetime parameters that are in scope.
1298 /// It primarily stores the bounds information.
1300 /// Note: This information might seem to be redundant with the data in
1301 /// `tcx.ty_param_defs`, but it is not. That table contains the
1302 /// parameter definitions from an "outside" perspective, but this
1303 /// struct will contain the bounds for a parameter as seen from inside
1304 /// the function body. Currently the only real distinction is that
1305 /// bound lifetime parameters are replaced with free ones, but in the
1306 /// future I hope to refine the representation of types so as to make
1307 /// more distinctions clearer.
1309 pub struct ParameterEnvironment<'a, 'tcx:'a> {
1310 pub tcx: &'a ctxt<'tcx>,
1312 /// See `construct_free_substs` for details.
1313 pub free_substs: Substs<'tcx>,
1315 /// Each type parameter has an implicit region bound that
1316 /// indicates it must outlive at least the function body (the user
1317 /// may specify stronger requirements). This field indicates the
1318 /// region of the callee.
1319 pub implicit_region_bound: ty::Region,
1321 /// Obligations that the caller must satisfy. This is basically
1322 /// the set of bounds on the in-scope type parameters, translated
1323 /// into Obligations, and elaborated and normalized.
1324 pub caller_bounds: Vec<ty::Predicate<'tcx>>,
1326 /// Caches the results of trait selection. This cache is used
1327 /// for things that have to do with the parameters in scope.
1328 pub selection_cache: traits::SelectionCache<'tcx>,
1330 /// Scope that is attached to free regions for this scope. This
1331 /// is usually the id of the fn body, but for more abstract scopes
1332 /// like structs we often use the node-id of the struct.
1334 /// FIXME(#3696). It would be nice to refactor so that free
1335 /// regions don't have this implicit scope and instead introduce
1336 /// relationships in the environment.
1337 pub free_id: ast::NodeId,
1340 impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
1341 pub fn with_caller_bounds(&self,
1342 caller_bounds: Vec<ty::Predicate<'tcx>>)
1343 -> ParameterEnvironment<'a,'tcx>
1345 ParameterEnvironment {
1347 free_substs: self.free_substs.clone(),
1348 implicit_region_bound: self.implicit_region_bound,
1349 caller_bounds: caller_bounds,
1350 selection_cache: traits::SelectionCache::new(),
1351 free_id: self.free_id,
1355 pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx> {
1356 match cx.map.find(id) {
1357 Some(ast_map::NodeImplItem(ref impl_item)) => {
1358 match impl_item.node {
1359 hir::TypeImplItem(_) => {
1360 // associated types don't have their own entry (for some reason),
1361 // so for now just grab environment for the impl
1362 let impl_id = cx.map.get_parent(id);
1363 let impl_def_id = DefId::local(impl_id);
1364 let scheme = cx.lookup_item_type(impl_def_id);
1365 let predicates = cx.lookup_predicates(impl_def_id);
1366 cx.construct_parameter_environment(impl_item.span,
1371 hir::ConstImplItem(_, _) => {
1372 let def_id = DefId::local(id);
1373 let scheme = cx.lookup_item_type(def_id);
1374 let predicates = cx.lookup_predicates(def_id);
1375 cx.construct_parameter_environment(impl_item.span,
1380 hir::MethodImplItem(_, ref body) => {
1381 let method_def_id = DefId::local(id);
1382 match cx.impl_or_trait_item(method_def_id) {
1383 MethodTraitItem(ref method_ty) => {
1384 let method_generics = &method_ty.generics;
1385 let method_bounds = &method_ty.predicates;
1386 cx.construct_parameter_environment(
1394 .bug("ParameterEnvironment::for_item(): \
1395 got non-method item from impl method?!")
1401 Some(ast_map::NodeTraitItem(trait_item)) => {
1402 match trait_item.node {
1403 hir::TypeTraitItem(..) => {
1404 // associated types don't have their own entry (for some reason),
1405 // so for now just grab environment for the trait
1406 let trait_id = cx.map.get_parent(id);
1407 let trait_def_id = DefId::local(trait_id);
1408 let trait_def = cx.lookup_trait_def(trait_def_id);
1409 let predicates = cx.lookup_predicates(trait_def_id);
1410 cx.construct_parameter_environment(trait_item.span,
1411 &trait_def.generics,
1415 hir::ConstTraitItem(..) => {
1416 let def_id = DefId::local(id);
1417 let scheme = cx.lookup_item_type(def_id);
1418 let predicates = cx.lookup_predicates(def_id);
1419 cx.construct_parameter_environment(trait_item.span,
1424 hir::MethodTraitItem(_, ref body) => {
1425 // for the body-id, use the id of the body
1426 // block, unless this is a trait method with
1427 // no default, then fallback to the method id.
1428 let body_id = body.as_ref().map(|b| b.id).unwrap_or(id);
1429 let method_def_id = DefId::local(id);
1431 match cx.impl_or_trait_item(method_def_id) {
1432 MethodTraitItem(ref method_ty) => {
1433 let method_generics = &method_ty.generics;
1434 let method_bounds = &method_ty.predicates;
1435 cx.construct_parameter_environment(
1443 .bug("ParameterEnvironment::for_item(): \
1444 got non-method item from provided \
1451 Some(ast_map::NodeItem(item)) => {
1453 hir::ItemFn(_, _, _, _, _, ref body) => {
1454 // We assume this is a function.
1455 let fn_def_id = DefId::local(id);
1456 let fn_scheme = cx.lookup_item_type(fn_def_id);
1457 let fn_predicates = cx.lookup_predicates(fn_def_id);
1459 cx.construct_parameter_environment(item.span,
1460 &fn_scheme.generics,
1465 hir::ItemStruct(..) |
1467 hir::ItemConst(..) |
1468 hir::ItemStatic(..) => {
1469 let def_id = DefId::local(id);
1470 let scheme = cx.lookup_item_type(def_id);
1471 let predicates = cx.lookup_predicates(def_id);
1472 cx.construct_parameter_environment(item.span,
1477 hir::ItemTrait(..) => {
1478 let def_id = DefId::local(id);
1479 let trait_def = cx.lookup_trait_def(def_id);
1480 let predicates = cx.lookup_predicates(def_id);
1481 cx.construct_parameter_environment(item.span,
1482 &trait_def.generics,
1487 cx.sess.span_bug(item.span,
1488 "ParameterEnvironment::from_item():
1489 can't create a parameter \
1490 environment for this kind of item")
1494 Some(ast_map::NodeExpr(..)) => {
1495 // This is a convenience to allow closures to work.
1496 ParameterEnvironment::for_item(cx, cx.map.get_parent(id))
1499 cx.sess.bug(&format!("ParameterEnvironment::from_item(): \
1500 `{}` is not an item",
1501 cx.map.node_to_string(id)))
1506 pub fn can_type_implement_copy(&self, self_type: Ty<'tcx>, span: Span)
1507 -> Result<(),CopyImplementationError> {
1510 // FIXME: (@jroesch) float this code up
1511 let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(self.clone()), false);
1513 let adt = match self_type.sty {
1514 ty::TyStruct(struct_def, substs) => {
1515 for field in struct_def.all_fields() {
1516 let field_ty = field.ty(tcx, substs);
1517 if infcx.type_moves_by_default(field_ty, span) {
1518 return Err(FieldDoesNotImplementCopy(field.name))
1523 ty::TyEnum(enum_def, substs) => {
1524 for variant in &enum_def.variants {
1525 for field in &variant.fields {
1526 let field_ty = field.ty(tcx, substs);
1527 if infcx.type_moves_by_default(field_ty, span) {
1528 return Err(VariantDoesNotImplementCopy(variant.name))
1534 _ => return Err(TypeIsStructural),
1538 return Err(TypeHasDestructor)
1545 #[derive(Copy, Clone)]
1546 pub enum CopyImplementationError {
1547 FieldDoesNotImplementCopy(Name),
1548 VariantDoesNotImplementCopy(Name),
1553 /// A "type scheme", in ML terminology, is a type combined with some
1554 /// set of generic types that the type is, well, generic over. In Rust
1555 /// terms, it is the "type" of a fn item or struct -- this type will
1556 /// include various generic parameters that must be substituted when
1557 /// the item/struct is referenced. That is called converting the type
1558 /// scheme to a monotype.
1560 /// - `generics`: the set of type parameters and their bounds
1561 /// - `ty`: the base types, which may reference the parameters defined
1564 /// Note that TypeSchemes are also sometimes called "polytypes" (and
1565 /// in fact this struct used to carry that name, so you may find some
1566 /// stray references in a comment or something). We try to reserve the
1567 /// "poly" prefix to refer to higher-ranked things, as in
1570 /// Note that each item also comes with predicates, see
1571 /// `lookup_predicates`.
1572 #[derive(Clone, Debug)]
1573 pub struct TypeScheme<'tcx> {
1574 pub generics: Generics<'tcx>,
1579 flags TraitFlags: u32 {
1580 const NO_TRAIT_FLAGS = 0,
1581 const HAS_DEFAULT_IMPL = 1 << 0,
1582 const IS_OBJECT_SAFE = 1 << 1,
1583 const OBJECT_SAFETY_VALID = 1 << 2,
1584 const IMPLS_VALID = 1 << 3,
1588 /// As `TypeScheme` but for a trait ref.
1589 pub struct TraitDef<'tcx> {
1590 pub unsafety: hir::Unsafety,
1592 /// If `true`, then this trait had the `#[rustc_paren_sugar]`
1593 /// attribute, indicating that it should be used with `Foo()`
1594 /// sugar. This is a temporary thing -- eventually any trait wil
1595 /// be usable with the sugar (or without it).
1596 pub paren_sugar: bool,
1598 /// Generic type definitions. Note that `Self` is listed in here
1599 /// as having a single bound, the trait itself (e.g., in the trait
1600 /// `Eq`, there is a single bound `Self : Eq`). This is so that
1601 /// default methods get to assume that the `Self` parameters
1602 /// implements the trait.
1603 pub generics: Generics<'tcx>,
1605 pub trait_ref: TraitRef<'tcx>,
1607 /// A list of the associated types defined in this trait. Useful
1608 /// for resolving `X::Foo` type markers.
1609 pub associated_type_names: Vec<Name>,
1611 // Impls of this trait. To allow for quicker lookup, the impls are indexed
1612 // by a simplified version of their Self type: impls with a simplifiable
1613 // Self are stored in nonblanket_impls keyed by it, while all other impls
1614 // are stored in blanket_impls.
1616 /// Impls of the trait.
1617 pub nonblanket_impls: RefCell<
1618 FnvHashMap<fast_reject::SimplifiedType, Vec<DefId>>
1621 /// Blanket impls associated with the trait.
1622 pub blanket_impls: RefCell<Vec<DefId>>,
1625 pub flags: Cell<TraitFlags>
1628 impl<'tcx> TraitDef<'tcx> {
1629 // returns None if not yet calculated
1630 pub fn object_safety(&self) -> Option<bool> {
1631 if self.flags.get().intersects(TraitFlags::OBJECT_SAFETY_VALID) {
1632 Some(self.flags.get().intersects(TraitFlags::IS_OBJECT_SAFE))
1638 pub fn set_object_safety(&self, is_safe: bool) {
1639 assert!(self.object_safety().map(|cs| cs == is_safe).unwrap_or(true));
1641 self.flags.get() | if is_safe {
1642 TraitFlags::OBJECT_SAFETY_VALID | TraitFlags::IS_OBJECT_SAFE
1644 TraitFlags::OBJECT_SAFETY_VALID
1649 /// Records a trait-to-implementation mapping.
1650 pub fn record_impl(&self,
1653 impl_trait_ref: TraitRef<'tcx>) {
1654 debug!("TraitDef::record_impl for {:?}, from {:?}",
1655 self, impl_trait_ref);
1657 // We don't want to borrow_mut after we already populated all impls,
1658 // so check if an impl is present with an immutable borrow first.
1659 if let Some(sty) = fast_reject::simplify_type(tcx,
1660 impl_trait_ref.self_ty(), false) {
1661 if let Some(is) = self.nonblanket_impls.borrow().get(&sty) {
1662 if is.contains(&impl_def_id) {
1663 return // duplicate - skip
1667 self.nonblanket_impls.borrow_mut().entry(sty).or_insert(vec![]).push(impl_def_id)
1669 if self.blanket_impls.borrow().contains(&impl_def_id) {
1670 return // duplicate - skip
1672 self.blanket_impls.borrow_mut().push(impl_def_id)
1677 pub fn for_each_impl<F: FnMut(DefId)>(&self, tcx: &ctxt<'tcx>, mut f: F) {
1678 tcx.populate_implementations_for_trait_if_necessary(self.trait_ref.def_id);
1680 for &impl_def_id in self.blanket_impls.borrow().iter() {
1684 for v in self.nonblanket_impls.borrow().values() {
1685 for &impl_def_id in v {
1691 /// Iterate over every impl that could possibly match the
1692 /// self-type `self_ty`.
1693 pub fn for_each_relevant_impl<F: FnMut(DefId)>(&self,
1698 tcx.populate_implementations_for_trait_if_necessary(self.trait_ref.def_id);
1700 for &impl_def_id in self.blanket_impls.borrow().iter() {
1704 // simplify_type(.., false) basically replaces type parameters and
1705 // projections with infer-variables. This is, of course, done on
1706 // the impl trait-ref when it is instantiated, but not on the
1707 // predicate trait-ref which is passed here.
1709 // for example, if we match `S: Copy` against an impl like
1710 // `impl<T:Copy> Copy for Option<T>`, we replace the type variable
1711 // in `Option<T>` with an infer variable, to `Option<_>` (this
1712 // doesn't actually change fast_reject output), but we don't
1713 // replace `S` with anything - this impl of course can't be
1714 // selected, and as there are hundreds of similar impls,
1715 // considering them would significantly harm performance.
1716 if let Some(simp) = fast_reject::simplify_type(tcx, self_ty, true) {
1717 if let Some(impls) = self.nonblanket_impls.borrow().get(&simp) {
1718 for &impl_def_id in impls {
1723 for v in self.nonblanket_impls.borrow().values() {
1724 for &impl_def_id in v {
1734 flags AdtFlags: u32 {
1735 const NO_ADT_FLAGS = 0,
1736 const IS_ENUM = 1 << 0,
1737 const IS_DTORCK = 1 << 1, // is this a dtorck type?
1738 const IS_DTORCK_VALID = 1 << 2,
1739 const IS_PHANTOM_DATA = 1 << 3,
1740 const IS_SIMD = 1 << 4,
1741 const IS_FUNDAMENTAL = 1 << 5,
1742 const IS_NO_DROP_FLAG = 1 << 6,
1746 pub type AdtDef<'tcx> = &'tcx AdtDefData<'tcx, 'static>;
1747 pub type VariantDef<'tcx> = &'tcx VariantDefData<'tcx, 'static>;
1748 pub type FieldDef<'tcx> = &'tcx FieldDefData<'tcx, 'static>;
1750 // See comment on AdtDefData for explanation
1751 pub type AdtDefMaster<'tcx> = &'tcx AdtDefData<'tcx, 'tcx>;
1752 pub type VariantDefMaster<'tcx> = &'tcx VariantDefData<'tcx, 'tcx>;
1753 pub type FieldDefMaster<'tcx> = &'tcx FieldDefData<'tcx, 'tcx>;
1755 pub struct VariantDefData<'tcx, 'container: 'tcx> {
1757 pub name: Name, // struct's name if this is a struct
1759 pub fields: Vec<FieldDefData<'tcx, 'container>>
1762 pub struct FieldDefData<'tcx, 'container: 'tcx> {
1763 /// The field's DefId. NOTE: the fields of tuple-like enum variants
1764 /// are not real items, and don't have entries in tcache etc.
1766 /// special_idents::unnamed_field.name
1767 /// if this is a tuple-like field
1769 pub vis: hir::Visibility,
1770 /// TyIVar is used here to allow for variance (see the doc at
1772 ty: ivar::TyIVar<'tcx, 'container>
1775 /// The definition of an abstract data type - a struct or enum.
1777 /// These are all interned (by intern_adt_def) into the adt_defs
1780 /// Because of the possibility of nested tcx-s, this type
1781 /// needs 2 lifetimes: the traditional variant lifetime ('tcx)
1782 /// bounding the lifetime of the inner types is of course necessary.
1783 /// However, it is not sufficient - types from a child tcx must
1784 /// not be leaked into the master tcx by being stored in an AdtDefData.
1786 /// The 'container lifetime ensures that by outliving the container
1787 /// tcx and preventing shorter-lived types from being inserted. When
1788 /// write access is not needed, the 'container lifetime can be
1789 /// erased to 'static, which can be done by the AdtDef wrapper.
1790 pub struct AdtDefData<'tcx, 'container: 'tcx> {
1792 pub variants: Vec<VariantDefData<'tcx, 'container>>,
1793 destructor: Cell<Option<DefId>>,
1794 flags: Cell<AdtFlags>,
1797 impl<'tcx, 'container> PartialEq for AdtDefData<'tcx, 'container> {
1798 // AdtDefData are always interned and this is part of TyS equality
1800 fn eq(&self, other: &Self) -> bool { self as *const _ == other as *const _ }
1803 impl<'tcx, 'container> Eq for AdtDefData<'tcx, 'container> {}
1805 impl<'tcx, 'container> Hash for AdtDefData<'tcx, 'container> {
1807 fn hash<H: Hasher>(&self, s: &mut H) {
1808 (self as *const AdtDefData).hash(s)
1813 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
1814 pub enum AdtKind { Struct, Enum }
1816 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
1817 pub enum VariantKind { Dict, Tuple, Unit }
1819 impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
1820 fn new(tcx: &ctxt<'tcx>,
1823 variants: Vec<VariantDefData<'tcx, 'container>>) -> Self {
1824 let mut flags = AdtFlags::NO_ADT_FLAGS;
1825 let attrs = tcx.get_attrs(did);
1826 if attr::contains_name(&attrs, "fundamental") {
1827 flags = flags | AdtFlags::IS_FUNDAMENTAL;
1829 if attr::contains_name(&attrs, "unsafe_no_drop_flag") {
1830 flags = flags | AdtFlags::IS_NO_DROP_FLAG;
1832 if tcx.lookup_simd(did) {
1833 flags = flags | AdtFlags::IS_SIMD;
1835 if Some(did) == tcx.lang_items.phantom_data() {
1836 flags = flags | AdtFlags::IS_PHANTOM_DATA;
1838 if let AdtKind::Enum = kind {
1839 flags = flags | AdtFlags::IS_ENUM;
1844 flags: Cell::new(flags),
1845 destructor: Cell::new(None)
1849 fn calculate_dtorck(&'tcx self, tcx: &ctxt<'tcx>) {
1850 if tcx.is_adt_dtorck(self) {
1851 self.flags.set(self.flags.get() | AdtFlags::IS_DTORCK);
1853 self.flags.set(self.flags.get() | AdtFlags::IS_DTORCK_VALID)
1856 /// Returns the kind of the ADT - Struct or Enum.
1858 pub fn adt_kind(&self) -> AdtKind {
1859 if self.flags.get().intersects(AdtFlags::IS_ENUM) {
1866 /// Returns whether this is a dtorck type. If this returns
1867 /// true, this type being safe for destruction requires it to be
1868 /// alive; Otherwise, only the contents are required to be.
1870 pub fn is_dtorck(&'tcx self, tcx: &ctxt<'tcx>) -> bool {
1871 if !self.flags.get().intersects(AdtFlags::IS_DTORCK_VALID) {
1872 self.calculate_dtorck(tcx)
1874 self.flags.get().intersects(AdtFlags::IS_DTORCK)
1877 /// Returns whether this type is #[fundamental] for the purposes
1878 /// of coherence checking.
1880 pub fn is_fundamental(&self) -> bool {
1881 self.flags.get().intersects(AdtFlags::IS_FUNDAMENTAL)
1885 pub fn is_simd(&self) -> bool {
1886 self.flags.get().intersects(AdtFlags::IS_SIMD)
1889 /// Returns true if this is PhantomData<T>.
1891 pub fn is_phantom_data(&self) -> bool {
1892 self.flags.get().intersects(AdtFlags::IS_PHANTOM_DATA)
1895 /// Returns whether this type has a destructor.
1896 pub fn has_dtor(&self) -> bool {
1897 match self.dtor_kind() {
1899 TraitDtor(..) => true
1903 /// Asserts this is a struct and returns the struct's unique
1905 pub fn struct_variant(&self) -> &VariantDefData<'tcx, 'container> {
1906 assert!(self.adt_kind() == AdtKind::Struct);
1911 pub fn type_scheme(&self, tcx: &ctxt<'tcx>) -> TypeScheme<'tcx> {
1912 tcx.lookup_item_type(self.did)
1916 pub fn predicates(&self, tcx: &ctxt<'tcx>) -> GenericPredicates<'tcx> {
1917 tcx.lookup_predicates(self.did)
1920 /// Returns an iterator over all fields contained
1923 pub fn all_fields(&self) ->
1925 slice::Iter<VariantDefData<'tcx, 'container>>,
1926 slice::Iter<FieldDefData<'tcx, 'container>>,
1927 for<'s> fn(&'s VariantDefData<'tcx, 'container>)
1928 -> slice::Iter<'s, FieldDefData<'tcx, 'container>>
1930 self.variants.iter().flat_map(VariantDefData::fields_iter)
1934 pub fn is_empty(&self) -> bool {
1935 self.variants.is_empty()
1939 pub fn is_univariant(&self) -> bool {
1940 self.variants.len() == 1
1943 pub fn is_payloadfree(&self) -> bool {
1944 !self.variants.is_empty() &&
1945 self.variants.iter().all(|v| v.fields.is_empty())
1948 pub fn variant_with_id(&self, vid: DefId) -> &VariantDefData<'tcx, 'container> {
1951 .find(|v| v.did == vid)
1952 .expect("variant_with_id: unknown variant")
1955 pub fn variant_index_with_id(&self, vid: DefId) -> usize {
1958 .position(|v| v.did == vid)
1959 .expect("variant_index_with_id: unknown variant")
1962 pub fn variant_of_def(&self, def: def::Def) -> &VariantDefData<'tcx, 'container> {
1964 def::DefVariant(_, vid, _) => self.variant_with_id(vid),
1965 def::DefStruct(..) | def::DefTy(..) => self.struct_variant(),
1966 _ => panic!("unexpected def {:?} in variant_of_def", def)
1970 pub fn destructor(&self) -> Option<DefId> {
1971 self.destructor.get()
1974 pub fn set_destructor(&self, dtor: DefId) {
1975 assert!(self.destructor.get().is_none());
1976 self.destructor.set(Some(dtor));
1979 pub fn dtor_kind(&self) -> DtorKind {
1980 match self.destructor.get() {
1982 TraitDtor(!self.flags.get().intersects(AdtFlags::IS_NO_DROP_FLAG))
1989 impl<'tcx, 'container> VariantDefData<'tcx, 'container> {
1991 fn fields_iter(&self) -> slice::Iter<FieldDefData<'tcx, 'container>> {
1995 pub fn kind(&self) -> VariantKind {
1996 match self.fields.get(0) {
1997 None => VariantKind::Unit,
1998 Some(&FieldDefData { name, .. }) if name == special_idents::unnamed_field.name => {
2001 Some(_) => VariantKind::Dict
2005 pub fn is_tuple_struct(&self) -> bool {
2006 self.kind() == VariantKind::Tuple
2010 pub fn find_field_named(&self,
2012 -> Option<&FieldDefData<'tcx, 'container>> {
2013 self.fields.iter().find(|f| f.name == name)
2017 pub fn field_named(&self, name: ast::Name) -> &FieldDefData<'tcx, 'container> {
2018 self.find_field_named(name).unwrap()
2022 impl<'tcx, 'container> FieldDefData<'tcx, 'container> {
2023 pub fn new(did: DefId,
2025 vis: hir::Visibility) -> Self {
2030 ty: ivar::TyIVar::new()
2034 pub fn ty(&self, tcx: &ctxt<'tcx>, subst: &Substs<'tcx>) -> Ty<'tcx> {
2035 self.unsubst_ty().subst(tcx, subst)
2038 pub fn unsubst_ty(&self) -> Ty<'tcx> {
2042 pub fn fulfill_ty(&self, ty: Ty<'container>) {
2043 self.ty.fulfill(ty);
2047 /// Records the substitutions used to translate the polytype for an
2048 /// item into the monotype of an item reference.
2050 pub struct ItemSubsts<'tcx> {
2051 pub substs: Substs<'tcx>,
2054 #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
2055 pub enum ClosureKind {
2056 // Warning: Ordering is significant here! The ordering is chosen
2057 // because the trait Fn is a subtrait of FnMut and so in turn, and
2058 // hence we order it so that Fn < FnMut < FnOnce.
2065 pub fn trait_did(&self, cx: &ctxt) -> DefId {
2066 let result = match *self {
2067 FnClosureKind => cx.lang_items.require(FnTraitLangItem),
2068 FnMutClosureKind => {
2069 cx.lang_items.require(FnMutTraitLangItem)
2071 FnOnceClosureKind => {
2072 cx.lang_items.require(FnOnceTraitLangItem)
2076 Ok(trait_did) => trait_did,
2077 Err(err) => cx.sess.fatal(&err[..]),
2081 /// True if this a type that impls this closure kind
2082 /// must also implement `other`.
2083 pub fn extends(self, other: ty::ClosureKind) -> bool {
2084 match (self, other) {
2085 (FnClosureKind, FnClosureKind) => true,
2086 (FnClosureKind, FnMutClosureKind) => true,
2087 (FnClosureKind, FnOnceClosureKind) => true,
2088 (FnMutClosureKind, FnMutClosureKind) => true,
2089 (FnMutClosureKind, FnOnceClosureKind) => true,
2090 (FnOnceClosureKind, FnOnceClosureKind) => true,
2096 impl<'tcx> ctxt<'tcx> {
2097 pub fn pat_contains_ref_binding(&self, pat: &hir::Pat) -> Option<hir::Mutability> {
2098 pat_util::pat_contains_ref_binding(&self.def_map, pat)
2101 pub fn arm_contains_ref_binding(&self, arm: &hir::Arm) -> Option<hir::Mutability> {
2102 pat_util::arm_contains_ref_binding(&self.def_map, arm)
2106 impl<'tcx> TyS<'tcx> {
2107 /// Iterator that walks `self` and any types reachable from
2108 /// `self`, in depth-first order. Note that just walks the types
2109 /// that appear in `self`, it does not descend into the fields of
2110 /// structs or variants. For example:
2113 /// isize => { isize }
2114 /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
2115 /// [isize] => { [isize], isize }
2117 pub fn walk(&'tcx self) -> TypeWalker<'tcx> {
2118 TypeWalker::new(self)
2121 /// Iterator that walks the immediate children of `self`. Hence
2122 /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
2123 /// (but not `i32`, like `walk`).
2124 pub fn walk_shallow(&'tcx self) -> IntoIter<Ty<'tcx>> {
2125 walk::walk_shallow(self)
2128 pub fn as_opt_param_ty(&self) -> Option<ty::ParamTy> {
2130 ty::TyParam(ref d) => Some(d.clone()),
2135 pub fn is_param(&self, space: ParamSpace, index: u32) -> bool {
2137 ty::TyParam(ref data) => data.space == space && data.idx == index,
2142 /// Returns the regions directly referenced from this type (but
2143 /// not types reachable from this type via `walk_tys`). This
2144 /// ignores late-bound regions binders.
2145 pub fn regions(&self) -> Vec<ty::Region> {
2147 TyRef(region, _) => {
2150 TyTrait(ref obj) => {
2151 let mut v = vec![obj.bounds.region_bound];
2152 v.push_all(obj.principal.skip_binder().substs.regions().as_slice());
2156 TyStruct(_, substs) => {
2157 substs.regions().as_slice().to_vec()
2159 TyClosure(_, ref substs) => {
2160 substs.func_substs.regions().as_slice().to_vec()
2162 TyProjection(ref data) => {
2163 data.trait_ref.substs.regions().as_slice().to_vec()
2185 /// Walks `ty` and any types appearing within `ty`, invoking the
2186 /// callback `f` on each type. If the callback returns false, then the
2187 /// children of the current type are ignored.
2189 /// Note: prefer `ty.walk()` where possible.
2190 pub fn maybe_walk<F>(&'tcx self, mut f: F)
2191 where F : FnMut(Ty<'tcx>) -> bool
2193 let mut walker = self.walk();
2194 while let Some(ty) = walker.next() {
2196 walker.skip_current_subtree();
2203 pub fn new(space: subst::ParamSpace,
2207 ParamTy { space: space, idx: index, name: name }
2210 pub fn for_self() -> ParamTy {
2211 ParamTy::new(subst::SelfSpace, 0, special_idents::type_self.name)
2214 pub fn for_def(def: &TypeParameterDef) -> ParamTy {
2215 ParamTy::new(def.space, def.index, def.name)
2218 pub fn to_ty<'tcx>(self, tcx: &ctxt<'tcx>) -> Ty<'tcx> {
2219 tcx.mk_param(self.space, self.idx, self.name)
2222 pub fn is_self(&self) -> bool {
2223 self.space == subst::SelfSpace && self.idx == 0
2227 impl<'tcx> ItemSubsts<'tcx> {
2228 pub fn empty() -> ItemSubsts<'tcx> {
2229 ItemSubsts { substs: Substs::empty() }
2232 pub fn is_noop(&self) -> bool {
2233 self.substs.is_noop()
2237 impl<'tcx> TyS<'tcx> {
2238 fn impls_bound<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
2239 bound: ty::BuiltinBound,
2243 let tcx = param_env.tcx;
2244 let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(param_env.clone()), false);
2246 let is_impld = traits::type_known_to_meet_builtin_bound(&infcx,
2249 debug!("Ty::impls_bound({:?}, {:?}) = {:?}",
2250 self, bound, is_impld);
2255 // FIXME (@jroesch): I made this public to use it, not sure if should be private
2256 pub fn moves_by_default<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
2257 span: Span) -> bool {
2258 if self.flags.get().intersects(TypeFlags::MOVENESS_CACHED) {
2259 return self.flags.get().intersects(TypeFlags::MOVES_BY_DEFAULT);
2262 assert!(!self.needs_infer());
2264 // Fast-path for primitive types
2265 let result = match self.sty {
2266 TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
2267 TyRawPtr(..) | TyBareFn(..) | TyRef(_, TypeAndMut {
2268 mutbl: hir::MutImmutable, ..
2271 TyStr | TyBox(..) | TyRef(_, TypeAndMut {
2272 mutbl: hir::MutMutable, ..
2275 TyArray(..) | TySlice(_) | TyTrait(..) | TyTuple(..) |
2276 TyClosure(..) | TyEnum(..) | TyStruct(..) |
2277 TyProjection(..) | TyParam(..) | TyInfer(..) | TyError => None
2278 }.unwrap_or_else(|| !self.impls_bound(param_env, ty::BoundCopy, span));
2280 if !self.has_param_types() && !self.has_self_ty() {
2281 self.flags.set(self.flags.get() | if result {
2282 TypeFlags::MOVENESS_CACHED | TypeFlags::MOVES_BY_DEFAULT
2284 TypeFlags::MOVENESS_CACHED
2292 pub fn is_sized<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
2295 if self.flags.get().intersects(TypeFlags::SIZEDNESS_CACHED) {
2296 return self.flags.get().intersects(TypeFlags::IS_SIZED);
2299 self.is_sized_uncached(param_env, span)
2302 fn is_sized_uncached<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
2303 span: Span) -> bool {
2304 assert!(!self.needs_infer());
2306 // Fast-path for primitive types
2307 let result = match self.sty {
2308 TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
2309 TyBox(..) | TyRawPtr(..) | TyRef(..) | TyBareFn(..) |
2310 TyArray(..) | TyTuple(..) | TyClosure(..) => Some(true),
2312 TyStr | TyTrait(..) | TySlice(_) => Some(false),
2314 TyEnum(..) | TyStruct(..) | TyProjection(..) | TyParam(..) |
2315 TyInfer(..) | TyError => None
2316 }.unwrap_or_else(|| self.impls_bound(param_env, ty::BoundSized, span));
2318 if !self.has_param_types() && !self.has_self_ty() {
2319 self.flags.set(self.flags.get() | if result {
2320 TypeFlags::SIZEDNESS_CACHED | TypeFlags::IS_SIZED
2322 TypeFlags::SIZEDNESS_CACHED
2330 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2331 pub enum LvaluePreference {
2336 impl LvaluePreference {
2337 pub fn from_mutbl(m: hir::Mutability) -> Self {
2339 hir::MutMutable => PreferMutLvalue,
2340 hir::MutImmutable => NoPreference,
2345 /// Describes whether a type is representable. For types that are not
2346 /// representable, 'SelfRecursive' and 'ContainsRecursive' are used to
2347 /// distinguish between types that are recursive with themselves and types that
2348 /// contain a different recursive type. These cases can therefore be treated
2349 /// differently when reporting errors.
2351 /// The ordering of the cases is significant. They are sorted so that cmp::max
2352 /// will keep the "more erroneous" of two values.
2353 #[derive(Copy, Clone, PartialOrd, Ord, Eq, PartialEq, Debug)]
2354 pub enum Representability {
2360 impl<'tcx> TyS<'tcx> {
2361 /// Check whether a type is representable. This means it cannot contain unboxed
2362 /// structural recursion. This check is needed for structs and enums.
2363 pub fn is_representable(&'tcx self, cx: &ctxt<'tcx>, sp: Span) -> Representability {
2365 // Iterate until something non-representable is found
2366 fn find_nonrepresentable<'tcx, It: Iterator<Item=Ty<'tcx>>>(cx: &ctxt<'tcx>, sp: Span,
2367 seen: &mut Vec<Ty<'tcx>>,
2369 -> Representability {
2370 iter.fold(Representable,
2371 |r, ty| cmp::max(r, is_type_structurally_recursive(cx, sp, seen, ty)))
2374 fn are_inner_types_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span,
2375 seen: &mut Vec<Ty<'tcx>>, ty: Ty<'tcx>)
2376 -> Representability {
2378 TyTuple(ref ts) => {
2379 find_nonrepresentable(cx, sp, seen, ts.iter().cloned())
2381 // Fixed-length vectors.
2382 // FIXME(#11924) Behavior undecided for zero-length vectors.
2384 is_type_structurally_recursive(cx, sp, seen, ty)
2386 TyStruct(def, substs) | TyEnum(def, substs) => {
2387 find_nonrepresentable(cx,
2390 def.all_fields().map(|f| f.ty(cx, substs)))
2393 // this check is run on type definitions, so we don't expect
2394 // to see closure types
2395 cx.sess.bug(&format!("requires check invoked on inapplicable type: {:?}", ty))
2401 fn same_struct_or_enum<'tcx>(ty: Ty<'tcx>, def: AdtDef<'tcx>) -> bool {
2403 TyStruct(ty_def, _) | TyEnum(ty_def, _) => {
2410 fn same_type<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
2411 match (&a.sty, &b.sty) {
2412 (&TyStruct(did_a, ref substs_a), &TyStruct(did_b, ref substs_b)) |
2413 (&TyEnum(did_a, ref substs_a), &TyEnum(did_b, ref substs_b)) => {
2418 let types_a = substs_a.types.get_slice(subst::TypeSpace);
2419 let types_b = substs_b.types.get_slice(subst::TypeSpace);
2421 let mut pairs = types_a.iter().zip(types_b);
2423 pairs.all(|(&a, &b)| same_type(a, b))
2431 // Does the type `ty` directly (without indirection through a pointer)
2432 // contain any types on stack `seen`?
2433 fn is_type_structurally_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span,
2434 seen: &mut Vec<Ty<'tcx>>,
2435 ty: Ty<'tcx>) -> Representability {
2436 debug!("is_type_structurally_recursive: {:?}", ty);
2439 TyStruct(def, _) | TyEnum(def, _) => {
2441 // Iterate through stack of previously seen types.
2442 let mut iter = seen.iter();
2444 // The first item in `seen` is the type we are actually curious about.
2445 // We want to return SelfRecursive if this type contains itself.
2446 // It is important that we DON'T take generic parameters into account
2447 // for this check, so that Bar<T> in this example counts as SelfRecursive:
2450 // struct Bar<T> { x: Bar<Foo> }
2453 Some(&seen_type) => {
2454 if same_struct_or_enum(seen_type, def) {
2455 debug!("SelfRecursive: {:?} contains {:?}",
2458 return SelfRecursive;
2464 // We also need to know whether the first item contains other types
2465 // that are structurally recursive. If we don't catch this case, we
2466 // will recurse infinitely for some inputs.
2468 // It is important that we DO take generic parameters into account
2469 // here, so that code like this is considered SelfRecursive, not
2470 // ContainsRecursive:
2472 // struct Foo { Option<Option<Foo>> }
2474 for &seen_type in iter {
2475 if same_type(ty, seen_type) {
2476 debug!("ContainsRecursive: {:?} contains {:?}",
2479 return ContainsRecursive;
2484 // For structs and enums, track all previously seen types by pushing them
2485 // onto the 'seen' stack.
2487 let out = are_inner_types_recursive(cx, sp, seen, ty);
2492 // No need to push in other cases.
2493 are_inner_types_recursive(cx, sp, seen, ty)
2498 debug!("is_type_representable: {:?}", self);
2500 // To avoid a stack overflow when checking an enum variant or struct that
2501 // contains a different, structurally recursive type, maintain a stack
2502 // of seen types and check recursion for each of them (issues #3008, #3779).
2503 let mut seen: Vec<Ty> = Vec::new();
2504 let r = is_type_structurally_recursive(cx, sp, &mut seen, self);
2505 debug!("is_type_representable: {:?} is {:?}", self, r);
2509 /// See `expr_ty_adjusted`
2510 pub fn adjust<F>(&'tcx self, cx: &ctxt<'tcx>,
2513 adjustment: Option<&AutoAdjustment<'tcx>>,
2516 F: FnMut(MethodCall) -> Option<Ty<'tcx>>,
2518 if let TyError = self.sty {
2522 return match adjustment {
2523 Some(adjustment) => {
2525 AdjustReifyFnPointer => {
2527 ty::TyBareFn(Some(_), b) => {
2532 &format!("AdjustReifyFnPointer adjustment on non-fn-item: \
2538 AdjustUnsafeFnPointer => {
2540 ty::TyBareFn(None, b) => cx.safe_to_unsafe_fn_ty(b),
2543 &format!("AdjustReifyFnPointer adjustment on non-fn-item: \
2550 AdjustDerefRef(ref adj) => {
2551 let mut adjusted_ty = self;
2553 if !adjusted_ty.references_error() {
2554 for i in 0..adj.autoderefs {
2556 adjusted_ty.adjust_for_autoderef(cx,
2564 if let Some(target) = adj.unsize {
2567 adjusted_ty.adjust_for_autoref(cx, adj.autoref)
2576 pub fn adjust_for_autoderef<F>(&'tcx self,
2578 expr_id: ast::NodeId,
2580 autoderef: u32, // how many autoderefs so far?
2583 F: FnMut(MethodCall) -> Option<Ty<'tcx>>,
2585 let method_call = MethodCall::autoderef(expr_id, autoderef);
2586 let mut adjusted_ty = self;
2587 if let Some(method_ty) = method_type(method_call) {
2588 // Method calls always have all late-bound regions
2589 // fully instantiated.
2590 let fn_ret = cx.no_late_bound_regions(&method_ty.fn_ret()).unwrap();
2591 adjusted_ty = fn_ret.unwrap();
2593 match adjusted_ty.builtin_deref(true, NoPreference) {
2598 &format!("the {}th autoderef failed: {}",
2606 pub fn adjust_for_autoref(&'tcx self, cx: &ctxt<'tcx>,
2607 autoref: Option<AutoRef<'tcx>>)
2611 Some(AutoPtr(r, m)) => {
2612 cx.mk_ref(r, TypeAndMut { ty: self, mutbl: m })
2614 Some(AutoUnsafe(m)) => {
2615 cx.mk_ptr(TypeAndMut { ty: self, mutbl: m })
2622 /// Helper for looking things up in the various maps that are populated during
2623 /// typeck::collect (e.g., `cx.impl_or_trait_items`, `cx.tcache`, etc). All of
2624 /// these share the pattern that if the id is local, it should have been loaded
2625 /// into the map by the `typeck::collect` phase. If the def-id is external,
2626 /// then we have to go consult the crate loading code (and cache the result for
2628 fn lookup_locally_or_in_crate_store<V, F>(descr: &str,
2630 map: &RefCell<DefIdMap<V>>,
2631 load_external: F) -> V where
2635 match map.borrow().get(&def_id).cloned() {
2636 Some(v) => { return v; }
2640 if def_id.is_local() {
2641 panic!("No def'n found for {:?} in tcx.{}", def_id, descr);
2643 let v = load_external();
2644 map.borrow_mut().insert(def_id, v.clone());
2649 pub fn from_mutbl(m: hir::Mutability) -> BorrowKind {
2651 hir::MutMutable => MutBorrow,
2652 hir::MutImmutable => ImmBorrow,
2656 /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow
2657 /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a
2658 /// mutability that is stronger than necessary so that it at least *would permit* the borrow in
2660 pub fn to_mutbl_lossy(self) -> hir::Mutability {
2662 MutBorrow => hir::MutMutable,
2663 ImmBorrow => hir::MutImmutable,
2665 // We have no type corresponding to a unique imm borrow, so
2666 // use `&mut`. It gives all the capabilities of an `&uniq`
2667 // and hence is a safe "over approximation".
2668 UniqueImmBorrow => hir::MutMutable,
2672 pub fn to_user_str(&self) -> &'static str {
2674 MutBorrow => "mutable",
2675 ImmBorrow => "immutable",
2676 UniqueImmBorrow => "uniquely immutable",
2681 impl<'tcx> ctxt<'tcx> {
2682 /// Returns the type of element at index `i` in tuple or tuple-like type `t`.
2683 /// For an enum `t`, `variant` is None only if `t` is a univariant enum.
2684 pub fn positional_element_ty(&self,
2687 variant: Option<DefId>) -> Option<Ty<'tcx>> {
2688 match (&ty.sty, variant) {
2689 (&TyStruct(def, substs), None) => {
2690 def.struct_variant().fields.get(i).map(|f| f.ty(self, substs))
2692 (&TyEnum(def, substs), Some(vid)) => {
2693 def.variant_with_id(vid).fields.get(i).map(|f| f.ty(self, substs))
2695 (&TyEnum(def, substs), None) => {
2696 assert!(def.is_univariant());
2697 def.variants[0].fields.get(i).map(|f| f.ty(self, substs))
2699 (&TyTuple(ref v), None) => v.get(i).cloned(),
2704 /// Returns the type of element at field `n` in struct or struct-like type `t`.
2705 /// For an enum `t`, `variant` must be some def id.
2706 pub fn named_element_ty(&self,
2709 variant: Option<DefId>) -> Option<Ty<'tcx>> {
2710 match (&ty.sty, variant) {
2711 (&TyStruct(def, substs), None) => {
2712 def.struct_variant().find_field_named(n).map(|f| f.ty(self, substs))
2714 (&TyEnum(def, substs), Some(vid)) => {
2715 def.variant_with_id(vid).find_field_named(n).map(|f| f.ty(self, substs))
2721 pub fn node_id_to_type(&self, id: NodeId) -> Ty<'tcx> {
2722 match self.node_id_to_type_opt(id) {
2724 None => self.sess.bug(
2725 &format!("node_id_to_type: no type for node `{}`",
2726 self.map.node_to_string(id)))
2730 pub fn node_id_to_type_opt(&self, id: NodeId) -> Option<Ty<'tcx>> {
2731 self.tables.borrow().node_types.get(&id).cloned()
2734 pub fn node_id_item_substs(&self, id: NodeId) -> ItemSubsts<'tcx> {
2735 match self.tables.borrow().item_substs.get(&id) {
2736 None => ItemSubsts::empty(),
2737 Some(ts) => ts.clone(),
2741 // Returns the type of a pattern as a monotype. Like @expr_ty, this function
2742 // doesn't provide type parameter substitutions.
2743 pub fn pat_ty(&self, pat: &hir::Pat) -> Ty<'tcx> {
2744 self.node_id_to_type(pat.id)
2746 pub fn pat_ty_opt(&self, pat: &hir::Pat) -> Option<Ty<'tcx>> {
2747 self.node_id_to_type_opt(pat.id)
2750 // Returns the type of an expression as a monotype.
2752 // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in
2753 // some cases, we insert `AutoAdjustment` annotations such as auto-deref or
2754 // auto-ref. The type returned by this function does not consider such
2755 // adjustments. See `expr_ty_adjusted()` instead.
2757 // NB (2): This type doesn't provide type parameter substitutions; e.g. if you
2758 // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
2759 // instead of "fn(ty) -> T with T = isize".
2760 pub fn expr_ty(&self, expr: &hir::Expr) -> Ty<'tcx> {
2761 self.node_id_to_type(expr.id)
2764 pub fn expr_ty_opt(&self, expr: &hir::Expr) -> Option<Ty<'tcx>> {
2765 self.node_id_to_type_opt(expr.id)
2768 /// Returns the type of `expr`, considering any `AutoAdjustment`
2769 /// entry recorded for that expression.
2771 /// It would almost certainly be better to store the adjusted ty in with
2772 /// the `AutoAdjustment`, but I opted not to do this because it would
2773 /// require serializing and deserializing the type and, although that's not
2774 /// hard to do, I just hate that code so much I didn't want to touch it
2775 /// unless it was to fix it properly, which seemed a distraction from the
2776 /// thread at hand! -nmatsakis
2777 pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> Ty<'tcx> {
2779 .adjust(self, expr.span, expr.id,
2780 self.tables.borrow().adjustments.get(&expr.id),
2782 self.tables.borrow().method_map.get(&method_call).map(|method| method.ty)
2786 pub fn expr_span(&self, id: NodeId) -> Span {
2787 match self.map.find(id) {
2788 Some(ast_map::NodeExpr(e)) => {
2792 self.sess.bug(&format!("Node id {} is not an expr: {:?}",
2796 self.sess.bug(&format!("Node id {} is not present \
2797 in the node map", id));
2802 pub fn local_var_name_str(&self, id: NodeId) -> InternedString {
2803 match self.map.find(id) {
2804 Some(ast_map::NodeLocal(pat)) => {
2806 hir::PatIdent(_, ref path1, _) => path1.node.name.as_str(),
2808 self.sess.bug(&format!("Variable id {} maps to {:?}, not local", id, pat));
2812 r => self.sess.bug(&format!("Variable id {} maps to {:?}, not local", id, r)),
2816 pub fn resolve_expr(&self, expr: &hir::Expr) -> def::Def {
2817 match self.def_map.borrow().get(&expr.id) {
2818 Some(def) => def.full_def(),
2820 self.sess.span_bug(expr.span, &format!(
2821 "no def-map entry for expr {}", expr.id));
2826 pub fn expr_is_lval(&self, expr: &hir::Expr) -> bool {
2828 hir::ExprPath(..) => {
2829 // We can't use resolve_expr here, as this needs to run on broken
2830 // programs. We don't need to through - associated items are all
2832 match self.def_map.borrow().get(&expr.id) {
2833 Some(&def::PathResolution {
2834 base_def: def::DefStatic(..), ..
2835 }) | Some(&def::PathResolution {
2836 base_def: def::DefUpvar(..), ..
2837 }) | Some(&def::PathResolution {
2838 base_def: def::DefLocal(..), ..
2845 None => self.sess.span_bug(expr.span, &format!(
2846 "no def for path {}", expr.id))
2850 hir::ExprUnary(hir::UnDeref, _) |
2851 hir::ExprField(..) |
2852 hir::ExprTupField(..) |
2853 hir::ExprIndex(..) => {
2858 hir::ExprMethodCall(..) |
2859 hir::ExprStruct(..) |
2860 hir::ExprRange(..) |
2863 hir::ExprMatch(..) |
2864 hir::ExprClosure(..) |
2865 hir::ExprBlock(..) |
2866 hir::ExprRepeat(..) |
2868 hir::ExprBreak(..) |
2869 hir::ExprAgain(..) |
2871 hir::ExprWhile(..) |
2873 hir::ExprAssign(..) |
2874 hir::ExprInlineAsm(..) |
2875 hir::ExprAssignOp(..) |
2877 hir::ExprUnary(..) |
2879 hir::ExprAddrOf(..) |
2880 hir::ExprBinary(..) |
2881 hir::ExprCast(..) => {
2885 hir::ExprParen(ref e) => self.expr_is_lval(e),
2889 pub fn provided_source(&self, id: DefId) -> Option<DefId> {
2890 self.provided_method_sources.borrow().get(&id).cloned()
2893 pub fn provided_trait_methods(&self, id: DefId) -> Vec<Rc<Method<'tcx>>> {
2895 if let ItemTrait(_, _, _, ref ms) = self.map.expect_item(id.node).node {
2896 ms.iter().filter_map(|ti| {
2897 if let hir::MethodTraitItem(_, Some(_)) = ti.node {
2898 match self.impl_or_trait_item(DefId::local(ti.id)) {
2899 MethodTraitItem(m) => Some(m),
2901 self.sess.bug("provided_trait_methods(): \
2902 non-method item found from \
2903 looking up provided method?!")
2911 self.sess.bug(&format!("provided_trait_methods: `{:?}` is not a trait", id))
2914 csearch::get_provided_trait_methods(self, id)
2918 pub fn associated_consts(&self, id: DefId) -> Vec<Rc<AssociatedConst<'tcx>>> {
2920 match self.map.expect_item(id.node).node {
2921 ItemTrait(_, _, _, ref tis) => {
2922 tis.iter().filter_map(|ti| {
2923 if let hir::ConstTraitItem(_, _) = ti.node {
2924 match self.impl_or_trait_item(DefId::local(ti.id)) {
2925 ConstTraitItem(ac) => Some(ac),
2927 self.sess.bug("associated_consts(): \
2928 non-const item found from \
2929 looking up a constant?!")
2937 ItemImpl(_, _, _, _, _, ref iis) => {
2938 iis.iter().filter_map(|ii| {
2939 if let hir::ConstImplItem(_, _) = ii.node {
2940 match self.impl_or_trait_item(DefId::local(ii.id)) {
2941 ConstTraitItem(ac) => Some(ac),
2943 self.sess.bug("associated_consts(): \
2944 non-const item found from \
2945 looking up a constant?!")
2954 self.sess.bug(&format!("associated_consts: `{:?}` is not a trait \
2959 csearch::get_associated_consts(self, id)
2963 pub fn trait_items(&self, trait_did: DefId) -> Rc<Vec<ImplOrTraitItem<'tcx>>> {
2964 let mut trait_items = self.trait_items_cache.borrow_mut();
2965 match trait_items.get(&trait_did).cloned() {
2966 Some(trait_items) => trait_items,
2968 let def_ids = self.trait_item_def_ids(trait_did);
2969 let items: Rc<Vec<ImplOrTraitItem>> =
2970 Rc::new(def_ids.iter()
2971 .map(|d| self.impl_or_trait_item(d.def_id()))
2973 trait_items.insert(trait_did, items.clone());
2979 pub fn trait_impl_polarity(&self, id: DefId) -> Option<hir::ImplPolarity> {
2981 match self.map.find(id.node) {
2982 Some(ast_map::NodeItem(item)) => {
2984 hir::ItemImpl(_, polarity, _, _, _, _) => Some(polarity),
2991 csearch::get_impl_polarity(self, id)
2995 pub fn custom_coerce_unsized_kind(&self, did: DefId) -> CustomCoerceUnsized {
2996 memoized(&self.custom_coerce_unsized_kinds, did, |did: DefId| {
2997 let (kind, src) = if did.krate != LOCAL_CRATE {
2998 (csearch::get_custom_coerce_unsized_kind(self, did), "external")
3006 self.sess.bug(&format!("custom_coerce_unsized_kind: \
3007 {} impl `{}` is missing its kind",
3008 src, self.item_path_str(did)));
3014 pub fn impl_or_trait_item(&self, id: DefId) -> ImplOrTraitItem<'tcx> {
3015 lookup_locally_or_in_crate_store(
3016 "impl_or_trait_items", id, &self.impl_or_trait_items,
3017 || csearch::get_impl_or_trait_item(self, id))
3020 pub fn trait_item_def_ids(&self, id: DefId) -> Rc<Vec<ImplOrTraitItemId>> {
3021 lookup_locally_or_in_crate_store(
3022 "trait_item_def_ids", id, &self.trait_item_def_ids,
3023 || Rc::new(csearch::get_trait_item_def_ids(&self.sess.cstore, id)))
3026 /// Returns the trait-ref corresponding to a given impl, or None if it is
3027 /// an inherent impl.
3028 pub fn impl_trait_ref(&self, id: DefId) -> Option<TraitRef<'tcx>> {
3029 lookup_locally_or_in_crate_store(
3030 "impl_trait_refs", id, &self.impl_trait_refs,
3031 || csearch::get_impl_trait(self, id))
3034 /// Returns whether this DefId refers to an impl
3035 pub fn is_impl(&self, id: DefId) -> bool {
3037 if let Some(ast_map::NodeItem(
3038 &hir::Item { node: hir::ItemImpl(..), .. })) = self.map.find(id.node) {
3044 csearch::is_impl(&self.sess.cstore, id)
3048 pub fn trait_ref_to_def_id(&self, tr: &hir::TraitRef) -> DefId {
3049 self.def_map.borrow().get(&tr.ref_id).expect("no def-map entry for trait").def_id()
3052 pub fn item_path_str(&self, id: DefId) -> String {
3053 self.with_path(id, |path| ast_map::path_to_string(path))
3056 pub fn with_path<T, F>(&self, id: DefId, f: F) -> T where
3057 F: FnOnce(ast_map::PathElems) -> T,
3060 self.map.with_path(id.node, f)
3062 f(csearch::get_item_path(self, id).iter().cloned().chain(LinkedPath::empty()))
3066 pub fn item_name(&self, id: DefId) -> ast::Name {
3068 self.map.get_path_elem(id.node).name()
3070 csearch::get_item_name(self, id)
3074 /// Returns `(normalized_type, ty)`, where `normalized_type` is the
3075 /// IntType representation of one of {i64,i32,i16,i8,u64,u32,u16,u8},
3076 /// and `ty` is the original type (i.e. may include `isize` or
3078 pub fn enum_repr_type(&self, opt_hint: Option<&attr::ReprAttr>)
3079 -> (attr::IntType, Ty<'tcx>) {
3080 let repr_type = match opt_hint {
3081 // Feed in the given type
3082 Some(&attr::ReprInt(_, int_t)) => int_t,
3083 // ... but provide sensible default if none provided
3085 // NB. Historically `fn enum_variants` generate i64 here, while
3086 // rustc_typeck::check would generate isize.
3087 _ => SignedInt(hir::TyIs),
3090 let repr_type_ty = repr_type.to_ty(self);
3091 let repr_type = match repr_type {
3092 SignedInt(hir::TyIs) =>
3093 SignedInt(self.sess.target.int_type),
3094 UnsignedInt(hir::TyUs) =>
3095 UnsignedInt(self.sess.target.uint_type),
3099 (repr_type, repr_type_ty)
3103 // Register a given item type
3104 pub fn register_item_type(&self, did: DefId, ty: TypeScheme<'tcx>) {
3105 self.tcache.borrow_mut().insert(did, ty);
3108 // If the given item is in an external crate, looks up its type and adds it to
3109 // the type cache. Returns the type parameters and type.
3110 pub fn lookup_item_type(&self, did: DefId) -> TypeScheme<'tcx> {
3111 lookup_locally_or_in_crate_store(
3112 "tcache", did, &self.tcache,
3113 || csearch::get_type(self, did))
3116 /// Given the did of a trait, returns its canonical trait ref.
3117 pub fn lookup_trait_def(&self, did: DefId) -> &'tcx TraitDef<'tcx> {
3118 lookup_locally_or_in_crate_store(
3119 "trait_defs", did, &self.trait_defs,
3120 || self.alloc_trait_def(csearch::get_trait_def(self, did))
3124 /// Given the did of an ADT, return a master reference to its
3125 /// definition. Unless you are planning on fulfilling the ADT's fields,
3126 /// use lookup_adt_def instead.
3127 pub fn lookup_adt_def_master(&self, did: DefId) -> AdtDefMaster<'tcx> {
3128 lookup_locally_or_in_crate_store(
3129 "adt_defs", did, &self.adt_defs,
3130 || csearch::get_adt_def(self, did)
3134 /// Given the did of an ADT, return a reference to its definition.
3135 pub fn lookup_adt_def(&self, did: DefId) -> AdtDef<'tcx> {
3136 // when reverse-variance goes away, a transmute::<AdtDefMaster,AdtDef>
3137 // woud be needed here.
3138 self.lookup_adt_def_master(did)
3141 /// Return the list of all interned ADT definitions
3142 pub fn adt_defs(&self) -> Vec<AdtDef<'tcx>> {
3143 self.adt_defs.borrow().values().cloned().collect()
3146 /// Given the did of an item, returns its full set of predicates.
3147 pub fn lookup_predicates(&self, did: DefId) -> GenericPredicates<'tcx> {
3148 lookup_locally_or_in_crate_store(
3149 "predicates", did, &self.predicates,
3150 || csearch::get_predicates(self, did))
3153 /// Given the did of a trait, returns its superpredicates.
3154 pub fn lookup_super_predicates(&self, did: DefId) -> GenericPredicates<'tcx> {
3155 lookup_locally_or_in_crate_store(
3156 "super_predicates", did, &self.super_predicates,
3157 || csearch::get_super_predicates(self, did))
3160 /// Get the attributes of a definition.
3161 pub fn get_attrs(&self, did: DefId) -> Cow<'tcx, [hir::Attribute]> {
3163 Cow::Borrowed(self.map.attrs(did.node))
3165 Cow::Owned(csearch::get_item_attrs(&self.sess.cstore, did))
3169 /// Determine whether an item is annotated with an attribute
3170 pub fn has_attr(&self, did: DefId, attr: &str) -> bool {
3171 self.get_attrs(did).iter().any(|item| item.check_name(attr))
3174 /// Determine whether an item is annotated with `#[repr(packed)]`
3175 pub fn lookup_packed(&self, did: DefId) -> bool {
3176 self.lookup_repr_hints(did).contains(&attr::ReprPacked)
3179 /// Determine whether an item is annotated with `#[simd]`
3180 pub fn lookup_simd(&self, did: DefId) -> bool {
3181 self.has_attr(did, "simd")
3182 || self.lookup_repr_hints(did).contains(&attr::ReprSimd)
3185 /// Obtain the representation annotation for a struct definition.
3186 pub fn lookup_repr_hints(&self, did: DefId) -> Rc<Vec<attr::ReprAttr>> {
3187 memoized(&self.repr_hint_cache, did, |did: DefId| {
3188 Rc::new(if did.is_local() {
3189 self.get_attrs(did).iter().flat_map(|meta| {
3190 attr::find_repr_attrs(self.sess.diagnostic(), meta).into_iter()
3193 csearch::get_repr_attrs(&self.sess.cstore, did)
3199 /// Returns the deeply last field of nested structures, or the same type,
3200 /// if not a structure at all. Corresponds to the only possible unsized
3201 /// field, and its type can be used to determine unsizing strategy.
3202 pub fn struct_tail(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
3203 while let TyStruct(def, substs) = ty.sty {
3204 match def.struct_variant().fields.last() {
3205 Some(f) => ty = f.ty(self, substs),
3212 /// Same as applying struct_tail on `source` and `target`, but only
3213 /// keeps going as long as the two types are instances of the same
3214 /// structure definitions.
3215 /// For `(Foo<Foo<T>>, Foo<Trait>)`, the result will be `(Foo<T>, Trait)`,
3216 /// whereas struct_tail produces `T`, and `Trait`, respectively.
3217 pub fn struct_lockstep_tails(&self,
3220 -> (Ty<'tcx>, Ty<'tcx>) {
3221 let (mut a, mut b) = (source, target);
3222 while let (&TyStruct(a_def, a_substs), &TyStruct(b_def, b_substs)) = (&a.sty, &b.sty) {
3226 if let Some(f) = a_def.struct_variant().fields.last() {
3227 a = f.ty(self, a_substs);
3228 b = f.ty(self, b_substs);
3236 // Returns the repeat count for a repeating vector expression.
3237 pub fn eval_repeat_count(&self, count_expr: &hir::Expr) -> usize {
3238 let hint = UncheckedExprHint(self.types.usize);
3239 match const_eval::eval_const_expr_partial(self, count_expr, hint) {
3241 let found = match val {
3242 ConstVal::Uint(count) => return count as usize,
3243 ConstVal::Int(count) if count >= 0 => return count as usize,
3244 const_val => const_val.description(),
3246 span_err!(self.sess, count_expr.span, E0306,
3247 "expected positive integer for repeat count, found {}",
3251 let err_msg = match count_expr.node {
3252 hir::ExprPath(None, hir::Path {
3256 }) if segments.len() == 1 =>
3257 format!("found variable"),
3258 _ => match err.kind {
3259 ErrKind::MiscCatchAll => format!("but found {}", err.description()),
3260 _ => format!("but {}", err.description())
3263 span_err!(self.sess, count_expr.span, E0307,
3264 "expected constant integer for repeat count, {}", err_msg);
3270 // Iterate over a type parameter's bounded traits and any supertraits
3271 // of those traits, ignoring kinds.
3272 // Here, the supertraits are the transitive closure of the supertrait
3273 // relation on the supertraits from each bounded trait's constraint
3275 pub fn each_bound_trait_and_supertraits<F>(&self,
3276 bounds: &[PolyTraitRef<'tcx>],
3279 F: FnMut(PolyTraitRef<'tcx>) -> bool,
3281 for bound_trait_ref in traits::transitive_bounds(self, bounds) {
3282 if !f(bound_trait_ref) {
3289 /// Given a set of predicates that apply to an object type, returns
3290 /// the region bounds that the (erased) `Self` type must
3291 /// outlive. Precisely *because* the `Self` type is erased, the
3292 /// parameter `erased_self_ty` must be supplied to indicate what type
3293 /// has been used to represent `Self` in the predicates
3294 /// themselves. This should really be a unique type; `FreshTy(0)` is a
3297 /// NB: in some cases, particularly around higher-ranked bounds,
3298 /// this function returns a kind of conservative approximation.
3299 /// That is, all regions returned by this function are definitely
3300 /// required, but there may be other region bounds that are not
3301 /// returned, as well as requirements like `for<'a> T: 'a`.
3303 /// Requires that trait definitions have been processed so that we can
3304 /// elaborate predicates and walk supertraits.
3305 pub fn required_region_bounds(&self,
3306 erased_self_ty: Ty<'tcx>,
3307 predicates: Vec<ty::Predicate<'tcx>>)
3308 -> Vec<ty::Region> {
3309 debug!("required_region_bounds(erased_self_ty={:?}, predicates={:?})",
3313 assert!(!erased_self_ty.has_escaping_regions());
3315 traits::elaborate_predicates(self, predicates)
3316 .filter_map(|predicate| {
3318 ty::Predicate::Projection(..) |
3319 ty::Predicate::Trait(..) |
3320 ty::Predicate::Equate(..) |
3321 ty::Predicate::WellFormed(..) |
3322 ty::Predicate::ObjectSafe(..) |
3323 ty::Predicate::RegionOutlives(..) => {
3326 ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(t, r))) => {
3327 // Search for a bound of the form `erased_self_ty
3328 // : 'a`, but be wary of something like `for<'a>
3329 // erased_self_ty : 'a` (we interpret a
3330 // higher-ranked bound like that as 'static,
3331 // though at present the code in `fulfill.rs`
3332 // considers such bounds to be unsatisfiable, so
3333 // it's kind of a moot point since you could never
3334 // construct such an object, but this seems
3335 // correct even if that code changes).
3336 if t == erased_self_ty && !r.has_escaping_regions() {
3347 pub fn item_variances(&self, item_id: DefId) -> Rc<ItemVariances> {
3348 lookup_locally_or_in_crate_store(
3349 "item_variance_map", item_id, &self.item_variance_map,
3350 || Rc::new(csearch::get_item_variances(&self.sess.cstore, item_id)))
3353 pub fn trait_has_default_impl(&self, trait_def_id: DefId) -> bool {
3354 self.populate_implementations_for_trait_if_necessary(trait_def_id);
3356 let def = self.lookup_trait_def(trait_def_id);
3357 def.flags.get().intersects(TraitFlags::HAS_DEFAULT_IMPL)
3360 /// Records a trait-to-implementation mapping.
3361 pub fn record_trait_has_default_impl(&self, trait_def_id: DefId) {
3362 let def = self.lookup_trait_def(trait_def_id);
3363 def.flags.set(def.flags.get() | TraitFlags::HAS_DEFAULT_IMPL)
3366 /// Load primitive inherent implementations if necessary
3367 pub fn populate_implementations_for_primitive_if_necessary(&self,
3368 primitive_def_id: DefId) {
3369 if primitive_def_id.is_local() {
3373 if self.populated_external_primitive_impls.borrow().contains(&primitive_def_id) {
3377 debug!("populate_implementations_for_primitive_if_necessary: searching for {:?}",
3380 let impl_items = csearch::get_impl_items(&self.sess.cstore, primitive_def_id);
3382 // Store the implementation info.
3383 self.impl_items.borrow_mut().insert(primitive_def_id, impl_items);
3384 self.populated_external_primitive_impls.borrow_mut().insert(primitive_def_id);
3387 /// Populates the type context with all the inherent implementations for
3388 /// the given type if necessary.
3389 pub fn populate_inherent_implementations_for_type_if_necessary(&self,
3391 if type_id.is_local() {
3395 if self.populated_external_types.borrow().contains(&type_id) {
3399 debug!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}",
3402 let mut inherent_impls = Vec::new();
3403 csearch::each_inherent_implementation_for_type(&self.sess.cstore, type_id, |impl_def_id| {
3404 // Record the implementation.
3405 inherent_impls.push(impl_def_id);
3407 // Store the implementation info.
3408 let impl_items = csearch::get_impl_items(&self.sess.cstore, impl_def_id);
3409 self.impl_items.borrow_mut().insert(impl_def_id, impl_items);
3412 self.inherent_impls.borrow_mut().insert(type_id, Rc::new(inherent_impls));
3413 self.populated_external_types.borrow_mut().insert(type_id);
3416 /// Populates the type context with all the implementations for the given
3417 /// trait if necessary.
3418 pub fn populate_implementations_for_trait_if_necessary(&self, trait_id: DefId) {
3419 if trait_id.is_local() {
3423 let def = self.lookup_trait_def(trait_id);
3424 if def.flags.get().intersects(TraitFlags::IMPLS_VALID) {
3428 debug!("populate_implementations_for_trait_if_necessary: searching for {:?}", def);
3430 if csearch::is_defaulted_trait(&self.sess.cstore, trait_id) {
3431 self.record_trait_has_default_impl(trait_id);
3434 csearch::each_implementation_for_trait(&self.sess.cstore, trait_id, |impl_def_id| {
3435 let impl_items = csearch::get_impl_items(&self.sess.cstore, impl_def_id);
3436 let trait_ref = self.impl_trait_ref(impl_def_id).unwrap();
3437 // Record the trait->implementation mapping.
3438 def.record_impl(self, impl_def_id, trait_ref);
3440 // For any methods that use a default implementation, add them to
3441 // the map. This is a bit unfortunate.
3442 for impl_item_def_id in &impl_items {
3443 let method_def_id = impl_item_def_id.def_id();
3444 match self.impl_or_trait_item(method_def_id) {
3445 MethodTraitItem(method) => {
3446 if let Some(source) = method.provided_source {
3447 self.provided_method_sources
3449 .insert(method_def_id, source);
3456 // Store the implementation info.
3457 self.impl_items.borrow_mut().insert(impl_def_id, impl_items);
3460 def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID);
3463 /// Given the def_id of an impl, return the def_id of the trait it implements.
3464 /// If it implements no trait, return `None`.
3465 pub fn trait_id_of_impl(&self, def_id: DefId) -> Option<DefId> {
3466 self.impl_trait_ref(def_id).map(|tr| tr.def_id)
3469 /// If the given def ID describes a method belonging to an impl, return the
3470 /// ID of the impl that the method belongs to. Otherwise, return `None`.
3471 pub fn impl_of_method(&self, def_id: DefId) -> Option<DefId> {
3472 if def_id.krate != LOCAL_CRATE {
3473 return match csearch::get_impl_or_trait_item(self,
3474 def_id).container() {
3475 TraitContainer(_) => None,
3476 ImplContainer(def_id) => Some(def_id),
3479 match self.impl_or_trait_items.borrow().get(&def_id).cloned() {
3480 Some(trait_item) => {
3481 match trait_item.container() {
3482 TraitContainer(_) => None,
3483 ImplContainer(def_id) => Some(def_id),
3490 /// If the given def ID describes an item belonging to a trait (either a
3491 /// default method or an implementation of a trait method), return the ID of
3492 /// the trait that the method belongs to. Otherwise, return `None`.
3493 pub fn trait_of_item(&self, def_id: DefId) -> Option<DefId> {
3494 if def_id.krate != LOCAL_CRATE {
3495 return csearch::get_trait_of_item(&self.sess.cstore, def_id, self);
3497 match self.impl_or_trait_items.borrow().get(&def_id).cloned() {
3498 Some(impl_or_trait_item) => {
3499 match impl_or_trait_item.container() {
3500 TraitContainer(def_id) => Some(def_id),
3501 ImplContainer(def_id) => self.trait_id_of_impl(def_id),
3508 /// If the given def ID describes an item belonging to a trait, (either a
3509 /// default method or an implementation of a trait method), return the ID of
3510 /// the method inside trait definition (this means that if the given def ID
3511 /// is already that of the original trait method, then the return value is
3513 /// Otherwise, return `None`.
3514 pub fn trait_item_of_item(&self, def_id: DefId) -> Option<ImplOrTraitItemId> {
3515 let impl_item = match self.impl_or_trait_items.borrow().get(&def_id) {
3516 Some(m) => m.clone(),
3517 None => return None,
3519 let name = impl_item.name();
3520 match self.trait_of_item(def_id) {
3521 Some(trait_did) => {
3522 self.trait_items(trait_did).iter()
3523 .find(|item| item.name() == name)
3524 .map(|item| item.id())
3530 /// Creates a hash of the type `Ty` which will be the same no matter what crate
3531 /// context it's calculated within. This is used by the `type_id` intrinsic.
3532 pub fn hash_crate_independent(&self, ty: Ty<'tcx>, svh: &Svh) -> u64 {
3533 let mut state = SipHasher::new();
3534 helper(self, ty, svh, &mut state);
3535 return state.finish();
3537 fn helper<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh,
3538 state: &mut SipHasher) {
3539 macro_rules! byte { ($b:expr) => { ($b as u8).hash(state) } }
3540 macro_rules! hash { ($e:expr) => { $e.hash(state) } }
3542 let region = |state: &mut SipHasher, r: Region| {
3545 ReLateBound(db, BrAnon(i)) => {
3555 ReSkolemized(..) => {
3556 tcx.sess.bug("unexpected region found when hashing a type")
3560 let did = |state: &mut SipHasher, did: DefId| {
3561 let h = if did.is_local() {
3564 tcx.sess.cstore.get_crate_hash(did.krate)
3566 h.as_str().hash(state);
3567 did.node.hash(state);
3569 let mt = |state: &mut SipHasher, mt: TypeAndMut| {
3570 mt.mutbl.hash(state);
3572 let fn_sig = |state: &mut SipHasher, sig: &Binder<FnSig<'tcx>>| {
3573 let sig = tcx.anonymize_late_bound_regions(sig).0;
3574 for a in &sig.inputs { helper(tcx, *a, svh, state); }
3575 if let ty::FnConverging(output) = sig.output {
3576 helper(tcx, output, svh, state);
3579 ty.maybe_walk(|ty| {
3621 TyBareFn(opt_def_id, ref b) => {
3626 fn_sig(state, &b.sig);
3629 TyTrait(ref data) => {
3631 did(state, data.principal_def_id());
3634 let principal = tcx.anonymize_late_bound_regions(&data.principal).0;
3635 for subty in &principal.substs.types {
3636 helper(tcx, subty, svh, state);
3645 TyTuple(ref inner) => {
3653 hash!(p.name.as_str());
3655 TyInfer(_) => unreachable!(),
3656 TyError => byte!(21),
3657 TyClosure(d, _) => {
3661 TyProjection(ref data) => {
3663 did(state, data.trait_ref.def_id);
3664 hash!(data.item_name.as_str());
3672 /// Construct a parameter environment suitable for static contexts or other contexts where there
3673 /// are no free type/lifetime parameters in scope.
3674 pub fn empty_parameter_environment<'a>(&'a self)
3675 -> ParameterEnvironment<'a,'tcx> {
3676 ty::ParameterEnvironment { tcx: self,
3677 free_substs: Substs::empty(),
3678 caller_bounds: Vec::new(),
3679 implicit_region_bound: ty::ReEmpty,
3680 selection_cache: traits::SelectionCache::new(),
3682 // for an empty parameter
3683 // environment, there ARE no free
3684 // regions, so it shouldn't matter
3685 // what we use for the free id
3686 free_id: ast::DUMMY_NODE_ID }
3689 /// Constructs and returns a substitution that can be applied to move from
3690 /// the "outer" view of a type or method to the "inner" view.
3691 /// In general, this means converting from bound parameters to
3692 /// free parameters. Since we currently represent bound/free type
3693 /// parameters in the same way, this only has an effect on regions.
3694 pub fn construct_free_substs(&self, generics: &Generics<'tcx>,
3695 free_id: NodeId) -> Substs<'tcx> {
3697 let mut types = VecPerParamSpace::empty();
3698 for def in generics.types.as_slice() {
3699 debug!("construct_parameter_environment(): push_types_from_defs: def={:?}",
3701 types.push(def.space, self.mk_param_from_def(def));
3704 let free_id_outlive = self.region_maps.item_extent(free_id);
3706 // map bound 'a => free 'a
3707 let mut regions = VecPerParamSpace::empty();
3708 for def in generics.regions.as_slice() {
3710 ReFree(FreeRegion { scope: free_id_outlive,
3711 bound_region: BrNamed(def.def_id, def.name) });
3712 debug!("push_region_params {:?}", region);
3713 regions.push(def.space, region);
3718 regions: subst::NonerasedRegions(regions)
3722 /// See `ParameterEnvironment` struct def'n for details
3723 pub fn construct_parameter_environment<'a>(&'a self,
3725 generics: &ty::Generics<'tcx>,
3726 generic_predicates: &ty::GenericPredicates<'tcx>,
3728 -> ParameterEnvironment<'a, 'tcx>
3731 // Construct the free substs.
3734 let free_substs = self.construct_free_substs(generics, free_id);
3735 let free_id_outlive = self.region_maps.item_extent(free_id);
3738 // Compute the bounds on Self and the type parameters.
3741 let bounds = generic_predicates.instantiate(self, &free_substs);
3742 let bounds = self.liberate_late_bound_regions(free_id_outlive, &ty::Binder(bounds));
3743 let predicates = bounds.predicates.into_vec();
3745 debug!("construct_parameter_environment: free_id={:?} free_subst={:?} predicates={:?}",
3751 // Finally, we have to normalize the bounds in the environment, in
3752 // case they contain any associated type projections. This process
3753 // can yield errors if the put in illegal associated types, like
3754 // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
3755 // report these errors right here; this doesn't actually feel
3756 // right to me, because constructing the environment feels like a
3757 // kind of a "idempotent" action, but I'm not sure where would be
3758 // a better place. In practice, we construct environments for
3759 // every fn once during type checking, and we'll abort if there
3760 // are any errors at that point, so after type checking you can be
3761 // sure that this will succeed without errors anyway.
3764 let unnormalized_env = ty::ParameterEnvironment {
3766 free_substs: free_substs,
3767 implicit_region_bound: ty::ReScope(free_id_outlive),
3768 caller_bounds: predicates,
3769 selection_cache: traits::SelectionCache::new(),
3773 let cause = traits::ObligationCause::misc(span, free_id);
3774 traits::normalize_param_env_or_error(unnormalized_env, cause)
3777 pub fn is_method_call(&self, expr_id: NodeId) -> bool {
3778 self.tables.borrow().method_map.contains_key(&MethodCall::expr(expr_id))
3781 pub fn is_overloaded_autoderef(&self, expr_id: NodeId, autoderefs: u32) -> bool {
3782 self.tables.borrow().method_map.contains_key(&MethodCall::autoderef(expr_id,
3786 pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
3787 Some(self.tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone())
3791 /// Returns true if this ADT is a dtorck type, i.e. whether it being
3792 /// safe for destruction requires it to be alive
3793 fn is_adt_dtorck(&self, adt: AdtDef<'tcx>) -> bool {
3794 let dtor_method = match adt.destructor() {
3796 None => return false
3798 let impl_did = self.impl_of_method(dtor_method).unwrap_or_else(|| {
3799 self.sess.bug(&format!("no Drop impl for the dtor of `{:?}`", adt))
3801 let generics = adt.type_scheme(self).generics;
3803 // In `impl<'a> Drop ...`, we automatically assume
3804 // `'a` is meaningful and thus represents a bound
3805 // through which we could reach borrowed data.
3807 // FIXME (pnkfelix): In the future it would be good to
3808 // extend the language to allow the user to express,
3809 // in the impl signature, that a lifetime is not
3810 // actually used (something like `where 'a: ?Live`).
3811 if generics.has_region_params(subst::TypeSpace) {
3812 debug!("typ: {:?} has interesting dtor due to region params",
3817 let mut seen_items = Vec::new();
3818 let mut items_to_inspect = vec![impl_did];
3819 while let Some(item_def_id) = items_to_inspect.pop() {
3820 if seen_items.contains(&item_def_id) {
3824 for pred in self.lookup_predicates(item_def_id).predicates {
3825 let result = match pred {
3826 ty::Predicate::Equate(..) |
3827 ty::Predicate::RegionOutlives(..) |
3828 ty::Predicate::TypeOutlives(..) |
3829 ty::Predicate::WellFormed(..) |
3830 ty::Predicate::ObjectSafe(..) |
3831 ty::Predicate::Projection(..) => {
3832 // For now, assume all these where-clauses
3833 // may give drop implementation capabilty
3834 // to access borrowed data.
3838 ty::Predicate::Trait(ty::Binder(ref t_pred)) => {
3839 let def_id = t_pred.trait_ref.def_id;
3840 if self.trait_items(def_id).len() != 0 {
3841 // If trait has items, assume it adds
3842 // capability to access borrowed data.
3845 // Trait without items is itself
3846 // uninteresting from POV of dropck.
3848 // However, may have parent w/ items;
3849 // so schedule checking of predicates,
3850 items_to_inspect.push(def_id);
3851 // and say "no capability found" for now.
3858 debug!("typ: {:?} has interesting dtor due to generic preds, e.g. {:?}",
3864 seen_items.push(item_def_id);
3867 debug!("typ: {:?} is dtorck-safe", adt);
3872 /// The category of explicit self.
3873 #[derive(Clone, Copy, Eq, PartialEq, Debug)]
3874 pub enum ExplicitSelfCategory {
3875 StaticExplicitSelfCategory,
3876 ByValueExplicitSelfCategory,
3877 ByReferenceExplicitSelfCategory(Region, hir::Mutability),
3878 ByBoxExplicitSelfCategory,
3881 /// A free variable referred to in a function.
3882 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
3883 pub struct Freevar {
3884 /// The variable being accessed free.
3887 // First span where it is accessed (there can be multiple).
3891 pub type FreevarMap = NodeMap<Vec<Freevar>>;
3893 pub type CaptureModeMap = NodeMap<hir::CaptureClause>;
3895 // Trait method resolution
3896 pub type TraitMap = NodeMap<Vec<DefId>>;
3898 // Map from the NodeId of a glob import to a list of items which are actually
3900 pub type GlobMap = HashMap<NodeId, HashSet<Name>>;
3902 impl<'tcx> AutoAdjustment<'tcx> {
3903 pub fn is_identity(&self) -> bool {
3905 AdjustReifyFnPointer |
3906 AdjustUnsafeFnPointer => false,
3907 AdjustDerefRef(ref r) => r.is_identity(),
3912 impl<'tcx> AutoDerefRef<'tcx> {
3913 pub fn is_identity(&self) -> bool {
3914 self.autoderefs == 0 && self.unsize.is_none() && self.autoref.is_none()
3918 impl<'tcx> ctxt<'tcx> {
3919 pub fn with_freevars<T, F>(&self, fid: NodeId, f: F) -> T where
3920 F: FnOnce(&[Freevar]) -> T,
3922 match self.freevars.borrow().get(&fid) {
3924 Some(d) => f(&d[..])
3928 pub fn make_substs_for_receiver_types(&self,
3929 trait_ref: &ty::TraitRef<'tcx>,
3930 method: &ty::Method<'tcx>)
3931 -> subst::Substs<'tcx>
3934 * Substitutes the values for the receiver's type parameters
3935 * that are found in method, leaving the method's type parameters
3939 let meth_tps: Vec<Ty> =
3940 method.generics.types.get_slice(subst::FnSpace)
3942 .map(|def| self.mk_param_from_def(def))
3944 let meth_regions: Vec<ty::Region> =
3945 method.generics.regions.get_slice(subst::FnSpace)
3947 .map(|def| def.to_early_bound_region())
3949 trait_ref.substs.clone().with_method(meth_tps, meth_regions)
3953 /// An "escaping region" is a bound region whose binder is not part of `t`.
3955 /// So, for example, consider a type like the following, which has two binders:
3957 /// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize))
3958 /// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope
3959 /// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope
3961 /// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the
3962 /// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
3963 /// fn type*, that type has an escaping region: `'a`.
3965 /// Note that what I'm calling an "escaping region" is often just called a "free region". However,
3966 /// we already use the term "free region". It refers to the regions that we use to represent bound
3967 /// regions on a fn definition while we are typechecking its body.
3969 /// To clarify, conceptually there is no particular difference between an "escaping" region and a
3970 /// "free" region. However, there is a big difference in practice. Basically, when "entering" a
3971 /// binding level, one is generally required to do some sort of processing to a bound region, such
3972 /// as replacing it with a fresh/skolemized region, or making an entry in the environment to
3973 /// represent the scope to which it is attached, etc. An escaping region represents a bound region
3974 /// for which this processing has not yet been done.
3975 pub trait RegionEscape {
3976 fn has_escaping_regions(&self) -> bool {
3977 self.has_regions_escaping_depth(0)
3980 fn has_regions_escaping_depth(&self, depth: u32) -> bool;
3983 pub trait HasTypeFlags {
3984 fn has_type_flags(&self, flags: TypeFlags) -> bool;
3985 fn has_projection_types(&self) -> bool {
3986 self.has_type_flags(TypeFlags::HAS_PROJECTION)
3988 fn references_error(&self) -> bool {
3989 self.has_type_flags(TypeFlags::HAS_TY_ERR)
3991 fn has_param_types(&self) -> bool {
3992 self.has_type_flags(TypeFlags::HAS_PARAMS)
3994 fn has_self_ty(&self) -> bool {
3995 self.has_type_flags(TypeFlags::HAS_SELF)
3997 fn has_infer_types(&self) -> bool {
3998 self.has_type_flags(TypeFlags::HAS_TY_INFER)
4000 fn needs_infer(&self) -> bool {
4001 self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER)
4003 fn needs_subst(&self) -> bool {
4004 self.has_type_flags(TypeFlags::NEEDS_SUBST)
4006 fn has_closure_types(&self) -> bool {
4007 self.has_type_flags(TypeFlags::HAS_TY_CLOSURE)
4009 fn has_erasable_regions(&self) -> bool {
4010 self.has_type_flags(TypeFlags::HAS_RE_EARLY_BOUND |
4011 TypeFlags::HAS_RE_INFER |
4012 TypeFlags::HAS_FREE_REGIONS)
4014 /// Indicates whether this value references only 'global'
4015 /// types/lifetimes that are the same regardless of what fn we are
4016 /// in. This is used for caching. Errs on the side of returning
4018 fn is_global(&self) -> bool {
4019 !self.has_type_flags(TypeFlags::HAS_LOCAL_NAMES)