]> git.proxmox.com Git - rustc.git/blob - src/librustc/ty/mod.rs
New upstream version 1.15.0+dfsg1
[rustc.git] / src / librustc / ty / mod.rs
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.
4 //
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.
10
11 pub use self::Variance::*;
12 pub use self::DtorKind::*;
13 pub use self::AssociatedItemContainer::*;
14 pub use self::BorrowKind::*;
15 pub use self::IntVarValue::*;
16 pub use self::LvaluePreference::*;
17 pub use self::fold::TypeFoldable;
18
19 use dep_graph::{self, DepNode};
20 use hir::map as ast_map;
21 use middle;
22 use hir::def::{Def, CtorKind, ExportMap};
23 use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
24 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
25 use middle::region::{CodeExtent, ROOT_CODE_EXTENT};
26 use mir::Mir;
27 use traits;
28 use ty;
29 use ty::subst::{Subst, Substs};
30 use ty::walk::TypeWalker;
31 use util::common::MemoizationMap;
32 use util::nodemap::{NodeSet, NodeMap, FxHashMap, FxHashSet};
33
34 use serialize::{self, Encodable, Encoder};
35 use std::borrow::Cow;
36 use std::cell::{Cell, RefCell, Ref};
37 use std::hash::{Hash, Hasher};
38 use std::iter;
39 use std::ops::Deref;
40 use std::rc::Rc;
41 use std::slice;
42 use std::vec::IntoIter;
43 use std::mem;
44 use syntax::ast::{self, Name, NodeId};
45 use syntax::attr;
46 use syntax::symbol::{Symbol, InternedString};
47 use syntax_pos::{DUMMY_SP, Span};
48
49 use rustc_const_math::ConstInt;
50 use rustc_data_structures::accumulate_vec::IntoIter as AccIntoIter;
51
52 use hir;
53 use hir::itemlikevisit::ItemLikeVisitor;
54
55 pub use self::sty::{Binder, DebruijnIndex};
56 pub use self::sty::{BareFnTy, FnSig, PolyFnSig};
57 pub use self::sty::{ClosureTy, InferTy, ParamTy, ProjectionTy, ExistentialPredicate};
58 pub use self::sty::{ClosureSubsts, TypeAndMut};
59 pub use self::sty::{TraitRef, TypeVariants, PolyTraitRef};
60 pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef};
61 pub use self::sty::{ExistentialProjection, PolyExistentialProjection};
62 pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
63 pub use self::sty::Issue32330;
64 pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid};
65 pub use self::sty::BoundRegion::*;
66 pub use self::sty::InferTy::*;
67 pub use self::sty::Region::*;
68 pub use self::sty::TypeVariants::*;
69
70 pub use self::contents::TypeContents;
71 pub use self::context::{TyCtxt, tls};
72 pub use self::context::{CtxtArenas, Lift, Tables};
73
74 pub use self::trait_def::{TraitDef, TraitFlags};
75
76 pub mod adjustment;
77 pub mod cast;
78 pub mod error;
79 pub mod fast_reject;
80 pub mod fold;
81 pub mod item_path;
82 pub mod layout;
83 pub mod _match;
84 pub mod maps;
85 pub mod outlives;
86 pub mod relate;
87 pub mod subst;
88 pub mod trait_def;
89 pub mod walk;
90 pub mod wf;
91 pub mod util;
92
93 mod contents;
94 mod context;
95 mod flags;
96 mod structural_impls;
97 mod sty;
98
99 pub type Disr = ConstInt;
100
101 // Data types
102
103 /// The complete set of all analyses described in this module. This is
104 /// produced by the driver and fed to trans and later passes.
105 #[derive(Clone)]
106 pub struct CrateAnalysis<'tcx> {
107 pub export_map: ExportMap,
108 pub access_levels: middle::privacy::AccessLevels,
109 pub reachable: NodeSet,
110 pub name: String,
111 pub glob_map: Option<hir::GlobMap>,
112 pub hir_ty_to_ty: NodeMap<Ty<'tcx>>,
113 }
114
115 #[derive(Copy, Clone)]
116 pub enum DtorKind {
117 NoDtor,
118 TraitDtor
119 }
120
121 impl DtorKind {
122 pub fn is_present(&self) -> bool {
123 match *self {
124 TraitDtor => true,
125 _ => false
126 }
127 }
128 }
129
130 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
131 pub enum AssociatedItemContainer {
132 TraitContainer(DefId),
133 ImplContainer(DefId),
134 }
135
136 impl AssociatedItemContainer {
137 pub fn id(&self) -> DefId {
138 match *self {
139 TraitContainer(id) => id,
140 ImplContainer(id) => id,
141 }
142 }
143 }
144
145 /// The "header" of an impl is everything outside the body: a Self type, a trait
146 /// ref (in the case of a trait impl), and a set of predicates (from the
147 /// bounds/where clauses).
148 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
149 pub struct ImplHeader<'tcx> {
150 pub impl_def_id: DefId,
151 pub self_ty: Ty<'tcx>,
152 pub trait_ref: Option<TraitRef<'tcx>>,
153 pub predicates: Vec<Predicate<'tcx>>,
154 }
155
156 impl<'a, 'gcx, 'tcx> ImplHeader<'tcx> {
157 pub fn with_fresh_ty_vars(selcx: &mut traits::SelectionContext<'a, 'gcx, 'tcx>,
158 impl_def_id: DefId)
159 -> ImplHeader<'tcx>
160 {
161 let tcx = selcx.tcx();
162 let impl_substs = selcx.infcx().fresh_substs_for_item(DUMMY_SP, impl_def_id);
163
164 let header = ImplHeader {
165 impl_def_id: impl_def_id,
166 self_ty: tcx.item_type(impl_def_id),
167 trait_ref: tcx.impl_trait_ref(impl_def_id),
168 predicates: tcx.item_predicates(impl_def_id).predicates
169 }.subst(tcx, impl_substs);
170
171 let traits::Normalized { value: mut header, obligations } =
172 traits::normalize(selcx, traits::ObligationCause::dummy(), &header);
173
174 header.predicates.extend(obligations.into_iter().map(|o| o.predicate));
175 header
176 }
177 }
178
179 #[derive(Copy, Clone, Debug)]
180 pub struct AssociatedItem {
181 pub def_id: DefId,
182 pub name: Name,
183 pub kind: AssociatedKind,
184 pub vis: Visibility,
185 pub defaultness: hir::Defaultness,
186 pub container: AssociatedItemContainer,
187
188 /// Whether this is a method with an explicit self
189 /// as its first argument, allowing method calls.
190 pub method_has_self_argument: bool,
191 }
192
193 #[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
194 pub enum AssociatedKind {
195 Const,
196 Method,
197 Type
198 }
199
200 impl AssociatedItem {
201 pub fn def(&self) -> Def {
202 match self.kind {
203 AssociatedKind::Const => Def::AssociatedConst(self.def_id),
204 AssociatedKind::Method => Def::Method(self.def_id),
205 AssociatedKind::Type => Def::AssociatedTy(self.def_id),
206 }
207 }
208 }
209
210 #[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable)]
211 pub enum Visibility {
212 /// Visible everywhere (including in other crates).
213 Public,
214 /// Visible only in the given crate-local module.
215 Restricted(NodeId),
216 /// Not visible anywhere in the local crate. This is the visibility of private external items.
217 PrivateExternal,
218 }
219
220 pub trait NodeIdTree {
221 fn is_descendant_of(&self, node: NodeId, ancestor: NodeId) -> bool;
222 }
223
224 impl<'a> NodeIdTree for ast_map::Map<'a> {
225 fn is_descendant_of(&self, node: NodeId, ancestor: NodeId) -> bool {
226 let mut node_ancestor = node;
227 while node_ancestor != ancestor {
228 let node_ancestor_parent = self.get_module_parent(node_ancestor);
229 if node_ancestor_parent == node_ancestor {
230 return false;
231 }
232 node_ancestor = node_ancestor_parent;
233 }
234 true
235 }
236 }
237
238 impl Visibility {
239 pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: TyCtxt) -> Self {
240 match *visibility {
241 hir::Public => Visibility::Public,
242 hir::Visibility::Crate => Visibility::Restricted(ast::CRATE_NODE_ID),
243 hir::Visibility::Restricted { ref path, .. } => match path.def {
244 // If there is no resolution, `resolve` will have already reported an error, so
245 // assume that the visibility is public to avoid reporting more privacy errors.
246 Def::Err => Visibility::Public,
247 def => Visibility::Restricted(tcx.map.as_local_node_id(def.def_id()).unwrap()),
248 },
249 hir::Inherited => Visibility::Restricted(tcx.map.get_module_parent(id)),
250 }
251 }
252
253 /// Returns true if an item with this visibility is accessible from the given block.
254 pub fn is_accessible_from<T: NodeIdTree>(self, block: NodeId, tree: &T) -> bool {
255 let restriction = match self {
256 // Public items are visible everywhere.
257 Visibility::Public => return true,
258 // Private items from other crates are visible nowhere.
259 Visibility::PrivateExternal => return false,
260 // Restricted items are visible in an arbitrary local module.
261 Visibility::Restricted(module) => module,
262 };
263
264 tree.is_descendant_of(block, restriction)
265 }
266
267 /// Returns true if this visibility is at least as accessible as the given visibility
268 pub fn is_at_least<T: NodeIdTree>(self, vis: Visibility, tree: &T) -> bool {
269 let vis_restriction = match vis {
270 Visibility::Public => return self == Visibility::Public,
271 Visibility::PrivateExternal => return true,
272 Visibility::Restricted(module) => module,
273 };
274
275 self.is_accessible_from(vis_restriction, tree)
276 }
277 }
278
279 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Copy)]
280 pub enum Variance {
281 Covariant, // T<A> <: T<B> iff A <: B -- e.g., function return type
282 Invariant, // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
283 Contravariant, // T<A> <: T<B> iff B <: A -- e.g., function param type
284 Bivariant, // T<A> <: T<B> -- e.g., unused type parameter
285 }
286
287 #[derive(Clone, Copy, Debug, RustcDecodable, RustcEncodable)]
288 pub struct MethodCallee<'tcx> {
289 /// Impl method ID, for inherent methods, or trait method ID, otherwise.
290 pub def_id: DefId,
291 pub ty: Ty<'tcx>,
292 pub substs: &'tcx Substs<'tcx>
293 }
294
295 /// With method calls, we store some extra information in
296 /// side tables (i.e method_map). We use
297 /// MethodCall as a key to index into these tables instead of
298 /// just directly using the expression's NodeId. The reason
299 /// for this being that we may apply adjustments (coercions)
300 /// with the resulting expression also needing to use the
301 /// side tables. The problem with this is that we don't
302 /// assign a separate NodeId to this new expression
303 /// and so it would clash with the base expression if both
304 /// needed to add to the side tables. Thus to disambiguate
305 /// we also keep track of whether there's an adjustment in
306 /// our key.
307 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
308 pub struct MethodCall {
309 pub expr_id: NodeId,
310 pub autoderef: u32
311 }
312
313 impl MethodCall {
314 pub fn expr(id: NodeId) -> MethodCall {
315 MethodCall {
316 expr_id: id,
317 autoderef: 0
318 }
319 }
320
321 pub fn autoderef(expr_id: NodeId, autoderef: u32) -> MethodCall {
322 MethodCall {
323 expr_id: expr_id,
324 autoderef: 1 + autoderef
325 }
326 }
327 }
328
329 // maps from an expression id that corresponds to a method call to the details
330 // of the method to be invoked
331 pub type MethodMap<'tcx> = FxHashMap<MethodCall, MethodCallee<'tcx>>;
332
333 // Contains information needed to resolve types and (in the future) look up
334 // the types of AST nodes.
335 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
336 pub struct CReaderCacheKey {
337 pub cnum: CrateNum,
338 pub pos: usize,
339 }
340
341 /// Describes the fragment-state associated with a NodeId.
342 ///
343 /// Currently only unfragmented paths have entries in the table,
344 /// but longer-term this enum is expected to expand to also
345 /// include data for fragmented paths.
346 #[derive(Copy, Clone, Debug)]
347 pub enum FragmentInfo {
348 Moved { var: NodeId, move_expr: NodeId },
349 Assigned { var: NodeId, assign_expr: NodeId, assignee_id: NodeId },
350 }
351
352 // Flags that we track on types. These flags are propagated upwards
353 // through the type during type construction, so that we can quickly
354 // check whether the type has various kinds of types in it without
355 // recursing over the type itself.
356 bitflags! {
357 flags TypeFlags: u32 {
358 const HAS_PARAMS = 1 << 0,
359 const HAS_SELF = 1 << 1,
360 const HAS_TY_INFER = 1 << 2,
361 const HAS_RE_INFER = 1 << 3,
362 const HAS_RE_SKOL = 1 << 4,
363 const HAS_RE_EARLY_BOUND = 1 << 5,
364 const HAS_FREE_REGIONS = 1 << 6,
365 const HAS_TY_ERR = 1 << 7,
366 const HAS_PROJECTION = 1 << 8,
367 const HAS_TY_CLOSURE = 1 << 9,
368
369 // true if there are "names" of types and regions and so forth
370 // that are local to a particular fn
371 const HAS_LOCAL_NAMES = 1 << 10,
372
373 // Present if the type belongs in a local type context.
374 // Only set for TyInfer other than Fresh.
375 const KEEP_IN_LOCAL_TCX = 1 << 11,
376
377 // Is there a projection that does not involve a bound region?
378 // Currently we can't normalize projections w/ bound regions.
379 const HAS_NORMALIZABLE_PROJECTION = 1 << 12,
380
381 const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits |
382 TypeFlags::HAS_SELF.bits |
383 TypeFlags::HAS_RE_EARLY_BOUND.bits,
384
385 // Flags representing the nominal content of a type,
386 // computed by FlagsComputation. If you add a new nominal
387 // flag, it should be added here too.
388 const NOMINAL_FLAGS = TypeFlags::HAS_PARAMS.bits |
389 TypeFlags::HAS_SELF.bits |
390 TypeFlags::HAS_TY_INFER.bits |
391 TypeFlags::HAS_RE_INFER.bits |
392 TypeFlags::HAS_RE_SKOL.bits |
393 TypeFlags::HAS_RE_EARLY_BOUND.bits |
394 TypeFlags::HAS_FREE_REGIONS.bits |
395 TypeFlags::HAS_TY_ERR.bits |
396 TypeFlags::HAS_PROJECTION.bits |
397 TypeFlags::HAS_TY_CLOSURE.bits |
398 TypeFlags::HAS_LOCAL_NAMES.bits |
399 TypeFlags::KEEP_IN_LOCAL_TCX.bits,
400
401 // Caches for type_is_sized, type_moves_by_default
402 const SIZEDNESS_CACHED = 1 << 16,
403 const IS_SIZED = 1 << 17,
404 const MOVENESS_CACHED = 1 << 18,
405 const MOVES_BY_DEFAULT = 1 << 19,
406 }
407 }
408
409 pub struct TyS<'tcx> {
410 pub sty: TypeVariants<'tcx>,
411 pub flags: Cell<TypeFlags>,
412
413 // the maximal depth of any bound regions appearing in this type.
414 region_depth: u32,
415 }
416
417 impl<'tcx> PartialEq for TyS<'tcx> {
418 #[inline]
419 fn eq(&self, other: &TyS<'tcx>) -> bool {
420 // (self as *const _) == (other as *const _)
421 (self as *const TyS<'tcx>) == (other as *const TyS<'tcx>)
422 }
423 }
424 impl<'tcx> Eq for TyS<'tcx> {}
425
426 impl<'tcx> Hash for TyS<'tcx> {
427 fn hash<H: Hasher>(&self, s: &mut H) {
428 (self as *const TyS).hash(s)
429 }
430 }
431
432 pub type Ty<'tcx> = &'tcx TyS<'tcx>;
433
434 impl<'tcx> serialize::UseSpecializedEncodable for Ty<'tcx> {}
435 impl<'tcx> serialize::UseSpecializedDecodable for Ty<'tcx> {}
436
437 /// A wrapper for slices with the additional invariant
438 /// that the slice is interned and no other slice with
439 /// the same contents can exist in the same context.
440 /// This means we can use pointer + length for both
441 /// equality comparisons and hashing.
442 #[derive(Debug, RustcEncodable)]
443 pub struct Slice<T>([T]);
444
445 impl<T> PartialEq for Slice<T> {
446 #[inline]
447 fn eq(&self, other: &Slice<T>) -> bool {
448 (&self.0 as *const [T]) == (&other.0 as *const [T])
449 }
450 }
451 impl<T> Eq for Slice<T> {}
452
453 impl<T> Hash for Slice<T> {
454 fn hash<H: Hasher>(&self, s: &mut H) {
455 (self.as_ptr(), self.len()).hash(s)
456 }
457 }
458
459 impl<T> Deref for Slice<T> {
460 type Target = [T];
461 fn deref(&self) -> &[T] {
462 &self.0
463 }
464 }
465
466 impl<'a, T> IntoIterator for &'a Slice<T> {
467 type Item = &'a T;
468 type IntoIter = <&'a [T] as IntoIterator>::IntoIter;
469 fn into_iter(self) -> Self::IntoIter {
470 self[..].iter()
471 }
472 }
473
474 impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Slice<Ty<'tcx>> {}
475
476 impl<T> Slice<T> {
477 pub fn empty<'a>() -> &'a Slice<T> {
478 unsafe {
479 mem::transmute(slice::from_raw_parts(0x1 as *const T, 0))
480 }
481 }
482 }
483
484 /// Upvars do not get their own node-id. Instead, we use the pair of
485 /// the original var id (that is, the root variable that is referenced
486 /// by the upvar) and the id of the closure expression.
487 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
488 pub struct UpvarId {
489 pub var_id: NodeId,
490 pub closure_expr_id: NodeId,
491 }
492
493 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)]
494 pub enum BorrowKind {
495 /// Data must be immutable and is aliasable.
496 ImmBorrow,
497
498 /// Data must be immutable but not aliasable. This kind of borrow
499 /// cannot currently be expressed by the user and is used only in
500 /// implicit closure bindings. It is needed when you the closure
501 /// is borrowing or mutating a mutable referent, e.g.:
502 ///
503 /// let x: &mut isize = ...;
504 /// let y = || *x += 5;
505 ///
506 /// If we were to try to translate this closure into a more explicit
507 /// form, we'd encounter an error with the code as written:
508 ///
509 /// struct Env { x: & &mut isize }
510 /// let x: &mut isize = ...;
511 /// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn
512 /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
513 ///
514 /// This is then illegal because you cannot mutate a `&mut` found
515 /// in an aliasable location. To solve, you'd have to translate with
516 /// an `&mut` borrow:
517 ///
518 /// struct Env { x: & &mut isize }
519 /// let x: &mut isize = ...;
520 /// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
521 /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
522 ///
523 /// Now the assignment to `**env.x` is legal, but creating a
524 /// mutable pointer to `x` is not because `x` is not mutable. We
525 /// could fix this by declaring `x` as `let mut x`. This is ok in
526 /// user code, if awkward, but extra weird for closures, since the
527 /// borrow is hidden.
528 ///
529 /// So we introduce a "unique imm" borrow -- the referent is
530 /// immutable, but not aliasable. This solves the problem. For
531 /// simplicity, we don't give users the way to express this
532 /// borrow, it's just used when translating closures.
533 UniqueImmBorrow,
534
535 /// Data is mutable and not aliasable.
536 MutBorrow
537 }
538
539 /// Information describing the capture of an upvar. This is computed
540 /// during `typeck`, specifically by `regionck`.
541 #[derive(PartialEq, Clone, Debug, Copy, RustcEncodable, RustcDecodable)]
542 pub enum UpvarCapture<'tcx> {
543 /// Upvar is captured by value. This is always true when the
544 /// closure is labeled `move`, but can also be true in other cases
545 /// depending on inference.
546 ByValue,
547
548 /// Upvar is captured by reference.
549 ByRef(UpvarBorrow<'tcx>),
550 }
551
552 #[derive(PartialEq, Clone, Copy, RustcEncodable, RustcDecodable)]
553 pub struct UpvarBorrow<'tcx> {
554 /// The kind of borrow: by-ref upvars have access to shared
555 /// immutable borrows, which are not part of the normal language
556 /// syntax.
557 pub kind: BorrowKind,
558
559 /// Region of the resulting reference.
560 pub region: &'tcx ty::Region,
561 }
562
563 pub type UpvarCaptureMap<'tcx> = FxHashMap<UpvarId, UpvarCapture<'tcx>>;
564
565 #[derive(Copy, Clone)]
566 pub struct ClosureUpvar<'tcx> {
567 pub def: Def,
568 pub span: Span,
569 pub ty: Ty<'tcx>,
570 }
571
572 #[derive(Clone, Copy, PartialEq)]
573 pub enum IntVarValue {
574 IntType(ast::IntTy),
575 UintType(ast::UintTy),
576 }
577
578 /// Default region to use for the bound of objects that are
579 /// supplied as the value for this type parameter. This is derived
580 /// from `T:'a` annotations appearing in the type definition. If
581 /// this is `None`, then the default is inherited from the
582 /// surrounding context. See RFC #599 for details.
583 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
584 pub enum ObjectLifetimeDefault<'tcx> {
585 /// Require an explicit annotation. Occurs when multiple
586 /// `T:'a` constraints are found.
587 Ambiguous,
588
589 /// Use the base default, typically 'static, but in a fn body it is a fresh variable
590 BaseDefault,
591
592 /// Use the given region as the default.
593 Specific(&'tcx Region),
594 }
595
596 #[derive(Clone, RustcEncodable, RustcDecodable)]
597 pub struct TypeParameterDef<'tcx> {
598 pub name: Name,
599 pub def_id: DefId,
600 pub index: u32,
601 pub default_def_id: DefId, // for use in error reporing about defaults
602 pub default: Option<Ty<'tcx>>,
603 pub object_lifetime_default: ObjectLifetimeDefault<'tcx>,
604
605 /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute
606 /// on generic parameter `T`, asserts data behind the parameter
607 /// `T` won't be accessed during the parent type's `Drop` impl.
608 pub pure_wrt_drop: bool,
609 }
610
611 #[derive(Clone, RustcEncodable, RustcDecodable)]
612 pub struct RegionParameterDef<'tcx> {
613 pub name: Name,
614 pub def_id: DefId,
615 pub index: u32,
616 pub bounds: Vec<&'tcx ty::Region>,
617
618 /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute
619 /// on generic parameter `'a`, asserts data of lifetime `'a`
620 /// won't be accessed during the parent type's `Drop` impl.
621 pub pure_wrt_drop: bool,
622 }
623
624 impl<'tcx> RegionParameterDef<'tcx> {
625 pub fn to_early_bound_region_data(&self) -> ty::EarlyBoundRegion {
626 ty::EarlyBoundRegion {
627 index: self.index,
628 name: self.name,
629 }
630 }
631
632 pub fn to_bound_region(&self) -> ty::BoundRegion {
633 // this is an early bound region, so unaffected by #32330
634 ty::BoundRegion::BrNamed(self.def_id, self.name, Issue32330::WontChange)
635 }
636 }
637
638 /// Information about the formal type/lifetime parameters associated
639 /// with an item or method. Analogous to hir::Generics.
640 #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
641 pub struct Generics<'tcx> {
642 pub parent: Option<DefId>,
643 pub parent_regions: u32,
644 pub parent_types: u32,
645 pub regions: Vec<RegionParameterDef<'tcx>>,
646 pub types: Vec<TypeParameterDef<'tcx>>,
647 pub has_self: bool,
648 }
649
650 impl<'tcx> Generics<'tcx> {
651 pub fn parent_count(&self) -> usize {
652 self.parent_regions as usize + self.parent_types as usize
653 }
654
655 pub fn own_count(&self) -> usize {
656 self.regions.len() + self.types.len()
657 }
658
659 pub fn count(&self) -> usize {
660 self.parent_count() + self.own_count()
661 }
662
663 pub fn region_param(&self, param: &EarlyBoundRegion) -> &RegionParameterDef<'tcx> {
664 &self.regions[param.index as usize - self.has_self as usize]
665 }
666
667 pub fn type_param(&self, param: &ParamTy) -> &TypeParameterDef<'tcx> {
668 &self.types[param.idx as usize - self.has_self as usize - self.regions.len()]
669 }
670 }
671
672 /// Bounds on generics.
673 #[derive(Clone)]
674 pub struct GenericPredicates<'tcx> {
675 pub parent: Option<DefId>,
676 pub predicates: Vec<Predicate<'tcx>>,
677 }
678
679 impl<'tcx> serialize::UseSpecializedEncodable for GenericPredicates<'tcx> {}
680 impl<'tcx> serialize::UseSpecializedDecodable for GenericPredicates<'tcx> {}
681
682 impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {
683 pub fn instantiate(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>)
684 -> InstantiatedPredicates<'tcx> {
685 let mut instantiated = InstantiatedPredicates::empty();
686 self.instantiate_into(tcx, &mut instantiated, substs);
687 instantiated
688 }
689 pub fn instantiate_own(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>)
690 -> InstantiatedPredicates<'tcx> {
691 InstantiatedPredicates {
692 predicates: self.predicates.subst(tcx, substs)
693 }
694 }
695
696 fn instantiate_into(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
697 instantiated: &mut InstantiatedPredicates<'tcx>,
698 substs: &Substs<'tcx>) {
699 if let Some(def_id) = self.parent {
700 tcx.item_predicates(def_id).instantiate_into(tcx, instantiated, substs);
701 }
702 instantiated.predicates.extend(self.predicates.iter().map(|p| p.subst(tcx, substs)))
703 }
704
705 pub fn instantiate_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
706 poly_trait_ref: &ty::PolyTraitRef<'tcx>)
707 -> InstantiatedPredicates<'tcx>
708 {
709 assert_eq!(self.parent, None);
710 InstantiatedPredicates {
711 predicates: self.predicates.iter().map(|pred| {
712 pred.subst_supertrait(tcx, poly_trait_ref)
713 }).collect()
714 }
715 }
716 }
717
718 #[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
719 pub enum Predicate<'tcx> {
720 /// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
721 /// the `Self` type of the trait reference and `A`, `B`, and `C`
722 /// would be the type parameters.
723 Trait(PolyTraitPredicate<'tcx>),
724
725 /// where `T1 == T2`.
726 Equate(PolyEquatePredicate<'tcx>),
727
728 /// where 'a : 'b
729 RegionOutlives(PolyRegionOutlivesPredicate<'tcx>),
730
731 /// where T : 'a
732 TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),
733
734 /// where <T as TraitRef>::Name == X, approximately.
735 /// See `ProjectionPredicate` struct for details.
736 Projection(PolyProjectionPredicate<'tcx>),
737
738 /// no syntax: T WF
739 WellFormed(Ty<'tcx>),
740
741 /// trait must be object-safe
742 ObjectSafe(DefId),
743
744 /// No direct syntax. May be thought of as `where T : FnFoo<...>`
745 /// for some substitutions `...` and T being a closure type.
746 /// Satisfied (or refuted) once we know the closure's kind.
747 ClosureKind(DefId, ClosureKind),
748 }
749
750 impl<'a, 'gcx, 'tcx> Predicate<'tcx> {
751 /// Performs a substitution suitable for going from a
752 /// poly-trait-ref to supertraits that must hold if that
753 /// poly-trait-ref holds. This is slightly different from a normal
754 /// substitution in terms of what happens with bound regions. See
755 /// lengthy comment below for details.
756 pub fn subst_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
757 trait_ref: &ty::PolyTraitRef<'tcx>)
758 -> ty::Predicate<'tcx>
759 {
760 // The interaction between HRTB and supertraits is not entirely
761 // obvious. Let me walk you (and myself) through an example.
762 //
763 // Let's start with an easy case. Consider two traits:
764 //
765 // trait Foo<'a> : Bar<'a,'a> { }
766 // trait Bar<'b,'c> { }
767 //
768 // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
769 // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
770 // knew that `Foo<'x>` (for any 'x) then we also know that
771 // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
772 // normal substitution.
773 //
774 // In terms of why this is sound, the idea is that whenever there
775 // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
776 // holds. So if there is an impl of `T:Foo<'a>` that applies to
777 // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
778 // `'a`.
779 //
780 // Another example to be careful of is this:
781 //
782 // trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
783 // trait Bar1<'b,'c> { }
784 //
785 // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
786 // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
787 // reason is similar to the previous example: any impl of
788 // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`. So
789 // basically we would want to collapse the bound lifetimes from
790 // the input (`trait_ref`) and the supertraits.
791 //
792 // To achieve this in practice is fairly straightforward. Let's
793 // consider the more complicated scenario:
794 //
795 // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
796 // has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
797 // where both `'x` and `'b` would have a DB index of 1.
798 // The substitution from the input trait-ref is therefore going to be
799 // `'a => 'x` (where `'x` has a DB index of 1).
800 // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
801 // early-bound parameter and `'b' is a late-bound parameter with a
802 // DB index of 1.
803 // - If we replace `'a` with `'x` from the input, it too will have
804 // a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
805 // just as we wanted.
806 //
807 // There is only one catch. If we just apply the substitution `'a
808 // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
809 // adjust the DB index because we substituting into a binder (it
810 // tries to be so smart...) resulting in `for<'x> for<'b>
811 // Bar1<'x,'b>` (we have no syntax for this, so use your
812 // imagination). Basically the 'x will have DB index of 2 and 'b
813 // will have DB index of 1. Not quite what we want. So we apply
814 // the substitution to the *contents* of the trait reference,
815 // rather than the trait reference itself (put another way, the
816 // substitution code expects equal binding levels in the values
817 // from the substitution and the value being substituted into, and
818 // this trick achieves that).
819
820 let substs = &trait_ref.0.substs;
821 match *self {
822 Predicate::Trait(ty::Binder(ref data)) =>
823 Predicate::Trait(ty::Binder(data.subst(tcx, substs))),
824 Predicate::Equate(ty::Binder(ref data)) =>
825 Predicate::Equate(ty::Binder(data.subst(tcx, substs))),
826 Predicate::RegionOutlives(ty::Binder(ref data)) =>
827 Predicate::RegionOutlives(ty::Binder(data.subst(tcx, substs))),
828 Predicate::TypeOutlives(ty::Binder(ref data)) =>
829 Predicate::TypeOutlives(ty::Binder(data.subst(tcx, substs))),
830 Predicate::Projection(ty::Binder(ref data)) =>
831 Predicate::Projection(ty::Binder(data.subst(tcx, substs))),
832 Predicate::WellFormed(data) =>
833 Predicate::WellFormed(data.subst(tcx, substs)),
834 Predicate::ObjectSafe(trait_def_id) =>
835 Predicate::ObjectSafe(trait_def_id),
836 Predicate::ClosureKind(closure_def_id, kind) =>
837 Predicate::ClosureKind(closure_def_id, kind),
838 }
839 }
840 }
841
842 #[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
843 pub struct TraitPredicate<'tcx> {
844 pub trait_ref: TraitRef<'tcx>
845 }
846 pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;
847
848 impl<'tcx> TraitPredicate<'tcx> {
849 pub fn def_id(&self) -> DefId {
850 self.trait_ref.def_id
851 }
852
853 /// Creates the dep-node for selecting/evaluating this trait reference.
854 fn dep_node(&self) -> DepNode<DefId> {
855 // Ideally, the dep-node would just have all the input types
856 // in it. But they are limited to including def-ids. So as an
857 // approximation we include the def-ids for all nominal types
858 // found somewhere. This means that we will e.g. conflate the
859 // dep-nodes for `u32: SomeTrait` and `u64: SomeTrait`, but we
860 // would have distinct dep-nodes for `Vec<u32>: SomeTrait`,
861 // `Rc<u32>: SomeTrait`, and `(Vec<u32>, Rc<u32>): SomeTrait`.
862 // Note that it's always sound to conflate dep-nodes, it just
863 // leads to more recompilation.
864 let def_ids: Vec<_> =
865 self.input_types()
866 .flat_map(|t| t.walk())
867 .filter_map(|t| match t.sty {
868 ty::TyAdt(adt_def, _) =>
869 Some(adt_def.did),
870 _ =>
871 None
872 })
873 .chain(iter::once(self.def_id()))
874 .collect();
875 DepNode::TraitSelect(def_ids)
876 }
877
878 pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
879 self.trait_ref.input_types()
880 }
881
882 pub fn self_ty(&self) -> Ty<'tcx> {
883 self.trait_ref.self_ty()
884 }
885 }
886
887 impl<'tcx> PolyTraitPredicate<'tcx> {
888 pub fn def_id(&self) -> DefId {
889 // ok to skip binder since trait def-id does not care about regions
890 self.0.def_id()
891 }
892
893 pub fn dep_node(&self) -> DepNode<DefId> {
894 // ok to skip binder since depnode does not care about regions
895 self.0.dep_node()
896 }
897 }
898
899 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
900 pub struct EquatePredicate<'tcx>(pub Ty<'tcx>, pub Ty<'tcx>); // `0 == 1`
901 pub type PolyEquatePredicate<'tcx> = ty::Binder<EquatePredicate<'tcx>>;
902
903 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
904 pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
905 pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
906 pub type PolyRegionOutlivesPredicate<'tcx> = PolyOutlivesPredicate<&'tcx ty::Region,
907 &'tcx ty::Region>;
908 pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate<Ty<'tcx>, &'tcx ty::Region>;
909
910 /// This kind of predicate has no *direct* correspondent in the
911 /// syntax, but it roughly corresponds to the syntactic forms:
912 ///
913 /// 1. `T : TraitRef<..., Item=Type>`
914 /// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
915 ///
916 /// In particular, form #1 is "desugared" to the combination of a
917 /// normal trait predicate (`T : TraitRef<...>`) and one of these
918 /// predicates. Form #2 is a broader form in that it also permits
919 /// equality between arbitrary types. Processing an instance of Form
920 /// #2 eventually yields one of these `ProjectionPredicate`
921 /// instances to normalize the LHS.
922 #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
923 pub struct ProjectionPredicate<'tcx> {
924 pub projection_ty: ProjectionTy<'tcx>,
925 pub ty: Ty<'tcx>,
926 }
927
928 pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;
929
930 impl<'tcx> PolyProjectionPredicate<'tcx> {
931 pub fn item_name(&self) -> Name {
932 self.0.projection_ty.item_name // safe to skip the binder to access a name
933 }
934 }
935
936 pub trait ToPolyTraitRef<'tcx> {
937 fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
938 }
939
940 impl<'tcx> ToPolyTraitRef<'tcx> for TraitRef<'tcx> {
941 fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
942 assert!(!self.has_escaping_regions());
943 ty::Binder(self.clone())
944 }
945 }
946
947 impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
948 fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
949 self.map_bound_ref(|trait_pred| trait_pred.trait_ref)
950 }
951 }
952
953 impl<'tcx> ToPolyTraitRef<'tcx> for PolyProjectionPredicate<'tcx> {
954 fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
955 // Note: unlike with TraitRef::to_poly_trait_ref(),
956 // self.0.trait_ref is permitted to have escaping regions.
957 // This is because here `self` has a `Binder` and so does our
958 // return value, so we are preserving the number of binding
959 // levels.
960 ty::Binder(self.0.projection_ty.trait_ref)
961 }
962 }
963
964 pub trait ToPredicate<'tcx> {
965 fn to_predicate(&self) -> Predicate<'tcx>;
966 }
967
968 impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
969 fn to_predicate(&self) -> Predicate<'tcx> {
970 // we're about to add a binder, so let's check that we don't
971 // accidentally capture anything, or else that might be some
972 // weird debruijn accounting.
973 assert!(!self.has_escaping_regions());
974
975 ty::Predicate::Trait(ty::Binder(ty::TraitPredicate {
976 trait_ref: self.clone()
977 }))
978 }
979 }
980
981 impl<'tcx> ToPredicate<'tcx> for PolyTraitRef<'tcx> {
982 fn to_predicate(&self) -> Predicate<'tcx> {
983 ty::Predicate::Trait(self.to_poly_trait_predicate())
984 }
985 }
986
987 impl<'tcx> ToPredicate<'tcx> for PolyEquatePredicate<'tcx> {
988 fn to_predicate(&self) -> Predicate<'tcx> {
989 Predicate::Equate(self.clone())
990 }
991 }
992
993 impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
994 fn to_predicate(&self) -> Predicate<'tcx> {
995 Predicate::RegionOutlives(self.clone())
996 }
997 }
998
999 impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
1000 fn to_predicate(&self) -> Predicate<'tcx> {
1001 Predicate::TypeOutlives(self.clone())
1002 }
1003 }
1004
1005 impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
1006 fn to_predicate(&self) -> Predicate<'tcx> {
1007 Predicate::Projection(self.clone())
1008 }
1009 }
1010
1011 impl<'tcx> Predicate<'tcx> {
1012 /// Iterates over the types in this predicate. Note that in all
1013 /// cases this is skipping over a binder, so late-bound regions
1014 /// with depth 0 are bound by the predicate.
1015 pub fn walk_tys(&self) -> IntoIter<Ty<'tcx>> {
1016 let vec: Vec<_> = match *self {
1017 ty::Predicate::Trait(ref data) => {
1018 data.skip_binder().input_types().collect()
1019 }
1020 ty::Predicate::Equate(ty::Binder(ref data)) => {
1021 vec![data.0, data.1]
1022 }
1023 ty::Predicate::TypeOutlives(ty::Binder(ref data)) => {
1024 vec![data.0]
1025 }
1026 ty::Predicate::RegionOutlives(..) => {
1027 vec![]
1028 }
1029 ty::Predicate::Projection(ref data) => {
1030 let trait_inputs = data.0.projection_ty.trait_ref.input_types();
1031 trait_inputs.chain(Some(data.0.ty)).collect()
1032 }
1033 ty::Predicate::WellFormed(data) => {
1034 vec![data]
1035 }
1036 ty::Predicate::ObjectSafe(_trait_def_id) => {
1037 vec![]
1038 }
1039 ty::Predicate::ClosureKind(_closure_def_id, _kind) => {
1040 vec![]
1041 }
1042 };
1043
1044 // The only reason to collect into a vector here is that I was
1045 // too lazy to make the full (somewhat complicated) iterator
1046 // type that would be needed here. But I wanted this fn to
1047 // return an iterator conceptually, rather than a `Vec`, so as
1048 // to be closer to `Ty::walk`.
1049 vec.into_iter()
1050 }
1051
1052 pub fn to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'tcx>> {
1053 match *self {
1054 Predicate::Trait(ref t) => {
1055 Some(t.to_poly_trait_ref())
1056 }
1057 Predicate::Projection(..) |
1058 Predicate::Equate(..) |
1059 Predicate::RegionOutlives(..) |
1060 Predicate::WellFormed(..) |
1061 Predicate::ObjectSafe(..) |
1062 Predicate::ClosureKind(..) |
1063 Predicate::TypeOutlives(..) => {
1064 None
1065 }
1066 }
1067 }
1068 }
1069
1070 /// Represents the bounds declared on a particular set of type
1071 /// parameters. Should eventually be generalized into a flag list of
1072 /// where clauses. You can obtain a `InstantiatedPredicates` list from a
1073 /// `GenericPredicates` by using the `instantiate` method. Note that this method
1074 /// reflects an important semantic invariant of `InstantiatedPredicates`: while
1075 /// the `GenericPredicates` are expressed in terms of the bound type
1076 /// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance
1077 /// represented a set of bounds for some particular instantiation,
1078 /// meaning that the generic parameters have been substituted with
1079 /// their values.
1080 ///
1081 /// Example:
1082 ///
1083 /// struct Foo<T,U:Bar<T>> { ... }
1084 ///
1085 /// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
1086 /// `[[], [U:Bar<T>]]`. Now if there were some particular reference
1087 /// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
1088 /// [usize:Bar<isize>]]`.
1089 #[derive(Clone)]
1090 pub struct InstantiatedPredicates<'tcx> {
1091 pub predicates: Vec<Predicate<'tcx>>,
1092 }
1093
1094 impl<'tcx> InstantiatedPredicates<'tcx> {
1095 pub fn empty() -> InstantiatedPredicates<'tcx> {
1096 InstantiatedPredicates { predicates: vec![] }
1097 }
1098
1099 pub fn is_empty(&self) -> bool {
1100 self.predicates.is_empty()
1101 }
1102 }
1103
1104 impl<'tcx> TraitRef<'tcx> {
1105 pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>) -> TraitRef<'tcx> {
1106 TraitRef { def_id: def_id, substs: substs }
1107 }
1108
1109 pub fn self_ty(&self) -> Ty<'tcx> {
1110 self.substs.type_at(0)
1111 }
1112
1113 pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
1114 // Select only the "input types" from a trait-reference. For
1115 // now this is all the types that appear in the
1116 // trait-reference, but it should eventually exclude
1117 // associated types.
1118 self.substs.types()
1119 }
1120 }
1121
1122 /// When type checking, we use the `ParameterEnvironment` to track
1123 /// details about the type/lifetime parameters that are in scope.
1124 /// It primarily stores the bounds information.
1125 ///
1126 /// Note: This information might seem to be redundant with the data in
1127 /// `tcx.ty_param_defs`, but it is not. That table contains the
1128 /// parameter definitions from an "outside" perspective, but this
1129 /// struct will contain the bounds for a parameter as seen from inside
1130 /// the function body. Currently the only real distinction is that
1131 /// bound lifetime parameters are replaced with free ones, but in the
1132 /// future I hope to refine the representation of types so as to make
1133 /// more distinctions clearer.
1134 #[derive(Clone)]
1135 pub struct ParameterEnvironment<'tcx> {
1136 /// See `construct_free_substs` for details.
1137 pub free_substs: &'tcx Substs<'tcx>,
1138
1139 /// Each type parameter has an implicit region bound that
1140 /// indicates it must outlive at least the function body (the user
1141 /// may specify stronger requirements). This field indicates the
1142 /// region of the callee.
1143 pub implicit_region_bound: &'tcx ty::Region,
1144
1145 /// Obligations that the caller must satisfy. This is basically
1146 /// the set of bounds on the in-scope type parameters, translated
1147 /// into Obligations, and elaborated and normalized.
1148 pub caller_bounds: Vec<ty::Predicate<'tcx>>,
1149
1150 /// Scope that is attached to free regions for this scope. This
1151 /// is usually the id of the fn body, but for more abstract scopes
1152 /// like structs we often use the node-id of the struct.
1153 ///
1154 /// FIXME(#3696). It would be nice to refactor so that free
1155 /// regions don't have this implicit scope and instead introduce
1156 /// relationships in the environment.
1157 pub free_id_outlive: CodeExtent,
1158
1159 /// A cache for `moves_by_default`.
1160 pub is_copy_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>,
1161
1162 /// A cache for `type_is_sized`
1163 pub is_sized_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>,
1164 }
1165
1166 impl<'a, 'tcx> ParameterEnvironment<'tcx> {
1167 pub fn with_caller_bounds(&self,
1168 caller_bounds: Vec<ty::Predicate<'tcx>>)
1169 -> ParameterEnvironment<'tcx>
1170 {
1171 ParameterEnvironment {
1172 free_substs: self.free_substs,
1173 implicit_region_bound: self.implicit_region_bound,
1174 caller_bounds: caller_bounds,
1175 free_id_outlive: self.free_id_outlive,
1176 is_copy_cache: RefCell::new(FxHashMap()),
1177 is_sized_cache: RefCell::new(FxHashMap()),
1178 }
1179 }
1180
1181 /// Construct a parameter environment given an item, impl item, or trait item
1182 pub fn for_item(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: NodeId)
1183 -> ParameterEnvironment<'tcx> {
1184 match tcx.map.find(id) {
1185 Some(ast_map::NodeImplItem(ref impl_item)) => {
1186 match impl_item.node {
1187 hir::ImplItemKind::Type(_) | hir::ImplItemKind::Const(..) => {
1188 // associated types don't have their own entry (for some reason),
1189 // so for now just grab environment for the impl
1190 let impl_id = tcx.map.get_parent(id);
1191 let impl_def_id = tcx.map.local_def_id(impl_id);
1192 tcx.construct_parameter_environment(impl_item.span,
1193 impl_def_id,
1194 tcx.region_maps.item_extent(id))
1195 }
1196 hir::ImplItemKind::Method(_, ref body) => {
1197 tcx.construct_parameter_environment(
1198 impl_item.span,
1199 tcx.map.local_def_id(id),
1200 tcx.region_maps.call_site_extent(id, body.node_id()))
1201 }
1202 }
1203 }
1204 Some(ast_map::NodeTraitItem(trait_item)) => {
1205 match trait_item.node {
1206 hir::TypeTraitItem(..) | hir::ConstTraitItem(..) => {
1207 // associated types don't have their own entry (for some reason),
1208 // so for now just grab environment for the trait
1209 let trait_id = tcx.map.get_parent(id);
1210 let trait_def_id = tcx.map.local_def_id(trait_id);
1211 tcx.construct_parameter_environment(trait_item.span,
1212 trait_def_id,
1213 tcx.region_maps.item_extent(id))
1214 }
1215 hir::MethodTraitItem(_, ref body) => {
1216 // Use call-site for extent (unless this is a
1217 // trait method with no default; then fallback
1218 // to the method id).
1219 let extent = if let Some(body_id) = *body {
1220 // default impl: use call_site extent as free_id_outlive bound.
1221 tcx.region_maps.call_site_extent(id, body_id.node_id())
1222 } else {
1223 // no default impl: use item extent as free_id_outlive bound.
1224 tcx.region_maps.item_extent(id)
1225 };
1226 tcx.construct_parameter_environment(
1227 trait_item.span,
1228 tcx.map.local_def_id(id),
1229 extent)
1230 }
1231 }
1232 }
1233 Some(ast_map::NodeItem(item)) => {
1234 match item.node {
1235 hir::ItemFn(.., body_id) => {
1236 // We assume this is a function.
1237 let fn_def_id = tcx.map.local_def_id(id);
1238
1239 tcx.construct_parameter_environment(
1240 item.span,
1241 fn_def_id,
1242 tcx.region_maps.call_site_extent(id, body_id.node_id()))
1243 }
1244 hir::ItemEnum(..) |
1245 hir::ItemStruct(..) |
1246 hir::ItemUnion(..) |
1247 hir::ItemTy(..) |
1248 hir::ItemImpl(..) |
1249 hir::ItemConst(..) |
1250 hir::ItemStatic(..) => {
1251 let def_id = tcx.map.local_def_id(id);
1252 tcx.construct_parameter_environment(item.span,
1253 def_id,
1254 tcx.region_maps.item_extent(id))
1255 }
1256 hir::ItemTrait(..) => {
1257 let def_id = tcx.map.local_def_id(id);
1258 tcx.construct_parameter_environment(item.span,
1259 def_id,
1260 tcx.region_maps.item_extent(id))
1261 }
1262 _ => {
1263 span_bug!(item.span,
1264 "ParameterEnvironment::for_item():
1265 can't create a parameter \
1266 environment for this kind of item")
1267 }
1268 }
1269 }
1270 Some(ast_map::NodeExpr(expr)) => {
1271 // This is a convenience to allow closures to work.
1272 if let hir::ExprClosure(.., body, _) = expr.node {
1273 let def_id = tcx.map.local_def_id(id);
1274 let base_def_id = tcx.closure_base_def_id(def_id);
1275 tcx.construct_parameter_environment(
1276 expr.span,
1277 base_def_id,
1278 tcx.region_maps.call_site_extent(id, body.node_id()))
1279 } else {
1280 tcx.empty_parameter_environment()
1281 }
1282 }
1283 Some(ast_map::NodeForeignItem(item)) => {
1284 let def_id = tcx.map.local_def_id(id);
1285 tcx.construct_parameter_environment(item.span,
1286 def_id,
1287 ROOT_CODE_EXTENT)
1288 }
1289 _ => {
1290 bug!("ParameterEnvironment::from_item(): \
1291 `{}` is not an item",
1292 tcx.map.node_to_string(id))
1293 }
1294 }
1295 }
1296 }
1297
1298 bitflags! {
1299 flags AdtFlags: u32 {
1300 const NO_ADT_FLAGS = 0,
1301 const IS_ENUM = 1 << 0,
1302 const IS_DTORCK = 1 << 1, // is this a dtorck type?
1303 const IS_DTORCK_VALID = 1 << 2,
1304 const IS_PHANTOM_DATA = 1 << 3,
1305 const IS_SIMD = 1 << 4,
1306 const IS_FUNDAMENTAL = 1 << 5,
1307 const IS_UNION = 1 << 6,
1308 }
1309 }
1310
1311 pub struct VariantDef {
1312 /// The variant's DefId. If this is a tuple-like struct,
1313 /// this is the DefId of the struct's ctor.
1314 pub did: DefId,
1315 pub name: Name, // struct's name if this is a struct
1316 pub disr_val: Disr,
1317 pub fields: Vec<FieldDef>,
1318 pub ctor_kind: CtorKind,
1319 }
1320
1321 pub struct FieldDef {
1322 pub did: DefId,
1323 pub name: Name,
1324 pub vis: Visibility,
1325 }
1326
1327 /// The definition of an abstract data type - a struct or enum.
1328 ///
1329 /// These are all interned (by intern_adt_def) into the adt_defs
1330 /// table.
1331 pub struct AdtDef {
1332 pub did: DefId,
1333 pub variants: Vec<VariantDef>,
1334 destructor: Cell<Option<DefId>>,
1335 flags: Cell<AdtFlags>
1336 }
1337
1338 impl PartialEq for AdtDef {
1339 // AdtDef are always interned and this is part of TyS equality
1340 #[inline]
1341 fn eq(&self, other: &Self) -> bool { self as *const _ == other as *const _ }
1342 }
1343
1344 impl Eq for AdtDef {}
1345
1346 impl Hash for AdtDef {
1347 #[inline]
1348 fn hash<H: Hasher>(&self, s: &mut H) {
1349 (self as *const AdtDef).hash(s)
1350 }
1351 }
1352
1353 impl<'tcx> serialize::UseSpecializedEncodable for &'tcx AdtDef {
1354 fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
1355 self.did.encode(s)
1356 }
1357 }
1358
1359 impl<'tcx> serialize::UseSpecializedDecodable for &'tcx AdtDef {}
1360
1361 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
1362 pub enum AdtKind { Struct, Union, Enum }
1363
1364 impl<'a, 'gcx, 'tcx> AdtDef {
1365 fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
1366 did: DefId,
1367 kind: AdtKind,
1368 variants: Vec<VariantDef>) -> Self {
1369 let mut flags = AdtFlags::NO_ADT_FLAGS;
1370 let attrs = tcx.get_attrs(did);
1371 if attr::contains_name(&attrs, "fundamental") {
1372 flags = flags | AdtFlags::IS_FUNDAMENTAL;
1373 }
1374 if tcx.lookup_simd(did) {
1375 flags = flags | AdtFlags::IS_SIMD;
1376 }
1377 if Some(did) == tcx.lang_items.phantom_data() {
1378 flags = flags | AdtFlags::IS_PHANTOM_DATA;
1379 }
1380 match kind {
1381 AdtKind::Enum => flags = flags | AdtFlags::IS_ENUM,
1382 AdtKind::Union => flags = flags | AdtFlags::IS_UNION,
1383 AdtKind::Struct => {}
1384 }
1385 AdtDef {
1386 did: did,
1387 variants: variants,
1388 flags: Cell::new(flags),
1389 destructor: Cell::new(None),
1390 }
1391 }
1392
1393 fn calculate_dtorck(&'gcx self, tcx: TyCtxt) {
1394 if tcx.is_adt_dtorck(self) {
1395 self.flags.set(self.flags.get() | AdtFlags::IS_DTORCK);
1396 }
1397 self.flags.set(self.flags.get() | AdtFlags::IS_DTORCK_VALID)
1398 }
1399
1400 #[inline]
1401 pub fn is_uninhabited_recurse(&self,
1402 visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>,
1403 block: Option<NodeId>,
1404 tcx: TyCtxt<'a, 'gcx, 'tcx>,
1405 substs: &'tcx Substs<'tcx>) -> bool {
1406 if !visited.insert((self.did, substs)) {
1407 return false;
1408 };
1409 self.variants.iter().all(|v| {
1410 v.is_uninhabited_recurse(visited, block, tcx, substs, self.is_union())
1411 })
1412 }
1413
1414 #[inline]
1415 pub fn is_struct(&self) -> bool {
1416 !self.is_union() && !self.is_enum()
1417 }
1418
1419 #[inline]
1420 pub fn is_union(&self) -> bool {
1421 self.flags.get().intersects(AdtFlags::IS_UNION)
1422 }
1423
1424 #[inline]
1425 pub fn is_enum(&self) -> bool {
1426 self.flags.get().intersects(AdtFlags::IS_ENUM)
1427 }
1428
1429 /// Returns the kind of the ADT - Struct or Enum.
1430 #[inline]
1431 pub fn adt_kind(&self) -> AdtKind {
1432 if self.is_enum() {
1433 AdtKind::Enum
1434 } else if self.is_union() {
1435 AdtKind::Union
1436 } else {
1437 AdtKind::Struct
1438 }
1439 }
1440
1441 pub fn descr(&self) -> &'static str {
1442 match self.adt_kind() {
1443 AdtKind::Struct => "struct",
1444 AdtKind::Union => "union",
1445 AdtKind::Enum => "enum",
1446 }
1447 }
1448
1449 pub fn variant_descr(&self) -> &'static str {
1450 match self.adt_kind() {
1451 AdtKind::Struct => "struct",
1452 AdtKind::Union => "union",
1453 AdtKind::Enum => "variant",
1454 }
1455 }
1456
1457 /// Returns whether this is a dtorck type. If this returns
1458 /// true, this type being safe for destruction requires it to be
1459 /// alive; Otherwise, only the contents are required to be.
1460 #[inline]
1461 pub fn is_dtorck(&'gcx self, tcx: TyCtxt) -> bool {
1462 if !self.flags.get().intersects(AdtFlags::IS_DTORCK_VALID) {
1463 self.calculate_dtorck(tcx)
1464 }
1465 self.flags.get().intersects(AdtFlags::IS_DTORCK)
1466 }
1467
1468 /// Returns whether this type is #[fundamental] for the purposes
1469 /// of coherence checking.
1470 #[inline]
1471 pub fn is_fundamental(&self) -> bool {
1472 self.flags.get().intersects(AdtFlags::IS_FUNDAMENTAL)
1473 }
1474
1475 #[inline]
1476 pub fn is_simd(&self) -> bool {
1477 self.flags.get().intersects(AdtFlags::IS_SIMD)
1478 }
1479
1480 /// Returns true if this is PhantomData<T>.
1481 #[inline]
1482 pub fn is_phantom_data(&self) -> bool {
1483 self.flags.get().intersects(AdtFlags::IS_PHANTOM_DATA)
1484 }
1485
1486 /// Returns whether this type has a destructor.
1487 pub fn has_dtor(&self) -> bool {
1488 self.dtor_kind().is_present()
1489 }
1490
1491 /// Asserts this is a struct and returns the struct's unique
1492 /// variant.
1493 pub fn struct_variant(&self) -> &VariantDef {
1494 assert!(!self.is_enum());
1495 &self.variants[0]
1496 }
1497
1498 #[inline]
1499 pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> GenericPredicates<'gcx> {
1500 tcx.item_predicates(self.did)
1501 }
1502
1503 /// Returns an iterator over all fields contained
1504 /// by this ADT.
1505 #[inline]
1506 pub fn all_fields<'s>(&'s self) -> impl Iterator<Item = &'s FieldDef> {
1507 self.variants.iter().flat_map(|v| v.fields.iter())
1508 }
1509
1510 #[inline]
1511 pub fn is_univariant(&self) -> bool {
1512 self.variants.len() == 1
1513 }
1514
1515 pub fn is_payloadfree(&self) -> bool {
1516 !self.variants.is_empty() &&
1517 self.variants.iter().all(|v| v.fields.is_empty())
1518 }
1519
1520 pub fn variant_with_id(&self, vid: DefId) -> &VariantDef {
1521 self.variants
1522 .iter()
1523 .find(|v| v.did == vid)
1524 .expect("variant_with_id: unknown variant")
1525 }
1526
1527 pub fn variant_index_with_id(&self, vid: DefId) -> usize {
1528 self.variants
1529 .iter()
1530 .position(|v| v.did == vid)
1531 .expect("variant_index_with_id: unknown variant")
1532 }
1533
1534 pub fn variant_of_def(&self, def: Def) -> &VariantDef {
1535 match def {
1536 Def::Variant(vid) | Def::VariantCtor(vid, ..) => self.variant_with_id(vid),
1537 Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) |
1538 Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => self.struct_variant(),
1539 _ => bug!("unexpected def {:?} in variant_of_def", def)
1540 }
1541 }
1542
1543 pub fn destructor(&self) -> Option<DefId> {
1544 self.destructor.get()
1545 }
1546
1547 pub fn set_destructor(&self, dtor: DefId) {
1548 self.destructor.set(Some(dtor));
1549 }
1550
1551 pub fn dtor_kind(&self) -> DtorKind {
1552 match self.destructor.get() {
1553 Some(_) => TraitDtor,
1554 None => NoDtor,
1555 }
1556 }
1557
1558 /// Returns a simpler type such that `Self: Sized` if and only
1559 /// if that type is Sized, or `TyErr` if this type is recursive.
1560 ///
1561 /// HACK: instead of returning a list of types, this function can
1562 /// return a tuple. In that case, the result is Sized only if
1563 /// all elements of the tuple are Sized.
1564 ///
1565 /// This is generally the `struct_tail` if this is a struct, or a
1566 /// tuple of them if this is an enum.
1567 ///
1568 /// Oddly enough, checking that the sized-constraint is Sized is
1569 /// actually more expressive than checking all members:
1570 /// the Sized trait is inductive, so an associated type that references
1571 /// Self would prevent its containing ADT from being Sized.
1572 ///
1573 /// Due to normalization being eager, this applies even if
1574 /// the associated type is behind a pointer, e.g. issue #31299.
1575 pub fn sized_constraint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
1576 self.calculate_sized_constraint_inner(tcx.global_tcx(), &mut Vec::new())
1577 }
1578
1579 /// Calculates the Sized-constraint.
1580 ///
1581 /// As the Sized-constraint of enums can be a *set* of types,
1582 /// the Sized-constraint may need to be a set also. Because introducing
1583 /// a new type of IVar is currently a complex affair, the Sized-constraint
1584 /// may be a tuple.
1585 ///
1586 /// In fact, there are only a few options for the constraint:
1587 /// - `bool`, if the type is always Sized
1588 /// - an obviously-unsized type
1589 /// - a type parameter or projection whose Sizedness can't be known
1590 /// - a tuple of type parameters or projections, if there are multiple
1591 /// such.
1592 /// - a TyError, if a type contained itself. The representability
1593 /// check should catch this case.
1594 fn calculate_sized_constraint_inner(&self,
1595 tcx: TyCtxt<'a, 'tcx, 'tcx>,
1596 stack: &mut Vec<DefId>)
1597 -> Ty<'tcx>
1598 {
1599 if let Some(ty) = tcx.adt_sized_constraint.borrow().get(&self.did) {
1600 return ty;
1601 }
1602
1603 // Follow the memoization pattern: push the computation of
1604 // DepNode::SizedConstraint as our current task.
1605 let _task = tcx.dep_graph.in_task(DepNode::SizedConstraint(self.did));
1606
1607 if stack.contains(&self.did) {
1608 debug!("calculate_sized_constraint: {:?} is recursive", self);
1609 // This should be reported as an error by `check_representable`.
1610 //
1611 // Consider the type as Sized in the meanwhile to avoid
1612 // further errors.
1613 tcx.adt_sized_constraint.borrow_mut().insert(self.did, tcx.types.err);
1614 return tcx.types.err;
1615 }
1616
1617 stack.push(self.did);
1618
1619 let tys : Vec<_> =
1620 self.variants.iter().flat_map(|v| {
1621 v.fields.last()
1622 }).flat_map(|f| {
1623 let ty = tcx.item_type(f.did);
1624 self.sized_constraint_for_ty(tcx, stack, ty)
1625 }).collect();
1626
1627 let self_ = stack.pop().unwrap();
1628 assert_eq!(self_, self.did);
1629
1630 let ty = match tys.len() {
1631 _ if tys.references_error() => tcx.types.err,
1632 0 => tcx.types.bool,
1633 1 => tys[0],
1634 _ => tcx.intern_tup(&tys[..])
1635 };
1636
1637 let old = tcx.adt_sized_constraint.borrow().get(&self.did).cloned();
1638 match old {
1639 Some(old_ty) => {
1640 debug!("calculate_sized_constraint: {:?} recurred", self);
1641 assert_eq!(old_ty, tcx.types.err);
1642 old_ty
1643 }
1644 None => {
1645 debug!("calculate_sized_constraint: {:?} => {:?}", self, ty);
1646 tcx.adt_sized_constraint.borrow_mut().insert(self.did, ty);
1647 ty
1648 }
1649 }
1650 }
1651
1652 fn sized_constraint_for_ty(&self,
1653 tcx: TyCtxt<'a, 'tcx, 'tcx>,
1654 stack: &mut Vec<DefId>,
1655 ty: Ty<'tcx>)
1656 -> Vec<Ty<'tcx>> {
1657 let result = match ty.sty {
1658 TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
1659 TyBox(..) | TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) |
1660 TyArray(..) | TyClosure(..) | TyNever => {
1661 vec![]
1662 }
1663
1664 TyStr | TyDynamic(..) | TySlice(_) | TyError => {
1665 // these are never sized - return the target type
1666 vec![ty]
1667 }
1668
1669 TyTuple(ref tys) => {
1670 match tys.last() {
1671 None => vec![],
1672 Some(ty) => self.sized_constraint_for_ty(tcx, stack, ty)
1673 }
1674 }
1675
1676 TyAdt(adt, substs) => {
1677 // recursive case
1678 let adt_ty =
1679 adt.calculate_sized_constraint_inner(tcx, stack)
1680 .subst(tcx, substs);
1681 debug!("sized_constraint_for_ty({:?}) intermediate = {:?}",
1682 ty, adt_ty);
1683 if let ty::TyTuple(ref tys) = adt_ty.sty {
1684 tys.iter().flat_map(|ty| {
1685 self.sized_constraint_for_ty(tcx, stack, ty)
1686 }).collect()
1687 } else {
1688 self.sized_constraint_for_ty(tcx, stack, adt_ty)
1689 }
1690 }
1691
1692 TyProjection(..) | TyAnon(..) => {
1693 // must calculate explicitly.
1694 // FIXME: consider special-casing always-Sized projections
1695 vec![ty]
1696 }
1697
1698 TyParam(..) => {
1699 // perf hack: if there is a `T: Sized` bound, then
1700 // we know that `T` is Sized and do not need to check
1701 // it on the impl.
1702
1703 let sized_trait = match tcx.lang_items.sized_trait() {
1704 Some(x) => x,
1705 _ => return vec![ty]
1706 };
1707 let sized_predicate = Binder(TraitRef {
1708 def_id: sized_trait,
1709 substs: tcx.mk_substs_trait(ty, &[])
1710 }).to_predicate();
1711 let predicates = tcx.item_predicates(self.did).predicates;
1712 if predicates.into_iter().any(|p| p == sized_predicate) {
1713 vec![]
1714 } else {
1715 vec![ty]
1716 }
1717 }
1718
1719 TyInfer(..) => {
1720 bug!("unexpected type `{:?}` in sized_constraint_for_ty",
1721 ty)
1722 }
1723 };
1724 debug!("sized_constraint_for_ty({:?}) = {:?}", ty, result);
1725 result
1726 }
1727 }
1728
1729 impl<'a, 'gcx, 'tcx> VariantDef {
1730 #[inline]
1731 pub fn find_field_named(&self,
1732 name: ast::Name)
1733 -> Option<&FieldDef> {
1734 self.fields.iter().find(|f| f.name == name)
1735 }
1736
1737 #[inline]
1738 pub fn index_of_field_named(&self,
1739 name: ast::Name)
1740 -> Option<usize> {
1741 self.fields.iter().position(|f| f.name == name)
1742 }
1743
1744 #[inline]
1745 pub fn field_named(&self, name: ast::Name) -> &FieldDef {
1746 self.find_field_named(name).unwrap()
1747 }
1748
1749 #[inline]
1750 pub fn is_uninhabited_recurse(&self,
1751 visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>,
1752 block: Option<NodeId>,
1753 tcx: TyCtxt<'a, 'gcx, 'tcx>,
1754 substs: &'tcx Substs<'tcx>,
1755 is_union: bool) -> bool {
1756 if is_union {
1757 self.fields.iter().all(|f| f.is_uninhabited_recurse(visited, block, tcx, substs))
1758 } else {
1759 self.fields.iter().any(|f| f.is_uninhabited_recurse(visited, block, tcx, substs))
1760 }
1761 }
1762 }
1763
1764 impl<'a, 'gcx, 'tcx> FieldDef {
1765 pub fn ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, subst: &Substs<'tcx>) -> Ty<'tcx> {
1766 tcx.item_type(self.did).subst(tcx, subst)
1767 }
1768
1769 #[inline]
1770 pub fn is_uninhabited_recurse(&self,
1771 visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>,
1772 block: Option<NodeId>,
1773 tcx: TyCtxt<'a, 'gcx, 'tcx>,
1774 substs: &'tcx Substs<'tcx>) -> bool {
1775 block.map_or(true, |b| self.vis.is_accessible_from(b, &tcx.map)) &&
1776 self.ty(tcx, substs).is_uninhabited_recurse(visited, block, tcx)
1777 }
1778 }
1779
1780 /// Records the substitutions used to translate the polytype for an
1781 /// item into the monotype of an item reference.
1782 #[derive(Clone, RustcEncodable, RustcDecodable)]
1783 pub struct ItemSubsts<'tcx> {
1784 pub substs: &'tcx Substs<'tcx>,
1785 }
1786
1787 #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
1788 pub enum ClosureKind {
1789 // Warning: Ordering is significant here! The ordering is chosen
1790 // because the trait Fn is a subtrait of FnMut and so in turn, and
1791 // hence we order it so that Fn < FnMut < FnOnce.
1792 Fn,
1793 FnMut,
1794 FnOnce,
1795 }
1796
1797 impl<'a, 'tcx> ClosureKind {
1798 pub fn trait_did(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> DefId {
1799 match *self {
1800 ClosureKind::Fn => tcx.require_lang_item(FnTraitLangItem),
1801 ClosureKind::FnMut => {
1802 tcx.require_lang_item(FnMutTraitLangItem)
1803 }
1804 ClosureKind::FnOnce => {
1805 tcx.require_lang_item(FnOnceTraitLangItem)
1806 }
1807 }
1808 }
1809
1810 /// True if this a type that impls this closure kind
1811 /// must also implement `other`.
1812 pub fn extends(self, other: ty::ClosureKind) -> bool {
1813 match (self, other) {
1814 (ClosureKind::Fn, ClosureKind::Fn) => true,
1815 (ClosureKind::Fn, ClosureKind::FnMut) => true,
1816 (ClosureKind::Fn, ClosureKind::FnOnce) => true,
1817 (ClosureKind::FnMut, ClosureKind::FnMut) => true,
1818 (ClosureKind::FnMut, ClosureKind::FnOnce) => true,
1819 (ClosureKind::FnOnce, ClosureKind::FnOnce) => true,
1820 _ => false,
1821 }
1822 }
1823 }
1824
1825 impl<'tcx> TyS<'tcx> {
1826 /// Iterator that walks `self` and any types reachable from
1827 /// `self`, in depth-first order. Note that just walks the types
1828 /// that appear in `self`, it does not descend into the fields of
1829 /// structs or variants. For example:
1830 ///
1831 /// ```notrust
1832 /// isize => { isize }
1833 /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
1834 /// [isize] => { [isize], isize }
1835 /// ```
1836 pub fn walk(&'tcx self) -> TypeWalker<'tcx> {
1837 TypeWalker::new(self)
1838 }
1839
1840 /// Iterator that walks the immediate children of `self`. Hence
1841 /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
1842 /// (but not `i32`, like `walk`).
1843 pub fn walk_shallow(&'tcx self) -> AccIntoIter<walk::TypeWalkerArray<'tcx>> {
1844 walk::walk_shallow(self)
1845 }
1846
1847 /// Walks `ty` and any types appearing within `ty`, invoking the
1848 /// callback `f` on each type. If the callback returns false, then the
1849 /// children of the current type are ignored.
1850 ///
1851 /// Note: prefer `ty.walk()` where possible.
1852 pub fn maybe_walk<F>(&'tcx self, mut f: F)
1853 where F : FnMut(Ty<'tcx>) -> bool
1854 {
1855 let mut walker = self.walk();
1856 while let Some(ty) = walker.next() {
1857 if !f(ty) {
1858 walker.skip_current_subtree();
1859 }
1860 }
1861 }
1862 }
1863
1864 impl<'tcx> ItemSubsts<'tcx> {
1865 pub fn is_noop(&self) -> bool {
1866 self.substs.is_noop()
1867 }
1868 }
1869
1870 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1871 pub enum LvaluePreference {
1872 PreferMutLvalue,
1873 NoPreference
1874 }
1875
1876 impl LvaluePreference {
1877 pub fn from_mutbl(m: hir::Mutability) -> Self {
1878 match m {
1879 hir::MutMutable => PreferMutLvalue,
1880 hir::MutImmutable => NoPreference,
1881 }
1882 }
1883 }
1884
1885 /// Helper for looking things up in the various maps that are populated during
1886 /// typeck::collect (e.g., `tcx.associated_items`, `tcx.types`, etc). All of
1887 /// these share the pattern that if the id is local, it should have been loaded
1888 /// into the map by the `typeck::collect` phase. If the def-id is external,
1889 /// then we have to go consult the crate loading code (and cache the result for
1890 /// the future).
1891 fn lookup_locally_or_in_crate_store<M, F>(descr: &str,
1892 def_id: DefId,
1893 map: &M,
1894 load_external: F)
1895 -> M::Value where
1896 M: MemoizationMap<Key=DefId>,
1897 F: FnOnce() -> M::Value,
1898 {
1899 map.memoize(def_id, || {
1900 if def_id.is_local() {
1901 bug!("No def'n found for {:?} in tcx.{}", def_id, descr);
1902 }
1903 load_external()
1904 })
1905 }
1906
1907 impl BorrowKind {
1908 pub fn from_mutbl(m: hir::Mutability) -> BorrowKind {
1909 match m {
1910 hir::MutMutable => MutBorrow,
1911 hir::MutImmutable => ImmBorrow,
1912 }
1913 }
1914
1915 /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow
1916 /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a
1917 /// mutability that is stronger than necessary so that it at least *would permit* the borrow in
1918 /// question.
1919 pub fn to_mutbl_lossy(self) -> hir::Mutability {
1920 match self {
1921 MutBorrow => hir::MutMutable,
1922 ImmBorrow => hir::MutImmutable,
1923
1924 // We have no type corresponding to a unique imm borrow, so
1925 // use `&mut`. It gives all the capabilities of an `&uniq`
1926 // and hence is a safe "over approximation".
1927 UniqueImmBorrow => hir::MutMutable,
1928 }
1929 }
1930
1931 pub fn to_user_str(&self) -> &'static str {
1932 match *self {
1933 MutBorrow => "mutable",
1934 ImmBorrow => "immutable",
1935 UniqueImmBorrow => "uniquely immutable",
1936 }
1937 }
1938 }
1939
1940 impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
1941 pub fn tables(self) -> Ref<'a, Tables<'gcx>> {
1942 self.tables.borrow()
1943 }
1944
1945 pub fn expr_span(self, id: NodeId) -> Span {
1946 match self.map.find(id) {
1947 Some(ast_map::NodeExpr(e)) => {
1948 e.span
1949 }
1950 Some(f) => {
1951 bug!("Node id {} is not an expr: {:?}", id, f);
1952 }
1953 None => {
1954 bug!("Node id {} is not present in the node map", id);
1955 }
1956 }
1957 }
1958
1959 pub fn local_var_name_str(self, id: NodeId) -> InternedString {
1960 match self.map.find(id) {
1961 Some(ast_map::NodeLocal(pat)) => {
1962 match pat.node {
1963 hir::PatKind::Binding(_, _, ref path1, _) => path1.node.as_str(),
1964 _ => {
1965 bug!("Variable id {} maps to {:?}, not local", id, pat);
1966 },
1967 }
1968 },
1969 r => bug!("Variable id {} maps to {:?}, not local", id, r),
1970 }
1971 }
1972
1973 pub fn expr_is_lval(self, expr: &hir::Expr) -> bool {
1974 match expr.node {
1975 hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
1976 match path.def {
1977 Def::Local(..) | Def::Upvar(..) | Def::Static(..) | Def::Err => true,
1978 _ => false,
1979 }
1980 }
1981
1982 hir::ExprType(ref e, _) => {
1983 self.expr_is_lval(e)
1984 }
1985
1986 hir::ExprUnary(hir::UnDeref, _) |
1987 hir::ExprField(..) |
1988 hir::ExprTupField(..) |
1989 hir::ExprIndex(..) => {
1990 true
1991 }
1992
1993 // Partially qualified paths in expressions can only legally
1994 // refer to associated items which are always rvalues.
1995 hir::ExprPath(hir::QPath::TypeRelative(..)) |
1996
1997 hir::ExprCall(..) |
1998 hir::ExprMethodCall(..) |
1999 hir::ExprStruct(..) |
2000 hir::ExprTup(..) |
2001 hir::ExprIf(..) |
2002 hir::ExprMatch(..) |
2003 hir::ExprClosure(..) |
2004 hir::ExprBlock(..) |
2005 hir::ExprRepeat(..) |
2006 hir::ExprArray(..) |
2007 hir::ExprBreak(..) |
2008 hir::ExprAgain(..) |
2009 hir::ExprRet(..) |
2010 hir::ExprWhile(..) |
2011 hir::ExprLoop(..) |
2012 hir::ExprAssign(..) |
2013 hir::ExprInlineAsm(..) |
2014 hir::ExprAssignOp(..) |
2015 hir::ExprLit(_) |
2016 hir::ExprUnary(..) |
2017 hir::ExprBox(..) |
2018 hir::ExprAddrOf(..) |
2019 hir::ExprBinary(..) |
2020 hir::ExprCast(..) => {
2021 false
2022 }
2023 }
2024 }
2025
2026 pub fn provided_trait_methods(self, id: DefId) -> Vec<AssociatedItem> {
2027 self.associated_items(id)
2028 .filter(|item| item.kind == AssociatedKind::Method && item.defaultness.has_value())
2029 .collect()
2030 }
2031
2032 pub fn trait_impl_polarity(self, id: DefId) -> hir::ImplPolarity {
2033 if let Some(id) = self.map.as_local_node_id(id) {
2034 match self.map.expect_item(id).node {
2035 hir::ItemImpl(_, polarity, ..) => polarity,
2036 ref item => bug!("trait_impl_polarity: {:?} not an impl", item)
2037 }
2038 } else {
2039 self.sess.cstore.impl_polarity(id)
2040 }
2041 }
2042
2043 pub fn custom_coerce_unsized_kind(self, did: DefId) -> adjustment::CustomCoerceUnsized {
2044 self.custom_coerce_unsized_kinds.memoize(did, || {
2045 let (kind, src) = if did.krate != LOCAL_CRATE {
2046 (self.sess.cstore.custom_coerce_unsized_kind(did), "external")
2047 } else {
2048 (None, "local")
2049 };
2050
2051 match kind {
2052 Some(kind) => kind,
2053 None => {
2054 bug!("custom_coerce_unsized_kind: \
2055 {} impl `{}` is missing its kind",
2056 src, self.item_path_str(did));
2057 }
2058 }
2059 })
2060 }
2061
2062 pub fn associated_item(self, def_id: DefId) -> AssociatedItem {
2063 self.associated_items.memoize(def_id, || {
2064 if !def_id.is_local() {
2065 return self.sess.cstore.associated_item(def_id)
2066 .expect("missing AssociatedItem in metadata");
2067 }
2068
2069 // When the user asks for a given associated item, we
2070 // always go ahead and convert all the associated items in
2071 // the container. Note that we are also careful only to
2072 // ever register a read on the *container* of the assoc
2073 // item, not the assoc item itself. This prevents changes
2074 // in the details of an item (for example, the type to
2075 // which an associated type is bound) from contaminating
2076 // those tasks that just need to scan the names of items
2077 // and so forth.
2078
2079 let id = self.map.as_local_node_id(def_id).unwrap();
2080 let parent_id = self.map.get_parent(id);
2081 let parent_def_id = self.map.local_def_id(parent_id);
2082 let parent_item = self.map.expect_item(parent_id);
2083 match parent_item.node {
2084 hir::ItemImpl(.., ref impl_trait_ref, _, ref impl_item_refs) => {
2085 for impl_item_ref in impl_item_refs {
2086 let assoc_item =
2087 self.associated_item_from_impl_item_ref(parent_def_id,
2088 impl_trait_ref.is_some(),
2089 impl_item_ref);
2090 self.associated_items.borrow_mut().insert(assoc_item.def_id, assoc_item);
2091 }
2092 }
2093
2094 hir::ItemTrait(.., ref trait_items) => {
2095 for trait_item in trait_items {
2096 let assoc_item =
2097 self.associated_item_from_trait_item_ref(parent_def_id, trait_item);
2098 self.associated_items.borrow_mut().insert(assoc_item.def_id, assoc_item);
2099 }
2100 }
2101
2102 ref r => {
2103 panic!("unexpected container of associated items: {:?}", r)
2104 }
2105 }
2106
2107 // memoize wants us to return something, so return
2108 // the one we generated for this def-id
2109 *self.associated_items.borrow().get(&def_id).unwrap()
2110 })
2111 }
2112
2113 fn associated_item_from_trait_item_ref(self,
2114 parent_def_id: DefId,
2115 trait_item: &hir::TraitItem)
2116 -> AssociatedItem {
2117 let def_id = self.map.local_def_id(trait_item.id);
2118
2119 let (kind, has_self, has_value) = match trait_item.node {
2120 hir::MethodTraitItem(ref sig, ref body) => {
2121 (AssociatedKind::Method, sig.decl.get_self().is_some(),
2122 body.is_some())
2123 }
2124 hir::ConstTraitItem(_, ref value) => {
2125 (AssociatedKind::Const, false, value.is_some())
2126 }
2127 hir::TypeTraitItem(_, ref ty) => {
2128 (AssociatedKind::Type, false, ty.is_some())
2129 }
2130 };
2131
2132 AssociatedItem {
2133 name: trait_item.name,
2134 kind: kind,
2135 vis: Visibility::from_hir(&hir::Inherited, trait_item.id, self),
2136 defaultness: hir::Defaultness::Default { has_value: has_value },
2137 def_id: def_id,
2138 container: TraitContainer(parent_def_id),
2139 method_has_self_argument: has_self
2140 }
2141 }
2142
2143 fn associated_item_from_impl_item_ref(self,
2144 parent_def_id: DefId,
2145 from_trait_impl: bool,
2146 impl_item_ref: &hir::ImplItemRef)
2147 -> AssociatedItem {
2148 let def_id = self.map.local_def_id(impl_item_ref.id.node_id);
2149 let (kind, has_self) = match impl_item_ref.kind {
2150 hir::AssociatedItemKind::Const => (ty::AssociatedKind::Const, false),
2151 hir::AssociatedItemKind::Method { has_self } => {
2152 (ty::AssociatedKind::Method, has_self)
2153 }
2154 hir::AssociatedItemKind::Type => (ty::AssociatedKind::Type, false),
2155 };
2156
2157 // Trait impl items are always public.
2158 let public = hir::Public;
2159 let vis = if from_trait_impl { &public } else { &impl_item_ref.vis };
2160
2161 ty::AssociatedItem {
2162 name: impl_item_ref.name,
2163 kind: kind,
2164 vis: ty::Visibility::from_hir(vis, impl_item_ref.id.node_id, self),
2165 defaultness: impl_item_ref.defaultness,
2166 def_id: def_id,
2167 container: ImplContainer(parent_def_id),
2168 method_has_self_argument: has_self
2169 }
2170 }
2171
2172 pub fn associated_item_def_ids(self, def_id: DefId) -> Rc<Vec<DefId>> {
2173 self.associated_item_def_ids.memoize(def_id, || {
2174 if !def_id.is_local() {
2175 return Rc::new(self.sess.cstore.associated_item_def_ids(def_id));
2176 }
2177
2178 let id = self.map.as_local_node_id(def_id).unwrap();
2179 let item = self.map.expect_item(id);
2180 let vec: Vec<_> = match item.node {
2181 hir::ItemTrait(.., ref trait_items) => {
2182 trait_items.iter()
2183 .map(|trait_item| trait_item.id)
2184 .map(|id| self.map.local_def_id(id))
2185 .collect()
2186 }
2187 hir::ItemImpl(.., ref impl_item_refs) => {
2188 impl_item_refs.iter()
2189 .map(|impl_item_ref| impl_item_ref.id)
2190 .map(|id| self.map.local_def_id(id.node_id))
2191 .collect()
2192 }
2193 _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait")
2194 };
2195 Rc::new(vec)
2196 })
2197 }
2198
2199 #[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait.
2200 pub fn associated_items(self, def_id: DefId)
2201 -> impl Iterator<Item = ty::AssociatedItem> + 'a {
2202 let def_ids = self.associated_item_def_ids(def_id);
2203 (0..def_ids.len()).map(move |i| self.associated_item(def_ids[i]))
2204 }
2205
2206 /// Returns the trait-ref corresponding to a given impl, or None if it is
2207 /// an inherent impl.
2208 pub fn impl_trait_ref(self, id: DefId) -> Option<TraitRef<'gcx>> {
2209 lookup_locally_or_in_crate_store(
2210 "impl_trait_refs", id, &self.impl_trait_refs,
2211 || self.sess.cstore.impl_trait_ref(self.global_tcx(), id))
2212 }
2213
2214 // Returns `ty::VariantDef` if `def` refers to a struct,
2215 // or variant or their constructors, panics otherwise.
2216 pub fn expect_variant_def(self, def: Def) -> &'tcx VariantDef {
2217 match def {
2218 Def::Variant(did) | Def::VariantCtor(did, ..) => {
2219 let enum_did = self.parent_def_id(did).unwrap();
2220 self.lookup_adt_def(enum_did).variant_with_id(did)
2221 }
2222 Def::Struct(did) | Def::Union(did) => {
2223 self.lookup_adt_def(did).struct_variant()
2224 }
2225 Def::StructCtor(ctor_did, ..) => {
2226 let did = self.parent_def_id(ctor_did).expect("struct ctor has no parent");
2227 self.lookup_adt_def(did).struct_variant()
2228 }
2229 _ => bug!("expect_variant_def used with unexpected def {:?}", def)
2230 }
2231 }
2232
2233 pub fn def_key(self, id: DefId) -> ast_map::DefKey {
2234 if id.is_local() {
2235 self.map.def_key(id)
2236 } else {
2237 self.sess.cstore.def_key(id)
2238 }
2239 }
2240
2241 /// Convert a `DefId` into its fully expanded `DefPath` (every
2242 /// `DefId` is really just an interned def-path).
2243 ///
2244 /// Note that if `id` is not local to this crate -- or is
2245 /// inlined into this crate -- the result will be a non-local
2246 /// `DefPath`.
2247 ///
2248 /// This function is only safe to use when you are sure that the
2249 /// full def-path is accessible. Examples that are known to be
2250 /// safe are local def-ids or items; see `opt_def_path` for more
2251 /// details.
2252 pub fn def_path(self, id: DefId) -> ast_map::DefPath {
2253 self.opt_def_path(id).unwrap_or_else(|| {
2254 bug!("could not load def-path for {:?}", id)
2255 })
2256 }
2257
2258 /// Convert a `DefId` into its fully expanded `DefPath` (every
2259 /// `DefId` is really just an interned def-path).
2260 ///
2261 /// When going across crates, we do not save the full info for
2262 /// every cross-crate def-id, and hence we may not always be able
2263 /// to create a def-path. Therefore, this returns
2264 /// `Option<DefPath>` to cover that possibility. It will always
2265 /// return `Some` for local def-ids, however, as well as for
2266 /// items. The problems arise with "minor" def-ids like those
2267 /// associated with a pattern, `impl Trait`, or other internal
2268 /// detail to a fn.
2269 ///
2270 /// Note that if `id` is not local to this crate -- or is
2271 /// inlined into this crate -- the result will be a non-local
2272 /// `DefPath`.
2273 pub fn opt_def_path(self, id: DefId) -> Option<ast_map::DefPath> {
2274 if id.is_local() {
2275 Some(self.map.def_path(id))
2276 } else {
2277 self.sess.cstore.relative_def_path(id)
2278 }
2279 }
2280
2281 pub fn def_span(self, def_id: DefId) -> Span {
2282 if let Some(id) = self.map.as_local_node_id(def_id) {
2283 self.map.span(id)
2284 } else {
2285 self.sess.cstore.def_span(&self.sess, def_id)
2286 }
2287 }
2288
2289 pub fn item_name(self, id: DefId) -> ast::Name {
2290 if let Some(id) = self.map.as_local_node_id(id) {
2291 self.map.name(id)
2292 } else if id.index == CRATE_DEF_INDEX {
2293 self.sess.cstore.original_crate_name(id.krate)
2294 } else {
2295 let def_key = self.sess.cstore.def_key(id);
2296 // The name of a StructCtor is that of its struct parent.
2297 if let ast_map::DefPathData::StructCtor = def_key.disambiguated_data.data {
2298 self.item_name(DefId {
2299 krate: id.krate,
2300 index: def_key.parent.unwrap()
2301 })
2302 } else {
2303 def_key.disambiguated_data.data.get_opt_name().unwrap_or_else(|| {
2304 bug!("item_name: no name for {:?}", self.def_path(id));
2305 })
2306 }
2307 }
2308 }
2309
2310 // If the given item is in an external crate, looks up its type and adds it to
2311 // the type cache. Returns the type parameters and type.
2312 pub fn item_type(self, did: DefId) -> Ty<'gcx> {
2313 lookup_locally_or_in_crate_store(
2314 "item_types", did, &self.item_types,
2315 || self.sess.cstore.item_type(self.global_tcx(), did))
2316 }
2317
2318 /// Given the did of a trait, returns its canonical trait ref.
2319 pub fn lookup_trait_def(self, did: DefId) -> &'gcx TraitDef {
2320 lookup_locally_or_in_crate_store(
2321 "trait_defs", did, &self.trait_defs,
2322 || self.alloc_trait_def(self.sess.cstore.trait_def(self.global_tcx(), did))
2323 )
2324 }
2325
2326 /// Given the did of an ADT, return a reference to its definition.
2327 pub fn lookup_adt_def(self, did: DefId) -> &'gcx AdtDef {
2328 lookup_locally_or_in_crate_store(
2329 "adt_defs", did, &self.adt_defs,
2330 || self.sess.cstore.adt_def(self.global_tcx(), did))
2331 }
2332
2333 /// Given the did of an item, returns its generics.
2334 pub fn item_generics(self, did: DefId) -> &'gcx Generics<'gcx> {
2335 lookup_locally_or_in_crate_store(
2336 "generics", did, &self.generics,
2337 || self.alloc_generics(self.sess.cstore.item_generics(self.global_tcx(), did)))
2338 }
2339
2340 /// Given the did of an item, returns its full set of predicates.
2341 pub fn item_predicates(self, did: DefId) -> GenericPredicates<'gcx> {
2342 lookup_locally_or_in_crate_store(
2343 "predicates", did, &self.predicates,
2344 || self.sess.cstore.item_predicates(self.global_tcx(), did))
2345 }
2346
2347 /// Given the did of a trait, returns its superpredicates.
2348 pub fn item_super_predicates(self, did: DefId) -> GenericPredicates<'gcx> {
2349 lookup_locally_or_in_crate_store(
2350 "super_predicates", did, &self.super_predicates,
2351 || self.sess.cstore.item_super_predicates(self.global_tcx(), did))
2352 }
2353
2354 /// Given the did of an item, returns its MIR, borrowed immutably.
2355 pub fn item_mir(self, did: DefId) -> Ref<'gcx, Mir<'gcx>> {
2356 lookup_locally_or_in_crate_store("mir_map", did, &self.mir_map, || {
2357 let mir = self.sess.cstore.get_item_mir(self.global_tcx(), did);
2358 let mir = self.alloc_mir(mir);
2359
2360 // Perma-borrow MIR from extern crates to prevent mutation.
2361 mem::forget(mir.borrow());
2362
2363 mir
2364 }).borrow()
2365 }
2366
2367 /// If `type_needs_drop` returns true, then `ty` is definitely
2368 /// non-copy and *might* have a destructor attached; if it returns
2369 /// false, then `ty` definitely has no destructor (i.e. no drop glue).
2370 ///
2371 /// (Note that this implies that if `ty` has a destructor attached,
2372 /// then `type_needs_drop` will definitely return `true` for `ty`.)
2373 pub fn type_needs_drop_given_env(self,
2374 ty: Ty<'gcx>,
2375 param_env: &ty::ParameterEnvironment<'gcx>) -> bool {
2376 // Issue #22536: We first query type_moves_by_default. It sees a
2377 // normalized version of the type, and therefore will definitely
2378 // know whether the type implements Copy (and thus needs no
2379 // cleanup/drop/zeroing) ...
2380 let tcx = self.global_tcx();
2381 let implements_copy = !ty.moves_by_default(tcx, param_env, DUMMY_SP);
2382
2383 if implements_copy { return false; }
2384
2385 // ... (issue #22536 continued) but as an optimization, still use
2386 // prior logic of asking if the `needs_drop` bit is set; we need
2387 // not zero non-Copy types if they have no destructor.
2388
2389 // FIXME(#22815): Note that calling `ty::type_contents` is a
2390 // conservative heuristic; it may report that `needs_drop` is set
2391 // when actual type does not actually have a destructor associated
2392 // with it. But since `ty` absolutely did not have the `Copy`
2393 // bound attached (see above), it is sound to treat it as having a
2394 // destructor (e.g. zero its memory on move).
2395
2396 let contents = ty.type_contents(tcx);
2397 debug!("type_needs_drop ty={:?} contents={:?}", ty, contents);
2398 contents.needs_drop(tcx)
2399 }
2400
2401 /// Get the attributes of a definition.
2402 pub fn get_attrs(self, did: DefId) -> Cow<'gcx, [ast::Attribute]> {
2403 if let Some(id) = self.map.as_local_node_id(did) {
2404 Cow::Borrowed(self.map.attrs(id))
2405 } else {
2406 Cow::Owned(self.sess.cstore.item_attrs(did))
2407 }
2408 }
2409
2410 /// Determine whether an item is annotated with an attribute
2411 pub fn has_attr(self, did: DefId, attr: &str) -> bool {
2412 self.get_attrs(did).iter().any(|item| item.check_name(attr))
2413 }
2414
2415 /// Determine whether an item is annotated with `#[repr(packed)]`
2416 pub fn lookup_packed(self, did: DefId) -> bool {
2417 self.lookup_repr_hints(did).contains(&attr::ReprPacked)
2418 }
2419
2420 /// Determine whether an item is annotated with `#[simd]`
2421 pub fn lookup_simd(self, did: DefId) -> bool {
2422 self.has_attr(did, "simd")
2423 || self.lookup_repr_hints(did).contains(&attr::ReprSimd)
2424 }
2425
2426 pub fn item_variances(self, item_id: DefId) -> Rc<Vec<ty::Variance>> {
2427 lookup_locally_or_in_crate_store(
2428 "item_variance_map", item_id, &self.item_variance_map,
2429 || Rc::new(self.sess.cstore.item_variances(item_id)))
2430 }
2431
2432 pub fn trait_has_default_impl(self, trait_def_id: DefId) -> bool {
2433 self.populate_implementations_for_trait_if_necessary(trait_def_id);
2434
2435 let def = self.lookup_trait_def(trait_def_id);
2436 def.flags.get().intersects(TraitFlags::HAS_DEFAULT_IMPL)
2437 }
2438
2439 /// Records a trait-to-implementation mapping.
2440 pub fn record_trait_has_default_impl(self, trait_def_id: DefId) {
2441 let def = self.lookup_trait_def(trait_def_id);
2442 def.flags.set(def.flags.get() | TraitFlags::HAS_DEFAULT_IMPL)
2443 }
2444
2445 /// Populates the type context with all the inherent implementations for
2446 /// the given type if necessary.
2447 pub fn populate_inherent_implementations_for_type_if_necessary(self,
2448 type_id: DefId) {
2449 if type_id.is_local() {
2450 return
2451 }
2452
2453 // The type is not local, hence we are reading this out of
2454 // metadata and don't need to track edges.
2455 let _ignore = self.dep_graph.in_ignore();
2456
2457 if self.populated_external_types.borrow().contains(&type_id) {
2458 return
2459 }
2460
2461 debug!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}",
2462 type_id);
2463
2464 let inherent_impls = self.sess.cstore.inherent_implementations_for_type(type_id);
2465
2466 self.inherent_impls.borrow_mut().insert(type_id, inherent_impls);
2467 self.populated_external_types.borrow_mut().insert(type_id);
2468 }
2469
2470 /// Populates the type context with all the implementations for the given
2471 /// trait if necessary.
2472 pub fn populate_implementations_for_trait_if_necessary(self, trait_id: DefId) {
2473 if trait_id.is_local() {
2474 return
2475 }
2476
2477 // The type is not local, hence we are reading this out of
2478 // metadata and don't need to track edges.
2479 let _ignore = self.dep_graph.in_ignore();
2480
2481 let def = self.lookup_trait_def(trait_id);
2482 if def.flags.get().intersects(TraitFlags::IMPLS_VALID) {
2483 return;
2484 }
2485
2486 debug!("populate_implementations_for_trait_if_necessary: searching for {:?}", def);
2487
2488 if self.sess.cstore.is_defaulted_trait(trait_id) {
2489 self.record_trait_has_default_impl(trait_id);
2490 }
2491
2492 for impl_def_id in self.sess.cstore.implementations_of_trait(Some(trait_id)) {
2493 let trait_ref = self.impl_trait_ref(impl_def_id).unwrap();
2494
2495 // Record the trait->implementation mapping.
2496 let parent = self.sess.cstore.impl_parent(impl_def_id).unwrap_or(trait_id);
2497 def.record_remote_impl(self, impl_def_id, trait_ref, parent);
2498 }
2499
2500 def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID);
2501 }
2502
2503 pub fn closure_kind(self, def_id: DefId) -> ty::ClosureKind {
2504 // If this is a local def-id, it should be inserted into the
2505 // tables by typeck; else, it will be retreived from
2506 // the external crate metadata.
2507 if let Some(&kind) = self.tables.borrow().closure_kinds.get(&def_id) {
2508 return kind;
2509 }
2510
2511 let kind = self.sess.cstore.closure_kind(def_id);
2512 self.tables.borrow_mut().closure_kinds.insert(def_id, kind);
2513 kind
2514 }
2515
2516 pub fn closure_type(self,
2517 def_id: DefId,
2518 substs: ClosureSubsts<'tcx>)
2519 -> ty::ClosureTy<'tcx>
2520 {
2521 // If this is a local def-id, it should be inserted into the
2522 // tables by typeck; else, it will be retreived from
2523 // the external crate metadata.
2524 if let Some(ty) = self.tables.borrow().closure_tys.get(&def_id) {
2525 return ty.subst(self, substs.substs);
2526 }
2527
2528 let ty = self.sess.cstore.closure_ty(self.global_tcx(), def_id);
2529 self.tables.borrow_mut().closure_tys.insert(def_id, ty.clone());
2530 ty.subst(self, substs.substs)
2531 }
2532
2533 /// Given the def_id of an impl, return the def_id of the trait it implements.
2534 /// If it implements no trait, return `None`.
2535 pub fn trait_id_of_impl(self, def_id: DefId) -> Option<DefId> {
2536 self.impl_trait_ref(def_id).map(|tr| tr.def_id)
2537 }
2538
2539 /// If the given def ID describes a method belonging to an impl, return the
2540 /// ID of the impl that the method belongs to. Otherwise, return `None`.
2541 pub fn impl_of_method(self, def_id: DefId) -> Option<DefId> {
2542 if def_id.krate != LOCAL_CRATE {
2543 return self.sess.cstore.associated_item(def_id)
2544 .and_then(|item| {
2545 match item.container {
2546 TraitContainer(_) => None,
2547 ImplContainer(def_id) => Some(def_id),
2548 }
2549 });
2550 }
2551 match self.associated_items.borrow().get(&def_id).cloned() {
2552 Some(trait_item) => {
2553 match trait_item.container {
2554 TraitContainer(_) => None,
2555 ImplContainer(def_id) => Some(def_id),
2556 }
2557 }
2558 None => None
2559 }
2560 }
2561
2562 /// If the given def ID describes an item belonging to a trait,
2563 /// return the ID of the trait that the trait item belongs to.
2564 /// Otherwise, return `None`.
2565 pub fn trait_of_item(self, def_id: DefId) -> Option<DefId> {
2566 if def_id.krate != LOCAL_CRATE {
2567 return self.sess.cstore.trait_of_item(def_id);
2568 }
2569 match self.associated_items.borrow().get(&def_id) {
2570 Some(associated_item) => {
2571 match associated_item.container {
2572 TraitContainer(def_id) => Some(def_id),
2573 ImplContainer(_) => None
2574 }
2575 }
2576 None => None
2577 }
2578 }
2579
2580 /// Construct a parameter environment suitable for static contexts or other contexts where there
2581 /// are no free type/lifetime parameters in scope.
2582 pub fn empty_parameter_environment(self) -> ParameterEnvironment<'tcx> {
2583
2584 // for an empty parameter environment, there ARE no free
2585 // regions, so it shouldn't matter what we use for the free id
2586 let free_id_outlive = self.region_maps.node_extent(ast::DUMMY_NODE_ID);
2587 ty::ParameterEnvironment {
2588 free_substs: self.intern_substs(&[]),
2589 caller_bounds: Vec::new(),
2590 implicit_region_bound: self.mk_region(ty::ReEmpty),
2591 free_id_outlive: free_id_outlive,
2592 is_copy_cache: RefCell::new(FxHashMap()),
2593 is_sized_cache: RefCell::new(FxHashMap()),
2594 }
2595 }
2596
2597 /// Constructs and returns a substitution that can be applied to move from
2598 /// the "outer" view of a type or method to the "inner" view.
2599 /// In general, this means converting from bound parameters to
2600 /// free parameters. Since we currently represent bound/free type
2601 /// parameters in the same way, this only has an effect on regions.
2602 pub fn construct_free_substs(self, def_id: DefId,
2603 free_id_outlive: CodeExtent)
2604 -> &'gcx Substs<'gcx> {
2605
2606 let substs = Substs::for_item(self.global_tcx(), def_id, |def, _| {
2607 // map bound 'a => free 'a
2608 self.global_tcx().mk_region(ReFree(FreeRegion {
2609 scope: free_id_outlive,
2610 bound_region: def.to_bound_region()
2611 }))
2612 }, |def, _| {
2613 // map T => T
2614 self.global_tcx().mk_param_from_def(def)
2615 });
2616
2617 debug!("construct_parameter_environment: {:?}", substs);
2618 substs
2619 }
2620
2621 /// See `ParameterEnvironment` struct def'n for details.
2622 /// If you were using `free_id: NodeId`, you might try `self.region_maps.item_extent(free_id)`
2623 /// for the `free_id_outlive` parameter. (But note that this is not always quite right.)
2624 pub fn construct_parameter_environment(self,
2625 span: Span,
2626 def_id: DefId,
2627 free_id_outlive: CodeExtent)
2628 -> ParameterEnvironment<'gcx>
2629 {
2630 //
2631 // Construct the free substs.
2632 //
2633
2634 let free_substs = self.construct_free_substs(def_id, free_id_outlive);
2635
2636 //
2637 // Compute the bounds on Self and the type parameters.
2638 //
2639
2640 let tcx = self.global_tcx();
2641 let generic_predicates = tcx.item_predicates(def_id);
2642 let bounds = generic_predicates.instantiate(tcx, free_substs);
2643 let bounds = tcx.liberate_late_bound_regions(free_id_outlive, &ty::Binder(bounds));
2644 let predicates = bounds.predicates;
2645
2646 // Finally, we have to normalize the bounds in the environment, in
2647 // case they contain any associated type projections. This process
2648 // can yield errors if the put in illegal associated types, like
2649 // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
2650 // report these errors right here; this doesn't actually feel
2651 // right to me, because constructing the environment feels like a
2652 // kind of a "idempotent" action, but I'm not sure where would be
2653 // a better place. In practice, we construct environments for
2654 // every fn once during type checking, and we'll abort if there
2655 // are any errors at that point, so after type checking you can be
2656 // sure that this will succeed without errors anyway.
2657 //
2658
2659 let unnormalized_env = ty::ParameterEnvironment {
2660 free_substs: free_substs,
2661 implicit_region_bound: tcx.mk_region(ty::ReScope(free_id_outlive)),
2662 caller_bounds: predicates,
2663 free_id_outlive: free_id_outlive,
2664 is_copy_cache: RefCell::new(FxHashMap()),
2665 is_sized_cache: RefCell::new(FxHashMap()),
2666 };
2667
2668 let cause = traits::ObligationCause::misc(span, free_id_outlive.node_id(&self.region_maps));
2669 traits::normalize_param_env_or_error(tcx, unnormalized_env, cause)
2670 }
2671
2672 pub fn node_scope_region(self, id: NodeId) -> &'tcx Region {
2673 self.mk_region(ty::ReScope(self.region_maps.node_extent(id)))
2674 }
2675
2676 pub fn visit_all_item_likes_in_krate<V,F>(self,
2677 dep_node_fn: F,
2678 visitor: &mut V)
2679 where F: FnMut(DefId) -> DepNode<DefId>, V: ItemLikeVisitor<'gcx>
2680 {
2681 dep_graph::visit_all_item_likes_in_krate(self.global_tcx(), dep_node_fn, visitor);
2682 }
2683
2684 /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
2685 /// with the name of the crate containing the impl.
2686 pub fn span_of_impl(self, impl_did: DefId) -> Result<Span, Symbol> {
2687 if impl_did.is_local() {
2688 let node_id = self.map.as_local_node_id(impl_did).unwrap();
2689 Ok(self.map.span(node_id))
2690 } else {
2691 Err(self.sess.cstore.crate_name(impl_did.krate))
2692 }
2693 }
2694 }
2695
2696 impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
2697 pub fn with_freevars<T, F>(self, fid: NodeId, f: F) -> T where
2698 F: FnOnce(&[hir::Freevar]) -> T,
2699 {
2700 match self.freevars.borrow().get(&fid) {
2701 None => f(&[]),
2702 Some(d) => f(&d[..])
2703 }
2704 }
2705 }