]> git.proxmox.com Git - rustc.git/blob - src/librustc/middle/ty.rs
Imported Upstream version 1.2.0+dfsg1
[rustc.git] / src / librustc / middle / ty.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
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 #![allow(non_camel_case_types)]
12
13 pub use self::terr_vstore_kind::*;
14 pub use self::type_err::*;
15 pub use self::InferTy::*;
16 pub use self::InferRegion::*;
17 pub use self::ImplOrTraitItemId::*;
18 pub use self::ClosureKind::*;
19 pub use self::Variance::*;
20 pub use self::AutoAdjustment::*;
21 pub use self::Representability::*;
22 pub use self::AutoRef::*;
23 pub use self::DtorKind::*;
24 pub use self::ExplicitSelfCategory::*;
25 pub use self::FnOutput::*;
26 pub use self::Region::*;
27 pub use self::ImplOrTraitItemContainer::*;
28 pub use self::BorrowKind::*;
29 pub use self::ImplOrTraitItem::*;
30 pub use self::BoundRegion::*;
31 pub use self::TypeVariants::*;
32 pub use self::IntVarValue::*;
33 pub use self::MethodOrigin::*;
34 pub use self::CopyImplementationError::*;
35
36 pub use self::BuiltinBound::Send as BoundSend;
37 pub use self::BuiltinBound::Sized as BoundSized;
38 pub use self::BuiltinBound::Copy as BoundCopy;
39 pub use self::BuiltinBound::Sync as BoundSync;
40
41 use ast_map::{self, LinkedPath};
42 use back::svh::Svh;
43 use session::Session;
44 use lint;
45 use metadata::csearch;
46 use middle;
47 use middle::cast;
48 use middle::check_const;
49 use middle::const_eval::{self, ConstVal};
50 use middle::def::{self, DefMap, ExportMap};
51 use middle::dependency_format;
52 use middle::fast_reject;
53 use middle::free_region::FreeRegionMap;
54 use middle::infer::error_reporting::note_and_explain_region;
55 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
56 use middle::mem_categorization as mc;
57 use middle::region;
58 use middle::resolve_lifetime;
59 use middle::infer;
60 use middle::pat_util;
61 use middle::region::RegionMaps;
62 use middle::stability;
63 use middle::subst::{self, ParamSpace, Subst, Substs, VecPerParamSpace};
64 use middle::traits;
65 use middle::ty;
66 use middle::ty_fold::{self, TypeFoldable, TypeFolder};
67 use middle::ty_walk::{self, TypeWalker};
68 use util::common::{memoized, ErrorReported};
69 use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
70 use util::nodemap::FnvHashMap;
71 use util::num::ToPrimitive;
72
73 use arena::TypedArena;
74 use std::borrow::{Borrow, Cow};
75 use std::cell::{Cell, RefCell, Ref};
76 use std::cmp;
77 use std::fmt;
78 use std::hash::{Hash, SipHasher, Hasher};
79 use std::mem;
80 use std::ops;
81 use std::rc::Rc;
82 use std::vec::IntoIter;
83 use collections::enum_set::{self, EnumSet, CLike};
84 use std::collections::{HashMap, HashSet};
85 use syntax::abi;
86 use syntax::ast::{CrateNum, DefId, ItemImpl, ItemTrait, LOCAL_CRATE};
87 use syntax::ast::{MutImmutable, MutMutable, Name, NamedField, NodeId};
88 use syntax::ast::{StmtExpr, StmtSemi, StructField, UnnamedField, Visibility};
89 use syntax::ast_util::{self, is_local, local_def};
90 use syntax::attr::{self, AttrMetaMethods, SignedInt, UnsignedInt};
91 use syntax::codemap::Span;
92 use syntax::parse::token::{self, InternedString, special_idents};
93 use syntax::print::pprust;
94 use syntax::ptr::P;
95 use syntax::ast;
96
97 pub type Disr = u64;
98
99 pub const INITIAL_DISCRIMINANT_VALUE: Disr = 0;
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 pub struct CrateAnalysis {
106 pub export_map: ExportMap,
107 pub exported_items: middle::privacy::ExportedItems,
108 pub public_items: middle::privacy::PublicItems,
109 pub reachable: NodeSet,
110 pub name: String,
111 pub glob_map: Option<GlobMap>,
112 }
113
114 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
115 pub struct field<'tcx> {
116 pub name: ast::Name,
117 pub mt: mt<'tcx>
118 }
119
120 #[derive(Clone, Copy, Debug)]
121 pub enum ImplOrTraitItemContainer {
122 TraitContainer(ast::DefId),
123 ImplContainer(ast::DefId),
124 }
125
126 impl ImplOrTraitItemContainer {
127 pub fn id(&self) -> ast::DefId {
128 match *self {
129 TraitContainer(id) => id,
130 ImplContainer(id) => id,
131 }
132 }
133 }
134
135 #[derive(Clone)]
136 pub enum ImplOrTraitItem<'tcx> {
137 ConstTraitItem(Rc<AssociatedConst<'tcx>>),
138 MethodTraitItem(Rc<Method<'tcx>>),
139 TypeTraitItem(Rc<AssociatedType<'tcx>>),
140 }
141
142 impl<'tcx> ImplOrTraitItem<'tcx> {
143 fn id(&self) -> ImplOrTraitItemId {
144 match *self {
145 ConstTraitItem(ref associated_const) => {
146 ConstTraitItemId(associated_const.def_id)
147 }
148 MethodTraitItem(ref method) => MethodTraitItemId(method.def_id),
149 TypeTraitItem(ref associated_type) => {
150 TypeTraitItemId(associated_type.def_id)
151 }
152 }
153 }
154
155 pub fn def_id(&self) -> ast::DefId {
156 match *self {
157 ConstTraitItem(ref associated_const) => associated_const.def_id,
158 MethodTraitItem(ref method) => method.def_id,
159 TypeTraitItem(ref associated_type) => associated_type.def_id,
160 }
161 }
162
163 pub fn name(&self) -> ast::Name {
164 match *self {
165 ConstTraitItem(ref associated_const) => associated_const.name,
166 MethodTraitItem(ref method) => method.name,
167 TypeTraitItem(ref associated_type) => associated_type.name,
168 }
169 }
170
171 pub fn vis(&self) -> ast::Visibility {
172 match *self {
173 ConstTraitItem(ref associated_const) => associated_const.vis,
174 MethodTraitItem(ref method) => method.vis,
175 TypeTraitItem(ref associated_type) => associated_type.vis,
176 }
177 }
178
179 pub fn container(&self) -> ImplOrTraitItemContainer {
180 match *self {
181 ConstTraitItem(ref associated_const) => associated_const.container,
182 MethodTraitItem(ref method) => method.container,
183 TypeTraitItem(ref associated_type) => associated_type.container,
184 }
185 }
186
187 pub fn as_opt_method(&self) -> Option<Rc<Method<'tcx>>> {
188 match *self {
189 MethodTraitItem(ref m) => Some((*m).clone()),
190 _ => None,
191 }
192 }
193 }
194
195 #[derive(Clone, Copy, Debug)]
196 pub enum ImplOrTraitItemId {
197 ConstTraitItemId(ast::DefId),
198 MethodTraitItemId(ast::DefId),
199 TypeTraitItemId(ast::DefId),
200 }
201
202 impl ImplOrTraitItemId {
203 pub fn def_id(&self) -> ast::DefId {
204 match *self {
205 ConstTraitItemId(def_id) => def_id,
206 MethodTraitItemId(def_id) => def_id,
207 TypeTraitItemId(def_id) => def_id,
208 }
209 }
210 }
211
212 #[derive(Clone, Debug)]
213 pub struct Method<'tcx> {
214 pub name: ast::Name,
215 pub generics: Generics<'tcx>,
216 pub predicates: GenericPredicates<'tcx>,
217 pub fty: BareFnTy<'tcx>,
218 pub explicit_self: ExplicitSelfCategory,
219 pub vis: ast::Visibility,
220 pub def_id: ast::DefId,
221 pub container: ImplOrTraitItemContainer,
222
223 // If this method is provided, we need to know where it came from
224 pub provided_source: Option<ast::DefId>
225 }
226
227 impl<'tcx> Method<'tcx> {
228 pub fn new(name: ast::Name,
229 generics: ty::Generics<'tcx>,
230 predicates: GenericPredicates<'tcx>,
231 fty: BareFnTy<'tcx>,
232 explicit_self: ExplicitSelfCategory,
233 vis: ast::Visibility,
234 def_id: ast::DefId,
235 container: ImplOrTraitItemContainer,
236 provided_source: Option<ast::DefId>)
237 -> Method<'tcx> {
238 Method {
239 name: name,
240 generics: generics,
241 predicates: predicates,
242 fty: fty,
243 explicit_self: explicit_self,
244 vis: vis,
245 def_id: def_id,
246 container: container,
247 provided_source: provided_source
248 }
249 }
250
251 pub fn container_id(&self) -> ast::DefId {
252 match self.container {
253 TraitContainer(id) => id,
254 ImplContainer(id) => id,
255 }
256 }
257 }
258
259 #[derive(Clone, Copy, Debug)]
260 pub struct AssociatedConst<'tcx> {
261 pub name: ast::Name,
262 pub ty: Ty<'tcx>,
263 pub vis: ast::Visibility,
264 pub def_id: ast::DefId,
265 pub container: ImplOrTraitItemContainer,
266 pub default: Option<ast::DefId>,
267 }
268
269 #[derive(Clone, Copy, Debug)]
270 pub struct AssociatedType<'tcx> {
271 pub name: ast::Name,
272 pub ty: Option<Ty<'tcx>>,
273 pub vis: ast::Visibility,
274 pub def_id: ast::DefId,
275 pub container: ImplOrTraitItemContainer,
276 }
277
278 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
279 pub struct mt<'tcx> {
280 pub ty: Ty<'tcx>,
281 pub mutbl: ast::Mutability,
282 }
283
284 #[derive(Clone, Copy, Debug)]
285 pub struct field_ty {
286 pub name: Name,
287 pub id: DefId,
288 pub vis: ast::Visibility,
289 pub origin: ast::DefId, // The DefId of the struct in which the field is declared.
290 }
291
292 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable)]
293 pub struct ItemVariances {
294 pub types: VecPerParamSpace<Variance>,
295 pub regions: VecPerParamSpace<Variance>,
296 }
297
298 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Copy)]
299 pub enum Variance {
300 Covariant, // T<A> <: T<B> iff A <: B -- e.g., function return type
301 Invariant, // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
302 Contravariant, // T<A> <: T<B> iff B <: A -- e.g., function param type
303 Bivariant, // T<A> <: T<B> -- e.g., unused type parameter
304 }
305
306 #[derive(Copy, Clone)]
307 pub enum AutoAdjustment<'tcx> {
308 AdjustReifyFnPointer, // go from a fn-item type to a fn-pointer type
309 AdjustUnsafeFnPointer, // go from a safe fn pointer to an unsafe fn pointer
310 AdjustDerefRef(AutoDerefRef<'tcx>),
311 }
312
313 /// Represents coercing a pointer to a different kind of pointer - where 'kind'
314 /// here means either or both of raw vs borrowed vs unique and fat vs thin.
315 ///
316 /// We transform pointers by following the following steps in order:
317 /// 1. Deref the pointer `self.autoderefs` times (may be 0).
318 /// 2. If `autoref` is `Some(_)`, then take the address and produce either a
319 /// `&` or `*` pointer.
320 /// 3. If `unsize` is `Some(_)`, then apply the unsize transformation,
321 /// which will do things like convert thin pointers to fat
322 /// pointers, or convert structs containing thin pointers to
323 /// structs containing fat pointers, or convert between fat
324 /// pointers. We don't store the details of how the transform is
325 /// done (in fact, we don't know that, because it might depend on
326 /// the precise type parameters). We just store the target
327 /// type. Trans figures out what has to be done at monomorphization
328 /// time based on the precise source/target type at hand.
329 ///
330 /// To make that more concrete, here are some common scenarios:
331 ///
332 /// 1. The simplest cases are where the pointer is not adjusted fat vs thin.
333 /// Here the pointer will be dereferenced N times (where a dereference can
334 /// happen to to raw or borrowed pointers or any smart pointer which implements
335 /// Deref, including Box<_>). The number of dereferences is given by
336 /// `autoderefs`. It can then be auto-referenced zero or one times, indicated
337 /// by `autoref`, to either a raw or borrowed pointer. In these cases unsize is
338 /// None.
339 ///
340 /// 2. A thin-to-fat coercon involves unsizing the underlying data. We start
341 /// with a thin pointer, deref a number of times, unsize the underlying data,
342 /// then autoref. The 'unsize' phase may change a fixed length array to a
343 /// dynamically sized one, a concrete object to a trait object, or statically
344 /// sized struct to a dyncamically sized one. E.g., &[i32; 4] -> &[i32] is
345 /// represented by:
346 ///
347 /// ```
348 /// AutoDerefRef {
349 /// autoderefs: 1, // &[i32; 4] -> [i32; 4]
350 /// autoref: Some(AutoPtr), // [i32] -> &[i32]
351 /// unsize: Some([i32]), // [i32; 4] -> [i32]
352 /// }
353 /// ```
354 ///
355 /// Note that for a struct, the 'deep' unsizing of the struct is not recorded.
356 /// E.g., `struct Foo<T> { x: T }` we can coerce &Foo<[i32; 4]> to &Foo<[i32]>
357 /// The autoderef and -ref are the same as in the above example, but the type
358 /// stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about
359 /// the underlying conversions from `[i32; 4]` to `[i32]`.
360 ///
361 /// 3. Coercing a `Box<T>` to `Box<Trait>` is an interesting special case. In
362 /// that case, we have the pointer we need coming in, so there are no
363 /// autoderefs, and no autoref. Instead we just do the `Unsize` transformation.
364 /// At some point, of course, `Box` should move out of the compiler, in which
365 /// case this is analogous to transformating a struct. E.g., Box<[i32; 4]> ->
366 /// Box<[i32]> is represented by:
367 ///
368 /// ```
369 /// AutoDerefRef {
370 /// autoderefs: 0,
371 /// autoref: None,
372 /// unsize: Some(Box<[i32]>),
373 /// }
374 /// ```
375 #[derive(Copy, Clone)]
376 pub struct AutoDerefRef<'tcx> {
377 /// Step 1. Apply a number of dereferences, producing an lvalue.
378 pub autoderefs: usize,
379
380 /// Step 2. Optionally produce a pointer/reference from the value.
381 pub autoref: Option<AutoRef<'tcx>>,
382
383 /// Step 3. Unsize a pointer/reference value, e.g. `&[T; n]` to
384 /// `&[T]`. The stored type is the target pointer type. Note that
385 /// the source could be a thin or fat pointer.
386 pub unsize: Option<Ty<'tcx>>,
387 }
388
389 #[derive(Copy, Clone, PartialEq, Debug)]
390 pub enum AutoRef<'tcx> {
391 /// Convert from T to &T.
392 AutoPtr(&'tcx Region, ast::Mutability),
393
394 /// Convert from T to *T.
395 /// Value to thin pointer.
396 AutoUnsafe(ast::Mutability),
397 }
398
399 #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
400 pub enum CustomCoerceUnsized {
401 /// Records the index of the field being coerced.
402 Struct(usize)
403 }
404
405 #[derive(Clone)]
406 pub enum MethodOrigin<'tcx> {
407 // fully statically resolved method
408 MethodStatic(ast::DefId),
409
410 // fully statically resolved closure invocation
411 MethodStaticClosure(ast::DefId),
412
413 // method invoked on a type parameter with a bounded trait
414 MethodTypeParam(MethodParam<'tcx>),
415
416 // method invoked on a trait instance
417 MethodTraitObject(MethodObject<'tcx>),
418
419 }
420
421 // details for a method invoked with a receiver whose type is a type parameter
422 // with a bounded trait.
423 #[derive(Clone)]
424 pub struct MethodParam<'tcx> {
425 // the precise trait reference that occurs as a bound -- this may
426 // be a supertrait of what the user actually typed. Note that it
427 // never contains bound regions; those regions should have been
428 // instantiated with fresh variables at this point.
429 pub trait_ref: ty::TraitRef<'tcx>,
430
431 // index of usize in the list of trait items. Note that this is NOT
432 // the index into the vtable, because the list of trait items
433 // includes associated types.
434 pub method_num: usize,
435
436 /// The impl for the trait from which the method comes. This
437 /// should only be used for certain linting/heuristic purposes
438 /// since there is no guarantee that this is Some in every
439 /// situation that it could/should be.
440 pub impl_def_id: Option<ast::DefId>,
441 }
442
443 // details for a method invoked with a receiver whose type is an object
444 #[derive(Clone)]
445 pub struct MethodObject<'tcx> {
446 // the (super)trait containing the method to be invoked
447 pub trait_ref: TraitRef<'tcx>,
448
449 // the actual base trait id of the object
450 pub object_trait_id: ast::DefId,
451
452 // index of the method to be invoked amongst the trait's items
453 pub method_num: usize,
454
455 // index into the actual runtime vtable.
456 // the vtable is formed by concatenating together the method lists of
457 // the base object trait and all supertraits; this is the index into
458 // that vtable
459 pub vtable_index: usize,
460 }
461
462 #[derive(Clone, Debug)]
463 pub struct MethodCallee<'tcx> {
464 pub origin: MethodOrigin<'tcx>,
465 pub ty: Ty<'tcx>,
466 pub substs: subst::Substs<'tcx>
467 }
468
469 /// With method calls, we store some extra information in
470 /// side tables (i.e method_map). We use
471 /// MethodCall as a key to index into these tables instead of
472 /// just directly using the expression's NodeId. The reason
473 /// for this being that we may apply adjustments (coercions)
474 /// with the resulting expression also needing to use the
475 /// side tables. The problem with this is that we don't
476 /// assign a separate NodeId to this new expression
477 /// and so it would clash with the base expression if both
478 /// needed to add to the side tables. Thus to disambiguate
479 /// we also keep track of whether there's an adjustment in
480 /// our key.
481 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
482 pub struct MethodCall {
483 pub expr_id: ast::NodeId,
484 pub autoderef: u32
485 }
486
487 impl MethodCall {
488 pub fn expr(id: ast::NodeId) -> MethodCall {
489 MethodCall {
490 expr_id: id,
491 autoderef: 0
492 }
493 }
494
495 pub fn autoderef(expr_id: ast::NodeId, autoderef: u32) -> MethodCall {
496 MethodCall {
497 expr_id: expr_id,
498 autoderef: 1 + autoderef
499 }
500 }
501 }
502
503 // maps from an expression id that corresponds to a method call to the details
504 // of the method to be invoked
505 pub type MethodMap<'tcx> = RefCell<FnvHashMap<MethodCall, MethodCallee<'tcx>>>;
506
507 // Contains information needed to resolve types and (in the future) look up
508 // the types of AST nodes.
509 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
510 pub struct creader_cache_key {
511 pub cnum: CrateNum,
512 pub pos: usize,
513 pub len: usize
514 }
515
516 /// A restriction that certain types must be the same size. The use of
517 /// `transmute` gives rise to these restrictions. These generally
518 /// cannot be checked until trans; therefore, each call to `transmute`
519 /// will push one or more such restriction into the
520 /// `transmute_restrictions` vector during `intrinsicck`. They are
521 /// then checked during `trans` by the fn `check_intrinsics`.
522 #[derive(Copy, Clone)]
523 pub struct TransmuteRestriction<'tcx> {
524 /// The span whence the restriction comes.
525 pub span: Span,
526
527 /// The type being transmuted from.
528 pub original_from: Ty<'tcx>,
529
530 /// The type being transmuted to.
531 pub original_to: Ty<'tcx>,
532
533 /// The type being transmuted from, with all type parameters
534 /// substituted for an arbitrary representative. Not to be shown
535 /// to the end user.
536 pub substituted_from: Ty<'tcx>,
537
538 /// The type being transmuted to, with all type parameters
539 /// substituted for an arbitrary representative. Not to be shown
540 /// to the end user.
541 pub substituted_to: Ty<'tcx>,
542
543 /// NodeId of the transmute intrinsic.
544 pub id: ast::NodeId,
545 }
546
547 /// Internal storage
548 pub struct CtxtArenas<'tcx> {
549 // internings
550 type_: TypedArena<TyS<'tcx>>,
551 substs: TypedArena<Substs<'tcx>>,
552 bare_fn: TypedArena<BareFnTy<'tcx>>,
553 region: TypedArena<Region>,
554 stability: TypedArena<attr::Stability>,
555
556 // references
557 trait_defs: TypedArena<TraitDef<'tcx>>,
558 }
559
560 impl<'tcx> CtxtArenas<'tcx> {
561 pub fn new() -> CtxtArenas<'tcx> {
562 CtxtArenas {
563 type_: TypedArena::new(),
564 substs: TypedArena::new(),
565 bare_fn: TypedArena::new(),
566 region: TypedArena::new(),
567 stability: TypedArena::new(),
568
569 trait_defs: TypedArena::new()
570 }
571 }
572 }
573
574 pub struct CommonTypes<'tcx> {
575 pub bool: Ty<'tcx>,
576 pub char: Ty<'tcx>,
577 pub isize: Ty<'tcx>,
578 pub i8: Ty<'tcx>,
579 pub i16: Ty<'tcx>,
580 pub i32: Ty<'tcx>,
581 pub i64: Ty<'tcx>,
582 pub usize: Ty<'tcx>,
583 pub u8: Ty<'tcx>,
584 pub u16: Ty<'tcx>,
585 pub u32: Ty<'tcx>,
586 pub u64: Ty<'tcx>,
587 pub f32: Ty<'tcx>,
588 pub f64: Ty<'tcx>,
589 pub err: Ty<'tcx>,
590 }
591
592 /// The data structure to keep track of all the information that typechecker
593 /// generates so that so that it can be reused and doesn't have to be redone
594 /// later on.
595 pub struct ctxt<'tcx> {
596 /// The arenas that types etc are allocated from.
597 arenas: &'tcx CtxtArenas<'tcx>,
598
599 /// Specifically use a speedy hash algorithm for this hash map, it's used
600 /// quite often.
601 // FIXME(eddyb) use a FnvHashSet<InternedTy<'tcx>> when equivalent keys can
602 // queried from a HashSet.
603 interner: RefCell<FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>>,
604
605 // FIXME as above, use a hashset if equivalent elements can be queried.
606 substs_interner: RefCell<FnvHashMap<&'tcx Substs<'tcx>, &'tcx Substs<'tcx>>>,
607 bare_fn_interner: RefCell<FnvHashMap<&'tcx BareFnTy<'tcx>, &'tcx BareFnTy<'tcx>>>,
608 region_interner: RefCell<FnvHashMap<&'tcx Region, &'tcx Region>>,
609 stability_interner: RefCell<FnvHashMap<&'tcx attr::Stability, &'tcx attr::Stability>>,
610
611 /// Common types, pre-interned for your convenience.
612 pub types: CommonTypes<'tcx>,
613
614 pub sess: Session,
615 pub def_map: DefMap,
616
617 pub named_region_map: resolve_lifetime::NamedRegionMap,
618
619 pub region_maps: RegionMaps,
620
621 // For each fn declared in the local crate, type check stores the
622 // free-region relationships that were deduced from its where
623 // clauses and parameter types. These are then read-again by
624 // borrowck. (They are not used during trans, and hence are not
625 // serialized or needed for cross-crate fns.)
626 free_region_maps: RefCell<NodeMap<FreeRegionMap>>,
627
628 /// Stores the types for various nodes in the AST. Note that this table
629 /// is not guaranteed to be populated until after typeck. See
630 /// typeck::check::fn_ctxt for details.
631 node_types: RefCell<NodeMap<Ty<'tcx>>>,
632
633 /// Stores the type parameters which were substituted to obtain the type
634 /// of this node. This only applies to nodes that refer to entities
635 /// parameterized by type parameters, such as generic fns, types, or
636 /// other items.
637 pub item_substs: RefCell<NodeMap<ItemSubsts<'tcx>>>,
638
639 /// Maps from a trait item to the trait item "descriptor"
640 pub impl_or_trait_items: RefCell<DefIdMap<ImplOrTraitItem<'tcx>>>,
641
642 /// Maps from a trait def-id to a list of the def-ids of its trait items
643 pub trait_item_def_ids: RefCell<DefIdMap<Rc<Vec<ImplOrTraitItemId>>>>,
644
645 /// A cache for the trait_items() routine
646 pub trait_items_cache: RefCell<DefIdMap<Rc<Vec<ImplOrTraitItem<'tcx>>>>>,
647
648 pub impl_trait_refs: RefCell<DefIdMap<Option<TraitRef<'tcx>>>>,
649 pub trait_defs: RefCell<DefIdMap<&'tcx TraitDef<'tcx>>>,
650
651 /// Maps from the def-id of an item (trait/struct/enum/fn) to its
652 /// associated predicates.
653 pub predicates: RefCell<DefIdMap<GenericPredicates<'tcx>>>,
654
655 /// Maps from the def-id of a trait to the list of
656 /// super-predicates. This is a subset of the full list of
657 /// predicates. We store these in a separate map because we must
658 /// evaluate them even during type conversion, often before the
659 /// full predicates are available (note that supertraits have
660 /// additional acyclicity requirements).
661 pub super_predicates: RefCell<DefIdMap<GenericPredicates<'tcx>>>,
662
663 pub map: ast_map::Map<'tcx>,
664 pub freevars: RefCell<FreevarMap>,
665 pub tcache: RefCell<DefIdMap<TypeScheme<'tcx>>>,
666 pub rcache: RefCell<FnvHashMap<creader_cache_key, Ty<'tcx>>>,
667 pub tc_cache: RefCell<FnvHashMap<Ty<'tcx>, TypeContents>>,
668 pub ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
669 pub enum_var_cache: RefCell<DefIdMap<Rc<Vec<Rc<VariantInfo<'tcx>>>>>>,
670 pub ty_param_defs: RefCell<NodeMap<TypeParameterDef<'tcx>>>,
671 pub adjustments: RefCell<NodeMap<AutoAdjustment<'tcx>>>,
672 pub normalized_cache: RefCell<FnvHashMap<Ty<'tcx>, Ty<'tcx>>>,
673 pub lang_items: middle::lang_items::LanguageItems,
674 /// A mapping of fake provided method def_ids to the default implementation
675 pub provided_method_sources: RefCell<DefIdMap<ast::DefId>>,
676 pub struct_fields: RefCell<DefIdMap<Rc<Vec<field_ty>>>>,
677
678 /// Maps from def-id of a type or region parameter to its
679 /// (inferred) variance.
680 pub item_variance_map: RefCell<DefIdMap<Rc<ItemVariances>>>,
681
682 /// True if the variance has been computed yet; false otherwise.
683 pub variance_computed: Cell<bool>,
684
685 /// A mapping from the def ID of an enum or struct type to the def ID
686 /// of the method that implements its destructor. If the type is not
687 /// present in this map, it does not have a destructor. This map is
688 /// populated during the coherence phase of typechecking.
689 pub destructor_for_type: RefCell<DefIdMap<ast::DefId>>,
690
691 /// A method will be in this list if and only if it is a destructor.
692 pub destructors: RefCell<DefIdSet>,
693
694 /// Maps a DefId of a type to a list of its inherent impls.
695 /// Contains implementations of methods that are inherent to a type.
696 /// Methods in these implementations don't need to be exported.
697 pub inherent_impls: RefCell<DefIdMap<Rc<Vec<ast::DefId>>>>,
698
699 /// Maps a DefId of an impl to a list of its items.
700 /// Note that this contains all of the impls that we know about,
701 /// including ones in other crates. It's not clear that this is the best
702 /// way to do it.
703 pub impl_items: RefCell<DefIdMap<Vec<ImplOrTraitItemId>>>,
704
705 /// Set of used unsafe nodes (functions or blocks). Unsafe nodes not
706 /// present in this set can be warned about.
707 pub used_unsafe: RefCell<NodeSet>,
708
709 /// Set of nodes which mark locals as mutable which end up getting used at
710 /// some point. Local variable definitions not in this set can be warned
711 /// about.
712 pub used_mut_nodes: RefCell<NodeSet>,
713
714 /// The set of external nominal types whose implementations have been read.
715 /// This is used for lazy resolution of methods.
716 pub populated_external_types: RefCell<DefIdSet>,
717 /// The set of external primitive types whose implementations have been read.
718 /// FIXME(arielb1): why is this separate from populated_external_types?
719 pub populated_external_primitive_impls: RefCell<DefIdSet>,
720
721 /// Borrows
722 pub upvar_capture_map: RefCell<UpvarCaptureMap>,
723
724 /// These caches are used by const_eval when decoding external constants.
725 pub extern_const_statics: RefCell<DefIdMap<ast::NodeId>>,
726 pub extern_const_variants: RefCell<DefIdMap<ast::NodeId>>,
727 pub extern_const_fns: RefCell<DefIdMap<ast::NodeId>>,
728
729 pub method_map: MethodMap<'tcx>,
730
731 pub dependency_formats: RefCell<dependency_format::Dependencies>,
732
733 /// Records the type of each closure. The def ID is the ID of the
734 /// expression defining the closure.
735 pub closure_kinds: RefCell<DefIdMap<ClosureKind>>,
736
737 /// Records the type of each closure. The def ID is the ID of the
738 /// expression defining the closure.
739 pub closure_tys: RefCell<DefIdMap<ClosureTy<'tcx>>>,
740
741 pub node_lint_levels: RefCell<FnvHashMap<(ast::NodeId, lint::LintId),
742 lint::LevelSource>>,
743
744 /// The types that must be asserted to be the same size for `transmute`
745 /// to be valid. We gather up these restrictions in the intrinsicck pass
746 /// and check them in trans.
747 pub transmute_restrictions: RefCell<Vec<TransmuteRestriction<'tcx>>>,
748
749 /// Maps any item's def-id to its stability index.
750 pub stability: RefCell<stability::Index<'tcx>>,
751
752 /// Caches the results of trait selection. This cache is used
753 /// for things that do not have to do with the parameters in scope.
754 pub selection_cache: traits::SelectionCache<'tcx>,
755
756 /// A set of predicates that have been fulfilled *somewhere*.
757 /// This is used to avoid duplicate work. Predicates are only
758 /// added to this set when they mention only "global" names
759 /// (i.e., no type or lifetime parameters).
760 pub fulfilled_predicates: RefCell<traits::FulfilledPredicates<'tcx>>,
761
762 /// Caches the representation hints for struct definitions.
763 pub repr_hint_cache: RefCell<DefIdMap<Rc<Vec<attr::ReprAttr>>>>,
764
765 /// Maps Expr NodeId's to their constant qualification.
766 pub const_qualif_map: RefCell<NodeMap<check_const::ConstQualif>>,
767
768 /// Caches CoerceUnsized kinds for impls on custom types.
769 pub custom_coerce_unsized_kinds: RefCell<DefIdMap<CustomCoerceUnsized>>,
770
771 /// Maps a cast expression to its kind. This is keyed on the
772 /// *from* expression of the cast, not the cast itself.
773 pub cast_kinds: RefCell<NodeMap<cast::CastKind>>,
774 }
775
776 impl<'tcx> ctxt<'tcx> {
777 pub fn node_types(&self) -> Ref<NodeMap<Ty<'tcx>>> { self.node_types.borrow() }
778 pub fn node_type_insert(&self, id: NodeId, ty: Ty<'tcx>) {
779 self.node_types.borrow_mut().insert(id, ty);
780 }
781
782 pub fn intern_trait_def(&self, def: TraitDef<'tcx>) -> &'tcx TraitDef<'tcx> {
783 let did = def.trait_ref.def_id;
784 let interned = self.arenas.trait_defs.alloc(def);
785 self.trait_defs.borrow_mut().insert(did, interned);
786 interned
787 }
788
789 pub fn intern_stability(&self, stab: attr::Stability) -> &'tcx attr::Stability {
790 if let Some(st) = self.stability_interner.borrow().get(&stab) {
791 return st;
792 }
793
794 let interned = self.arenas.stability.alloc(stab);
795 self.stability_interner.borrow_mut().insert(interned, interned);
796 interned
797 }
798
799 pub fn store_free_region_map(&self, id: NodeId, map: FreeRegionMap) {
800 self.free_region_maps.borrow_mut()
801 .insert(id, map);
802 }
803
804 pub fn free_region_map(&self, id: NodeId) -> FreeRegionMap {
805 self.free_region_maps.borrow()[&id].clone()
806 }
807
808 pub fn lift<T: ?Sized + Lift<'tcx>>(&self, value: &T) -> Option<T::Lifted> {
809 value.lift_to_tcx(self)
810 }
811 }
812
813 /// A trait implemented for all X<'a> types which can be safely and
814 /// efficiently converted to X<'tcx> as long as they are part of the
815 /// provided ty::ctxt<'tcx>.
816 /// This can be done, for example, for Ty<'tcx> or &'tcx Substs<'tcx>
817 /// by looking them up in their respective interners.
818 /// None is returned if the value or one of the components is not part
819 /// of the provided context.
820 /// For Ty, None can be returned if either the type interner doesn't
821 /// contain the TypeVariants key or if the address of the interned
822 /// pointer differs. The latter case is possible if a primitive type,
823 /// e.g. `()` or `u8`, was interned in a different context.
824 pub trait Lift<'tcx> {
825 type Lifted;
826 fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<Self::Lifted>;
827 }
828
829 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {
830 type Lifted = (A::Lifted, B::Lifted);
831 fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<Self::Lifted> {
832 tcx.lift(&self.0).and_then(|a| tcx.lift(&self.1).map(|b| (a, b)))
833 }
834 }
835
836 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] {
837 type Lifted = Vec<T::Lifted>;
838 fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<Self::Lifted> {
839 let mut result = Vec::with_capacity(self.len());
840 for x in self {
841 if let Some(value) = tcx.lift(x) {
842 result.push(value);
843 } else {
844 return None;
845 }
846 }
847 Some(result)
848 }
849 }
850
851 impl<'tcx> Lift<'tcx> for Region {
852 type Lifted = Self;
853 fn lift_to_tcx(&self, _: &ctxt<'tcx>) -> Option<Region> {
854 Some(*self)
855 }
856 }
857
858 impl<'a, 'tcx> Lift<'tcx> for Ty<'a> {
859 type Lifted = Ty<'tcx>;
860 fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<Ty<'tcx>> {
861 if let Some(&ty) = tcx.interner.borrow().get(&self.sty) {
862 if *self as *const _ == ty as *const _ {
863 return Some(ty);
864 }
865 }
866 None
867 }
868 }
869
870 impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> {
871 type Lifted = &'tcx Substs<'tcx>;
872 fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<&'tcx Substs<'tcx>> {
873 if let Some(&substs) = tcx.substs_interner.borrow().get(*self) {
874 if *self as *const _ == substs as *const _ {
875 return Some(substs);
876 }
877 }
878 None
879 }
880 }
881
882 impl<'a, 'tcx> Lift<'tcx> for TraitRef<'a> {
883 type Lifted = TraitRef<'tcx>;
884 fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<TraitRef<'tcx>> {
885 tcx.lift(&self.substs).map(|substs| TraitRef {
886 def_id: self.def_id,
887 substs: substs
888 })
889 }
890 }
891
892 impl<'a, 'tcx> Lift<'tcx> for TraitPredicate<'a> {
893 type Lifted = TraitPredicate<'tcx>;
894 fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<TraitPredicate<'tcx>> {
895 tcx.lift(&self.trait_ref).map(|trait_ref| TraitPredicate {
896 trait_ref: trait_ref
897 })
898 }
899 }
900
901 impl<'a, 'tcx> Lift<'tcx> for EquatePredicate<'a> {
902 type Lifted = EquatePredicate<'tcx>;
903 fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<EquatePredicate<'tcx>> {
904 tcx.lift(&(self.0, self.1)).map(|(a, b)| EquatePredicate(a, b))
905 }
906 }
907
908 impl<'tcx, A: Copy+Lift<'tcx>, B: Copy+Lift<'tcx>> Lift<'tcx> for OutlivesPredicate<A, B> {
909 type Lifted = OutlivesPredicate<A::Lifted, B::Lifted>;
910 fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<Self::Lifted> {
911 tcx.lift(&(self.0, self.1)).map(|(a, b)| OutlivesPredicate(a, b))
912 }
913 }
914
915 impl<'a, 'tcx> Lift<'tcx> for ProjectionPredicate<'a> {
916 type Lifted = ProjectionPredicate<'tcx>;
917 fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<ProjectionPredicate<'tcx>> {
918 tcx.lift(&(self.projection_ty.trait_ref, self.ty)).map(|(trait_ref, ty)| {
919 ProjectionPredicate {
920 projection_ty: ProjectionTy {
921 trait_ref: trait_ref,
922 item_name: self.projection_ty.item_name
923 },
924 ty: ty
925 }
926 })
927 }
928 }
929
930 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Binder<T> {
931 type Lifted = Binder<T::Lifted>;
932 fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<Self::Lifted> {
933 tcx.lift(&self.0).map(|x| Binder(x))
934 }
935 }
936
937 pub mod tls {
938 use ast_map;
939 use middle::ty;
940 use session::Session;
941
942 use std::fmt;
943 use syntax::ast;
944 use syntax::codemap;
945
946 /// Marker type used for the scoped TLS slot.
947 /// The type context cannot be used directly because the scoped TLS
948 /// in libstd doesn't allow types generic over lifetimes.
949 struct ThreadLocalTyCx;
950
951 scoped_thread_local!(static TLS_TCX: ThreadLocalTyCx);
952
953 fn def_id_debug(def_id: ast::DefId, f: &mut fmt::Formatter) -> fmt::Result {
954 // Unfortunately, there seems to be no way to attempt to print
955 // a path for a def-id, so I'll just make a best effort for now
956 // and otherwise fallback to just printing the crate/node pair
957 with(|tcx| {
958 if def_id.krate == ast::LOCAL_CRATE {
959 match tcx.map.find(def_id.node) {
960 Some(ast_map::NodeItem(..)) |
961 Some(ast_map::NodeForeignItem(..)) |
962 Some(ast_map::NodeImplItem(..)) |
963 Some(ast_map::NodeTraitItem(..)) |
964 Some(ast_map::NodeVariant(..)) |
965 Some(ast_map::NodeStructCtor(..)) => {
966 return write!(f, "{}", ty::item_path_str(tcx, def_id));
967 }
968 _ => {}
969 }
970 }
971 Ok(())
972 })
973 }
974
975 fn span_debug(span: codemap::Span, f: &mut fmt::Formatter) -> fmt::Result {
976 with(|tcx| {
977 write!(f, "{}", tcx.sess.codemap().span_to_string(span))
978 })
979 }
980
981 pub fn enter<'tcx, F: FnOnce(&ty::ctxt<'tcx>) -> R, R>(tcx: ty::ctxt<'tcx>, f: F)
982 -> (Session, R) {
983 let result = ast::DEF_ID_DEBUG.with(|def_id_dbg| {
984 codemap::SPAN_DEBUG.with(|span_dbg| {
985 let original_def_id_debug = def_id_dbg.get();
986 def_id_dbg.set(def_id_debug);
987 let original_span_debug = span_dbg.get();
988 span_dbg.set(span_debug);
989 let tls_ptr = &tcx as *const _ as *const ThreadLocalTyCx;
990 let result = TLS_TCX.set(unsafe { &*tls_ptr }, || f(&tcx));
991 def_id_dbg.set(original_def_id_debug);
992 span_dbg.set(original_span_debug);
993 result
994 })
995 });
996 (tcx.sess, result)
997 }
998
999 pub fn with<F: FnOnce(&ty::ctxt) -> R, R>(f: F) -> R {
1000 TLS_TCX.with(|tcx| f(unsafe { &*(tcx as *const _ as *const ty::ctxt) }))
1001 }
1002 }
1003
1004 // Flags that we track on types. These flags are propagated upwards
1005 // through the type during type construction, so that we can quickly
1006 // check whether the type has various kinds of types in it without
1007 // recursing over the type itself.
1008 bitflags! {
1009 flags TypeFlags: u32 {
1010 const HAS_PARAMS = 1 << 0,
1011 const HAS_SELF = 1 << 1,
1012 const HAS_TY_INFER = 1 << 2,
1013 const HAS_RE_INFER = 1 << 3,
1014 const HAS_RE_EARLY_BOUND = 1 << 4,
1015 const HAS_FREE_REGIONS = 1 << 5,
1016 const HAS_TY_ERR = 1 << 6,
1017 const HAS_PROJECTION = 1 << 7,
1018 const HAS_TY_CLOSURE = 1 << 8,
1019
1020 // true if there are "names" of types and regions and so forth
1021 // that are local to a particular fn
1022 const HAS_LOCAL_NAMES = 1 << 9,
1023
1024 const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits |
1025 TypeFlags::HAS_SELF.bits |
1026 TypeFlags::HAS_RE_EARLY_BOUND.bits,
1027
1028 // Flags representing the nominal content of a type,
1029 // computed by FlagsComputation. If you add a new nominal
1030 // flag, it should be added here too.
1031 const NOMINAL_FLAGS = TypeFlags::HAS_PARAMS.bits |
1032 TypeFlags::HAS_SELF.bits |
1033 TypeFlags::HAS_TY_INFER.bits |
1034 TypeFlags::HAS_RE_INFER.bits |
1035 TypeFlags::HAS_RE_EARLY_BOUND.bits |
1036 TypeFlags::HAS_FREE_REGIONS.bits |
1037 TypeFlags::HAS_TY_ERR.bits |
1038 TypeFlags::HAS_PROJECTION.bits |
1039 TypeFlags::HAS_TY_CLOSURE.bits |
1040 TypeFlags::HAS_LOCAL_NAMES.bits,
1041
1042 // Caches for type_is_sized, type_moves_by_default
1043 const SIZEDNESS_CACHED = 1 << 16,
1044 const IS_SIZED = 1 << 17,
1045 const MOVENESS_CACHED = 1 << 18,
1046 const MOVES_BY_DEFAULT = 1 << 19,
1047 }
1048 }
1049
1050 macro_rules! sty_debug_print {
1051 ($ctxt: expr, $($variant: ident),*) => {{
1052 // curious inner module to allow variant names to be used as
1053 // variable names.
1054 #[allow(non_snake_case)]
1055 mod inner {
1056 use middle::ty;
1057 #[derive(Copy, Clone)]
1058 struct DebugStat {
1059 total: usize,
1060 region_infer: usize,
1061 ty_infer: usize,
1062 both_infer: usize,
1063 }
1064
1065 pub fn go(tcx: &ty::ctxt) {
1066 let mut total = DebugStat {
1067 total: 0,
1068 region_infer: 0, ty_infer: 0, both_infer: 0,
1069 };
1070 $(let mut $variant = total;)*
1071
1072
1073 for (_, t) in tcx.interner.borrow().iter() {
1074 let variant = match t.sty {
1075 ty::TyBool | ty::TyChar | ty::TyInt(..) | ty::TyUint(..) |
1076 ty::TyFloat(..) | ty::TyStr => continue,
1077 ty::TyError => /* unimportant */ continue,
1078 $(ty::$variant(..) => &mut $variant,)*
1079 };
1080 let region = t.flags.get().intersects(ty::TypeFlags::HAS_RE_INFER);
1081 let ty = t.flags.get().intersects(ty::TypeFlags::HAS_TY_INFER);
1082
1083 variant.total += 1;
1084 total.total += 1;
1085 if region { total.region_infer += 1; variant.region_infer += 1 }
1086 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1087 if region && ty { total.both_infer += 1; variant.both_infer += 1 }
1088 }
1089 println!("Ty interner total ty region both");
1090 $(println!(" {:18}: {uses:6} {usespc:4.1}%, \
1091 {ty:4.1}% {region:5.1}% {both:4.1}%",
1092 stringify!($variant),
1093 uses = $variant.total,
1094 usespc = $variant.total as f64 * 100.0 / total.total as f64,
1095 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
1096 region = $variant.region_infer as f64 * 100.0 / total.total as f64,
1097 both = $variant.both_infer as f64 * 100.0 / total.total as f64);
1098 )*
1099 println!(" total {uses:6} \
1100 {ty:4.1}% {region:5.1}% {both:4.1}%",
1101 uses = total.total,
1102 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
1103 region = total.region_infer as f64 * 100.0 / total.total as f64,
1104 both = total.both_infer as f64 * 100.0 / total.total as f64)
1105 }
1106 }
1107
1108 inner::go($ctxt)
1109 }}
1110 }
1111
1112 impl<'tcx> ctxt<'tcx> {
1113 pub fn print_debug_stats(&self) {
1114 sty_debug_print!(
1115 self,
1116 TyEnum, TyBox, TyArray, TySlice, TyRawPtr, TyRef, TyBareFn, TyTrait,
1117 TyStruct, TyClosure, TyTuple, TyParam, TyInfer, TyProjection);
1118
1119 println!("Substs interner: #{}", self.substs_interner.borrow().len());
1120 println!("BareFnTy interner: #{}", self.bare_fn_interner.borrow().len());
1121 println!("Region interner: #{}", self.region_interner.borrow().len());
1122 println!("Stability interner: #{}", self.stability_interner.borrow().len());
1123 }
1124 }
1125
1126 pub struct TyS<'tcx> {
1127 pub sty: TypeVariants<'tcx>,
1128 pub flags: Cell<TypeFlags>,
1129
1130 // the maximal depth of any bound regions appearing in this type.
1131 region_depth: u32,
1132 }
1133
1134 impl fmt::Debug for TypeFlags {
1135 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1136 write!(f, "{}", self.bits)
1137 }
1138 }
1139
1140 impl<'tcx> PartialEq for TyS<'tcx> {
1141 #[inline]
1142 fn eq(&self, other: &TyS<'tcx>) -> bool {
1143 // (self as *const _) == (other as *const _)
1144 (self as *const TyS<'tcx>) == (other as *const TyS<'tcx>)
1145 }
1146 }
1147 impl<'tcx> Eq for TyS<'tcx> {}
1148
1149 impl<'tcx> Hash for TyS<'tcx> {
1150 fn hash<H: Hasher>(&self, s: &mut H) {
1151 (self as *const TyS).hash(s)
1152 }
1153 }
1154
1155 pub type Ty<'tcx> = &'tcx TyS<'tcx>;
1156
1157 /// An entry in the type interner.
1158 pub struct InternedTy<'tcx> {
1159 ty: Ty<'tcx>
1160 }
1161
1162 // NB: An InternedTy compares and hashes as a sty.
1163 impl<'tcx> PartialEq for InternedTy<'tcx> {
1164 fn eq(&self, other: &InternedTy<'tcx>) -> bool {
1165 self.ty.sty == other.ty.sty
1166 }
1167 }
1168
1169 impl<'tcx> Eq for InternedTy<'tcx> {}
1170
1171 impl<'tcx> Hash for InternedTy<'tcx> {
1172 fn hash<H: Hasher>(&self, s: &mut H) {
1173 self.ty.sty.hash(s)
1174 }
1175 }
1176
1177 impl<'tcx> Borrow<TypeVariants<'tcx>> for InternedTy<'tcx> {
1178 fn borrow<'a>(&'a self) -> &'a TypeVariants<'tcx> {
1179 &self.ty.sty
1180 }
1181 }
1182
1183 pub fn type_has_params(ty: Ty) -> bool {
1184 ty.flags.get().intersects(TypeFlags::HAS_PARAMS)
1185 }
1186 pub fn type_has_self(ty: Ty) -> bool {
1187 ty.flags.get().intersects(TypeFlags::HAS_SELF)
1188 }
1189 pub fn type_has_ty_infer(ty: Ty) -> bool {
1190 ty.flags.get().intersects(TypeFlags::HAS_TY_INFER)
1191 }
1192 pub fn type_needs_infer(ty: Ty) -> bool {
1193 ty.flags.get().intersects(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER)
1194 }
1195 pub fn type_is_global(ty: Ty) -> bool {
1196 !ty.flags.get().intersects(TypeFlags::HAS_LOCAL_NAMES)
1197 }
1198 pub fn type_has_projection(ty: Ty) -> bool {
1199 ty.flags.get().intersects(TypeFlags::HAS_PROJECTION)
1200 }
1201 pub fn type_has_ty_closure(ty: Ty) -> bool {
1202 ty.flags.get().intersects(TypeFlags::HAS_TY_CLOSURE)
1203 }
1204
1205 pub fn type_has_erasable_regions(ty: Ty) -> bool {
1206 ty.flags.get().intersects(TypeFlags::HAS_RE_EARLY_BOUND |
1207 TypeFlags::HAS_RE_INFER |
1208 TypeFlags::HAS_FREE_REGIONS)
1209 }
1210
1211 /// An "escaping region" is a bound region whose binder is not part of `t`.
1212 ///
1213 /// So, for example, consider a type like the following, which has two binders:
1214 ///
1215 /// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize))
1216 /// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope
1217 /// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope
1218 ///
1219 /// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the
1220 /// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
1221 /// fn type*, that type has an escaping region: `'a`.
1222 ///
1223 /// Note that what I'm calling an "escaping region" is often just called a "free region". However,
1224 /// we already use the term "free region". It refers to the regions that we use to represent bound
1225 /// regions on a fn definition while we are typechecking its body.
1226 ///
1227 /// To clarify, conceptually there is no particular difference between an "escaping" region and a
1228 /// "free" region. However, there is a big difference in practice. Basically, when "entering" a
1229 /// binding level, one is generally required to do some sort of processing to a bound region, such
1230 /// as replacing it with a fresh/skolemized region, or making an entry in the environment to
1231 /// represent the scope to which it is attached, etc. An escaping region represents a bound region
1232 /// for which this processing has not yet been done.
1233 pub fn type_has_escaping_regions(ty: Ty) -> bool {
1234 type_escapes_depth(ty, 0)
1235 }
1236
1237 pub fn type_escapes_depth(ty: Ty, depth: u32) -> bool {
1238 ty.region_depth > depth
1239 }
1240
1241 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
1242 pub struct BareFnTy<'tcx> {
1243 pub unsafety: ast::Unsafety,
1244 pub abi: abi::Abi,
1245 pub sig: PolyFnSig<'tcx>,
1246 }
1247
1248 #[derive(Clone, PartialEq, Eq, Hash)]
1249 pub struct ClosureTy<'tcx> {
1250 pub unsafety: ast::Unsafety,
1251 pub abi: abi::Abi,
1252 pub sig: PolyFnSig<'tcx>,
1253 }
1254
1255 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1256 pub enum FnOutput<'tcx> {
1257 FnConverging(Ty<'tcx>),
1258 FnDiverging
1259 }
1260
1261 impl<'tcx> FnOutput<'tcx> {
1262 pub fn diverges(&self) -> bool {
1263 *self == FnDiverging
1264 }
1265
1266 pub fn unwrap(self) -> Ty<'tcx> {
1267 match self {
1268 ty::FnConverging(t) => t,
1269 ty::FnDiverging => unreachable!()
1270 }
1271 }
1272
1273 pub fn unwrap_or(self, def: Ty<'tcx>) -> Ty<'tcx> {
1274 match self {
1275 ty::FnConverging(t) => t,
1276 ty::FnDiverging => def
1277 }
1278 }
1279 }
1280
1281 pub type PolyFnOutput<'tcx> = Binder<FnOutput<'tcx>>;
1282
1283 impl<'tcx> PolyFnOutput<'tcx> {
1284 pub fn diverges(&self) -> bool {
1285 self.0.diverges()
1286 }
1287 }
1288
1289 /// Signature of a function type, which I have arbitrarily
1290 /// decided to use to refer to the input/output types.
1291 ///
1292 /// - `inputs` is the list of arguments and their modes.
1293 /// - `output` is the return type.
1294 /// - `variadic` indicates whether this is a variadic function. (only true for foreign fns)
1295 #[derive(Clone, PartialEq, Eq, Hash)]
1296 pub struct FnSig<'tcx> {
1297 pub inputs: Vec<Ty<'tcx>>,
1298 pub output: FnOutput<'tcx>,
1299 pub variadic: bool
1300 }
1301
1302 pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;
1303
1304 impl<'tcx> PolyFnSig<'tcx> {
1305 pub fn inputs(&self) -> ty::Binder<Vec<Ty<'tcx>>> {
1306 self.map_bound_ref(|fn_sig| fn_sig.inputs.clone())
1307 }
1308 pub fn input(&self, index: usize) -> ty::Binder<Ty<'tcx>> {
1309 self.map_bound_ref(|fn_sig| fn_sig.inputs[index])
1310 }
1311 pub fn output(&self) -> ty::Binder<FnOutput<'tcx>> {
1312 self.map_bound_ref(|fn_sig| fn_sig.output.clone())
1313 }
1314 pub fn variadic(&self) -> bool {
1315 self.skip_binder().variadic
1316 }
1317 }
1318
1319 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
1320 pub struct ParamTy {
1321 pub space: subst::ParamSpace,
1322 pub idx: u32,
1323 pub name: ast::Name,
1324 }
1325
1326 /// A [De Bruijn index][dbi] is a standard means of representing
1327 /// regions (and perhaps later types) in a higher-ranked setting. In
1328 /// particular, imagine a type like this:
1329 ///
1330 /// for<'a> fn(for<'b> fn(&'b isize, &'a isize), &'a char)
1331 /// ^ ^ | | |
1332 /// | | | | |
1333 /// | +------------+ 1 | |
1334 /// | | |
1335 /// +--------------------------------+ 2 |
1336 /// | |
1337 /// +------------------------------------------+ 1
1338 ///
1339 /// In this type, there are two binders (the outer fn and the inner
1340 /// fn). We need to be able to determine, for any given region, which
1341 /// fn type it is bound by, the inner or the outer one. There are
1342 /// various ways you can do this, but a De Bruijn index is one of the
1343 /// more convenient and has some nice properties. The basic idea is to
1344 /// count the number of binders, inside out. Some examples should help
1345 /// clarify what I mean.
1346 ///
1347 /// Let's start with the reference type `&'b isize` that is the first
1348 /// argument to the inner function. This region `'b` is assigned a De
1349 /// Bruijn index of 1, meaning "the innermost binder" (in this case, a
1350 /// fn). The region `'a` that appears in the second argument type (`&'a
1351 /// isize`) would then be assigned a De Bruijn index of 2, meaning "the
1352 /// second-innermost binder". (These indices are written on the arrays
1353 /// in the diagram).
1354 ///
1355 /// What is interesting is that De Bruijn index attached to a particular
1356 /// variable will vary depending on where it appears. For example,
1357 /// the final type `&'a char` also refers to the region `'a` declared on
1358 /// the outermost fn. But this time, this reference is not nested within
1359 /// any other binders (i.e., it is not an argument to the inner fn, but
1360 /// rather the outer one). Therefore, in this case, it is assigned a
1361 /// De Bruijn index of 1, because the innermost binder in that location
1362 /// is the outer fn.
1363 ///
1364 /// [dbi]: http://en.wikipedia.org/wiki/De_Bruijn_index
1365 #[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, Copy)]
1366 pub struct DebruijnIndex {
1367 // We maintain the invariant that this is never 0. So 1 indicates
1368 // the innermost binder. To ensure this, create with `DebruijnIndex::new`.
1369 pub depth: u32,
1370 }
1371
1372 /// Representation of regions:
1373 #[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Copy)]
1374 pub enum Region {
1375 // Region bound in a type or fn declaration which will be
1376 // substituted 'early' -- that is, at the same time when type
1377 // parameters are substituted.
1378 ReEarlyBound(EarlyBoundRegion),
1379
1380 // Region bound in a function scope, which will be substituted when the
1381 // function is called.
1382 ReLateBound(DebruijnIndex, BoundRegion),
1383
1384 /// When checking a function body, the types of all arguments and so forth
1385 /// that refer to bound region parameters are modified to refer to free
1386 /// region parameters.
1387 ReFree(FreeRegion),
1388
1389 /// A concrete region naming some statically determined extent
1390 /// (e.g. an expression or sequence of statements) within the
1391 /// current function.
1392 ReScope(region::CodeExtent),
1393
1394 /// Static data that has an "infinite" lifetime. Top in the region lattice.
1395 ReStatic,
1396
1397 /// A region variable. Should not exist after typeck.
1398 ReInfer(InferRegion),
1399
1400 /// Empty lifetime is for data that is never accessed.
1401 /// Bottom in the region lattice. We treat ReEmpty somewhat
1402 /// specially; at least right now, we do not generate instances of
1403 /// it during the GLB computations, but rather
1404 /// generate an error instead. This is to improve error messages.
1405 /// The only way to get an instance of ReEmpty is to have a region
1406 /// variable with no constraints.
1407 ReEmpty,
1408 }
1409
1410 #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
1411 pub struct EarlyBoundRegion {
1412 pub param_id: ast::NodeId,
1413 pub space: subst::ParamSpace,
1414 pub index: u32,
1415 pub name: ast::Name,
1416 }
1417
1418 /// Upvars do not get their own node-id. Instead, we use the pair of
1419 /// the original var id (that is, the root variable that is referenced
1420 /// by the upvar) and the id of the closure expression.
1421 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
1422 pub struct UpvarId {
1423 pub var_id: ast::NodeId,
1424 pub closure_expr_id: ast::NodeId,
1425 }
1426
1427 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)]
1428 pub enum BorrowKind {
1429 /// Data must be immutable and is aliasable.
1430 ImmBorrow,
1431
1432 /// Data must be immutable but not aliasable. This kind of borrow
1433 /// cannot currently be expressed by the user and is used only in
1434 /// implicit closure bindings. It is needed when you the closure
1435 /// is borrowing or mutating a mutable referent, e.g.:
1436 ///
1437 /// let x: &mut isize = ...;
1438 /// let y = || *x += 5;
1439 ///
1440 /// If we were to try to translate this closure into a more explicit
1441 /// form, we'd encounter an error with the code as written:
1442 ///
1443 /// struct Env { x: & &mut isize }
1444 /// let x: &mut isize = ...;
1445 /// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn
1446 /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
1447 ///
1448 /// This is then illegal because you cannot mutate a `&mut` found
1449 /// in an aliasable location. To solve, you'd have to translate with
1450 /// an `&mut` borrow:
1451 ///
1452 /// struct Env { x: & &mut isize }
1453 /// let x: &mut isize = ...;
1454 /// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
1455 /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
1456 ///
1457 /// Now the assignment to `**env.x` is legal, but creating a
1458 /// mutable pointer to `x` is not because `x` is not mutable. We
1459 /// could fix this by declaring `x` as `let mut x`. This is ok in
1460 /// user code, if awkward, but extra weird for closures, since the
1461 /// borrow is hidden.
1462 ///
1463 /// So we introduce a "unique imm" borrow -- the referent is
1464 /// immutable, but not aliasable. This solves the problem. For
1465 /// simplicity, we don't give users the way to express this
1466 /// borrow, it's just used when translating closures.
1467 UniqueImmBorrow,
1468
1469 /// Data is mutable and not aliasable.
1470 MutBorrow
1471 }
1472
1473 /// Information describing the capture of an upvar. This is computed
1474 /// during `typeck`, specifically by `regionck`.
1475 #[derive(PartialEq, Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
1476 pub enum UpvarCapture {
1477 /// Upvar is captured by value. This is always true when the
1478 /// closure is labeled `move`, but can also be true in other cases
1479 /// depending on inference.
1480 ByValue,
1481
1482 /// Upvar is captured by reference.
1483 ByRef(UpvarBorrow),
1484 }
1485
1486 #[derive(PartialEq, Clone, RustcEncodable, RustcDecodable, Copy)]
1487 pub struct UpvarBorrow {
1488 /// The kind of borrow: by-ref upvars have access to shared
1489 /// immutable borrows, which are not part of the normal language
1490 /// syntax.
1491 pub kind: BorrowKind,
1492
1493 /// Region of the resulting reference.
1494 pub region: ty::Region,
1495 }
1496
1497 pub type UpvarCaptureMap = FnvHashMap<UpvarId, UpvarCapture>;
1498
1499 impl Region {
1500 pub fn is_global(&self) -> bool {
1501 // does this represent a region that can be named in a global
1502 // way? used in fulfillment caching.
1503 match *self {
1504 ty::ReStatic | ty::ReEmpty => true,
1505 _ => false,
1506 }
1507 }
1508
1509 pub fn is_bound(&self) -> bool {
1510 match *self {
1511 ty::ReEarlyBound(..) => true,
1512 ty::ReLateBound(..) => true,
1513 _ => false
1514 }
1515 }
1516
1517 pub fn escapes_depth(&self, depth: u32) -> bool {
1518 match *self {
1519 ty::ReLateBound(debruijn, _) => debruijn.depth > depth,
1520 _ => false,
1521 }
1522 }
1523 }
1524
1525 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash,
1526 RustcEncodable, RustcDecodable, Copy)]
1527 /// A "free" region `fr` can be interpreted as "some region
1528 /// at least as big as the scope `fr.scope`".
1529 pub struct FreeRegion {
1530 pub scope: region::DestructionScopeData,
1531 pub bound_region: BoundRegion
1532 }
1533
1534 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash,
1535 RustcEncodable, RustcDecodable, Copy, Debug)]
1536 pub enum BoundRegion {
1537 /// An anonymous region parameter for a given fn (&T)
1538 BrAnon(u32),
1539
1540 /// Named region parameters for functions (a in &'a T)
1541 ///
1542 /// The def-id is needed to distinguish free regions in
1543 /// the event of shadowing.
1544 BrNamed(ast::DefId, ast::Name),
1545
1546 /// Fresh bound identifiers created during GLB computations.
1547 BrFresh(u32),
1548
1549 // Anonymous region for the implicit env pointer parameter
1550 // to a closure
1551 BrEnv
1552 }
1553
1554 // NB: If you change this, you'll probably want to change the corresponding
1555 // AST structure in libsyntax/ast.rs as well.
1556 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
1557 pub enum TypeVariants<'tcx> {
1558 /// The primitive boolean type. Written as `bool`.
1559 TyBool,
1560
1561 /// The primitive character type; holds a Unicode scalar value
1562 /// (a non-surrogate code point). Written as `char`.
1563 TyChar,
1564
1565 /// A primitive signed integer type. For example, `i32`.
1566 TyInt(ast::IntTy),
1567
1568 /// A primitive unsigned integer type. For example, `u32`.
1569 TyUint(ast::UintTy),
1570
1571 /// A primitive floating-point type. For example, `f64`.
1572 TyFloat(ast::FloatTy),
1573
1574 /// An enumerated type, defined with `enum`.
1575 ///
1576 /// Substs here, possibly against intuition, *may* contain `TyParam`s.
1577 /// That is, even after substitution it is possible that there are type
1578 /// variables. This happens when the `TyEnum` corresponds to an enum
1579 /// definition and not a concrete use of it. To get the correct `TyEnum`
1580 /// from the tcx, use the `NodeId` from the `ast::Ty` and look it up in
1581 /// the `ast_ty_to_ty_cache`. This is probably true for `TyStruct` as
1582 /// well.
1583 TyEnum(DefId, &'tcx Substs<'tcx>),
1584
1585 /// A structure type, defined with `struct`.
1586 ///
1587 /// See warning about substitutions for enumerated types.
1588 TyStruct(DefId, &'tcx Substs<'tcx>),
1589
1590 /// `Box<T>`; this is nominally a struct in the documentation, but is
1591 /// special-cased internally. For example, it is possible to implicitly
1592 /// move the contents of a box out of that box, and methods of any type
1593 /// can have type `Box<Self>`.
1594 TyBox(Ty<'tcx>),
1595
1596 /// The pointee of a string slice. Written as `str`.
1597 TyStr,
1598
1599 /// An array with the given length. Written as `[T; n]`.
1600 TyArray(Ty<'tcx>, usize),
1601
1602 /// The pointee of an array slice. Written as `[T]`.
1603 TySlice(Ty<'tcx>),
1604
1605 /// A raw pointer. Written as `*mut T` or `*const T`
1606 TyRawPtr(mt<'tcx>),
1607
1608 /// A reference; a pointer with an associated lifetime. Written as
1609 /// `&a mut T` or `&'a T`.
1610 TyRef(&'tcx Region, mt<'tcx>),
1611
1612 /// If the def-id is Some(_), then this is the type of a specific
1613 /// fn item. Otherwise, if None(_), it a fn pointer type.
1614 ///
1615 /// FIXME: Conflating function pointers and the type of a
1616 /// function is probably a terrible idea; a function pointer is a
1617 /// value with a specific type, but a function can be polymorphic
1618 /// or dynamically dispatched.
1619 TyBareFn(Option<DefId>, &'tcx BareFnTy<'tcx>),
1620
1621 /// A trait, defined with `trait`.
1622 TyTrait(Box<TraitTy<'tcx>>),
1623
1624 /// The anonymous type of a closure. Used to represent the type of
1625 /// `|a| a`.
1626 TyClosure(DefId, &'tcx Substs<'tcx>),
1627
1628 /// A tuple type. For example, `(i32, bool)`.
1629 TyTuple(Vec<Ty<'tcx>>),
1630
1631 /// The projection of an associated type. For example,
1632 /// `<T as Trait<..>>::N`.
1633 TyProjection(ProjectionTy<'tcx>),
1634
1635 /// A type parameter; for example, `T` in `fn f<T>(x: T) {}
1636 TyParam(ParamTy),
1637
1638 /// A type variable used during type-checking.
1639 TyInfer(InferTy),
1640
1641 /// A placeholder for a type which could not be computed; this is
1642 /// propagated to avoid useless error messages.
1643 TyError,
1644 }
1645
1646 #[derive(Clone, PartialEq, Eq, Hash)]
1647 pub struct TraitTy<'tcx> {
1648 pub principal: ty::PolyTraitRef<'tcx>,
1649 pub bounds: ExistentialBounds<'tcx>,
1650 }
1651
1652 impl<'tcx> TraitTy<'tcx> {
1653 pub fn principal_def_id(&self) -> ast::DefId {
1654 self.principal.0.def_id
1655 }
1656
1657 /// Object types don't have a self-type specified. Therefore, when
1658 /// we convert the principal trait-ref into a normal trait-ref,
1659 /// you must give *some* self-type. A common choice is `mk_err()`
1660 /// or some skolemized type.
1661 pub fn principal_trait_ref_with_self_ty(&self,
1662 tcx: &ctxt<'tcx>,
1663 self_ty: Ty<'tcx>)
1664 -> ty::PolyTraitRef<'tcx>
1665 {
1666 // otherwise the escaping regions would be captured by the binder
1667 assert!(!self_ty.has_escaping_regions());
1668
1669 ty::Binder(TraitRef {
1670 def_id: self.principal.0.def_id,
1671 substs: tcx.mk_substs(self.principal.0.substs.with_self_ty(self_ty)),
1672 })
1673 }
1674
1675 pub fn projection_bounds_with_self_ty(&self,
1676 tcx: &ctxt<'tcx>,
1677 self_ty: Ty<'tcx>)
1678 -> Vec<ty::PolyProjectionPredicate<'tcx>>
1679 {
1680 // otherwise the escaping regions would be captured by the binders
1681 assert!(!self_ty.has_escaping_regions());
1682
1683 self.bounds.projection_bounds.iter()
1684 .map(|in_poly_projection_predicate| {
1685 let in_projection_ty = &in_poly_projection_predicate.0.projection_ty;
1686 let substs = tcx.mk_substs(in_projection_ty.trait_ref.substs.with_self_ty(self_ty));
1687 let trait_ref = ty::TraitRef::new(in_projection_ty.trait_ref.def_id,
1688 substs);
1689 let projection_ty = ty::ProjectionTy {
1690 trait_ref: trait_ref,
1691 item_name: in_projection_ty.item_name
1692 };
1693 ty::Binder(ty::ProjectionPredicate {
1694 projection_ty: projection_ty,
1695 ty: in_poly_projection_predicate.0.ty
1696 })
1697 })
1698 .collect()
1699 }
1700 }
1701
1702 /// A complete reference to a trait. These take numerous guises in syntax,
1703 /// but perhaps the most recognizable form is in a where clause:
1704 ///
1705 /// T : Foo<U>
1706 ///
1707 /// This would be represented by a trait-reference where the def-id is the
1708 /// def-id for the trait `Foo` and the substs defines `T` as parameter 0 in the
1709 /// `SelfSpace` and `U` as parameter 0 in the `TypeSpace`.
1710 ///
1711 /// Trait references also appear in object types like `Foo<U>`, but in
1712 /// that case the `Self` parameter is absent from the substitutions.
1713 ///
1714 /// Note that a `TraitRef` introduces a level of region binding, to
1715 /// account for higher-ranked trait bounds like `T : for<'a> Foo<&'a
1716 /// U>` or higher-ranked object types.
1717 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
1718 pub struct TraitRef<'tcx> {
1719 pub def_id: DefId,
1720 pub substs: &'tcx Substs<'tcx>,
1721 }
1722
1723 pub type PolyTraitRef<'tcx> = Binder<TraitRef<'tcx>>;
1724
1725 impl<'tcx> PolyTraitRef<'tcx> {
1726 pub fn self_ty(&self) -> Ty<'tcx> {
1727 self.0.self_ty()
1728 }
1729
1730 pub fn def_id(&self) -> ast::DefId {
1731 self.0.def_id
1732 }
1733
1734 pub fn substs(&self) -> &'tcx Substs<'tcx> {
1735 // FIXME(#20664) every use of this fn is probably a bug, it should yield Binder<>
1736 self.0.substs
1737 }
1738
1739 pub fn input_types(&self) -> &[Ty<'tcx>] {
1740 // FIXME(#20664) every use of this fn is probably a bug, it should yield Binder<>
1741 self.0.input_types()
1742 }
1743
1744 pub fn to_poly_trait_predicate(&self) -> PolyTraitPredicate<'tcx> {
1745 // Note that we preserve binding levels
1746 Binder(TraitPredicate { trait_ref: self.0.clone() })
1747 }
1748 }
1749
1750 /// Binder is a binder for higher-ranked lifetimes. It is part of the
1751 /// compiler's representation for things like `for<'a> Fn(&'a isize)`
1752 /// (which would be represented by the type `PolyTraitRef ==
1753 /// Binder<TraitRef>`). Note that when we skolemize, instantiate,
1754 /// erase, or otherwise "discharge" these bound regions, we change the
1755 /// type from `Binder<T>` to just `T` (see
1756 /// e.g. `liberate_late_bound_regions`).
1757 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
1758 pub struct Binder<T>(pub T);
1759
1760 impl<T> Binder<T> {
1761 /// Skips the binder and returns the "bound" value. This is a
1762 /// risky thing to do because it's easy to get confused about
1763 /// debruijn indices and the like. It is usually better to
1764 /// discharge the binder using `no_late_bound_regions` or
1765 /// `replace_late_bound_regions` or something like
1766 /// that. `skip_binder` is only valid when you are either
1767 /// extracting data that has nothing to do with bound regions, you
1768 /// are doing some sort of test that does not involve bound
1769 /// regions, or you are being very careful about your depth
1770 /// accounting.
1771 ///
1772 /// Some examples where `skip_binder` is reasonable:
1773 /// - extracting the def-id from a PolyTraitRef;
1774 /// - comparing the self type of a PolyTraitRef to see if it is equal to
1775 /// a type parameter `X`, since the type `X` does not reference any regions
1776 pub fn skip_binder(&self) -> &T {
1777 &self.0
1778 }
1779
1780 pub fn as_ref(&self) -> Binder<&T> {
1781 ty::Binder(&self.0)
1782 }
1783
1784 pub fn map_bound_ref<F,U>(&self, f: F) -> Binder<U>
1785 where F: FnOnce(&T) -> U
1786 {
1787 self.as_ref().map_bound(f)
1788 }
1789
1790 pub fn map_bound<F,U>(self, f: F) -> Binder<U>
1791 where F: FnOnce(T) -> U
1792 {
1793 ty::Binder(f(self.0))
1794 }
1795 }
1796
1797 #[derive(Clone, Copy, PartialEq)]
1798 pub enum IntVarValue {
1799 IntType(ast::IntTy),
1800 UintType(ast::UintTy),
1801 }
1802
1803 #[derive(Clone, Copy, Debug)]
1804 pub enum terr_vstore_kind {
1805 terr_vec,
1806 terr_str,
1807 terr_fn,
1808 terr_trait
1809 }
1810
1811 #[derive(Clone, Copy, Debug)]
1812 pub struct expected_found<T> {
1813 pub expected: T,
1814 pub found: T
1815 }
1816
1817 // Data structures used in type unification
1818 #[derive(Clone, Copy, Debug)]
1819 pub enum type_err<'tcx> {
1820 terr_mismatch,
1821 terr_unsafety_mismatch(expected_found<ast::Unsafety>),
1822 terr_abi_mismatch(expected_found<abi::Abi>),
1823 terr_mutability,
1824 terr_box_mutability,
1825 terr_ptr_mutability,
1826 terr_ref_mutability,
1827 terr_vec_mutability,
1828 terr_tuple_size(expected_found<usize>),
1829 terr_fixed_array_size(expected_found<usize>),
1830 terr_ty_param_size(expected_found<usize>),
1831 terr_arg_count,
1832 terr_regions_does_not_outlive(Region, Region),
1833 terr_regions_not_same(Region, Region),
1834 terr_regions_no_overlap(Region, Region),
1835 terr_regions_insufficiently_polymorphic(BoundRegion, Region),
1836 terr_regions_overly_polymorphic(BoundRegion, Region),
1837 terr_sorts(expected_found<Ty<'tcx>>),
1838 terr_integer_as_char,
1839 terr_int_mismatch(expected_found<IntVarValue>),
1840 terr_float_mismatch(expected_found<ast::FloatTy>),
1841 terr_traits(expected_found<ast::DefId>),
1842 terr_builtin_bounds(expected_found<BuiltinBounds>),
1843 terr_variadic_mismatch(expected_found<bool>),
1844 terr_cyclic_ty,
1845 terr_convergence_mismatch(expected_found<bool>),
1846 terr_projection_name_mismatched(expected_found<ast::Name>),
1847 terr_projection_bounds_length(expected_found<usize>),
1848 }
1849
1850 /// Bounds suitable for an existentially quantified type parameter
1851 /// such as those that appear in object types or closure types.
1852 #[derive(PartialEq, Eq, Hash, Clone)]
1853 pub struct ExistentialBounds<'tcx> {
1854 pub region_bound: ty::Region,
1855 pub builtin_bounds: BuiltinBounds,
1856 pub projection_bounds: Vec<PolyProjectionPredicate<'tcx>>,
1857
1858 // If true, this TyTrait used a "default bound" in the surface
1859 // syntax. This makes no difference to the type system but is
1860 // handy for error reporting.
1861 pub region_bound_will_change: bool,
1862 }
1863
1864 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1865 pub struct BuiltinBounds(EnumSet<BuiltinBound>);
1866
1867 impl BuiltinBounds {
1868 pub fn empty() -> BuiltinBounds {
1869 BuiltinBounds(EnumSet::new())
1870 }
1871
1872 pub fn iter(&self) -> enum_set::Iter<BuiltinBound> {
1873 self.into_iter()
1874 }
1875
1876 pub fn to_predicates<'tcx>(&self,
1877 tcx: &ty::ctxt<'tcx>,
1878 self_ty: Ty<'tcx>) -> Vec<Predicate<'tcx>> {
1879 self.iter().filter_map(|builtin_bound|
1880 match traits::trait_ref_for_builtin_bound(tcx, builtin_bound, self_ty) {
1881 Ok(trait_ref) => Some(trait_ref.as_predicate()),
1882 Err(ErrorReported) => { None }
1883 }
1884 ).collect()
1885 }
1886 }
1887
1888 impl ops::Deref for BuiltinBounds {
1889 type Target = EnumSet<BuiltinBound>;
1890 fn deref(&self) -> &Self::Target { &self.0 }
1891 }
1892
1893 impl ops::DerefMut for BuiltinBounds {
1894 fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
1895 }
1896
1897 impl<'a> IntoIterator for &'a BuiltinBounds {
1898 type Item = BuiltinBound;
1899 type IntoIter = enum_set::Iter<BuiltinBound>;
1900 fn into_iter(self) -> Self::IntoIter {
1901 (**self).into_iter()
1902 }
1903 }
1904
1905 #[derive(Clone, RustcEncodable, PartialEq, Eq, RustcDecodable, Hash,
1906 Debug, Copy)]
1907 #[repr(usize)]
1908 pub enum BuiltinBound {
1909 Send,
1910 Sized,
1911 Copy,
1912 Sync,
1913 }
1914
1915 /// An existential bound that does not implement any traits.
1916 pub fn region_existential_bound<'tcx>(r: ty::Region) -> ExistentialBounds<'tcx> {
1917 ty::ExistentialBounds { region_bound: r,
1918 builtin_bounds: BuiltinBounds::empty(),
1919 projection_bounds: Vec::new(),
1920 region_bound_will_change: false, }
1921 }
1922
1923 impl CLike for BuiltinBound {
1924 fn to_usize(&self) -> usize {
1925 *self as usize
1926 }
1927 fn from_usize(v: usize) -> BuiltinBound {
1928 unsafe { mem::transmute(v) }
1929 }
1930 }
1931
1932 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
1933 pub struct TyVid {
1934 pub index: u32
1935 }
1936
1937 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
1938 pub struct IntVid {
1939 pub index: u32
1940 }
1941
1942 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
1943 pub struct FloatVid {
1944 pub index: u32
1945 }
1946
1947 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1948 pub struct RegionVid {
1949 pub index: u32
1950 }
1951
1952 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
1953 pub enum InferTy {
1954 TyVar(TyVid),
1955 IntVar(IntVid),
1956 FloatVar(FloatVid),
1957
1958 /// A `FreshTy` is one that is generated as a replacement for an
1959 /// unbound type variable. This is convenient for caching etc. See
1960 /// `middle::infer::freshen` for more details.
1961 FreshTy(u32),
1962 FreshIntTy(u32),
1963 FreshFloatTy(u32)
1964 }
1965
1966 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)]
1967 pub enum UnconstrainedNumeric {
1968 UnconstrainedFloat,
1969 UnconstrainedInt,
1970 Neither,
1971 }
1972
1973
1974 #[derive(Clone, RustcEncodable, RustcDecodable, Eq, Hash, Debug, Copy)]
1975 pub enum InferRegion {
1976 ReVar(RegionVid),
1977 ReSkolemized(u32, BoundRegion)
1978 }
1979
1980 impl cmp::PartialEq for InferRegion {
1981 fn eq(&self, other: &InferRegion) -> bool {
1982 match ((*self), *other) {
1983 (ReVar(rva), ReVar(rvb)) => {
1984 rva == rvb
1985 }
1986 (ReSkolemized(rva, _), ReSkolemized(rvb, _)) => {
1987 rva == rvb
1988 }
1989 _ => false
1990 }
1991 }
1992 fn ne(&self, other: &InferRegion) -> bool {
1993 !((*self) == (*other))
1994 }
1995 }
1996
1997 impl fmt::Debug for TyVid {
1998 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1999 write!(f, "_#{}t", self.index)
2000 }
2001 }
2002
2003 impl fmt::Debug for IntVid {
2004 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2005 write!(f, "_#{}i", self.index)
2006 }
2007 }
2008
2009 impl fmt::Debug for FloatVid {
2010 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2011 write!(f, "_#{}f", self.index)
2012 }
2013 }
2014
2015 impl fmt::Debug for RegionVid {
2016 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2017 write!(f, "'_#{}r", self.index)
2018 }
2019 }
2020
2021 impl<'tcx> fmt::Debug for FnSig<'tcx> {
2022 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2023 write!(f, "({:?}; variadic: {})->{:?}", self.inputs, self.variadic, self.output)
2024 }
2025 }
2026
2027 impl fmt::Debug for InferTy {
2028 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2029 match *self {
2030 TyVar(ref v) => v.fmt(f),
2031 IntVar(ref v) => v.fmt(f),
2032 FloatVar(ref v) => v.fmt(f),
2033 FreshTy(v) => write!(f, "FreshTy({:?})", v),
2034 FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
2035 FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v)
2036 }
2037 }
2038 }
2039
2040 impl fmt::Debug for IntVarValue {
2041 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2042 match *self {
2043 IntType(ref v) => v.fmt(f),
2044 UintType(ref v) => v.fmt(f),
2045 }
2046 }
2047 }
2048
2049 /// Default region to use for the bound of objects that are
2050 /// supplied as the value for this type parameter. This is derived
2051 /// from `T:'a` annotations appearing in the type definition. If
2052 /// this is `None`, then the default is inherited from the
2053 /// surrounding context. See RFC #599 for details.
2054 #[derive(Copy, Clone)]
2055 pub enum ObjectLifetimeDefault {
2056 /// Require an explicit annotation. Occurs when multiple
2057 /// `T:'a` constraints are found.
2058 Ambiguous,
2059
2060 /// Use the base default, typically 'static, but in a fn body it is a fresh variable
2061 BaseDefault,
2062
2063 /// Use the given region as the default.
2064 Specific(Region),
2065 }
2066
2067 #[derive(Clone)]
2068 pub struct TypeParameterDef<'tcx> {
2069 pub name: ast::Name,
2070 pub def_id: ast::DefId,
2071 pub space: subst::ParamSpace,
2072 pub index: u32,
2073 pub default: Option<Ty<'tcx>>,
2074 pub object_lifetime_default: ObjectLifetimeDefault,
2075 }
2076
2077 #[derive(RustcEncodable, RustcDecodable, Clone, Debug)]
2078 pub struct RegionParameterDef {
2079 pub name: ast::Name,
2080 pub def_id: ast::DefId,
2081 pub space: subst::ParamSpace,
2082 pub index: u32,
2083 pub bounds: Vec<ty::Region>,
2084 }
2085
2086 impl RegionParameterDef {
2087 pub fn to_early_bound_region(&self) -> ty::Region {
2088 ty::ReEarlyBound(ty::EarlyBoundRegion {
2089 param_id: self.def_id.node,
2090 space: self.space,
2091 index: self.index,
2092 name: self.name,
2093 })
2094 }
2095 pub fn to_bound_region(&self) -> ty::BoundRegion {
2096 ty::BoundRegion::BrNamed(self.def_id, self.name)
2097 }
2098 }
2099
2100 /// Information about the formal type/lifetime parameters associated
2101 /// with an item or method. Analogous to ast::Generics.
2102 #[derive(Clone, Debug)]
2103 pub struct Generics<'tcx> {
2104 pub types: VecPerParamSpace<TypeParameterDef<'tcx>>,
2105 pub regions: VecPerParamSpace<RegionParameterDef>,
2106 }
2107
2108 impl<'tcx> Generics<'tcx> {
2109 pub fn empty() -> Generics<'tcx> {
2110 Generics {
2111 types: VecPerParamSpace::empty(),
2112 regions: VecPerParamSpace::empty(),
2113 }
2114 }
2115
2116 pub fn is_empty(&self) -> bool {
2117 self.types.is_empty() && self.regions.is_empty()
2118 }
2119
2120 pub fn has_type_params(&self, space: subst::ParamSpace) -> bool {
2121 !self.types.is_empty_in(space)
2122 }
2123
2124 pub fn has_region_params(&self, space: subst::ParamSpace) -> bool {
2125 !self.regions.is_empty_in(space)
2126 }
2127 }
2128
2129 /// Bounds on generics.
2130 #[derive(Clone)]
2131 pub struct GenericPredicates<'tcx> {
2132 pub predicates: VecPerParamSpace<Predicate<'tcx>>,
2133 }
2134
2135 impl<'tcx> GenericPredicates<'tcx> {
2136 pub fn empty() -> GenericPredicates<'tcx> {
2137 GenericPredicates {
2138 predicates: VecPerParamSpace::empty(),
2139 }
2140 }
2141
2142 pub fn instantiate(&self, tcx: &ty::ctxt<'tcx>, substs: &Substs<'tcx>)
2143 -> InstantiatedPredicates<'tcx> {
2144 InstantiatedPredicates {
2145 predicates: self.predicates.subst(tcx, substs),
2146 }
2147 }
2148
2149 pub fn instantiate_supertrait(&self,
2150 tcx: &ty::ctxt<'tcx>,
2151 poly_trait_ref: &ty::PolyTraitRef<'tcx>)
2152 -> InstantiatedPredicates<'tcx>
2153 {
2154 InstantiatedPredicates {
2155 predicates: self.predicates.map(|pred| pred.subst_supertrait(tcx, poly_trait_ref))
2156 }
2157 }
2158 }
2159
2160 #[derive(Clone, PartialEq, Eq, Hash)]
2161 pub enum Predicate<'tcx> {
2162 /// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
2163 /// the `Self` type of the trait reference and `A`, `B`, and `C`
2164 /// would be the parameters in the `TypeSpace`.
2165 Trait(PolyTraitPredicate<'tcx>),
2166
2167 /// where `T1 == T2`.
2168 Equate(PolyEquatePredicate<'tcx>),
2169
2170 /// where 'a : 'b
2171 RegionOutlives(PolyRegionOutlivesPredicate),
2172
2173 /// where T : 'a
2174 TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),
2175
2176 /// where <T as TraitRef>::Name == X, approximately.
2177 /// See `ProjectionPredicate` struct for details.
2178 Projection(PolyProjectionPredicate<'tcx>),
2179 }
2180
2181 impl<'tcx> Predicate<'tcx> {
2182 /// Performs a substitution suitable for going from a
2183 /// poly-trait-ref to supertraits that must hold if that
2184 /// poly-trait-ref holds. This is slightly different from a normal
2185 /// substitution in terms of what happens with bound regions. See
2186 /// lengthy comment below for details.
2187 pub fn subst_supertrait(&self,
2188 tcx: &ty::ctxt<'tcx>,
2189 trait_ref: &ty::PolyTraitRef<'tcx>)
2190 -> ty::Predicate<'tcx>
2191 {
2192 // The interaction between HRTB and supertraits is not entirely
2193 // obvious. Let me walk you (and myself) through an example.
2194 //
2195 // Let's start with an easy case. Consider two traits:
2196 //
2197 // trait Foo<'a> : Bar<'a,'a> { }
2198 // trait Bar<'b,'c> { }
2199 //
2200 // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
2201 // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
2202 // knew that `Foo<'x>` (for any 'x) then we also know that
2203 // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
2204 // normal substitution.
2205 //
2206 // In terms of why this is sound, the idea is that whenever there
2207 // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
2208 // holds. So if there is an impl of `T:Foo<'a>` that applies to
2209 // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
2210 // `'a`.
2211 //
2212 // Another example to be careful of is this:
2213 //
2214 // trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
2215 // trait Bar1<'b,'c> { }
2216 //
2217 // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
2218 // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
2219 // reason is similar to the previous example: any impl of
2220 // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`. So
2221 // basically we would want to collapse the bound lifetimes from
2222 // the input (`trait_ref`) and the supertraits.
2223 //
2224 // To achieve this in practice is fairly straightforward. Let's
2225 // consider the more complicated scenario:
2226 //
2227 // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
2228 // has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
2229 // where both `'x` and `'b` would have a DB index of 1.
2230 // The substitution from the input trait-ref is therefore going to be
2231 // `'a => 'x` (where `'x` has a DB index of 1).
2232 // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
2233 // early-bound parameter and `'b' is a late-bound parameter with a
2234 // DB index of 1.
2235 // - If we replace `'a` with `'x` from the input, it too will have
2236 // a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
2237 // just as we wanted.
2238 //
2239 // There is only one catch. If we just apply the substitution `'a
2240 // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
2241 // adjust the DB index because we substituting into a binder (it
2242 // tries to be so smart...) resulting in `for<'x> for<'b>
2243 // Bar1<'x,'b>` (we have no syntax for this, so use your
2244 // imagination). Basically the 'x will have DB index of 2 and 'b
2245 // will have DB index of 1. Not quite what we want. So we apply
2246 // the substitution to the *contents* of the trait reference,
2247 // rather than the trait reference itself (put another way, the
2248 // substitution code expects equal binding levels in the values
2249 // from the substitution and the value being substituted into, and
2250 // this trick achieves that).
2251
2252 let substs = &trait_ref.0.substs;
2253 match *self {
2254 Predicate::Trait(ty::Binder(ref data)) =>
2255 Predicate::Trait(ty::Binder(data.subst(tcx, substs))),
2256 Predicate::Equate(ty::Binder(ref data)) =>
2257 Predicate::Equate(ty::Binder(data.subst(tcx, substs))),
2258 Predicate::RegionOutlives(ty::Binder(ref data)) =>
2259 Predicate::RegionOutlives(ty::Binder(data.subst(tcx, substs))),
2260 Predicate::TypeOutlives(ty::Binder(ref data)) =>
2261 Predicate::TypeOutlives(ty::Binder(data.subst(tcx, substs))),
2262 Predicate::Projection(ty::Binder(ref data)) =>
2263 Predicate::Projection(ty::Binder(data.subst(tcx, substs))),
2264 }
2265 }
2266
2267 // Indicates whether this predicate references only 'global'
2268 // types/lifetimes that are the same regardless of what fn we are
2269 // in. This is used for caching. Errs on the side of returning
2270 // false.
2271 pub fn is_global(&self) -> bool {
2272 match *self {
2273 ty::Predicate::Trait(ref data) => {
2274 let substs = data.skip_binder().trait_ref.substs;
2275
2276 substs.types.iter().all(|t| ty::type_is_global(t)) && {
2277 match substs.regions {
2278 subst::ErasedRegions => true,
2279 subst::NonerasedRegions(ref r) => r.iter().all(|r| r.is_global()),
2280 }
2281 }
2282 }
2283
2284 _ => {
2285 false
2286 }
2287 }
2288 }
2289 }
2290
2291 #[derive(Clone, PartialEq, Eq, Hash)]
2292 pub struct TraitPredicate<'tcx> {
2293 pub trait_ref: TraitRef<'tcx>
2294 }
2295 pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;
2296
2297 impl<'tcx> TraitPredicate<'tcx> {
2298 pub fn def_id(&self) -> ast::DefId {
2299 self.trait_ref.def_id
2300 }
2301
2302 pub fn input_types(&self) -> &[Ty<'tcx>] {
2303 self.trait_ref.substs.types.as_slice()
2304 }
2305
2306 pub fn self_ty(&self) -> Ty<'tcx> {
2307 self.trait_ref.self_ty()
2308 }
2309 }
2310
2311 impl<'tcx> PolyTraitPredicate<'tcx> {
2312 pub fn def_id(&self) -> ast::DefId {
2313 self.0.def_id()
2314 }
2315 }
2316
2317 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
2318 pub struct EquatePredicate<'tcx>(pub Ty<'tcx>, pub Ty<'tcx>); // `0 == 1`
2319 pub type PolyEquatePredicate<'tcx> = ty::Binder<EquatePredicate<'tcx>>;
2320
2321 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
2322 pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
2323 pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
2324 pub type PolyRegionOutlivesPredicate = PolyOutlivesPredicate<ty::Region, ty::Region>;
2325 pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate<Ty<'tcx>, ty::Region>;
2326
2327 /// This kind of predicate has no *direct* correspondent in the
2328 /// syntax, but it roughly corresponds to the syntactic forms:
2329 ///
2330 /// 1. `T : TraitRef<..., Item=Type>`
2331 /// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
2332 ///
2333 /// In particular, form #1 is "desugared" to the combination of a
2334 /// normal trait predicate (`T : TraitRef<...>`) and one of these
2335 /// predicates. Form #2 is a broader form in that it also permits
2336 /// equality between arbitrary types. Processing an instance of Form
2337 /// #2 eventually yields one of these `ProjectionPredicate`
2338 /// instances to normalize the LHS.
2339 #[derive(Clone, PartialEq, Eq, Hash)]
2340 pub struct ProjectionPredicate<'tcx> {
2341 pub projection_ty: ProjectionTy<'tcx>,
2342 pub ty: Ty<'tcx>,
2343 }
2344
2345 pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;
2346
2347 impl<'tcx> PolyProjectionPredicate<'tcx> {
2348 pub fn item_name(&self) -> ast::Name {
2349 self.0.projection_ty.item_name // safe to skip the binder to access a name
2350 }
2351
2352 pub fn sort_key(&self) -> (ast::DefId, ast::Name) {
2353 self.0.projection_ty.sort_key()
2354 }
2355 }
2356
2357 /// Represents the projection of an associated type. In explicit UFCS
2358 /// form this would be written `<T as Trait<..>>::N`.
2359 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
2360 pub struct ProjectionTy<'tcx> {
2361 /// The trait reference `T as Trait<..>`.
2362 pub trait_ref: ty::TraitRef<'tcx>,
2363
2364 /// The name `N` of the associated type.
2365 pub item_name: ast::Name,
2366 }
2367
2368 impl<'tcx> ProjectionTy<'tcx> {
2369 pub fn sort_key(&self) -> (ast::DefId, ast::Name) {
2370 (self.trait_ref.def_id, self.item_name)
2371 }
2372 }
2373
2374 pub trait ToPolyTraitRef<'tcx> {
2375 fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
2376 }
2377
2378 impl<'tcx> ToPolyTraitRef<'tcx> for TraitRef<'tcx> {
2379 fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
2380 assert!(!self.has_escaping_regions());
2381 ty::Binder(self.clone())
2382 }
2383 }
2384
2385 impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
2386 fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
2387 self.map_bound_ref(|trait_pred| trait_pred.trait_ref.clone())
2388 }
2389 }
2390
2391 impl<'tcx> ToPolyTraitRef<'tcx> for PolyProjectionPredicate<'tcx> {
2392 fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
2393 // Note: unlike with TraitRef::to_poly_trait_ref(),
2394 // self.0.trait_ref is permitted to have escaping regions.
2395 // This is because here `self` has a `Binder` and so does our
2396 // return value, so we are preserving the number of binding
2397 // levels.
2398 ty::Binder(self.0.projection_ty.trait_ref.clone())
2399 }
2400 }
2401
2402 pub trait AsPredicate<'tcx> {
2403 fn as_predicate(&self) -> Predicate<'tcx>;
2404 }
2405
2406 impl<'tcx> AsPredicate<'tcx> for TraitRef<'tcx> {
2407 fn as_predicate(&self) -> Predicate<'tcx> {
2408 // we're about to add a binder, so let's check that we don't
2409 // accidentally capture anything, or else that might be some
2410 // weird debruijn accounting.
2411 assert!(!self.has_escaping_regions());
2412
2413 ty::Predicate::Trait(ty::Binder(ty::TraitPredicate {
2414 trait_ref: self.clone()
2415 }))
2416 }
2417 }
2418
2419 impl<'tcx> AsPredicate<'tcx> for PolyTraitRef<'tcx> {
2420 fn as_predicate(&self) -> Predicate<'tcx> {
2421 ty::Predicate::Trait(self.to_poly_trait_predicate())
2422 }
2423 }
2424
2425 impl<'tcx> AsPredicate<'tcx> for PolyEquatePredicate<'tcx> {
2426 fn as_predicate(&self) -> Predicate<'tcx> {
2427 Predicate::Equate(self.clone())
2428 }
2429 }
2430
2431 impl<'tcx> AsPredicate<'tcx> for PolyRegionOutlivesPredicate {
2432 fn as_predicate(&self) -> Predicate<'tcx> {
2433 Predicate::RegionOutlives(self.clone())
2434 }
2435 }
2436
2437 impl<'tcx> AsPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
2438 fn as_predicate(&self) -> Predicate<'tcx> {
2439 Predicate::TypeOutlives(self.clone())
2440 }
2441 }
2442
2443 impl<'tcx> AsPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
2444 fn as_predicate(&self) -> Predicate<'tcx> {
2445 Predicate::Projection(self.clone())
2446 }
2447 }
2448
2449 impl<'tcx> Predicate<'tcx> {
2450 /// Iterates over the types in this predicate. Note that in all
2451 /// cases this is skipping over a binder, so late-bound regions
2452 /// with depth 0 are bound by the predicate.
2453 pub fn walk_tys(&self) -> IntoIter<Ty<'tcx>> {
2454 let vec: Vec<_> = match *self {
2455 ty::Predicate::Trait(ref data) => {
2456 data.0.trait_ref.substs.types.as_slice().to_vec()
2457 }
2458 ty::Predicate::Equate(ty::Binder(ref data)) => {
2459 vec![data.0, data.1]
2460 }
2461 ty::Predicate::TypeOutlives(ty::Binder(ref data)) => {
2462 vec![data.0]
2463 }
2464 ty::Predicate::RegionOutlives(..) => {
2465 vec![]
2466 }
2467 ty::Predicate::Projection(ref data) => {
2468 let trait_inputs = data.0.projection_ty.trait_ref.substs.types.as_slice();
2469 trait_inputs.iter()
2470 .cloned()
2471 .chain(Some(data.0.ty))
2472 .collect()
2473 }
2474 };
2475
2476 // The only reason to collect into a vector here is that I was
2477 // too lazy to make the full (somewhat complicated) iterator
2478 // type that would be needed here. But I wanted this fn to
2479 // return an iterator conceptually, rather than a `Vec`, so as
2480 // to be closer to `Ty::walk`.
2481 vec.into_iter()
2482 }
2483
2484 pub fn has_escaping_regions(&self) -> bool {
2485 match *self {
2486 Predicate::Trait(ref trait_ref) => trait_ref.has_escaping_regions(),
2487 Predicate::Equate(ref p) => p.has_escaping_regions(),
2488 Predicate::RegionOutlives(ref p) => p.has_escaping_regions(),
2489 Predicate::TypeOutlives(ref p) => p.has_escaping_regions(),
2490 Predicate::Projection(ref p) => p.has_escaping_regions(),
2491 }
2492 }
2493
2494 pub fn to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'tcx>> {
2495 match *self {
2496 Predicate::Trait(ref t) => {
2497 Some(t.to_poly_trait_ref())
2498 }
2499 Predicate::Projection(..) |
2500 Predicate::Equate(..) |
2501 Predicate::RegionOutlives(..) |
2502 Predicate::TypeOutlives(..) => {
2503 None
2504 }
2505 }
2506 }
2507 }
2508
2509 /// Represents the bounds declared on a particular set of type
2510 /// parameters. Should eventually be generalized into a flag list of
2511 /// where clauses. You can obtain a `InstantiatedPredicates` list from a
2512 /// `GenericPredicates` by using the `instantiate` method. Note that this method
2513 /// reflects an important semantic invariant of `InstantiatedPredicates`: while
2514 /// the `GenericPredicates` are expressed in terms of the bound type
2515 /// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance
2516 /// represented a set of bounds for some particular instantiation,
2517 /// meaning that the generic parameters have been substituted with
2518 /// their values.
2519 ///
2520 /// Example:
2521 ///
2522 /// struct Foo<T,U:Bar<T>> { ... }
2523 ///
2524 /// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
2525 /// `[[], [U:Bar<T>]]`. Now if there were some particular reference
2526 /// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
2527 /// [usize:Bar<isize>]]`.
2528 #[derive(Clone)]
2529 pub struct InstantiatedPredicates<'tcx> {
2530 pub predicates: VecPerParamSpace<Predicate<'tcx>>,
2531 }
2532
2533 impl<'tcx> InstantiatedPredicates<'tcx> {
2534 pub fn empty() -> InstantiatedPredicates<'tcx> {
2535 InstantiatedPredicates { predicates: VecPerParamSpace::empty() }
2536 }
2537
2538 pub fn has_escaping_regions(&self) -> bool {
2539 self.predicates.any(|p| p.has_escaping_regions())
2540 }
2541
2542 pub fn is_empty(&self) -> bool {
2543 self.predicates.is_empty()
2544 }
2545 }
2546
2547 impl<'tcx> TraitRef<'tcx> {
2548 pub fn new(def_id: ast::DefId, substs: &'tcx Substs<'tcx>) -> TraitRef<'tcx> {
2549 TraitRef { def_id: def_id, substs: substs }
2550 }
2551
2552 pub fn self_ty(&self) -> Ty<'tcx> {
2553 self.substs.self_ty().unwrap()
2554 }
2555
2556 pub fn input_types(&self) -> &[Ty<'tcx>] {
2557 // Select only the "input types" from a trait-reference. For
2558 // now this is all the types that appear in the
2559 // trait-reference, but it should eventually exclude
2560 // associated types.
2561 self.substs.types.as_slice()
2562 }
2563 }
2564
2565 /// When type checking, we use the `ParameterEnvironment` to track
2566 /// details about the type/lifetime parameters that are in scope.
2567 /// It primarily stores the bounds information.
2568 ///
2569 /// Note: This information might seem to be redundant with the data in
2570 /// `tcx.ty_param_defs`, but it is not. That table contains the
2571 /// parameter definitions from an "outside" perspective, but this
2572 /// struct will contain the bounds for a parameter as seen from inside
2573 /// the function body. Currently the only real distinction is that
2574 /// bound lifetime parameters are replaced with free ones, but in the
2575 /// future I hope to refine the representation of types so as to make
2576 /// more distinctions clearer.
2577 #[derive(Clone)]
2578 pub struct ParameterEnvironment<'a, 'tcx:'a> {
2579 pub tcx: &'a ctxt<'tcx>,
2580
2581 /// See `construct_free_substs` for details.
2582 pub free_substs: Substs<'tcx>,
2583
2584 /// Each type parameter has an implicit region bound that
2585 /// indicates it must outlive at least the function body (the user
2586 /// may specify stronger requirements). This field indicates the
2587 /// region of the callee.
2588 pub implicit_region_bound: ty::Region,
2589
2590 /// Obligations that the caller must satisfy. This is basically
2591 /// the set of bounds on the in-scope type parameters, translated
2592 /// into Obligations, and elaborated and normalized.
2593 pub caller_bounds: Vec<ty::Predicate<'tcx>>,
2594
2595 /// Caches the results of trait selection. This cache is used
2596 /// for things that have to do with the parameters in scope.
2597 pub selection_cache: traits::SelectionCache<'tcx>,
2598 }
2599
2600 impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
2601 pub fn with_caller_bounds(&self,
2602 caller_bounds: Vec<ty::Predicate<'tcx>>)
2603 -> ParameterEnvironment<'a,'tcx>
2604 {
2605 ParameterEnvironment {
2606 tcx: self.tcx,
2607 free_substs: self.free_substs.clone(),
2608 implicit_region_bound: self.implicit_region_bound,
2609 caller_bounds: caller_bounds,
2610 selection_cache: traits::SelectionCache::new(),
2611 }
2612 }
2613
2614 pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx> {
2615 match cx.map.find(id) {
2616 Some(ast_map::NodeImplItem(ref impl_item)) => {
2617 match impl_item.node {
2618 ast::ConstImplItem(_, _) => {
2619 let def_id = ast_util::local_def(id);
2620 let scheme = lookup_item_type(cx, def_id);
2621 let predicates = lookup_predicates(cx, def_id);
2622 construct_parameter_environment(cx,
2623 impl_item.span,
2624 &scheme.generics,
2625 &predicates,
2626 id)
2627 }
2628 ast::MethodImplItem(_, ref body) => {
2629 let method_def_id = ast_util::local_def(id);
2630 match ty::impl_or_trait_item(cx, method_def_id) {
2631 MethodTraitItem(ref method_ty) => {
2632 let method_generics = &method_ty.generics;
2633 let method_bounds = &method_ty.predicates;
2634 construct_parameter_environment(
2635 cx,
2636 impl_item.span,
2637 method_generics,
2638 method_bounds,
2639 body.id)
2640 }
2641 _ => {
2642 cx.sess
2643 .bug("ParameterEnvironment::for_item(): \
2644 got non-method item from impl method?!")
2645 }
2646 }
2647 }
2648 ast::TypeImplItem(_) => {
2649 cx.sess.bug("ParameterEnvironment::for_item(): \
2650 can't create a parameter environment \
2651 for type impl items")
2652 }
2653 ast::MacImplItem(_) => cx.sess.bug("unexpanded macro")
2654 }
2655 }
2656 Some(ast_map::NodeTraitItem(trait_item)) => {
2657 match trait_item.node {
2658 ast::ConstTraitItem(_, ref default) => {
2659 match *default {
2660 Some(_) => {
2661 let def_id = ast_util::local_def(id);
2662 let scheme = lookup_item_type(cx, def_id);
2663 let predicates = lookup_predicates(cx, def_id);
2664 construct_parameter_environment(cx,
2665 trait_item.span,
2666 &scheme.generics,
2667 &predicates,
2668 id)
2669 }
2670 None => {
2671 cx.sess.bug("ParameterEnvironment::from_item(): \
2672 can't create a parameter environment \
2673 for const trait items without defaults")
2674 }
2675 }
2676 }
2677 ast::MethodTraitItem(_, None) => {
2678 cx.sess.span_bug(trait_item.span,
2679 "ParameterEnvironment::for_item():
2680 can't create a parameter \
2681 environment for required trait \
2682 methods")
2683 }
2684 ast::MethodTraitItem(_, Some(ref body)) => {
2685 let method_def_id = ast_util::local_def(id);
2686 match ty::impl_or_trait_item(cx, method_def_id) {
2687 MethodTraitItem(ref method_ty) => {
2688 let method_generics = &method_ty.generics;
2689 let method_bounds = &method_ty.predicates;
2690 construct_parameter_environment(
2691 cx,
2692 trait_item.span,
2693 method_generics,
2694 method_bounds,
2695 body.id)
2696 }
2697 _ => {
2698 cx.sess
2699 .bug("ParameterEnvironment::for_item(): \
2700 got non-method item from provided \
2701 method?!")
2702 }
2703 }
2704 }
2705 ast::TypeTraitItem(..) => {
2706 cx.sess.bug("ParameterEnvironment::from_item(): \
2707 can't create a parameter environment \
2708 for type trait items")
2709 }
2710 }
2711 }
2712 Some(ast_map::NodeItem(item)) => {
2713 match item.node {
2714 ast::ItemFn(_, _, _, _, _, ref body) => {
2715 // We assume this is a function.
2716 let fn_def_id = ast_util::local_def(id);
2717 let fn_scheme = lookup_item_type(cx, fn_def_id);
2718 let fn_predicates = lookup_predicates(cx, fn_def_id);
2719
2720 construct_parameter_environment(cx,
2721 item.span,
2722 &fn_scheme.generics,
2723 &fn_predicates,
2724 body.id)
2725 }
2726 ast::ItemEnum(..) |
2727 ast::ItemStruct(..) |
2728 ast::ItemImpl(..) |
2729 ast::ItemConst(..) |
2730 ast::ItemStatic(..) => {
2731 let def_id = ast_util::local_def(id);
2732 let scheme = lookup_item_type(cx, def_id);
2733 let predicates = lookup_predicates(cx, def_id);
2734 construct_parameter_environment(cx,
2735 item.span,
2736 &scheme.generics,
2737 &predicates,
2738 id)
2739 }
2740 _ => {
2741 cx.sess.span_bug(item.span,
2742 "ParameterEnvironment::from_item():
2743 can't create a parameter \
2744 environment for this kind of item")
2745 }
2746 }
2747 }
2748 Some(ast_map::NodeExpr(..)) => {
2749 // This is a convenience to allow closures to work.
2750 ParameterEnvironment::for_item(cx, cx.map.get_parent(id))
2751 }
2752 _ => {
2753 cx.sess.bug(&format!("ParameterEnvironment::from_item(): \
2754 `{}` is not an item",
2755 cx.map.node_to_string(id)))
2756 }
2757 }
2758 }
2759 }
2760
2761 /// A "type scheme", in ML terminology, is a type combined with some
2762 /// set of generic types that the type is, well, generic over. In Rust
2763 /// terms, it is the "type" of a fn item or struct -- this type will
2764 /// include various generic parameters that must be substituted when
2765 /// the item/struct is referenced. That is called converting the type
2766 /// scheme to a monotype.
2767 ///
2768 /// - `generics`: the set of type parameters and their bounds
2769 /// - `ty`: the base types, which may reference the parameters defined
2770 /// in `generics`
2771 ///
2772 /// Note that TypeSchemes are also sometimes called "polytypes" (and
2773 /// in fact this struct used to carry that name, so you may find some
2774 /// stray references in a comment or something). We try to reserve the
2775 /// "poly" prefix to refer to higher-ranked things, as in
2776 /// `PolyTraitRef`.
2777 ///
2778 /// Note that each item also comes with predicates, see
2779 /// `lookup_predicates`.
2780 #[derive(Clone, Debug)]
2781 pub struct TypeScheme<'tcx> {
2782 pub generics: Generics<'tcx>,
2783 pub ty: Ty<'tcx>,
2784 }
2785
2786 bitflags! {
2787 flags TraitFlags: u32 {
2788 const NO_TRAIT_FLAGS = 0,
2789 const HAS_DEFAULT_IMPL = 1 << 0,
2790 const IS_OBJECT_SAFE = 1 << 1,
2791 const OBJECT_SAFETY_VALID = 1 << 2,
2792 const IMPLS_VALID = 1 << 3,
2793 }
2794 }
2795
2796 /// As `TypeScheme` but for a trait ref.
2797 pub struct TraitDef<'tcx> {
2798 pub unsafety: ast::Unsafety,
2799
2800 /// If `true`, then this trait had the `#[rustc_paren_sugar]`
2801 /// attribute, indicating that it should be used with `Foo()`
2802 /// sugar. This is a temporary thing -- eventually any trait wil
2803 /// be usable with the sugar (or without it).
2804 pub paren_sugar: bool,
2805
2806 /// Generic type definitions. Note that `Self` is listed in here
2807 /// as having a single bound, the trait itself (e.g., in the trait
2808 /// `Eq`, there is a single bound `Self : Eq`). This is so that
2809 /// default methods get to assume that the `Self` parameters
2810 /// implements the trait.
2811 pub generics: Generics<'tcx>,
2812
2813 pub trait_ref: TraitRef<'tcx>,
2814
2815 /// A list of the associated types defined in this trait. Useful
2816 /// for resolving `X::Foo` type markers.
2817 pub associated_type_names: Vec<ast::Name>,
2818
2819 // Impls of this trait. To allow for quicker lookup, the impls are indexed
2820 // by a simplified version of their Self type: impls with a simplifiable
2821 // Self are stored in nonblanket_impls keyed by it, while all other impls
2822 // are stored in blanket_impls.
2823
2824 /// Impls of the trait.
2825 pub nonblanket_impls: RefCell<
2826 FnvHashMap<fast_reject::SimplifiedType, Vec<DefId>>
2827 >,
2828
2829 /// Blanket impls associated with the trait.
2830 pub blanket_impls: RefCell<Vec<DefId>>,
2831
2832 /// Various flags
2833 pub flags: Cell<TraitFlags>
2834 }
2835
2836 impl<'tcx> TraitDef<'tcx> {
2837 // returns None if not yet calculated
2838 pub fn object_safety(&self) -> Option<bool> {
2839 if self.flags.get().intersects(TraitFlags::OBJECT_SAFETY_VALID) {
2840 Some(self.flags.get().intersects(TraitFlags::IS_OBJECT_SAFE))
2841 } else {
2842 None
2843 }
2844 }
2845
2846 pub fn set_object_safety(&self, is_safe: bool) {
2847 assert!(self.object_safety().map(|cs| cs == is_safe).unwrap_or(true));
2848 self.flags.set(
2849 self.flags.get() | if is_safe {
2850 TraitFlags::OBJECT_SAFETY_VALID | TraitFlags::IS_OBJECT_SAFE
2851 } else {
2852 TraitFlags::OBJECT_SAFETY_VALID
2853 }
2854 );
2855 }
2856
2857 /// Records a trait-to-implementation mapping.
2858 pub fn record_impl(&self,
2859 tcx: &ctxt<'tcx>,
2860 impl_def_id: DefId,
2861 impl_trait_ref: TraitRef<'tcx>) {
2862 debug!("TraitDef::record_impl for {:?}, from {:?}",
2863 self, impl_trait_ref);
2864
2865 // We don't want to borrow_mut after we already populated all impls,
2866 // so check if an impl is present with an immutable borrow first.
2867 if let Some(sty) = fast_reject::simplify_type(tcx,
2868 impl_trait_ref.self_ty(), false) {
2869 if let Some(is) = self.nonblanket_impls.borrow().get(&sty) {
2870 if is.contains(&impl_def_id) {
2871 return // duplicate - skip
2872 }
2873 }
2874
2875 self.nonblanket_impls.borrow_mut().entry(sty).or_insert(vec![]).push(impl_def_id)
2876 } else {
2877 if self.blanket_impls.borrow().contains(&impl_def_id) {
2878 return // duplicate - skip
2879 }
2880 self.blanket_impls.borrow_mut().push(impl_def_id)
2881 }
2882 }
2883
2884
2885 pub fn for_each_impl<F: FnMut(DefId)>(&self, tcx: &ctxt<'tcx>, mut f: F) {
2886 ty::populate_implementations_for_trait_if_necessary(tcx, self.trait_ref.def_id);
2887
2888 for &impl_def_id in self.blanket_impls.borrow().iter() {
2889 f(impl_def_id);
2890 }
2891
2892 for v in self.nonblanket_impls.borrow().values() {
2893 for &impl_def_id in v {
2894 f(impl_def_id);
2895 }
2896 }
2897 }
2898
2899 pub fn for_each_relevant_impl<F: FnMut(DefId)>(&self,
2900 tcx: &ctxt<'tcx>,
2901 self_ty: Ty<'tcx>,
2902 mut f: F)
2903 {
2904 ty::populate_implementations_for_trait_if_necessary(tcx, self.trait_ref.def_id);
2905
2906 for &impl_def_id in self.blanket_impls.borrow().iter() {
2907 f(impl_def_id);
2908 }
2909
2910 if let Some(simp) = fast_reject::simplify_type(tcx, self_ty, false) {
2911 if let Some(impls) = self.nonblanket_impls.borrow().get(&simp) {
2912 for &impl_def_id in impls {
2913 f(impl_def_id);
2914 }
2915 return; // we don't need to process the other non-blanket impls
2916 }
2917 }
2918
2919 for v in self.nonblanket_impls.borrow().values() {
2920 for &impl_def_id in v {
2921 f(impl_def_id);
2922 }
2923 }
2924 }
2925
2926 }
2927
2928 /// Records the substitutions used to translate the polytype for an
2929 /// item into the monotype of an item reference.
2930 #[derive(Clone)]
2931 pub struct ItemSubsts<'tcx> {
2932 pub substs: Substs<'tcx>,
2933 }
2934
2935 #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
2936 pub enum ClosureKind {
2937 // Warning: Ordering is significant here! The ordering is chosen
2938 // because the trait Fn is a subtrait of FnMut and so in turn, and
2939 // hence we order it so that Fn < FnMut < FnOnce.
2940 FnClosureKind,
2941 FnMutClosureKind,
2942 FnOnceClosureKind,
2943 }
2944
2945 impl ClosureKind {
2946 pub fn trait_did(&self, cx: &ctxt) -> ast::DefId {
2947 let result = match *self {
2948 FnClosureKind => cx.lang_items.require(FnTraitLangItem),
2949 FnMutClosureKind => {
2950 cx.lang_items.require(FnMutTraitLangItem)
2951 }
2952 FnOnceClosureKind => {
2953 cx.lang_items.require(FnOnceTraitLangItem)
2954 }
2955 };
2956 match result {
2957 Ok(trait_did) => trait_did,
2958 Err(err) => cx.sess.fatal(&err[..]),
2959 }
2960 }
2961
2962 /// True if this a type that impls this closure kind
2963 /// must also implement `other`.
2964 pub fn extends(self, other: ty::ClosureKind) -> bool {
2965 match (self, other) {
2966 (FnClosureKind, FnClosureKind) => true,
2967 (FnClosureKind, FnMutClosureKind) => true,
2968 (FnClosureKind, FnOnceClosureKind) => true,
2969 (FnMutClosureKind, FnMutClosureKind) => true,
2970 (FnMutClosureKind, FnOnceClosureKind) => true,
2971 (FnOnceClosureKind, FnOnceClosureKind) => true,
2972 _ => false,
2973 }
2974 }
2975 }
2976
2977 pub trait ClosureTyper<'tcx> {
2978 fn tcx(&self) -> &ty::ctxt<'tcx> {
2979 self.param_env().tcx
2980 }
2981
2982 fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx>;
2983
2984 /// Is this a `Fn`, `FnMut` or `FnOnce` closure? During typeck,
2985 /// returns `None` if the kind of this closure has not yet been
2986 /// inferred.
2987 fn closure_kind(&self,
2988 def_id: ast::DefId)
2989 -> Option<ty::ClosureKind>;
2990
2991 /// Returns the argument/return types of this closure.
2992 fn closure_type(&self,
2993 def_id: ast::DefId,
2994 substs: &subst::Substs<'tcx>)
2995 -> ty::ClosureTy<'tcx>;
2996
2997 /// Returns the set of all upvars and their transformed
2998 /// types. During typeck, maybe return `None` if the upvar types
2999 /// have not yet been inferred.
3000 fn closure_upvars(&self,
3001 def_id: ast::DefId,
3002 substs: &Substs<'tcx>)
3003 -> Option<Vec<ClosureUpvar<'tcx>>>;
3004 }
3005
3006 impl<'tcx> CommonTypes<'tcx> {
3007 fn new(arena: &'tcx TypedArena<TyS<'tcx>>,
3008 interner: &mut FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>)
3009 -> CommonTypes<'tcx>
3010 {
3011 CommonTypes {
3012 bool: intern_ty(arena, interner, TyBool),
3013 char: intern_ty(arena, interner, TyChar),
3014 err: intern_ty(arena, interner, TyError),
3015 isize: intern_ty(arena, interner, TyInt(ast::TyIs)),
3016 i8: intern_ty(arena, interner, TyInt(ast::TyI8)),
3017 i16: intern_ty(arena, interner, TyInt(ast::TyI16)),
3018 i32: intern_ty(arena, interner, TyInt(ast::TyI32)),
3019 i64: intern_ty(arena, interner, TyInt(ast::TyI64)),
3020 usize: intern_ty(arena, interner, TyUint(ast::TyUs)),
3021 u8: intern_ty(arena, interner, TyUint(ast::TyU8)),
3022 u16: intern_ty(arena, interner, TyUint(ast::TyU16)),
3023 u32: intern_ty(arena, interner, TyUint(ast::TyU32)),
3024 u64: intern_ty(arena, interner, TyUint(ast::TyU64)),
3025 f32: intern_ty(arena, interner, TyFloat(ast::TyF32)),
3026 f64: intern_ty(arena, interner, TyFloat(ast::TyF64)),
3027 }
3028 }
3029 }
3030
3031 /// Create a type context and call the closure with a `&ty::ctxt` reference
3032 /// to the context. The closure enforces that the type context and any interned
3033 /// value (types, substs, etc.) can only be used while `ty::tls` has a valid
3034 /// reference to the context, to allow formatting values that need it.
3035 pub fn with_ctxt<'tcx, F, R>(s: Session,
3036 arenas: &'tcx CtxtArenas<'tcx>,
3037 def_map: DefMap,
3038 named_region_map: resolve_lifetime::NamedRegionMap,
3039 map: ast_map::Map<'tcx>,
3040 freevars: RefCell<FreevarMap>,
3041 region_maps: RegionMaps,
3042 lang_items: middle::lang_items::LanguageItems,
3043 stability: stability::Index<'tcx>,
3044 f: F) -> (Session, R)
3045 where F: FnOnce(&ctxt<'tcx>) -> R
3046 {
3047 let mut interner = FnvHashMap();
3048 let common_types = CommonTypes::new(&arenas.type_, &mut interner);
3049
3050 tls::enter(ctxt {
3051 arenas: arenas,
3052 interner: RefCell::new(interner),
3053 substs_interner: RefCell::new(FnvHashMap()),
3054 bare_fn_interner: RefCell::new(FnvHashMap()),
3055 region_interner: RefCell::new(FnvHashMap()),
3056 stability_interner: RefCell::new(FnvHashMap()),
3057 types: common_types,
3058 named_region_map: named_region_map,
3059 region_maps: region_maps,
3060 free_region_maps: RefCell::new(FnvHashMap()),
3061 item_variance_map: RefCell::new(DefIdMap()),
3062 variance_computed: Cell::new(false),
3063 sess: s,
3064 def_map: def_map,
3065 node_types: RefCell::new(FnvHashMap()),
3066 item_substs: RefCell::new(NodeMap()),
3067 impl_trait_refs: RefCell::new(DefIdMap()),
3068 trait_defs: RefCell::new(DefIdMap()),
3069 predicates: RefCell::new(DefIdMap()),
3070 super_predicates: RefCell::new(DefIdMap()),
3071 fulfilled_predicates: RefCell::new(traits::FulfilledPredicates::new()),
3072 map: map,
3073 freevars: freevars,
3074 tcache: RefCell::new(DefIdMap()),
3075 rcache: RefCell::new(FnvHashMap()),
3076 tc_cache: RefCell::new(FnvHashMap()),
3077 ast_ty_to_ty_cache: RefCell::new(NodeMap()),
3078 enum_var_cache: RefCell::new(DefIdMap()),
3079 impl_or_trait_items: RefCell::new(DefIdMap()),
3080 trait_item_def_ids: RefCell::new(DefIdMap()),
3081 trait_items_cache: RefCell::new(DefIdMap()),
3082 ty_param_defs: RefCell::new(NodeMap()),
3083 adjustments: RefCell::new(NodeMap()),
3084 normalized_cache: RefCell::new(FnvHashMap()),
3085 lang_items: lang_items,
3086 provided_method_sources: RefCell::new(DefIdMap()),
3087 struct_fields: RefCell::new(DefIdMap()),
3088 destructor_for_type: RefCell::new(DefIdMap()),
3089 destructors: RefCell::new(DefIdSet()),
3090 inherent_impls: RefCell::new(DefIdMap()),
3091 impl_items: RefCell::new(DefIdMap()),
3092 used_unsafe: RefCell::new(NodeSet()),
3093 used_mut_nodes: RefCell::new(NodeSet()),
3094 populated_external_types: RefCell::new(DefIdSet()),
3095 populated_external_primitive_impls: RefCell::new(DefIdSet()),
3096 upvar_capture_map: RefCell::new(FnvHashMap()),
3097 extern_const_statics: RefCell::new(DefIdMap()),
3098 extern_const_variants: RefCell::new(DefIdMap()),
3099 extern_const_fns: RefCell::new(DefIdMap()),
3100 method_map: RefCell::new(FnvHashMap()),
3101 dependency_formats: RefCell::new(FnvHashMap()),
3102 closure_kinds: RefCell::new(DefIdMap()),
3103 closure_tys: RefCell::new(DefIdMap()),
3104 node_lint_levels: RefCell::new(FnvHashMap()),
3105 transmute_restrictions: RefCell::new(Vec::new()),
3106 stability: RefCell::new(stability),
3107 selection_cache: traits::SelectionCache::new(),
3108 repr_hint_cache: RefCell::new(DefIdMap()),
3109 const_qualif_map: RefCell::new(NodeMap()),
3110 custom_coerce_unsized_kinds: RefCell::new(DefIdMap()),
3111 cast_kinds: RefCell::new(NodeMap()),
3112 }, f)
3113 }
3114
3115 // Type constructors
3116
3117 impl<'tcx> ctxt<'tcx> {
3118 pub fn mk_substs(&self, substs: Substs<'tcx>) -> &'tcx Substs<'tcx> {
3119 if let Some(substs) = self.substs_interner.borrow().get(&substs) {
3120 return *substs;
3121 }
3122
3123 let substs = self.arenas.substs.alloc(substs);
3124 self.substs_interner.borrow_mut().insert(substs, substs);
3125 substs
3126 }
3127
3128 /// Create an unsafe fn ty based on a safe fn ty.
3129 pub fn safe_to_unsafe_fn_ty(&self, bare_fn: &BareFnTy<'tcx>) -> Ty<'tcx> {
3130 assert_eq!(bare_fn.unsafety, ast::Unsafety::Normal);
3131 let unsafe_fn_ty_a = self.mk_bare_fn(ty::BareFnTy {
3132 unsafety: ast::Unsafety::Unsafe,
3133 abi: bare_fn.abi,
3134 sig: bare_fn.sig.clone()
3135 });
3136 ty::mk_bare_fn(self, None, unsafe_fn_ty_a)
3137 }
3138
3139 pub fn mk_bare_fn(&self, bare_fn: BareFnTy<'tcx>) -> &'tcx BareFnTy<'tcx> {
3140 if let Some(bare_fn) = self.bare_fn_interner.borrow().get(&bare_fn) {
3141 return *bare_fn;
3142 }
3143
3144 let bare_fn = self.arenas.bare_fn.alloc(bare_fn);
3145 self.bare_fn_interner.borrow_mut().insert(bare_fn, bare_fn);
3146 bare_fn
3147 }
3148
3149 pub fn mk_region(&self, region: Region) -> &'tcx Region {
3150 if let Some(region) = self.region_interner.borrow().get(&region) {
3151 return *region;
3152 }
3153
3154 let region = self.arenas.region.alloc(region);
3155 self.region_interner.borrow_mut().insert(region, region);
3156 region
3157 }
3158
3159 pub fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
3160 *self.closure_kinds.borrow().get(&def_id).unwrap()
3161 }
3162
3163 pub fn closure_type(&self,
3164 def_id: ast::DefId,
3165 substs: &subst::Substs<'tcx>)
3166 -> ty::ClosureTy<'tcx>
3167 {
3168 self.closure_tys.borrow().get(&def_id).unwrap().subst(self, substs)
3169 }
3170
3171 pub fn type_parameter_def(&self,
3172 node_id: ast::NodeId)
3173 -> TypeParameterDef<'tcx>
3174 {
3175 self.ty_param_defs.borrow().get(&node_id).unwrap().clone()
3176 }
3177
3178 pub fn pat_contains_ref_binding(&self, pat: &ast::Pat) -> Option<ast::Mutability> {
3179 pat_util::pat_contains_ref_binding(&self.def_map, pat)
3180 }
3181
3182 pub fn arm_contains_ref_binding(&self, arm: &ast::Arm) -> Option<ast::Mutability> {
3183 pat_util::arm_contains_ref_binding(&self.def_map, arm)
3184 }
3185 }
3186
3187 // Interns a type/name combination, stores the resulting box in cx.interner,
3188 // and returns the box as cast to an unsafe ptr (see comments for Ty above).
3189 pub fn mk_t<'tcx>(cx: &ctxt<'tcx>, st: TypeVariants<'tcx>) -> Ty<'tcx> {
3190 let mut interner = cx.interner.borrow_mut();
3191 intern_ty(&cx.arenas.type_, &mut *interner, st)
3192 }
3193
3194 fn intern_ty<'tcx>(type_arena: &'tcx TypedArena<TyS<'tcx>>,
3195 interner: &mut FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>,
3196 st: TypeVariants<'tcx>)
3197 -> Ty<'tcx>
3198 {
3199 match interner.get(&st) {
3200 Some(ty) => return *ty,
3201 _ => ()
3202 }
3203
3204 let flags = FlagComputation::for_sty(&st);
3205
3206 let ty = match () {
3207 () => type_arena.alloc(TyS { sty: st,
3208 flags: Cell::new(flags.flags),
3209 region_depth: flags.depth, }),
3210 };
3211
3212 debug!("Interned type: {:?} Pointer: {:?}",
3213 ty, ty as *const TyS);
3214
3215 interner.insert(InternedTy { ty: ty }, ty);
3216
3217 ty
3218 }
3219
3220 struct FlagComputation {
3221 flags: TypeFlags,
3222
3223 // maximum depth of any bound region that we have seen thus far
3224 depth: u32,
3225 }
3226
3227 impl FlagComputation {
3228 fn new() -> FlagComputation {
3229 FlagComputation { flags: TypeFlags::empty(), depth: 0 }
3230 }
3231
3232 fn for_sty(st: &TypeVariants) -> FlagComputation {
3233 let mut result = FlagComputation::new();
3234 result.add_sty(st);
3235 result
3236 }
3237
3238 fn add_flags(&mut self, flags: TypeFlags) {
3239 self.flags = self.flags | (flags & TypeFlags::NOMINAL_FLAGS);
3240 }
3241
3242 fn add_depth(&mut self, depth: u32) {
3243 if depth > self.depth {
3244 self.depth = depth;
3245 }
3246 }
3247
3248 /// Adds the flags/depth from a set of types that appear within the current type, but within a
3249 /// region binder.
3250 fn add_bound_computation(&mut self, computation: &FlagComputation) {
3251 self.add_flags(computation.flags);
3252
3253 // The types that contributed to `computation` occurred within
3254 // a region binder, so subtract one from the region depth
3255 // within when adding the depth to `self`.
3256 let depth = computation.depth;
3257 if depth > 0 {
3258 self.add_depth(depth - 1);
3259 }
3260 }
3261
3262 fn add_sty(&mut self, st: &TypeVariants) {
3263 match st {
3264 &TyBool |
3265 &TyChar |
3266 &TyInt(_) |
3267 &TyFloat(_) |
3268 &TyUint(_) |
3269 &TyStr => {
3270 }
3271
3272 // You might think that we could just return TyError for
3273 // any type containing TyError as a component, and get
3274 // rid of the TypeFlags::HAS_TY_ERR flag -- likewise for ty_bot (with
3275 // the exception of function types that return bot).
3276 // But doing so caused sporadic memory corruption, and
3277 // neither I (tjc) nor nmatsakis could figure out why,
3278 // so we're doing it this way.
3279 &TyError => {
3280 self.add_flags(TypeFlags::HAS_TY_ERR)
3281 }
3282
3283 &TyParam(ref p) => {
3284 self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
3285 if p.space == subst::SelfSpace {
3286 self.add_flags(TypeFlags::HAS_SELF);
3287 } else {
3288 self.add_flags(TypeFlags::HAS_PARAMS);
3289 }
3290 }
3291
3292 &TyClosure(_, substs) => {
3293 self.add_flags(TypeFlags::HAS_TY_CLOSURE);
3294 self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
3295 self.add_substs(substs);
3296 }
3297
3298 &TyInfer(_) => {
3299 self.add_flags(TypeFlags::HAS_LOCAL_NAMES); // it might, right?
3300 self.add_flags(TypeFlags::HAS_TY_INFER)
3301 }
3302
3303 &TyEnum(_, substs) | &TyStruct(_, substs) => {
3304 self.add_substs(substs);
3305 }
3306
3307 &TyProjection(ref data) => {
3308 self.add_flags(TypeFlags::HAS_PROJECTION);
3309 self.add_projection_ty(data);
3310 }
3311
3312 &TyTrait(box TraitTy { ref principal, ref bounds }) => {
3313 let mut computation = FlagComputation::new();
3314 computation.add_substs(principal.0.substs);
3315 for projection_bound in &bounds.projection_bounds {
3316 let mut proj_computation = FlagComputation::new();
3317 proj_computation.add_projection_predicate(&projection_bound.0);
3318 self.add_bound_computation(&proj_computation);
3319 }
3320 self.add_bound_computation(&computation);
3321
3322 self.add_bounds(bounds);
3323 }
3324
3325 &TyBox(tt) | &TyArray(tt, _) | &TySlice(tt) => {
3326 self.add_ty(tt)
3327 }
3328
3329 &TyRawPtr(ref m) => {
3330 self.add_ty(m.ty);
3331 }
3332
3333 &TyRef(r, ref m) => {
3334 self.add_region(*r);
3335 self.add_ty(m.ty);
3336 }
3337
3338 &TyTuple(ref ts) => {
3339 self.add_tys(&ts[..]);
3340 }
3341
3342 &TyBareFn(_, ref f) => {
3343 self.add_fn_sig(&f.sig);
3344 }
3345 }
3346 }
3347
3348 fn add_ty(&mut self, ty: Ty) {
3349 self.add_flags(ty.flags.get());
3350 self.add_depth(ty.region_depth);
3351 }
3352
3353 fn add_tys(&mut self, tys: &[Ty]) {
3354 for &ty in tys {
3355 self.add_ty(ty);
3356 }
3357 }
3358
3359 fn add_fn_sig(&mut self, fn_sig: &PolyFnSig) {
3360 let mut computation = FlagComputation::new();
3361
3362 computation.add_tys(&fn_sig.0.inputs);
3363
3364 if let ty::FnConverging(output) = fn_sig.0.output {
3365 computation.add_ty(output);
3366 }
3367
3368 self.add_bound_computation(&computation);
3369 }
3370
3371 fn add_region(&mut self, r: Region) {
3372 match r {
3373 ty::ReInfer(_) => { self.add_flags(TypeFlags::HAS_RE_INFER); }
3374 ty::ReLateBound(debruijn, _) => { self.add_depth(debruijn.depth); }
3375 ty::ReEarlyBound(..) => { self.add_flags(TypeFlags::HAS_RE_EARLY_BOUND); }
3376 ty::ReStatic => {}
3377 _ => { self.add_flags(TypeFlags::HAS_FREE_REGIONS); }
3378 }
3379
3380 if !r.is_global() {
3381 self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
3382 }
3383 }
3384
3385 fn add_projection_predicate(&mut self, projection_predicate: &ProjectionPredicate) {
3386 self.add_projection_ty(&projection_predicate.projection_ty);
3387 self.add_ty(projection_predicate.ty);
3388 }
3389
3390 fn add_projection_ty(&mut self, projection_ty: &ProjectionTy) {
3391 self.add_substs(projection_ty.trait_ref.substs);
3392 }
3393
3394 fn add_substs(&mut self, substs: &Substs) {
3395 self.add_tys(substs.types.as_slice());
3396 match substs.regions {
3397 subst::ErasedRegions => {}
3398 subst::NonerasedRegions(ref regions) => {
3399 for &r in regions {
3400 self.add_region(r);
3401 }
3402 }
3403 }
3404 }
3405
3406 fn add_bounds(&mut self, bounds: &ExistentialBounds) {
3407 self.add_region(bounds.region_bound);
3408 }
3409 }
3410
3411 pub fn mk_mach_int<'tcx>(tcx: &ctxt<'tcx>, tm: ast::IntTy) -> Ty<'tcx> {
3412 match tm {
3413 ast::TyIs => tcx.types.isize,
3414 ast::TyI8 => tcx.types.i8,
3415 ast::TyI16 => tcx.types.i16,
3416 ast::TyI32 => tcx.types.i32,
3417 ast::TyI64 => tcx.types.i64,
3418 }
3419 }
3420
3421 pub fn mk_mach_uint<'tcx>(tcx: &ctxt<'tcx>, tm: ast::UintTy) -> Ty<'tcx> {
3422 match tm {
3423 ast::TyUs => tcx.types.usize,
3424 ast::TyU8 => tcx.types.u8,
3425 ast::TyU16 => tcx.types.u16,
3426 ast::TyU32 => tcx.types.u32,
3427 ast::TyU64 => tcx.types.u64,
3428 }
3429 }
3430
3431 pub fn mk_mach_float<'tcx>(tcx: &ctxt<'tcx>, tm: ast::FloatTy) -> Ty<'tcx> {
3432 match tm {
3433 ast::TyF32 => tcx.types.f32,
3434 ast::TyF64 => tcx.types.f64,
3435 }
3436 }
3437
3438 pub fn mk_str<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
3439 mk_t(cx, TyStr)
3440 }
3441
3442 pub fn mk_str_slice<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, m: ast::Mutability) -> Ty<'tcx> {
3443 mk_rptr(cx, r,
3444 mt {
3445 ty: mk_t(cx, TyStr),
3446 mutbl: m
3447 })
3448 }
3449
3450 pub fn mk_enum<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
3451 // take a copy of substs so that we own the vectors inside
3452 mk_t(cx, TyEnum(did, substs))
3453 }
3454
3455 pub fn mk_uniq<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { mk_t(cx, TyBox(ty)) }
3456
3457 pub fn mk_ptr<'tcx>(cx: &ctxt<'tcx>, tm: mt<'tcx>) -> Ty<'tcx> { mk_t(cx, TyRawPtr(tm)) }
3458
3459 pub fn mk_rptr<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, tm: mt<'tcx>) -> Ty<'tcx> {
3460 mk_t(cx, TyRef(r, tm))
3461 }
3462
3463 pub fn mk_mut_rptr<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
3464 mk_rptr(cx, r, mt {ty: ty, mutbl: ast::MutMutable})
3465 }
3466 pub fn mk_imm_rptr<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
3467 mk_rptr(cx, r, mt {ty: ty, mutbl: ast::MutImmutable})
3468 }
3469
3470 pub fn mk_mut_ptr<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
3471 mk_ptr(cx, mt {ty: ty, mutbl: ast::MutMutable})
3472 }
3473
3474 pub fn mk_imm_ptr<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
3475 mk_ptr(cx, mt {ty: ty, mutbl: ast::MutImmutable})
3476 }
3477
3478 pub fn mk_nil_ptr<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
3479 mk_ptr(cx, mt {ty: mk_nil(cx), mutbl: ast::MutImmutable})
3480 }
3481
3482 pub fn mk_vec<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>, sz: Option<usize>) -> Ty<'tcx> {
3483 match sz {
3484 Some(n) => mk_t(cx, TyArray(ty, n)),
3485 None => mk_t(cx, TySlice(ty))
3486 }
3487 }
3488
3489 pub fn mk_slice<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, tm: mt<'tcx>) -> Ty<'tcx> {
3490 mk_rptr(cx, r,
3491 mt {
3492 ty: mk_vec(cx, tm.ty, None),
3493 mutbl: tm.mutbl
3494 })
3495 }
3496
3497 pub fn mk_tup<'tcx>(cx: &ctxt<'tcx>, ts: Vec<Ty<'tcx>>) -> Ty<'tcx> {
3498 mk_t(cx, TyTuple(ts))
3499 }
3500
3501 pub fn mk_nil<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
3502 mk_tup(cx, Vec::new())
3503 }
3504
3505 pub fn mk_bool<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
3506 mk_t(cx, TyBool)
3507 }
3508
3509 pub fn mk_bare_fn<'tcx>(cx: &ctxt<'tcx>,
3510 opt_def_id: Option<ast::DefId>,
3511 fty: &'tcx BareFnTy<'tcx>) -> Ty<'tcx> {
3512 mk_t(cx, TyBareFn(opt_def_id, fty))
3513 }
3514
3515 pub fn mk_ctor_fn<'tcx>(cx: &ctxt<'tcx>,
3516 def_id: ast::DefId,
3517 input_tys: &[Ty<'tcx>],
3518 output: Ty<'tcx>) -> Ty<'tcx> {
3519 let input_args = input_tys.iter().cloned().collect();
3520 mk_bare_fn(cx,
3521 Some(def_id),
3522 cx.mk_bare_fn(BareFnTy {
3523 unsafety: ast::Unsafety::Normal,
3524 abi: abi::Rust,
3525 sig: ty::Binder(FnSig {
3526 inputs: input_args,
3527 output: ty::FnConverging(output),
3528 variadic: false
3529 })
3530 }))
3531 }
3532
3533 pub fn mk_trait<'tcx>(cx: &ctxt<'tcx>,
3534 principal: ty::PolyTraitRef<'tcx>,
3535 bounds: ExistentialBounds<'tcx>)
3536 -> Ty<'tcx>
3537 {
3538 assert!(bound_list_is_sorted(&bounds.projection_bounds));
3539
3540 let inner = box TraitTy {
3541 principal: principal,
3542 bounds: bounds
3543 };
3544 mk_t(cx, TyTrait(inner))
3545 }
3546
3547 fn bound_list_is_sorted(bounds: &[ty::PolyProjectionPredicate]) -> bool {
3548 bounds.is_empty() ||
3549 bounds[1..].iter().enumerate().all(
3550 |(index, bound)| bounds[index].sort_key() <= bound.sort_key())
3551 }
3552
3553 pub fn sort_bounds_list(bounds: &mut [ty::PolyProjectionPredicate]) {
3554 bounds.sort_by(|a, b| a.sort_key().cmp(&b.sort_key()))
3555 }
3556
3557 pub fn mk_projection<'tcx>(cx: &ctxt<'tcx>,
3558 trait_ref: TraitRef<'tcx>,
3559 item_name: ast::Name)
3560 -> Ty<'tcx> {
3561 // take a copy of substs so that we own the vectors inside
3562 let inner = ProjectionTy { trait_ref: trait_ref, item_name: item_name };
3563 mk_t(cx, TyProjection(inner))
3564 }
3565
3566 pub fn mk_struct<'tcx>(cx: &ctxt<'tcx>, struct_id: ast::DefId,
3567 substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
3568 // take a copy of substs so that we own the vectors inside
3569 mk_t(cx, TyStruct(struct_id, substs))
3570 }
3571
3572 pub fn mk_closure<'tcx>(cx: &ctxt<'tcx>, closure_id: ast::DefId, substs: &'tcx Substs<'tcx>)
3573 -> Ty<'tcx> {
3574 mk_t(cx, TyClosure(closure_id, substs))
3575 }
3576
3577 pub fn mk_var<'tcx>(cx: &ctxt<'tcx>, v: TyVid) -> Ty<'tcx> {
3578 mk_infer(cx, TyVar(v))
3579 }
3580
3581 pub fn mk_int_var<'tcx>(cx: &ctxt<'tcx>, v: IntVid) -> Ty<'tcx> {
3582 mk_infer(cx, IntVar(v))
3583 }
3584
3585 pub fn mk_float_var<'tcx>(cx: &ctxt<'tcx>, v: FloatVid) -> Ty<'tcx> {
3586 mk_infer(cx, FloatVar(v))
3587 }
3588
3589 pub fn mk_infer<'tcx>(cx: &ctxt<'tcx>, it: InferTy) -> Ty<'tcx> {
3590 mk_t(cx, TyInfer(it))
3591 }
3592
3593 pub fn mk_param<'tcx>(cx: &ctxt<'tcx>,
3594 space: subst::ParamSpace,
3595 index: u32,
3596 name: ast::Name) -> Ty<'tcx> {
3597 mk_t(cx, TyParam(ParamTy { space: space, idx: index, name: name }))
3598 }
3599
3600 pub fn mk_self_type<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
3601 mk_param(cx, subst::SelfSpace, 0, special_idents::type_self.name)
3602 }
3603
3604 pub fn mk_param_from_def<'tcx>(cx: &ctxt<'tcx>, def: &TypeParameterDef) -> Ty<'tcx> {
3605 mk_param(cx, def.space, def.index, def.name)
3606 }
3607
3608 impl<'tcx> TyS<'tcx> {
3609 /// Iterator that walks `self` and any types reachable from
3610 /// `self`, in depth-first order. Note that just walks the types
3611 /// that appear in `self`, it does not descend into the fields of
3612 /// structs or variants. For example:
3613 ///
3614 /// ```notrust
3615 /// isize => { isize }
3616 /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
3617 /// [isize] => { [isize], isize }
3618 /// ```
3619 pub fn walk(&'tcx self) -> TypeWalker<'tcx> {
3620 TypeWalker::new(self)
3621 }
3622
3623 /// Iterator that walks the immediate children of `self`. Hence
3624 /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
3625 /// (but not `i32`, like `walk`).
3626 pub fn walk_shallow(&'tcx self) -> IntoIter<Ty<'tcx>> {
3627 ty_walk::walk_shallow(self)
3628 }
3629
3630 pub fn as_opt_param_ty(&self) -> Option<ty::ParamTy> {
3631 match self.sty {
3632 ty::TyParam(ref d) => Some(d.clone()),
3633 _ => None,
3634 }
3635 }
3636
3637 pub fn is_param(&self, space: ParamSpace, index: u32) -> bool {
3638 match self.sty {
3639 ty::TyParam(ref data) => data.space == space && data.idx == index,
3640 _ => false,
3641 }
3642 }
3643 }
3644
3645 pub fn walk_ty<'tcx, F>(ty_root: Ty<'tcx>, mut f: F)
3646 where F: FnMut(Ty<'tcx>),
3647 {
3648 for ty in ty_root.walk() {
3649 f(ty);
3650 }
3651 }
3652
3653 /// Walks `ty` and any types appearing within `ty`, invoking the
3654 /// callback `f` on each type. If the callback returns false, then the
3655 /// children of the current type are ignored.
3656 ///
3657 /// Note: prefer `ty.walk()` where possible.
3658 pub fn maybe_walk_ty<'tcx,F>(ty_root: Ty<'tcx>, mut f: F)
3659 where F : FnMut(Ty<'tcx>) -> bool
3660 {
3661 let mut walker = ty_root.walk();
3662 while let Some(ty) = walker.next() {
3663 if !f(ty) {
3664 walker.skip_current_subtree();
3665 }
3666 }
3667 }
3668
3669 // Folds types from the bottom up.
3670 pub fn fold_ty<'tcx, F>(cx: &ctxt<'tcx>, t0: Ty<'tcx>,
3671 fldop: F)
3672 -> Ty<'tcx> where
3673 F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
3674 {
3675 let mut f = ty_fold::BottomUpFolder {tcx: cx, fldop: fldop};
3676 f.fold_ty(t0)
3677 }
3678
3679 impl ParamTy {
3680 pub fn new(space: subst::ParamSpace,
3681 index: u32,
3682 name: ast::Name)
3683 -> ParamTy {
3684 ParamTy { space: space, idx: index, name: name }
3685 }
3686
3687 pub fn for_self() -> ParamTy {
3688 ParamTy::new(subst::SelfSpace, 0, special_idents::type_self.name)
3689 }
3690
3691 pub fn for_def(def: &TypeParameterDef) -> ParamTy {
3692 ParamTy::new(def.space, def.index, def.name)
3693 }
3694
3695 pub fn to_ty<'tcx>(self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> {
3696 ty::mk_param(tcx, self.space, self.idx, self.name)
3697 }
3698
3699 pub fn is_self(&self) -> bool {
3700 self.space == subst::SelfSpace && self.idx == 0
3701 }
3702 }
3703
3704 impl<'tcx> ItemSubsts<'tcx> {
3705 pub fn empty() -> ItemSubsts<'tcx> {
3706 ItemSubsts { substs: Substs::empty() }
3707 }
3708
3709 pub fn is_noop(&self) -> bool {
3710 self.substs.is_noop()
3711 }
3712 }
3713
3714 // Type utilities
3715
3716 pub fn type_is_nil(ty: Ty) -> bool {
3717 match ty.sty {
3718 TyTuple(ref tys) => tys.is_empty(),
3719 _ => false
3720 }
3721 }
3722
3723 pub fn type_is_error(ty: Ty) -> bool {
3724 ty.flags.get().intersects(TypeFlags::HAS_TY_ERR)
3725 }
3726
3727 pub fn type_needs_subst(ty: Ty) -> bool {
3728 ty.flags.get().intersects(TypeFlags::NEEDS_SUBST)
3729 }
3730
3731 pub fn trait_ref_contains_error(tref: &ty::TraitRef) -> bool {
3732 tref.substs.types.any(|&ty| type_is_error(ty))
3733 }
3734
3735 pub fn type_is_ty_var(ty: Ty) -> bool {
3736 match ty.sty {
3737 TyInfer(TyVar(_)) => true,
3738 _ => false
3739 }
3740 }
3741
3742 pub fn type_is_bool(ty: Ty) -> bool { ty.sty == TyBool }
3743
3744 pub fn type_is_self(ty: Ty) -> bool {
3745 match ty.sty {
3746 TyParam(ref p) => p.space == subst::SelfSpace,
3747 _ => false
3748 }
3749 }
3750
3751 fn type_is_slice(ty: Ty) -> bool {
3752 match ty.sty {
3753 TyRawPtr(mt) | TyRef(_, mt) => match mt.ty.sty {
3754 TySlice(_) | TyStr => true,
3755 _ => false,
3756 },
3757 _ => false
3758 }
3759 }
3760
3761 pub fn type_is_structural(ty: Ty) -> bool {
3762 match ty.sty {
3763 TyStruct(..) | TyTuple(_) | TyEnum(..) |
3764 TyArray(..) | TyClosure(..) => true,
3765 _ => type_is_slice(ty) | type_is_trait(ty)
3766 }
3767 }
3768
3769 pub fn type_is_simd(cx: &ctxt, ty: Ty) -> bool {
3770 match ty.sty {
3771 TyStruct(did, _) => lookup_simd(cx, did),
3772 _ => false
3773 }
3774 }
3775
3776 pub fn sequence_element_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
3777 match ty.sty {
3778 TyArray(ty, _) | TySlice(ty) => ty,
3779 TyStr => mk_mach_uint(cx, ast::TyU8),
3780 _ => cx.sess.bug(&format!("sequence_element_type called on non-sequence value: {}",
3781 ty)),
3782 }
3783 }
3784
3785 pub fn simd_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
3786 match ty.sty {
3787 TyStruct(did, substs) => {
3788 let fields = lookup_struct_fields(cx, did);
3789 lookup_field_type(cx, did, fields[0].id, substs)
3790 }
3791 _ => panic!("simd_type called on invalid type")
3792 }
3793 }
3794
3795 pub fn simd_size(cx: &ctxt, ty: Ty) -> usize {
3796 match ty.sty {
3797 TyStruct(did, _) => {
3798 let fields = lookup_struct_fields(cx, did);
3799 fields.len()
3800 }
3801 _ => panic!("simd_size called on invalid type")
3802 }
3803 }
3804
3805 pub fn type_is_region_ptr(ty: Ty) -> bool {
3806 match ty.sty {
3807 TyRef(..) => true,
3808 _ => false
3809 }
3810 }
3811
3812 pub fn type_is_unsafe_ptr(ty: Ty) -> bool {
3813 match ty.sty {
3814 TyRawPtr(_) => return true,
3815 _ => return false
3816 }
3817 }
3818
3819 pub fn type_is_unique(ty: Ty) -> bool {
3820 match ty.sty {
3821 TyBox(_) => true,
3822 _ => false
3823 }
3824 }
3825
3826 /*
3827 A scalar type is one that denotes an atomic datum, with no sub-components.
3828 (A TyRawPtr is scalar because it represents a non-managed pointer, so its
3829 contents are abstract to rustc.)
3830 */
3831 pub fn type_is_scalar(ty: Ty) -> bool {
3832 match ty.sty {
3833 TyBool | TyChar | TyInt(_) | TyFloat(_) | TyUint(_) |
3834 TyInfer(IntVar(_)) | TyInfer(FloatVar(_)) |
3835 TyBareFn(..) | TyRawPtr(_) => true,
3836 _ => false
3837 }
3838 }
3839
3840 /// Returns true if this type is a floating point type and false otherwise.
3841 pub fn type_is_floating_point(ty: Ty) -> bool {
3842 match ty.sty {
3843 TyFloat(_) |
3844 TyInfer(FloatVar(_)) =>
3845 true,
3846
3847 _ =>
3848 false,
3849 }
3850 }
3851
3852 /// Type contents is how the type checker reasons about kinds.
3853 /// They track what kinds of things are found within a type. You can
3854 /// think of them as kind of an "anti-kind". They track the kinds of values
3855 /// and thinks that are contained in types. Having a larger contents for
3856 /// a type tends to rule that type *out* from various kinds. For example,
3857 /// a type that contains a reference is not sendable.
3858 ///
3859 /// The reason we compute type contents and not kinds is that it is
3860 /// easier for me (nmatsakis) to think about what is contained within
3861 /// a type than to think about what is *not* contained within a type.
3862 #[derive(Clone, Copy)]
3863 pub struct TypeContents {
3864 pub bits: u64
3865 }
3866
3867 macro_rules! def_type_content_sets {
3868 (mod $mname:ident { $($name:ident = $bits:expr),+ }) => {
3869 #[allow(non_snake_case)]
3870 mod $mname {
3871 use middle::ty::TypeContents;
3872 $(
3873 #[allow(non_upper_case_globals)]
3874 pub const $name: TypeContents = TypeContents { bits: $bits };
3875 )+
3876 }
3877 }
3878 }
3879
3880 def_type_content_sets! {
3881 mod TC {
3882 None = 0b0000_0000__0000_0000__0000,
3883
3884 // Things that are interior to the value (first nibble):
3885 InteriorUnsized = 0b0000_0000__0000_0000__0001,
3886 InteriorUnsafe = 0b0000_0000__0000_0000__0010,
3887 InteriorParam = 0b0000_0000__0000_0000__0100,
3888 // InteriorAll = 0b00000000__00000000__1111,
3889
3890 // Things that are owned by the value (second and third nibbles):
3891 OwnsOwned = 0b0000_0000__0000_0001__0000,
3892 OwnsDtor = 0b0000_0000__0000_0010__0000,
3893 OwnsAll = 0b0000_0000__1111_1111__0000,
3894
3895 // Things that are reachable by the value in any way (fourth nibble):
3896 ReachesBorrowed = 0b0000_0010__0000_0000__0000,
3897 ReachesMutable = 0b0000_1000__0000_0000__0000,
3898 ReachesFfiUnsafe = 0b0010_0000__0000_0000__0000,
3899 ReachesAll = 0b0011_1111__0000_0000__0000,
3900
3901 // Things that mean drop glue is necessary
3902 NeedsDrop = 0b0000_0000__0000_0111__0000,
3903
3904 // Things that prevent values from being considered sized
3905 Nonsized = 0b0000_0000__0000_0000__0001,
3906
3907 // All bits
3908 All = 0b1111_1111__1111_1111__1111
3909 }
3910 }
3911
3912 impl TypeContents {
3913 pub fn when(&self, cond: bool) -> TypeContents {
3914 if cond {*self} else {TC::None}
3915 }
3916
3917 pub fn intersects(&self, tc: TypeContents) -> bool {
3918 (self.bits & tc.bits) != 0
3919 }
3920
3921 pub fn owns_owned(&self) -> bool {
3922 self.intersects(TC::OwnsOwned)
3923 }
3924
3925 pub fn is_sized(&self, _: &ctxt) -> bool {
3926 !self.intersects(TC::Nonsized)
3927 }
3928
3929 pub fn interior_param(&self) -> bool {
3930 self.intersects(TC::InteriorParam)
3931 }
3932
3933 pub fn interior_unsafe(&self) -> bool {
3934 self.intersects(TC::InteriorUnsafe)
3935 }
3936
3937 pub fn interior_unsized(&self) -> bool {
3938 self.intersects(TC::InteriorUnsized)
3939 }
3940
3941 pub fn needs_drop(&self, _: &ctxt) -> bool {
3942 self.intersects(TC::NeedsDrop)
3943 }
3944
3945 /// Includes only those bits that still apply when indirected through a `Box` pointer
3946 pub fn owned_pointer(&self) -> TypeContents {
3947 TC::OwnsOwned | (
3948 *self & (TC::OwnsAll | TC::ReachesAll))
3949 }
3950
3951 /// Includes only those bits that still apply when indirected through a reference (`&`)
3952 pub fn reference(&self, bits: TypeContents) -> TypeContents {
3953 bits | (
3954 *self & TC::ReachesAll)
3955 }
3956
3957 /// Includes only those bits that still apply when indirected through a raw pointer (`*`)
3958 pub fn unsafe_pointer(&self) -> TypeContents {
3959 *self & TC::ReachesAll
3960 }
3961
3962 pub fn union<T, F>(v: &[T], mut f: F) -> TypeContents where
3963 F: FnMut(&T) -> TypeContents,
3964 {
3965 v.iter().fold(TC::None, |tc, ty| tc | f(ty))
3966 }
3967
3968 pub fn has_dtor(&self) -> bool {
3969 self.intersects(TC::OwnsDtor)
3970 }
3971 }
3972
3973 impl ops::BitOr for TypeContents {
3974 type Output = TypeContents;
3975
3976 fn bitor(self, other: TypeContents) -> TypeContents {
3977 TypeContents {bits: self.bits | other.bits}
3978 }
3979 }
3980
3981 impl ops::BitAnd for TypeContents {
3982 type Output = TypeContents;
3983
3984 fn bitand(self, other: TypeContents) -> TypeContents {
3985 TypeContents {bits: self.bits & other.bits}
3986 }
3987 }
3988
3989 impl ops::Sub for TypeContents {
3990 type Output = TypeContents;
3991
3992 fn sub(self, other: TypeContents) -> TypeContents {
3993 TypeContents {bits: self.bits & !other.bits}
3994 }
3995 }
3996
3997 impl fmt::Debug for TypeContents {
3998 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3999 write!(f, "TypeContents({:b})", self.bits)
4000 }
4001 }
4002
4003 pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
4004 return memoized(&cx.tc_cache, ty, |ty| {
4005 tc_ty(cx, ty, &mut FnvHashMap())
4006 });
4007
4008 fn tc_ty<'tcx>(cx: &ctxt<'tcx>,
4009 ty: Ty<'tcx>,
4010 cache: &mut FnvHashMap<Ty<'tcx>, TypeContents>) -> TypeContents
4011 {
4012 // Subtle: Note that we are *not* using cx.tc_cache here but rather a
4013 // private cache for this walk. This is needed in the case of cyclic
4014 // types like:
4015 //
4016 // struct List { next: Box<Option<List>>, ... }
4017 //
4018 // When computing the type contents of such a type, we wind up deeply
4019 // recursing as we go. So when we encounter the recursive reference
4020 // to List, we temporarily use TC::None as its contents. Later we'll
4021 // patch up the cache with the correct value, once we've computed it
4022 // (this is basically a co-inductive process, if that helps). So in
4023 // the end we'll compute TC::OwnsOwned, in this case.
4024 //
4025 // The problem is, as we are doing the computation, we will also
4026 // compute an *intermediate* contents for, e.g., Option<List> of
4027 // TC::None. This is ok during the computation of List itself, but if
4028 // we stored this intermediate value into cx.tc_cache, then later
4029 // requests for the contents of Option<List> would also yield TC::None
4030 // which is incorrect. This value was computed based on the crutch
4031 // value for the type contents of list. The correct value is
4032 // TC::OwnsOwned. This manifested as issue #4821.
4033 match cache.get(&ty) {
4034 Some(tc) => { return *tc; }
4035 None => {}
4036 }
4037 match cx.tc_cache.borrow().get(&ty) { // Must check both caches!
4038 Some(tc) => { return *tc; }
4039 None => {}
4040 }
4041 cache.insert(ty, TC::None);
4042
4043 let result = match ty.sty {
4044 // usize and isize are ffi-unsafe
4045 TyUint(ast::TyUs) | TyInt(ast::TyIs) => {
4046 TC::ReachesFfiUnsafe
4047 }
4048
4049 // Scalar and unique types are sendable, and durable
4050 TyInfer(ty::FreshIntTy(_)) | TyInfer(ty::FreshFloatTy(_)) |
4051 TyBool | TyInt(_) | TyUint(_) | TyFloat(_) |
4052 TyBareFn(..) | ty::TyChar => {
4053 TC::None
4054 }
4055
4056 TyBox(typ) => {
4057 TC::ReachesFfiUnsafe | match typ.sty {
4058 TyStr => TC::OwnsOwned,
4059 _ => tc_ty(cx, typ, cache).owned_pointer(),
4060 }
4061 }
4062
4063 TyTrait(box TraitTy { ref bounds, .. }) => {
4064 object_contents(bounds) | TC::ReachesFfiUnsafe | TC::Nonsized
4065 }
4066
4067 TyRawPtr(ref mt) => {
4068 tc_ty(cx, mt.ty, cache).unsafe_pointer()
4069 }
4070
4071 TyRef(r, ref mt) => {
4072 TC::ReachesFfiUnsafe | match mt.ty.sty {
4073 TyStr => borrowed_contents(*r, ast::MutImmutable),
4074 TyArray(..) |
4075 TySlice(_) => tc_ty(cx, mt.ty, cache).reference(borrowed_contents(*r,
4076 mt.mutbl)),
4077 _ => tc_ty(cx, mt.ty, cache).reference(borrowed_contents(*r, mt.mutbl)),
4078 }
4079 }
4080
4081 TyArray(ty, _) => {
4082 tc_ty(cx, ty, cache)
4083 }
4084
4085 TySlice(ty) => {
4086 tc_ty(cx, ty, cache) | TC::Nonsized
4087 }
4088 TyStr => TC::Nonsized,
4089
4090 TyStruct(did, substs) => {
4091 let flds = struct_fields(cx, did, substs);
4092 let mut res =
4093 TypeContents::union(&flds[..],
4094 |f| tc_mt(cx, f.mt, cache));
4095
4096 if !lookup_repr_hints(cx, did).contains(&attr::ReprExtern) {
4097 res = res | TC::ReachesFfiUnsafe;
4098 }
4099
4100 if ty::has_dtor(cx, did) {
4101 res = res | TC::OwnsDtor;
4102 }
4103 apply_lang_items(cx, did, res)
4104 }
4105
4106 TyClosure(did, substs) => {
4107 // FIXME(#14449): `borrowed_contents` below assumes `&mut` closure.
4108 let param_env = ty::empty_parameter_environment(cx);
4109 let upvars = closure_upvars(&param_env, did, substs).unwrap();
4110 TypeContents::union(&upvars, |f| tc_ty(cx, &f.ty, cache))
4111 }
4112
4113 TyTuple(ref tys) => {
4114 TypeContents::union(&tys[..],
4115 |ty| tc_ty(cx, *ty, cache))
4116 }
4117
4118 TyEnum(did, substs) => {
4119 let variants = substd_enum_variants(cx, did, substs);
4120 let mut res =
4121 TypeContents::union(&variants[..], |variant| {
4122 TypeContents::union(&variant.args,
4123 |arg_ty| {
4124 tc_ty(cx, *arg_ty, cache)
4125 })
4126 });
4127
4128 if ty::has_dtor(cx, did) {
4129 res = res | TC::OwnsDtor;
4130 }
4131
4132 if !variants.is_empty() {
4133 let repr_hints = lookup_repr_hints(cx, did);
4134 if repr_hints.len() > 1 {
4135 // this is an error later on, but this type isn't safe
4136 res = res | TC::ReachesFfiUnsafe;
4137 }
4138
4139 match repr_hints.get(0) {
4140 Some(h) => if !h.is_ffi_safe() {
4141 res = res | TC::ReachesFfiUnsafe;
4142 },
4143 // ReprAny
4144 None => {
4145 res = res | TC::ReachesFfiUnsafe;
4146
4147 // We allow ReprAny enums if they are eligible for
4148 // the nullable pointer optimization and the
4149 // contained type is an `extern fn`
4150
4151 if variants.len() == 2 {
4152 let mut data_idx = 0;
4153
4154 if variants[0].args.is_empty() {
4155 data_idx = 1;
4156 }
4157
4158 if variants[data_idx].args.len() == 1 {
4159 match variants[data_idx].args[0].sty {
4160 TyBareFn(..) => { res = res - TC::ReachesFfiUnsafe; }
4161 _ => { }
4162 }
4163 }
4164 }
4165 }
4166 }
4167 }
4168
4169
4170 apply_lang_items(cx, did, res)
4171 }
4172
4173 TyProjection(..) |
4174 TyParam(_) => {
4175 TC::All
4176 }
4177
4178 TyInfer(_) |
4179 TyError => {
4180 cx.sess.bug("asked to compute contents of error type");
4181 }
4182 };
4183
4184 cache.insert(ty, result);
4185 result
4186 }
4187
4188 fn tc_mt<'tcx>(cx: &ctxt<'tcx>,
4189 mt: mt<'tcx>,
4190 cache: &mut FnvHashMap<Ty<'tcx>, TypeContents>) -> TypeContents
4191 {
4192 let mc = TC::ReachesMutable.when(mt.mutbl == MutMutable);
4193 mc | tc_ty(cx, mt.ty, cache)
4194 }
4195
4196 fn apply_lang_items(cx: &ctxt, did: ast::DefId, tc: TypeContents)
4197 -> TypeContents {
4198 if Some(did) == cx.lang_items.unsafe_cell_type() {
4199 tc | TC::InteriorUnsafe
4200 } else {
4201 tc
4202 }
4203 }
4204
4205 /// Type contents due to containing a reference with the region `region` and borrow kind `bk`
4206 fn borrowed_contents(region: ty::Region,
4207 mutbl: ast::Mutability)
4208 -> TypeContents {
4209 let b = match mutbl {
4210 ast::MutMutable => TC::ReachesMutable,
4211 ast::MutImmutable => TC::None,
4212 };
4213 b | (TC::ReachesBorrowed).when(region != ty::ReStatic)
4214 }
4215
4216 fn object_contents(bounds: &ExistentialBounds) -> TypeContents {
4217 // These are the type contents of the (opaque) interior. We
4218 // make no assumptions (other than that it cannot have an
4219 // in-scope type parameter within, which makes no sense).
4220 let mut tc = TC::All - TC::InteriorParam;
4221 for bound in &bounds.builtin_bounds {
4222 tc = tc - match bound {
4223 BoundSync | BoundSend | BoundCopy => TC::None,
4224 BoundSized => TC::Nonsized,
4225 };
4226 }
4227 return tc;
4228 }
4229 }
4230
4231 fn type_impls_bound<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'tcx>>,
4232 tcx: &ty::ctxt<'tcx>,
4233 ty: Ty<'tcx>,
4234 bound: ty::BuiltinBound,
4235 span: Span)
4236 -> bool
4237 {
4238 let pe;
4239 let param_env = match param_env {
4240 Some(e) => e,
4241 None => {
4242 pe = empty_parameter_environment(tcx);
4243 &pe
4244 }
4245 };
4246 let infcx = infer::new_infer_ctxt(tcx);
4247
4248 let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env, ty, bound, span);
4249
4250 debug!("type_impls_bound({:?}, {:?}) = {:?}",
4251 ty,
4252 bound,
4253 is_impld);
4254
4255 is_impld
4256 }
4257
4258 pub fn type_moves_by_default<'a,'tcx>(param_env: &ParameterEnvironment<'a,'tcx>,
4259 span: Span,
4260 ty: Ty<'tcx>)
4261 -> bool
4262 {
4263 if ty.flags.get().intersects(TypeFlags::MOVENESS_CACHED) {
4264 return ty.flags.get().intersects(TypeFlags::MOVES_BY_DEFAULT);
4265 }
4266
4267 assert!(!ty::type_needs_infer(ty));
4268
4269 // Fast-path for primitive types
4270 let result = match ty.sty {
4271 TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
4272 TyRawPtr(..) | TyBareFn(..) | TyRef(_, mt {
4273 mutbl: ast::MutImmutable, ..
4274 }) => Some(false),
4275
4276 TyStr | TyBox(..) | TyRef(_, mt {
4277 mutbl: ast::MutMutable, ..
4278 }) => Some(true),
4279
4280 TyArray(..) | TySlice(_) | TyTrait(..) | TyTuple(..) |
4281 TyClosure(..) | TyEnum(..) | TyStruct(..) |
4282 TyProjection(..) | TyParam(..) | TyInfer(..) | TyError => None
4283 }.unwrap_or_else(|| !type_impls_bound(Some(param_env),
4284 param_env.tcx,
4285 ty,
4286 ty::BoundCopy,
4287 span));
4288
4289 if !type_has_params(ty) && !type_has_self(ty) {
4290 ty.flags.set(ty.flags.get() | if result {
4291 TypeFlags::MOVENESS_CACHED | TypeFlags::MOVES_BY_DEFAULT
4292 } else {
4293 TypeFlags::MOVENESS_CACHED
4294 });
4295 }
4296
4297 result
4298 }
4299
4300 #[inline]
4301 pub fn type_is_sized<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'tcx>>,
4302 tcx: &ty::ctxt<'tcx>,
4303 span: Span,
4304 ty: Ty<'tcx>)
4305 -> bool
4306 {
4307 if ty.flags.get().intersects(TypeFlags::SIZEDNESS_CACHED) {
4308 let result = ty.flags.get().intersects(TypeFlags::IS_SIZED);
4309 return result;
4310 }
4311
4312 type_is_sized_uncached(param_env, tcx, span, ty)
4313 }
4314
4315 fn type_is_sized_uncached<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'tcx>>,
4316 tcx: &ty::ctxt<'tcx>,
4317 span: Span,
4318 ty: Ty<'tcx>) -> bool {
4319 assert!(!ty::type_needs_infer(ty));
4320
4321 // Fast-path for primitive types
4322 let result = match ty.sty {
4323 TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
4324 TyBox(..) | TyRawPtr(..) | TyRef(..) | TyBareFn(..) |
4325 TyArray(..) | TyTuple(..) | TyClosure(..) => Some(true),
4326
4327 TyStr | TyTrait(..) | TySlice(_) => Some(false),
4328
4329 TyEnum(..) | TyStruct(..) | TyProjection(..) | TyParam(..) |
4330 TyInfer(..) | TyError => None
4331 }.unwrap_or_else(|| type_impls_bound(param_env, tcx, ty, ty::BoundSized, span));
4332
4333 if !type_has_params(ty) && !type_has_self(ty) {
4334 ty.flags.set(ty.flags.get() | if result {
4335 TypeFlags::SIZEDNESS_CACHED | TypeFlags::IS_SIZED
4336 } else {
4337 TypeFlags::SIZEDNESS_CACHED
4338 });
4339 }
4340
4341 result
4342 }
4343
4344 pub fn is_ffi_safe<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
4345 !type_contents(cx, ty).intersects(TC::ReachesFfiUnsafe)
4346 }
4347
4348 // True if instantiating an instance of `r_ty` requires an instance of `r_ty`.
4349 pub fn is_instantiable<'tcx>(cx: &ctxt<'tcx>, r_ty: Ty<'tcx>) -> bool {
4350 fn type_requires<'tcx>(cx: &ctxt<'tcx>, seen: &mut Vec<DefId>,
4351 r_ty: Ty<'tcx>, ty: Ty<'tcx>) -> bool {
4352 debug!("type_requires({:?}, {:?})?",
4353 r_ty, ty);
4354
4355 let r = r_ty == ty || subtypes_require(cx, seen, r_ty, ty);
4356
4357 debug!("type_requires({:?}, {:?})? {:?}",
4358 r_ty, ty, r);
4359 return r;
4360 }
4361
4362 fn subtypes_require<'tcx>(cx: &ctxt<'tcx>, seen: &mut Vec<DefId>,
4363 r_ty: Ty<'tcx>, ty: Ty<'tcx>) -> bool {
4364 debug!("subtypes_require({:?}, {:?})?",
4365 r_ty, ty);
4366
4367 let r = match ty.sty {
4368 // fixed length vectors need special treatment compared to
4369 // normal vectors, since they don't necessarily have the
4370 // possibility to have length zero.
4371 TyArray(_, 0) => false, // don't need no contents
4372 TyArray(ty, _) => type_requires(cx, seen, r_ty, ty),
4373
4374 TyBool |
4375 TyChar |
4376 TyInt(_) |
4377 TyUint(_) |
4378 TyFloat(_) |
4379 TyStr |
4380 TyBareFn(..) |
4381 TyParam(_) |
4382 TyProjection(_) |
4383 TySlice(_) => {
4384 false
4385 }
4386 TyBox(typ) => {
4387 type_requires(cx, seen, r_ty, typ)
4388 }
4389 TyRef(_, ref mt) => {
4390 type_requires(cx, seen, r_ty, mt.ty)
4391 }
4392
4393 TyRawPtr(..) => {
4394 false // unsafe ptrs can always be NULL
4395 }
4396
4397 TyTrait(..) => {
4398 false
4399 }
4400
4401 TyStruct(ref did, _) if seen.contains(did) => {
4402 false
4403 }
4404
4405 TyStruct(did, substs) => {
4406 seen.push(did);
4407 let fields = struct_fields(cx, did, substs);
4408 let r = fields.iter().any(|f| type_requires(cx, seen, r_ty, f.mt.ty));
4409 seen.pop().unwrap();
4410 r
4411 }
4412
4413 TyError |
4414 TyInfer(_) |
4415 TyClosure(..) => {
4416 // this check is run on type definitions, so we don't expect to see
4417 // inference by-products or closure types
4418 cx.sess.bug(&format!("requires check invoked on inapplicable type: {:?}", ty))
4419 }
4420
4421 TyTuple(ref ts) => {
4422 ts.iter().any(|ty| type_requires(cx, seen, r_ty, *ty))
4423 }
4424
4425 TyEnum(ref did, _) if seen.contains(did) => {
4426 false
4427 }
4428
4429 TyEnum(did, substs) => {
4430 seen.push(did);
4431 let vs = enum_variants(cx, did);
4432 let r = !vs.is_empty() && vs.iter().all(|variant| {
4433 variant.args.iter().any(|aty| {
4434 let sty = aty.subst(cx, substs);
4435 type_requires(cx, seen, r_ty, sty)
4436 })
4437 });
4438 seen.pop().unwrap();
4439 r
4440 }
4441 };
4442
4443 debug!("subtypes_require({:?}, {:?})? {:?}",
4444 r_ty, ty, r);
4445
4446 return r;
4447 }
4448
4449 let mut seen = Vec::new();
4450 !subtypes_require(cx, &mut seen, r_ty, r_ty)
4451 }
4452
4453 /// Describes whether a type is representable. For types that are not
4454 /// representable, 'SelfRecursive' and 'ContainsRecursive' are used to
4455 /// distinguish between types that are recursive with themselves and types that
4456 /// contain a different recursive type. These cases can therefore be treated
4457 /// differently when reporting errors.
4458 ///
4459 /// The ordering of the cases is significant. They are sorted so that cmp::max
4460 /// will keep the "more erroneous" of two values.
4461 #[derive(Copy, Clone, PartialOrd, Ord, Eq, PartialEq, Debug)]
4462 pub enum Representability {
4463 Representable,
4464 ContainsRecursive,
4465 SelfRecursive,
4466 }
4467
4468 /// Check whether a type is representable. This means it cannot contain unboxed
4469 /// structural recursion. This check is needed for structs and enums.
4470 pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>)
4471 -> Representability {
4472
4473 // Iterate until something non-representable is found
4474 fn find_nonrepresentable<'tcx, It: Iterator<Item=Ty<'tcx>>>(cx: &ctxt<'tcx>, sp: Span,
4475 seen: &mut Vec<Ty<'tcx>>,
4476 iter: It)
4477 -> Representability {
4478 iter.fold(Representable,
4479 |r, ty| cmp::max(r, is_type_structurally_recursive(cx, sp, seen, ty)))
4480 }
4481
4482 fn are_inner_types_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span,
4483 seen: &mut Vec<Ty<'tcx>>, ty: Ty<'tcx>)
4484 -> Representability {
4485 match ty.sty {
4486 TyTuple(ref ts) => {
4487 find_nonrepresentable(cx, sp, seen, ts.iter().cloned())
4488 }
4489 // Fixed-length vectors.
4490 // FIXME(#11924) Behavior undecided for zero-length vectors.
4491 TyArray(ty, _) => {
4492 is_type_structurally_recursive(cx, sp, seen, ty)
4493 }
4494 TyStruct(did, substs) => {
4495 let fields = struct_fields(cx, did, substs);
4496 find_nonrepresentable(cx, sp, seen, fields.iter().map(|f| f.mt.ty))
4497 }
4498 TyEnum(did, substs) => {
4499 let vs = enum_variants(cx, did);
4500 let iter = vs.iter()
4501 .flat_map(|variant| &variant.args)
4502 .map(|aty| { aty.subst_spanned(cx, substs, Some(sp)) });
4503
4504 find_nonrepresentable(cx, sp, seen, iter)
4505 }
4506 TyClosure(..) => {
4507 // this check is run on type definitions, so we don't expect
4508 // to see closure types
4509 cx.sess.bug(&format!("requires check invoked on inapplicable type: {:?}", ty))
4510 }
4511 _ => Representable,
4512 }
4513 }
4514
4515 fn same_struct_or_enum_def_id(ty: Ty, did: DefId) -> bool {
4516 match ty.sty {
4517 TyStruct(ty_did, _) | TyEnum(ty_did, _) => {
4518 ty_did == did
4519 }
4520 _ => false
4521 }
4522 }
4523
4524 fn same_type<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
4525 match (&a.sty, &b.sty) {
4526 (&TyStruct(did_a, ref substs_a), &TyStruct(did_b, ref substs_b)) |
4527 (&TyEnum(did_a, ref substs_a), &TyEnum(did_b, ref substs_b)) => {
4528 if did_a != did_b {
4529 return false;
4530 }
4531
4532 let types_a = substs_a.types.get_slice(subst::TypeSpace);
4533 let types_b = substs_b.types.get_slice(subst::TypeSpace);
4534
4535 let mut pairs = types_a.iter().zip(types_b);
4536
4537 pairs.all(|(&a, &b)| same_type(a, b))
4538 }
4539 _ => {
4540 a == b
4541 }
4542 }
4543 }
4544
4545 // Does the type `ty` directly (without indirection through a pointer)
4546 // contain any types on stack `seen`?
4547 fn is_type_structurally_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span,
4548 seen: &mut Vec<Ty<'tcx>>,
4549 ty: Ty<'tcx>) -> Representability {
4550 debug!("is_type_structurally_recursive: {:?}", ty);
4551
4552 match ty.sty {
4553 TyStruct(did, _) | TyEnum(did, _) => {
4554 {
4555 // Iterate through stack of previously seen types.
4556 let mut iter = seen.iter();
4557
4558 // The first item in `seen` is the type we are actually curious about.
4559 // We want to return SelfRecursive if this type contains itself.
4560 // It is important that we DON'T take generic parameters into account
4561 // for this check, so that Bar<T> in this example counts as SelfRecursive:
4562 //
4563 // struct Foo;
4564 // struct Bar<T> { x: Bar<Foo> }
4565
4566 match iter.next() {
4567 Some(&seen_type) => {
4568 if same_struct_or_enum_def_id(seen_type, did) {
4569 debug!("SelfRecursive: {:?} contains {:?}",
4570 seen_type,
4571 ty);
4572 return SelfRecursive;
4573 }
4574 }
4575 None => {}
4576 }
4577
4578 // We also need to know whether the first item contains other types that
4579 // are structurally recursive. If we don't catch this case, we will recurse
4580 // infinitely for some inputs.
4581 //
4582 // It is important that we DO take generic parameters into account here,
4583 // so that code like this is considered SelfRecursive, not ContainsRecursive:
4584 //
4585 // struct Foo { Option<Option<Foo>> }
4586
4587 for &seen_type in iter {
4588 if same_type(ty, seen_type) {
4589 debug!("ContainsRecursive: {:?} contains {:?}",
4590 seen_type,
4591 ty);
4592 return ContainsRecursive;
4593 }
4594 }
4595 }
4596
4597 // For structs and enums, track all previously seen types by pushing them
4598 // onto the 'seen' stack.
4599 seen.push(ty);
4600 let out = are_inner_types_recursive(cx, sp, seen, ty);
4601 seen.pop();
4602 out
4603 }
4604 _ => {
4605 // No need to push in other cases.
4606 are_inner_types_recursive(cx, sp, seen, ty)
4607 }
4608 }
4609 }
4610
4611 debug!("is_type_representable: {:?}", ty);
4612
4613 // To avoid a stack overflow when checking an enum variant or struct that
4614 // contains a different, structurally recursive type, maintain a stack
4615 // of seen types and check recursion for each of them (issues #3008, #3779).
4616 let mut seen: Vec<Ty> = Vec::new();
4617 let r = is_type_structurally_recursive(cx, sp, &mut seen, ty);
4618 debug!("is_type_representable: {:?} is {:?}", ty, r);
4619 r
4620 }
4621
4622 pub fn type_is_trait(ty: Ty) -> bool {
4623 match ty.sty {
4624 TyTrait(..) => true,
4625 _ => false
4626 }
4627 }
4628
4629 pub fn type_is_integral(ty: Ty) -> bool {
4630 match ty.sty {
4631 TyInfer(IntVar(_)) | TyInt(_) | TyUint(_) => true,
4632 _ => false
4633 }
4634 }
4635
4636 pub fn type_is_fresh(ty: Ty) -> bool {
4637 match ty.sty {
4638 TyInfer(FreshTy(_)) => true,
4639 TyInfer(FreshIntTy(_)) => true,
4640 TyInfer(FreshFloatTy(_)) => true,
4641 _ => false
4642 }
4643 }
4644
4645 pub fn type_is_uint(ty: Ty) -> bool {
4646 match ty.sty {
4647 TyInfer(IntVar(_)) | TyUint(ast::TyUs) => true,
4648 _ => false
4649 }
4650 }
4651
4652 pub fn type_is_char(ty: Ty) -> bool {
4653 match ty.sty {
4654 TyChar => true,
4655 _ => false
4656 }
4657 }
4658
4659 pub fn type_is_bare_fn(ty: Ty) -> bool {
4660 match ty.sty {
4661 TyBareFn(..) => true,
4662 _ => false
4663 }
4664 }
4665
4666 pub fn type_is_bare_fn_item(ty: Ty) -> bool {
4667 match ty.sty {
4668 TyBareFn(Some(_), _) => true,
4669 _ => false
4670 }
4671 }
4672
4673 pub fn type_is_fp(ty: Ty) -> bool {
4674 match ty.sty {
4675 TyInfer(FloatVar(_)) | TyFloat(_) => true,
4676 _ => false
4677 }
4678 }
4679
4680 pub fn type_is_numeric(ty: Ty) -> bool {
4681 return type_is_integral(ty) || type_is_fp(ty);
4682 }
4683
4684 pub fn type_is_signed(ty: Ty) -> bool {
4685 match ty.sty {
4686 TyInt(_) => true,
4687 _ => false
4688 }
4689 }
4690
4691 pub fn type_is_machine(ty: Ty) -> bool {
4692 match ty.sty {
4693 TyInt(ast::TyIs) | TyUint(ast::TyUs) => false,
4694 TyInt(..) | TyUint(..) | TyFloat(..) => true,
4695 _ => false
4696 }
4697 }
4698
4699 // Whether a type is enum like, that is an enum type with only nullary
4700 // constructors
4701 pub fn type_is_c_like_enum(cx: &ctxt, ty: Ty) -> bool {
4702 match ty.sty {
4703 TyEnum(did, _) => {
4704 let variants = enum_variants(cx, did);
4705 if variants.is_empty() {
4706 false
4707 } else {
4708 variants.iter().all(|v| v.args.is_empty())
4709 }
4710 }
4711 _ => false
4712 }
4713 }
4714
4715 // Returns the type and mutability of *ty.
4716 //
4717 // The parameter `explicit` indicates if this is an *explicit* dereference.
4718 // Some types---notably unsafe ptrs---can only be dereferenced explicitly.
4719 pub fn deref<'tcx>(ty: Ty<'tcx>, explicit: bool) -> Option<mt<'tcx>> {
4720 match ty.sty {
4721 TyBox(ty) => {
4722 Some(mt {
4723 ty: ty,
4724 mutbl: ast::MutImmutable,
4725 })
4726 },
4727 TyRef(_, mt) => Some(mt),
4728 TyRawPtr(mt) if explicit => Some(mt),
4729 _ => None
4730 }
4731 }
4732
4733 pub fn type_content<'tcx>(ty: Ty<'tcx>) -> Ty<'tcx> {
4734 match ty.sty {
4735 TyBox(ty) => ty,
4736 TyRef(_, mt) | TyRawPtr(mt) => mt.ty,
4737 _ => ty
4738 }
4739 }
4740
4741 // Returns the type of ty[i]
4742 pub fn index<'tcx>(ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
4743 match ty.sty {
4744 TyArray(ty, _) | TySlice(ty) => Some(ty),
4745 _ => None
4746 }
4747 }
4748
4749 // Returns the type of elements contained within an 'array-like' type.
4750 // This is exactly the same as the above, except it supports strings,
4751 // which can't actually be indexed.
4752 pub fn array_element_ty<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
4753 match ty.sty {
4754 TyArray(ty, _) | TySlice(ty) => Some(ty),
4755 TyStr => Some(tcx.types.u8),
4756 _ => None
4757 }
4758 }
4759
4760 /// Returns the type of element at index `i` in tuple or tuple-like type `t`.
4761 /// For an enum `t`, `variant` is None only if `t` is a univariant enum.
4762 pub fn positional_element_ty<'tcx>(cx: &ctxt<'tcx>,
4763 ty: Ty<'tcx>,
4764 i: usize,
4765 variant: Option<ast::DefId>) -> Option<Ty<'tcx>> {
4766
4767 match (&ty.sty, variant) {
4768 (&TyTuple(ref v), None) => v.get(i).cloned(),
4769
4770
4771 (&TyStruct(def_id, substs), None) => lookup_struct_fields(cx, def_id)
4772 .get(i)
4773 .map(|&t|lookup_item_type(cx, t.id).ty.subst(cx, substs)),
4774
4775 (&TyEnum(def_id, substs), Some(variant_def_id)) => {
4776 let variant_info = enum_variant_with_id(cx, def_id, variant_def_id);
4777 variant_info.args.get(i).map(|t|t.subst(cx, substs))
4778 }
4779
4780 (&TyEnum(def_id, substs), None) => {
4781 assert!(enum_is_univariant(cx, def_id));
4782 let enum_variants = enum_variants(cx, def_id);
4783 let variant_info = &(*enum_variants)[0];
4784 variant_info.args.get(i).map(|t|t.subst(cx, substs))
4785 }
4786
4787 _ => None
4788 }
4789 }
4790
4791 /// Returns the type of element at field `n` in struct or struct-like type `t`.
4792 /// For an enum `t`, `variant` must be some def id.
4793 pub fn named_element_ty<'tcx>(cx: &ctxt<'tcx>,
4794 ty: Ty<'tcx>,
4795 n: ast::Name,
4796 variant: Option<ast::DefId>) -> Option<Ty<'tcx>> {
4797
4798 match (&ty.sty, variant) {
4799 (&TyStruct(def_id, substs), None) => {
4800 let r = lookup_struct_fields(cx, def_id);
4801 r.iter().find(|f| f.name == n)
4802 .map(|&f| lookup_field_type(cx, def_id, f.id, substs))
4803 }
4804 (&TyEnum(def_id, substs), Some(variant_def_id)) => {
4805 let variant_info = enum_variant_with_id(cx, def_id, variant_def_id);
4806 variant_info.arg_names.as_ref()
4807 .expect("must have struct enum variant if accessing a named fields")
4808 .iter().zip(&variant_info.args)
4809 .find(|&(&name, _)| name == n)
4810 .map(|(_name, arg_t)| arg_t.subst(cx, substs))
4811 }
4812 _ => None
4813 }
4814 }
4815
4816 pub fn node_id_to_type<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> Ty<'tcx> {
4817 match node_id_to_type_opt(cx, id) {
4818 Some(ty) => ty,
4819 None => cx.sess.bug(
4820 &format!("node_id_to_type: no type for node `{}`",
4821 cx.map.node_to_string(id)))
4822 }
4823 }
4824
4825 pub fn node_id_to_type_opt<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> Option<Ty<'tcx>> {
4826 match cx.node_types.borrow().get(&id) {
4827 Some(&ty) => Some(ty),
4828 None => None
4829 }
4830 }
4831
4832 pub fn node_id_item_substs<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> ItemSubsts<'tcx> {
4833 match cx.item_substs.borrow().get(&id) {
4834 None => ItemSubsts::empty(),
4835 Some(ts) => ts.clone(),
4836 }
4837 }
4838
4839 pub fn fn_is_variadic(fty: Ty) -> bool {
4840 match fty.sty {
4841 TyBareFn(_, ref f) => f.sig.0.variadic,
4842 ref s => {
4843 panic!("fn_is_variadic() called on non-fn type: {:?}", s)
4844 }
4845 }
4846 }
4847
4848 pub fn ty_fn_sig<'tcx>(fty: Ty<'tcx>) -> &'tcx PolyFnSig<'tcx> {
4849 match fty.sty {
4850 TyBareFn(_, ref f) => &f.sig,
4851 ref s => {
4852 panic!("ty_fn_sig() called on non-fn type: {:?}", s)
4853 }
4854 }
4855 }
4856
4857 /// Returns the ABI of the given function.
4858 pub fn ty_fn_abi(fty: Ty) -> abi::Abi {
4859 match fty.sty {
4860 TyBareFn(_, ref f) => f.abi,
4861 _ => panic!("ty_fn_abi() called on non-fn type"),
4862 }
4863 }
4864
4865 // Type accessors for substructures of types
4866 pub fn ty_fn_args<'tcx>(fty: Ty<'tcx>) -> ty::Binder<Vec<Ty<'tcx>>> {
4867 ty_fn_sig(fty).inputs()
4868 }
4869
4870 pub fn ty_fn_ret<'tcx>(fty: Ty<'tcx>) -> Binder<FnOutput<'tcx>> {
4871 match fty.sty {
4872 TyBareFn(_, ref f) => f.sig.output(),
4873 ref s => {
4874 panic!("ty_fn_ret() called on non-fn type: {:?}", s)
4875 }
4876 }
4877 }
4878
4879 pub fn is_fn_ty(fty: Ty) -> bool {
4880 match fty.sty {
4881 TyBareFn(..) => true,
4882 _ => false
4883 }
4884 }
4885
4886 pub fn ty_region(tcx: &ctxt,
4887 span: Span,
4888 ty: Ty) -> Region {
4889 match ty.sty {
4890 TyRef(r, _) => *r,
4891 ref s => {
4892 tcx.sess.span_bug(
4893 span,
4894 &format!("ty_region() invoked on an inappropriate ty: {:?}",
4895 s));
4896 }
4897 }
4898 }
4899
4900 pub fn free_region_from_def(outlives_extent: region::DestructionScopeData,
4901 def: &RegionParameterDef)
4902 -> ty::Region
4903 {
4904 let ret =
4905 ty::ReFree(ty::FreeRegion { scope: outlives_extent,
4906 bound_region: ty::BrNamed(def.def_id,
4907 def.name) });
4908 debug!("free_region_from_def returns {:?}", ret);
4909 ret
4910 }
4911
4912 // Returns the type of a pattern as a monotype. Like @expr_ty, this function
4913 // doesn't provide type parameter substitutions.
4914 pub fn pat_ty<'tcx>(cx: &ctxt<'tcx>, pat: &ast::Pat) -> Ty<'tcx> {
4915 return node_id_to_type(cx, pat.id);
4916 }
4917 pub fn pat_ty_opt<'tcx>(cx: &ctxt<'tcx>, pat: &ast::Pat) -> Option<Ty<'tcx>> {
4918 return node_id_to_type_opt(cx, pat.id);
4919 }
4920
4921
4922 // Returns the type of an expression as a monotype.
4923 //
4924 // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in
4925 // some cases, we insert `AutoAdjustment` annotations such as auto-deref or
4926 // auto-ref. The type returned by this function does not consider such
4927 // adjustments. See `expr_ty_adjusted()` instead.
4928 //
4929 // NB (2): This type doesn't provide type parameter substitutions; e.g. if you
4930 // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
4931 // instead of "fn(ty) -> T with T = isize".
4932 pub fn expr_ty<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr) -> Ty<'tcx> {
4933 return node_id_to_type(cx, expr.id);
4934 }
4935
4936 pub fn expr_ty_opt<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr) -> Option<Ty<'tcx>> {
4937 return node_id_to_type_opt(cx, expr.id);
4938 }
4939
4940 /// Returns the type of `expr`, considering any `AutoAdjustment`
4941 /// entry recorded for that expression.
4942 ///
4943 /// It would almost certainly be better to store the adjusted ty in with
4944 /// the `AutoAdjustment`, but I opted not to do this because it would
4945 /// require serializing and deserializing the type and, although that's not
4946 /// hard to do, I just hate that code so much I didn't want to touch it
4947 /// unless it was to fix it properly, which seemed a distraction from the
4948 /// thread at hand! -nmatsakis
4949 pub fn expr_ty_adjusted<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr) -> Ty<'tcx> {
4950 adjust_ty(cx, expr.span, expr.id, expr_ty(cx, expr),
4951 cx.adjustments.borrow().get(&expr.id),
4952 |method_call| cx.method_map.borrow().get(&method_call).map(|method| method.ty))
4953 }
4954
4955 pub fn expr_span(cx: &ctxt, id: NodeId) -> Span {
4956 match cx.map.find(id) {
4957 Some(ast_map::NodeExpr(e)) => {
4958 e.span
4959 }
4960 Some(f) => {
4961 cx.sess.bug(&format!("Node id {} is not an expr: {:?}",
4962 id,
4963 f));
4964 }
4965 None => {
4966 cx.sess.bug(&format!("Node id {} is not present \
4967 in the node map", id));
4968 }
4969 }
4970 }
4971
4972 pub fn local_var_name_str(cx: &ctxt, id: NodeId) -> InternedString {
4973 match cx.map.find(id) {
4974 Some(ast_map::NodeLocal(pat)) => {
4975 match pat.node {
4976 ast::PatIdent(_, ref path1, _) => {
4977 token::get_ident(path1.node)
4978 }
4979 _ => {
4980 cx.sess.bug(
4981 &format!("Variable id {} maps to {:?}, not local",
4982 id,
4983 pat));
4984 }
4985 }
4986 }
4987 r => {
4988 cx.sess.bug(&format!("Variable id {} maps to {:?}, not local",
4989 id,
4990 r));
4991 }
4992 }
4993 }
4994
4995 /// See `expr_ty_adjusted`
4996 pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>,
4997 span: Span,
4998 expr_id: ast::NodeId,
4999 unadjusted_ty: Ty<'tcx>,
5000 adjustment: Option<&AutoAdjustment<'tcx>>,
5001 mut method_type: F)
5002 -> Ty<'tcx> where
5003 F: FnMut(MethodCall) -> Option<Ty<'tcx>>,
5004 {
5005 if let TyError = unadjusted_ty.sty {
5006 return unadjusted_ty;
5007 }
5008
5009 return match adjustment {
5010 Some(adjustment) => {
5011 match *adjustment {
5012 AdjustReifyFnPointer => {
5013 match unadjusted_ty.sty {
5014 ty::TyBareFn(Some(_), b) => {
5015 ty::mk_bare_fn(cx, None, b)
5016 }
5017 _ => {
5018 cx.sess.bug(
5019 &format!("AdjustReifyFnPointer adjustment on non-fn-item: \
5020 {:?}", unadjusted_ty));
5021 }
5022 }
5023 }
5024
5025 AdjustUnsafeFnPointer => {
5026 match unadjusted_ty.sty {
5027 ty::TyBareFn(None, b) => cx.safe_to_unsafe_fn_ty(b),
5028 ref b => {
5029 cx.sess.bug(
5030 &format!("AdjustReifyFnPointer adjustment on non-fn-item: \
5031 {:?}",
5032 b));
5033 }
5034 }
5035 }
5036
5037 AdjustDerefRef(ref adj) => {
5038 let mut adjusted_ty = unadjusted_ty;
5039
5040 if !ty::type_is_error(adjusted_ty) {
5041 for i in 0..adj.autoderefs {
5042 let method_call = MethodCall::autoderef(expr_id, i as u32);
5043 match method_type(method_call) {
5044 Some(method_ty) => {
5045 // Overloaded deref operators have all late-bound
5046 // regions fully instantiated and coverge.
5047 let fn_ret =
5048 ty::no_late_bound_regions(cx,
5049 &ty_fn_ret(method_ty)).unwrap();
5050 adjusted_ty = fn_ret.unwrap();
5051 }
5052 None => {}
5053 }
5054 match deref(adjusted_ty, true) {
5055 Some(mt) => { adjusted_ty = mt.ty; }
5056 None => {
5057 cx.sess.span_bug(
5058 span,
5059 &format!("the {}th autoderef failed: {}",
5060 i,
5061 adjusted_ty)
5062 );
5063 }
5064 }
5065 }
5066 }
5067
5068 if let Some(target) = adj.unsize {
5069 target
5070 } else {
5071 adjust_ty_for_autoref(cx, adjusted_ty, adj.autoref)
5072 }
5073 }
5074 }
5075 }
5076 None => unadjusted_ty
5077 };
5078 }
5079
5080 pub fn adjust_ty_for_autoref<'tcx>(cx: &ctxt<'tcx>,
5081 ty: Ty<'tcx>,
5082 autoref: Option<AutoRef<'tcx>>)
5083 -> Ty<'tcx> {
5084 match autoref {
5085 None => ty,
5086 Some(AutoPtr(r, m)) => {
5087 mk_rptr(cx, r, mt { ty: ty, mutbl: m })
5088 }
5089 Some(AutoUnsafe(m)) => {
5090 mk_ptr(cx, mt { ty: ty, mutbl: m })
5091 }
5092 }
5093 }
5094
5095 pub fn resolve_expr(tcx: &ctxt, expr: &ast::Expr) -> def::Def {
5096 match tcx.def_map.borrow().get(&expr.id) {
5097 Some(def) => def.full_def(),
5098 None => {
5099 tcx.sess.span_bug(expr.span, &format!(
5100 "no def-map entry for expr {}", expr.id));
5101 }
5102 }
5103 }
5104
5105 pub fn expr_is_lval(tcx: &ctxt, expr: &ast::Expr) -> bool {
5106 match expr.node {
5107 ast::ExprPath(..) => {
5108 // We can't use resolve_expr here, as this needs to run on broken
5109 // programs. We don't need to through - associated items are all
5110 // rvalues.
5111 match tcx.def_map.borrow().get(&expr.id) {
5112 Some(&def::PathResolution {
5113 base_def: def::DefStatic(..), ..
5114 }) | Some(&def::PathResolution {
5115 base_def: def::DefUpvar(..), ..
5116 }) | Some(&def::PathResolution {
5117 base_def: def::DefLocal(..), ..
5118 }) => {
5119 true
5120 }
5121
5122 Some(..) => false,
5123
5124 None => tcx.sess.span_bug(expr.span, &format!(
5125 "no def for path {}", expr.id))
5126 }
5127 }
5128
5129 ast::ExprUnary(ast::UnDeref, _) |
5130 ast::ExprField(..) |
5131 ast::ExprTupField(..) |
5132 ast::ExprIndex(..) => {
5133 true
5134 }
5135
5136 ast::ExprCall(..) |
5137 ast::ExprMethodCall(..) |
5138 ast::ExprStruct(..) |
5139 ast::ExprRange(..) |
5140 ast::ExprTup(..) |
5141 ast::ExprIf(..) |
5142 ast::ExprMatch(..) |
5143 ast::ExprClosure(..) |
5144 ast::ExprBlock(..) |
5145 ast::ExprRepeat(..) |
5146 ast::ExprVec(..) |
5147 ast::ExprBreak(..) |
5148 ast::ExprAgain(..) |
5149 ast::ExprRet(..) |
5150 ast::ExprWhile(..) |
5151 ast::ExprLoop(..) |
5152 ast::ExprAssign(..) |
5153 ast::ExprInlineAsm(..) |
5154 ast::ExprAssignOp(..) |
5155 ast::ExprLit(_) |
5156 ast::ExprUnary(..) |
5157 ast::ExprBox(..) |
5158 ast::ExprAddrOf(..) |
5159 ast::ExprBinary(..) |
5160 ast::ExprCast(..) => {
5161 false
5162 }
5163
5164 ast::ExprParen(ref e) => expr_is_lval(tcx, e),
5165
5166 ast::ExprIfLet(..) |
5167 ast::ExprWhileLet(..) |
5168 ast::ExprForLoop(..) |
5169 ast::ExprMac(..) => {
5170 tcx.sess.span_bug(
5171 expr.span,
5172 "macro expression remains after expansion");
5173 }
5174 }
5175 }
5176
5177 pub fn stmt_node_id(s: &ast::Stmt) -> ast::NodeId {
5178 match s.node {
5179 ast::StmtDecl(_, id) | StmtExpr(_, id) | StmtSemi(_, id) => {
5180 return id;
5181 }
5182 ast::StmtMac(..) => panic!("unexpanded macro in trans")
5183 }
5184 }
5185
5186 pub fn field_idx_strict(tcx: &ctxt, name: ast::Name, fields: &[field])
5187 -> usize {
5188 let mut i = 0;
5189 for f in fields { if f.name == name { return i; } i += 1; }
5190 tcx.sess.bug(&format!(
5191 "no field named `{}` found in the list of fields `{:?}`",
5192 token::get_name(name),
5193 fields.iter()
5194 .map(|f| token::get_name(f.name).to_string())
5195 .collect::<Vec<String>>()));
5196 }
5197
5198 pub fn impl_or_trait_item_idx(id: ast::Name, trait_items: &[ImplOrTraitItem])
5199 -> Option<usize> {
5200 trait_items.iter().position(|m| m.name() == id)
5201 }
5202
5203 pub fn ty_sort_string(cx: &ctxt, ty: Ty) -> String {
5204 match ty.sty {
5205 TyBool | TyChar | TyInt(_) |
5206 TyUint(_) | TyFloat(_) | TyStr => ty.to_string(),
5207 TyTuple(ref tys) if tys.is_empty() => ty.to_string(),
5208
5209 TyEnum(id, _) => format!("enum `{}`", item_path_str(cx, id)),
5210 TyBox(_) => "box".to_string(),
5211 TyArray(_, n) => format!("array of {} elements", n),
5212 TySlice(_) => "slice".to_string(),
5213 TyRawPtr(_) => "*-ptr".to_string(),
5214 TyRef(_, _) => "&-ptr".to_string(),
5215 TyBareFn(Some(_), _) => format!("fn item"),
5216 TyBareFn(None, _) => "fn pointer".to_string(),
5217 TyTrait(ref inner) => {
5218 format!("trait {}", item_path_str(cx, inner.principal_def_id()))
5219 }
5220 TyStruct(id, _) => {
5221 format!("struct `{}`", item_path_str(cx, id))
5222 }
5223 TyClosure(..) => "closure".to_string(),
5224 TyTuple(_) => "tuple".to_string(),
5225 TyInfer(TyVar(_)) => "inferred type".to_string(),
5226 TyInfer(IntVar(_)) => "integral variable".to_string(),
5227 TyInfer(FloatVar(_)) => "floating-point variable".to_string(),
5228 TyInfer(FreshTy(_)) => "skolemized type".to_string(),
5229 TyInfer(FreshIntTy(_)) => "skolemized integral type".to_string(),
5230 TyInfer(FreshFloatTy(_)) => "skolemized floating-point type".to_string(),
5231 TyProjection(_) => "associated type".to_string(),
5232 TyParam(ref p) => {
5233 if p.space == subst::SelfSpace {
5234 "Self".to_string()
5235 } else {
5236 "type parameter".to_string()
5237 }
5238 }
5239 TyError => "type error".to_string(),
5240 }
5241 }
5242
5243 /// Explains the source of a type err in a short, human readable way. This is meant to be placed
5244 /// in parentheses after some larger message. You should also invoke `note_and_explain_type_err()`
5245 /// afterwards to present additional details, particularly when it comes to lifetime-related
5246 /// errors.
5247 impl<'tcx> fmt::Display for type_err<'tcx> {
5248 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5249 match *self {
5250 terr_cyclic_ty => write!(f, "cyclic type of infinite size"),
5251 terr_mismatch => write!(f, "types differ"),
5252 terr_unsafety_mismatch(values) => {
5253 write!(f, "expected {} fn, found {} fn",
5254 values.expected,
5255 values.found)
5256 }
5257 terr_abi_mismatch(values) => {
5258 write!(f, "expected {} fn, found {} fn",
5259 values.expected,
5260 values.found)
5261 }
5262 terr_mutability => write!(f, "values differ in mutability"),
5263 terr_box_mutability => {
5264 write!(f, "boxed values differ in mutability")
5265 }
5266 terr_vec_mutability => write!(f, "vectors differ in mutability"),
5267 terr_ptr_mutability => write!(f, "pointers differ in mutability"),
5268 terr_ref_mutability => write!(f, "references differ in mutability"),
5269 terr_ty_param_size(values) => {
5270 write!(f, "expected a type with {} type params, \
5271 found one with {} type params",
5272 values.expected,
5273 values.found)
5274 }
5275 terr_fixed_array_size(values) => {
5276 write!(f, "expected an array with a fixed size of {} elements, \
5277 found one with {} elements",
5278 values.expected,
5279 values.found)
5280 }
5281 terr_tuple_size(values) => {
5282 write!(f, "expected a tuple with {} elements, \
5283 found one with {} elements",
5284 values.expected,
5285 values.found)
5286 }
5287 terr_arg_count => {
5288 write!(f, "incorrect number of function parameters")
5289 }
5290 terr_regions_does_not_outlive(..) => {
5291 write!(f, "lifetime mismatch")
5292 }
5293 terr_regions_not_same(..) => {
5294 write!(f, "lifetimes are not the same")
5295 }
5296 terr_regions_no_overlap(..) => {
5297 write!(f, "lifetimes do not intersect")
5298 }
5299 terr_regions_insufficiently_polymorphic(br, _) => {
5300 write!(f, "expected bound lifetime parameter {}, \
5301 found concrete lifetime", br)
5302 }
5303 terr_regions_overly_polymorphic(br, _) => {
5304 write!(f, "expected concrete lifetime, \
5305 found bound lifetime parameter {}", br)
5306 }
5307 terr_sorts(values) => tls::with(|tcx| {
5308 // A naive approach to making sure that we're not reporting silly errors such as:
5309 // (expected closure, found closure).
5310 let expected_str = ty_sort_string(tcx, values.expected);
5311 let found_str = ty_sort_string(tcx, values.found);
5312 if expected_str == found_str {
5313 write!(f, "expected {}, found a different {}", expected_str, found_str)
5314 } else {
5315 write!(f, "expected {}, found {}", expected_str, found_str)
5316 }
5317 }),
5318 terr_traits(values) => tls::with(|tcx| {
5319 write!(f, "expected trait `{}`, found trait `{}`",
5320 item_path_str(tcx, values.expected),
5321 item_path_str(tcx, values.found))
5322 }),
5323 terr_builtin_bounds(values) => {
5324 if values.expected.is_empty() {
5325 write!(f, "expected no bounds, found `{}`",
5326 values.found)
5327 } else if values.found.is_empty() {
5328 write!(f, "expected bounds `{}`, found no bounds",
5329 values.expected)
5330 } else {
5331 write!(f, "expected bounds `{}`, found bounds `{}`",
5332 values.expected,
5333 values.found)
5334 }
5335 }
5336 terr_integer_as_char => {
5337 write!(f, "expected an integral type, found `char`")
5338 }
5339 terr_int_mismatch(ref values) => {
5340 write!(f, "expected `{:?}`, found `{:?}`",
5341 values.expected,
5342 values.found)
5343 }
5344 terr_float_mismatch(ref values) => {
5345 write!(f, "expected `{:?}`, found `{:?}`",
5346 values.expected,
5347 values.found)
5348 }
5349 terr_variadic_mismatch(ref values) => {
5350 write!(f, "expected {} fn, found {} function",
5351 if values.expected { "variadic" } else { "non-variadic" },
5352 if values.found { "variadic" } else { "non-variadic" })
5353 }
5354 terr_convergence_mismatch(ref values) => {
5355 write!(f, "expected {} fn, found {} function",
5356 if values.expected { "converging" } else { "diverging" },
5357 if values.found { "converging" } else { "diverging" })
5358 }
5359 terr_projection_name_mismatched(ref values) => {
5360 write!(f, "expected {}, found {}",
5361 values.expected,
5362 values.found)
5363 }
5364 terr_projection_bounds_length(ref values) => {
5365 write!(f, "expected {} associated type bindings, found {}",
5366 values.expected,
5367 values.found)
5368 }
5369 }
5370 }
5371 }
5372
5373 pub fn note_and_explain_type_err<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>, sp: Span) {
5374 match *err {
5375 terr_regions_does_not_outlive(subregion, superregion) => {
5376 note_and_explain_region(cx, "", subregion, "...");
5377 note_and_explain_region(cx, "...does not necessarily outlive ",
5378 superregion, "");
5379 }
5380 terr_regions_not_same(region1, region2) => {
5381 note_and_explain_region(cx, "", region1, "...");
5382 note_and_explain_region(cx, "...is not the same lifetime as ",
5383 region2, "");
5384 }
5385 terr_regions_no_overlap(region1, region2) => {
5386 note_and_explain_region(cx, "", region1, "...");
5387 note_and_explain_region(cx, "...does not overlap ",
5388 region2, "");
5389 }
5390 terr_regions_insufficiently_polymorphic(_, conc_region) => {
5391 note_and_explain_region(cx,
5392 "concrete lifetime that was found is ",
5393 conc_region, "");
5394 }
5395 terr_regions_overly_polymorphic(_, ty::ReInfer(ty::ReVar(_))) => {
5396 // don't bother to print out the message below for
5397 // inference variables, it's not very illuminating.
5398 }
5399 terr_regions_overly_polymorphic(_, conc_region) => {
5400 note_and_explain_region(cx,
5401 "expected concrete lifetime is ",
5402 conc_region, "");
5403 }
5404 terr_sorts(values) => {
5405 let expected_str = ty_sort_string(cx, values.expected);
5406 let found_str = ty_sort_string(cx, values.found);
5407 if expected_str == found_str && expected_str == "closure" {
5408 cx.sess.span_note(sp, &format!("no two closures, even if identical, have the same \
5409 type"));
5410 cx.sess.span_help(sp, &format!("consider boxing your closure and/or \
5411 using it as a trait object"));
5412 }
5413 }
5414 _ => {}
5415 }
5416 }
5417
5418 pub fn provided_source(cx: &ctxt, id: ast::DefId) -> Option<ast::DefId> {
5419 cx.provided_method_sources.borrow().get(&id).cloned()
5420 }
5421
5422 pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
5423 -> Vec<Rc<Method<'tcx>>> {
5424 if is_local(id) {
5425 if let ItemTrait(_, _, _, ref ms) = cx.map.expect_item(id.node).node {
5426 ms.iter().filter_map(|ti| {
5427 if let ast::MethodTraitItem(_, Some(_)) = ti.node {
5428 match impl_or_trait_item(cx, ast_util::local_def(ti.id)) {
5429 MethodTraitItem(m) => Some(m),
5430 _ => {
5431 cx.sess.bug("provided_trait_methods(): \
5432 non-method item found from \
5433 looking up provided method?!")
5434 }
5435 }
5436 } else {
5437 None
5438 }
5439 }).collect()
5440 } else {
5441 cx.sess.bug(&format!("provided_trait_methods: `{:?}` is not a trait", id))
5442 }
5443 } else {
5444 csearch::get_provided_trait_methods(cx, id)
5445 }
5446 }
5447
5448 pub fn associated_consts<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
5449 -> Vec<Rc<AssociatedConst<'tcx>>> {
5450 if is_local(id) {
5451 match cx.map.expect_item(id.node).node {
5452 ItemTrait(_, _, _, ref tis) => {
5453 tis.iter().filter_map(|ti| {
5454 if let ast::ConstTraitItem(_, _) = ti.node {
5455 match impl_or_trait_item(cx, ast_util::local_def(ti.id)) {
5456 ConstTraitItem(ac) => Some(ac),
5457 _ => {
5458 cx.sess.bug("associated_consts(): \
5459 non-const item found from \
5460 looking up a constant?!")
5461 }
5462 }
5463 } else {
5464 None
5465 }
5466 }).collect()
5467 }
5468 ItemImpl(_, _, _, _, _, ref iis) => {
5469 iis.iter().filter_map(|ii| {
5470 if let ast::ConstImplItem(_, _) = ii.node {
5471 match impl_or_trait_item(cx, ast_util::local_def(ii.id)) {
5472 ConstTraitItem(ac) => Some(ac),
5473 _ => {
5474 cx.sess.bug("associated_consts(): \
5475 non-const item found from \
5476 looking up a constant?!")
5477 }
5478 }
5479 } else {
5480 None
5481 }
5482 }).collect()
5483 }
5484 _ => {
5485 cx.sess.bug(&format!("associated_consts: `{:?}` is not a trait \
5486 or impl", id))
5487 }
5488 }
5489 } else {
5490 csearch::get_associated_consts(cx, id)
5491 }
5492 }
5493
5494 /// Helper for looking things up in the various maps that are populated during
5495 /// typeck::collect (e.g., `cx.impl_or_trait_items`, `cx.tcache`, etc). All of
5496 /// these share the pattern that if the id is local, it should have been loaded
5497 /// into the map by the `typeck::collect` phase. If the def-id is external,
5498 /// then we have to go consult the crate loading code (and cache the result for
5499 /// the future).
5500 fn lookup_locally_or_in_crate_store<V, F>(descr: &str,
5501 def_id: ast::DefId,
5502 map: &RefCell<DefIdMap<V>>,
5503 load_external: F) -> V where
5504 V: Clone,
5505 F: FnOnce() -> V,
5506 {
5507 match map.borrow().get(&def_id).cloned() {
5508 Some(v) => { return v; }
5509 None => { }
5510 }
5511
5512 if def_id.krate == ast::LOCAL_CRATE {
5513 panic!("No def'n found for {:?} in tcx.{}", def_id, descr);
5514 }
5515 let v = load_external();
5516 map.borrow_mut().insert(def_id, v.clone());
5517 v
5518 }
5519
5520 pub fn trait_item<'tcx>(cx: &ctxt<'tcx>, trait_did: ast::DefId, idx: usize)
5521 -> ImplOrTraitItem<'tcx> {
5522 let method_def_id = (*ty::trait_item_def_ids(cx, trait_did))[idx].def_id();
5523 impl_or_trait_item(cx, method_def_id)
5524 }
5525
5526 pub fn trait_items<'tcx>(cx: &ctxt<'tcx>, trait_did: ast::DefId)
5527 -> Rc<Vec<ImplOrTraitItem<'tcx>>> {
5528 let mut trait_items = cx.trait_items_cache.borrow_mut();
5529 match trait_items.get(&trait_did).cloned() {
5530 Some(trait_items) => trait_items,
5531 None => {
5532 let def_ids = ty::trait_item_def_ids(cx, trait_did);
5533 let items: Rc<Vec<ImplOrTraitItem>> =
5534 Rc::new(def_ids.iter()
5535 .map(|d| impl_or_trait_item(cx, d.def_id()))
5536 .collect());
5537 trait_items.insert(trait_did, items.clone());
5538 items
5539 }
5540 }
5541 }
5542
5543 pub fn trait_impl_polarity<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
5544 -> Option<ast::ImplPolarity> {
5545 if id.krate == ast::LOCAL_CRATE {
5546 match cx.map.find(id.node) {
5547 Some(ast_map::NodeItem(item)) => {
5548 match item.node {
5549 ast::ItemImpl(_, polarity, _, _, _, _) => Some(polarity),
5550 _ => None
5551 }
5552 }
5553 _ => None
5554 }
5555 } else {
5556 csearch::get_impl_polarity(cx, id)
5557 }
5558 }
5559
5560 pub fn custom_coerce_unsized_kind<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
5561 -> CustomCoerceUnsized {
5562 memoized(&cx.custom_coerce_unsized_kinds, did, |did: DefId| {
5563 let (kind, src) = if did.krate != ast::LOCAL_CRATE {
5564 (csearch::get_custom_coerce_unsized_kind(cx, did), "external")
5565 } else {
5566 (None, "local")
5567 };
5568
5569 match kind {
5570 Some(kind) => kind,
5571 None => {
5572 cx.sess.bug(&format!("custom_coerce_unsized_kind: \
5573 {} impl `{}` is missing its kind",
5574 src, item_path_str(cx, did)));
5575 }
5576 }
5577 })
5578 }
5579
5580 pub fn impl_or_trait_item<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
5581 -> ImplOrTraitItem<'tcx> {
5582 lookup_locally_or_in_crate_store(
5583 "impl_or_trait_items", id, &cx.impl_or_trait_items,
5584 || csearch::get_impl_or_trait_item(cx, id))
5585 }
5586
5587 /// Returns the parameter index that the given associated type corresponds to.
5588 pub fn associated_type_parameter_index(cx: &ctxt,
5589 trait_def: &TraitDef,
5590 associated_type_id: ast::DefId)
5591 -> usize {
5592 for type_parameter_def in &trait_def.generics.types {
5593 if type_parameter_def.def_id == associated_type_id {
5594 return type_parameter_def.index as usize
5595 }
5596 }
5597 cx.sess.bug("couldn't find associated type parameter index")
5598 }
5599
5600 pub fn trait_item_def_ids(cx: &ctxt, id: ast::DefId)
5601 -> Rc<Vec<ImplOrTraitItemId>> {
5602 lookup_locally_or_in_crate_store(
5603 "trait_item_def_ids", id, &cx.trait_item_def_ids,
5604 || Rc::new(csearch::get_trait_item_def_ids(&cx.sess.cstore, id)))
5605 }
5606
5607 /// Returns the trait-ref corresponding to a given impl, or None if it is
5608 /// an inherent impl.
5609 pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
5610 -> Option<TraitRef<'tcx>>
5611 {
5612 lookup_locally_or_in_crate_store(
5613 "impl_trait_refs", id, &cx.impl_trait_refs,
5614 || csearch::get_impl_trait(cx, id))
5615 }
5616
5617 /// Returns whether this DefId refers to an impl
5618 pub fn is_impl<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) -> bool {
5619 if id.krate == ast::LOCAL_CRATE {
5620 if let Some(ast_map::NodeItem(
5621 &ast::Item { node: ast::ItemImpl(..), .. })) = cx.map.find(id.node) {
5622 true
5623 } else {
5624 false
5625 }
5626 } else {
5627 csearch::is_impl(&cx.sess.cstore, id)
5628 }
5629 }
5630
5631 pub fn trait_ref_to_def_id(tcx: &ctxt, tr: &ast::TraitRef) -> ast::DefId {
5632 tcx.def_map.borrow().get(&tr.ref_id).expect("no def-map entry for trait").def_id()
5633 }
5634
5635 pub fn try_add_builtin_trait(
5636 tcx: &ctxt,
5637 trait_def_id: ast::DefId,
5638 builtin_bounds: &mut EnumSet<BuiltinBound>)
5639 -> bool
5640 {
5641 //! Checks whether `trait_ref` refers to one of the builtin
5642 //! traits, like `Send`, and adds the corresponding
5643 //! bound to the set `builtin_bounds` if so. Returns true if `trait_ref`
5644 //! is a builtin trait.
5645
5646 match tcx.lang_items.to_builtin_kind(trait_def_id) {
5647 Some(bound) => { builtin_bounds.insert(bound); true }
5648 None => false
5649 }
5650 }
5651
5652 pub fn ty_to_def_id(ty: Ty) -> Option<ast::DefId> {
5653 match ty.sty {
5654 TyTrait(ref tt) =>
5655 Some(tt.principal_def_id()),
5656 TyStruct(id, _) |
5657 TyEnum(id, _) |
5658 TyClosure(id, _) =>
5659 Some(id),
5660 _ =>
5661 None
5662 }
5663 }
5664
5665 // Enum information
5666 #[derive(Clone)]
5667 pub struct VariantInfo<'tcx> {
5668 pub args: Vec<Ty<'tcx>>,
5669 pub arg_names: Option<Vec<ast::Name>>,
5670 pub ctor_ty: Option<Ty<'tcx>>,
5671 pub name: ast::Name,
5672 pub id: ast::DefId,
5673 pub disr_val: Disr,
5674 pub vis: Visibility
5675 }
5676
5677 impl<'tcx> VariantInfo<'tcx> {
5678
5679 /// Creates a new VariantInfo from the corresponding ast representation.
5680 ///
5681 /// Does not do any caching of the value in the type context.
5682 pub fn from_ast_variant(cx: &ctxt<'tcx>,
5683 ast_variant: &ast::Variant,
5684 discriminant: Disr) -> VariantInfo<'tcx> {
5685 let ctor_ty = node_id_to_type(cx, ast_variant.node.id);
5686
5687 match ast_variant.node.kind {
5688 ast::TupleVariantKind(ref args) => {
5689 let arg_tys = if !args.is_empty() {
5690 // the regions in the argument types come from the
5691 // enum def'n, and hence will all be early bound
5692 ty::no_late_bound_regions(cx, &ty_fn_args(ctor_ty)).unwrap()
5693 } else {
5694 Vec::new()
5695 };
5696
5697 return VariantInfo {
5698 args: arg_tys,
5699 arg_names: None,
5700 ctor_ty: Some(ctor_ty),
5701 name: ast_variant.node.name.name,
5702 id: ast_util::local_def(ast_variant.node.id),
5703 disr_val: discriminant,
5704 vis: ast_variant.node.vis
5705 };
5706 },
5707 ast::StructVariantKind(ref struct_def) => {
5708 let fields: &[StructField] = &struct_def.fields;
5709
5710 assert!(!fields.is_empty());
5711
5712 let arg_tys = struct_def.fields.iter()
5713 .map(|field| node_id_to_type(cx, field.node.id)).collect();
5714 let arg_names = fields.iter().map(|field| {
5715 match field.node.kind {
5716 NamedField(ident, _) => ident.name,
5717 UnnamedField(..) => cx.sess.bug(
5718 "enum_variants: all fields in struct must have a name")
5719 }
5720 }).collect();
5721
5722 return VariantInfo {
5723 args: arg_tys,
5724 arg_names: Some(arg_names),
5725 ctor_ty: None,
5726 name: ast_variant.node.name.name,
5727 id: ast_util::local_def(ast_variant.node.id),
5728 disr_val: discriminant,
5729 vis: ast_variant.node.vis
5730 };
5731 }
5732 }
5733 }
5734 }
5735
5736 pub fn substd_enum_variants<'tcx>(cx: &ctxt<'tcx>,
5737 id: ast::DefId,
5738 substs: &Substs<'tcx>)
5739 -> Vec<Rc<VariantInfo<'tcx>>> {
5740 enum_variants(cx, id).iter().map(|variant_info| {
5741 let substd_args = variant_info.args.iter()
5742 .map(|aty| aty.subst(cx, substs)).collect::<Vec<_>>();
5743
5744 let substd_ctor_ty = variant_info.ctor_ty.subst(cx, substs);
5745
5746 Rc::new(VariantInfo {
5747 args: substd_args,
5748 ctor_ty: substd_ctor_ty,
5749 ..(**variant_info).clone()
5750 })
5751 }).collect()
5752 }
5753
5754 pub fn item_path_str(cx: &ctxt, id: ast::DefId) -> String {
5755 with_path(cx, id, |path| ast_map::path_to_string(path)).to_string()
5756 }
5757
5758 #[derive(Copy, Clone)]
5759 pub enum DtorKind {
5760 NoDtor,
5761 TraitDtor(DefId, bool)
5762 }
5763
5764 impl DtorKind {
5765 pub fn is_present(&self) -> bool {
5766 match *self {
5767 TraitDtor(..) => true,
5768 _ => false
5769 }
5770 }
5771
5772 pub fn has_drop_flag(&self) -> bool {
5773 match self {
5774 &NoDtor => false,
5775 &TraitDtor(_, flag) => flag
5776 }
5777 }
5778 }
5779
5780 /* If struct_id names a struct with a dtor. */
5781 pub fn ty_dtor(cx: &ctxt, struct_id: DefId) -> DtorKind {
5782 match cx.destructor_for_type.borrow().get(&struct_id) {
5783 Some(&method_def_id) => {
5784 let flag = !has_attr(cx, struct_id, "unsafe_no_drop_flag");
5785
5786 TraitDtor(method_def_id, flag)
5787 }
5788 None => NoDtor,
5789 }
5790 }
5791
5792 pub fn has_dtor(cx: &ctxt, struct_id: DefId) -> bool {
5793 cx.destructor_for_type.borrow().contains_key(&struct_id)
5794 }
5795
5796 pub fn with_path<T, F>(cx: &ctxt, id: ast::DefId, f: F) -> T where
5797 F: FnOnce(ast_map::PathElems) -> T,
5798 {
5799 if id.krate == ast::LOCAL_CRATE {
5800 cx.map.with_path(id.node, f)
5801 } else {
5802 f(csearch::get_item_path(cx, id).iter().cloned().chain(LinkedPath::empty()))
5803 }
5804 }
5805
5806 pub fn enum_is_univariant(cx: &ctxt, id: ast::DefId) -> bool {
5807 enum_variants(cx, id).len() == 1
5808 }
5809
5810 pub fn type_is_empty(cx: &ctxt, ty: Ty) -> bool {
5811 match ty.sty {
5812 TyEnum(did, _) => (*enum_variants(cx, did)).is_empty(),
5813 _ => false
5814 }
5815 }
5816
5817 trait IntTypeExt {
5818 fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx>;
5819 fn i64_to_disr(&self, val: i64) -> Option<Disr>;
5820 fn u64_to_disr(&self, val: u64) -> Option<Disr>;
5821 fn disr_incr(&self, val: Disr) -> Option<Disr>;
5822 fn disr_string(&self, val: Disr) -> String;
5823 fn disr_wrap_incr(&self, val: Option<Disr>) -> Disr;
5824 }
5825
5826 impl IntTypeExt for attr::IntType {
5827 fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx> {
5828 match *self {
5829 SignedInt(ast::TyI8) => cx.types.i8,
5830 SignedInt(ast::TyI16) => cx.types.i16,
5831 SignedInt(ast::TyI32) => cx.types.i32,
5832 SignedInt(ast::TyI64) => cx.types.i64,
5833 SignedInt(ast::TyIs) => cx.types.isize,
5834 UnsignedInt(ast::TyU8) => cx.types.u8,
5835 UnsignedInt(ast::TyU16) => cx.types.u16,
5836 UnsignedInt(ast::TyU32) => cx.types.u32,
5837 UnsignedInt(ast::TyU64) => cx.types.u64,
5838 UnsignedInt(ast::TyUs) => cx.types.usize,
5839 }
5840 }
5841
5842 fn i64_to_disr(&self, val: i64) -> Option<Disr> {
5843 match *self {
5844 SignedInt(ast::TyI8) => val.to_i8() .map(|v| v as Disr),
5845 SignedInt(ast::TyI16) => val.to_i16() .map(|v| v as Disr),
5846 SignedInt(ast::TyI32) => val.to_i32() .map(|v| v as Disr),
5847 SignedInt(ast::TyI64) => val.to_i64() .map(|v| v as Disr),
5848 UnsignedInt(ast::TyU8) => val.to_u8() .map(|v| v as Disr),
5849 UnsignedInt(ast::TyU16) => val.to_u16() .map(|v| v as Disr),
5850 UnsignedInt(ast::TyU32) => val.to_u32() .map(|v| v as Disr),
5851 UnsignedInt(ast::TyU64) => val.to_u64() .map(|v| v as Disr),
5852
5853 UnsignedInt(ast::TyUs) |
5854 SignedInt(ast::TyIs) => unreachable!(),
5855 }
5856 }
5857
5858 fn u64_to_disr(&self, val: u64) -> Option<Disr> {
5859 match *self {
5860 SignedInt(ast::TyI8) => val.to_i8() .map(|v| v as Disr),
5861 SignedInt(ast::TyI16) => val.to_i16() .map(|v| v as Disr),
5862 SignedInt(ast::TyI32) => val.to_i32() .map(|v| v as Disr),
5863 SignedInt(ast::TyI64) => val.to_i64() .map(|v| v as Disr),
5864 UnsignedInt(ast::TyU8) => val.to_u8() .map(|v| v as Disr),
5865 UnsignedInt(ast::TyU16) => val.to_u16() .map(|v| v as Disr),
5866 UnsignedInt(ast::TyU32) => val.to_u32() .map(|v| v as Disr),
5867 UnsignedInt(ast::TyU64) => val.to_u64() .map(|v| v as Disr),
5868
5869 UnsignedInt(ast::TyUs) |
5870 SignedInt(ast::TyIs) => unreachable!(),
5871 }
5872 }
5873
5874 fn disr_incr(&self, val: Disr) -> Option<Disr> {
5875 macro_rules! add1 {
5876 ($e:expr) => { $e.and_then(|v|v.checked_add(1)).map(|v| v as Disr) }
5877 }
5878 match *self {
5879 // SignedInt repr means we *want* to reinterpret the bits
5880 // treating the highest bit of Disr as a sign-bit, so
5881 // cast to i64 before range-checking.
5882 SignedInt(ast::TyI8) => add1!((val as i64).to_i8()),
5883 SignedInt(ast::TyI16) => add1!((val as i64).to_i16()),
5884 SignedInt(ast::TyI32) => add1!((val as i64).to_i32()),
5885 SignedInt(ast::TyI64) => add1!(Some(val as i64)),
5886
5887 UnsignedInt(ast::TyU8) => add1!(val.to_u8()),
5888 UnsignedInt(ast::TyU16) => add1!(val.to_u16()),
5889 UnsignedInt(ast::TyU32) => add1!(val.to_u32()),
5890 UnsignedInt(ast::TyU64) => add1!(Some(val)),
5891
5892 UnsignedInt(ast::TyUs) |
5893 SignedInt(ast::TyIs) => unreachable!(),
5894 }
5895 }
5896
5897 // This returns a String because (1.) it is only used for
5898 // rendering an error message and (2.) a string can represent the
5899 // full range from `i64::MIN` through `u64::MAX`.
5900 fn disr_string(&self, val: Disr) -> String {
5901 match *self {
5902 SignedInt(ast::TyI8) => format!("{}", val as i8 ),
5903 SignedInt(ast::TyI16) => format!("{}", val as i16),
5904 SignedInt(ast::TyI32) => format!("{}", val as i32),
5905 SignedInt(ast::TyI64) => format!("{}", val as i64),
5906 UnsignedInt(ast::TyU8) => format!("{}", val as u8 ),
5907 UnsignedInt(ast::TyU16) => format!("{}", val as u16),
5908 UnsignedInt(ast::TyU32) => format!("{}", val as u32),
5909 UnsignedInt(ast::TyU64) => format!("{}", val as u64),
5910
5911 UnsignedInt(ast::TyUs) |
5912 SignedInt(ast::TyIs) => unreachable!(),
5913 }
5914 }
5915
5916 fn disr_wrap_incr(&self, val: Option<Disr>) -> Disr {
5917 macro_rules! add1 {
5918 ($e:expr) => { ($e).wrapping_add(1) as Disr }
5919 }
5920 let val = val.unwrap_or(ty::INITIAL_DISCRIMINANT_VALUE);
5921 match *self {
5922 SignedInt(ast::TyI8) => add1!(val as i8 ),
5923 SignedInt(ast::TyI16) => add1!(val as i16),
5924 SignedInt(ast::TyI32) => add1!(val as i32),
5925 SignedInt(ast::TyI64) => add1!(val as i64),
5926 UnsignedInt(ast::TyU8) => add1!(val as u8 ),
5927 UnsignedInt(ast::TyU16) => add1!(val as u16),
5928 UnsignedInt(ast::TyU32) => add1!(val as u32),
5929 UnsignedInt(ast::TyU64) => add1!(val as u64),
5930
5931 UnsignedInt(ast::TyUs) |
5932 SignedInt(ast::TyIs) => unreachable!(),
5933 }
5934 }
5935 }
5936
5937 /// Returns `(normalized_type, ty)`, where `normalized_type` is the
5938 /// IntType representation of one of {i64,i32,i16,i8,u64,u32,u16,u8},
5939 /// and `ty` is the original type (i.e. may include `isize` or
5940 /// `usize`).
5941 pub fn enum_repr_type<'tcx>(cx: &ctxt<'tcx>,
5942 opt_hint: Option<&attr::ReprAttr>)
5943 -> (attr::IntType, Ty<'tcx>)
5944 {
5945 let repr_type = match opt_hint {
5946 // Feed in the given type
5947 Some(&attr::ReprInt(_, int_t)) => int_t,
5948 // ... but provide sensible default if none provided
5949 //
5950 // NB. Historically `fn enum_variants` generate i64 here, while
5951 // rustc_typeck::check would generate isize.
5952 _ => SignedInt(ast::TyIs),
5953 };
5954
5955 let repr_type_ty = repr_type.to_ty(cx);
5956 let repr_type = match repr_type {
5957 SignedInt(ast::TyIs) =>
5958 SignedInt(cx.sess.target.int_type),
5959 UnsignedInt(ast::TyUs) =>
5960 UnsignedInt(cx.sess.target.uint_type),
5961 other => other
5962 };
5963
5964 (repr_type, repr_type_ty)
5965 }
5966
5967 fn report_discrim_overflow(cx: &ctxt,
5968 variant_span: Span,
5969 variant_name: &str,
5970 repr_type: attr::IntType,
5971 prev_val: Disr) {
5972 let computed_value = repr_type.disr_wrap_incr(Some(prev_val));
5973 let computed_value = repr_type.disr_string(computed_value);
5974 let prev_val = repr_type.disr_string(prev_val);
5975 let repr_type = repr_type.to_ty(cx);
5976 span_err!(cx.sess, variant_span, E0370,
5977 "enum discriminant overflowed on value after {}: {}; \
5978 set explicitly via {} = {} if that is desired outcome",
5979 prev_val, repr_type, variant_name, computed_value);
5980 }
5981
5982 // This computes the discriminant values for the sequence of Variants
5983 // attached to a particular enum, taking into account the #[repr] (if
5984 // any) provided via the `opt_hint`.
5985 fn compute_enum_variants<'tcx>(cx: &ctxt<'tcx>,
5986 vs: &'tcx [P<ast::Variant>],
5987 opt_hint: Option<&attr::ReprAttr>)
5988 -> Vec<Rc<ty::VariantInfo<'tcx>>> {
5989 let mut variants: Vec<Rc<ty::VariantInfo>> = Vec::new();
5990 let mut prev_disr_val: Option<ty::Disr> = None;
5991
5992 let (repr_type, repr_type_ty) = ty::enum_repr_type(cx, opt_hint);
5993
5994 for v in vs {
5995 // If the discriminant value is specified explicitly in the
5996 // enum, check whether the initialization expression is valid,
5997 // otherwise use the last value plus one.
5998 let current_disr_val;
5999
6000 // This closure marks cases where, when an error occurs during
6001 // the computation, attempt to assign a (hopefully) fresh
6002 // value to avoid spurious error reports downstream.
6003 let attempt_fresh_value = move || -> Disr {
6004 repr_type.disr_wrap_incr(prev_disr_val)
6005 };
6006
6007 match v.node.disr_expr {
6008 Some(ref e) => {
6009 debug!("disr expr, checking {}", pprust::expr_to_string(&**e));
6010
6011 // check_expr (from check_const pass) doesn't guarantee
6012 // that the expression is in a form that eval_const_expr can
6013 // handle, so we may still get an internal compiler error
6014 //
6015 // pnkfelix: The above comment was transcribed from
6016 // the version of this code taken from rustc_typeck.
6017 // Presumably the implication is that we need to deal
6018 // with such ICE's as they arise.
6019 //
6020 // Since this can be called from `ty::enum_variants`
6021 // anyway, best thing is to make `eval_const_expr`
6022 // more robust (on case-by-case basis).
6023
6024 match const_eval::eval_const_expr_partial(cx, &**e, Some(repr_type_ty)) {
6025 Ok(ConstVal::Int(val)) => current_disr_val = val as Disr,
6026 Ok(ConstVal::Uint(val)) => current_disr_val = val as Disr,
6027 Ok(_) => {
6028 let sign_desc = if repr_type.is_signed() { "signed" } else { "unsigned" };
6029 span_err!(cx.sess, e.span, E0079,
6030 "expected {} integer constant",
6031 sign_desc);
6032 current_disr_val = attempt_fresh_value();
6033 }
6034 Err(ref err) => {
6035 span_err!(cx.sess, err.span, E0080,
6036 "constant evaluation error: {}",
6037 err.description());
6038 current_disr_val = attempt_fresh_value();
6039 }
6040 }
6041 },
6042 None => {
6043 current_disr_val = match prev_disr_val {
6044 Some(prev_disr_val) => {
6045 if let Some(v) = repr_type.disr_incr(prev_disr_val) {
6046 v
6047 } else {
6048 report_discrim_overflow(cx, v.span, v.node.name.as_str(),
6049 repr_type, prev_disr_val);
6050 attempt_fresh_value()
6051 }
6052 }
6053 None => ty::INITIAL_DISCRIMINANT_VALUE
6054 }
6055 }
6056 }
6057
6058 let variant_info = Rc::new(VariantInfo::from_ast_variant(cx, &**v, current_disr_val));
6059 prev_disr_val = Some(current_disr_val);
6060
6061 variants.push(variant_info);
6062 }
6063
6064 return variants;
6065 }
6066
6067 pub fn enum_variants<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
6068 -> Rc<Vec<Rc<VariantInfo<'tcx>>>> {
6069 memoized(&cx.enum_var_cache, id, |id: ast::DefId| {
6070 if ast::LOCAL_CRATE != id.krate {
6071 Rc::new(csearch::get_enum_variants(cx, id))
6072 } else {
6073 match cx.map.get(id.node) {
6074 ast_map::NodeItem(ref item) => {
6075 match item.node {
6076 ast::ItemEnum(ref enum_definition, _) => {
6077 Rc::new(compute_enum_variants(
6078 cx,
6079 &enum_definition.variants,
6080 lookup_repr_hints(cx, id).get(0)))
6081 }
6082 _ => {
6083 cx.sess.bug("enum_variants: id not bound to an enum")
6084 }
6085 }
6086 }
6087 _ => cx.sess.bug("enum_variants: id not bound to an enum")
6088 }
6089 }
6090 })
6091 }
6092
6093 // Returns information about the enum variant with the given ID:
6094 pub fn enum_variant_with_id<'tcx>(cx: &ctxt<'tcx>,
6095 enum_id: ast::DefId,
6096 variant_id: ast::DefId)
6097 -> Rc<VariantInfo<'tcx>> {
6098 enum_variants(cx, enum_id).iter()
6099 .find(|variant| variant.id == variant_id)
6100 .expect("enum_variant_with_id(): no variant exists with that ID")
6101 .clone()
6102 }
6103
6104
6105 // If the given item is in an external crate, looks up its type and adds it to
6106 // the type cache. Returns the type parameters and type.
6107 pub fn lookup_item_type<'tcx>(cx: &ctxt<'tcx>,
6108 did: ast::DefId)
6109 -> TypeScheme<'tcx> {
6110 lookup_locally_or_in_crate_store(
6111 "tcache", did, &cx.tcache,
6112 || csearch::get_type(cx, did))
6113 }
6114
6115 /// Given the did of a trait, returns its canonical trait ref.
6116 pub fn lookup_trait_def<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
6117 -> &'tcx TraitDef<'tcx> {
6118 lookup_locally_or_in_crate_store(
6119 "trait_defs", did, &cx.trait_defs,
6120 || cx.arenas.trait_defs.alloc(csearch::get_trait_def(cx, did))
6121 )
6122 }
6123
6124 /// Given the did of an item, returns its full set of predicates.
6125 pub fn lookup_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
6126 -> GenericPredicates<'tcx>
6127 {
6128 lookup_locally_or_in_crate_store(
6129 "predicates", did, &cx.predicates,
6130 || csearch::get_predicates(cx, did))
6131 }
6132
6133 /// Given the did of a trait, returns its superpredicates.
6134 pub fn lookup_super_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
6135 -> GenericPredicates<'tcx>
6136 {
6137 lookup_locally_or_in_crate_store(
6138 "super_predicates", did, &cx.super_predicates,
6139 || csearch::get_super_predicates(cx, did))
6140 }
6141
6142 /// Get the attributes of a definition.
6143 pub fn get_attrs<'tcx>(tcx: &'tcx ctxt, did: DefId)
6144 -> Cow<'tcx, [ast::Attribute]> {
6145 if is_local(did) {
6146 Cow::Borrowed(tcx.map.attrs(did.node))
6147 } else {
6148 Cow::Owned(csearch::get_item_attrs(&tcx.sess.cstore, did))
6149 }
6150 }
6151
6152 /// Determine whether an item is annotated with an attribute
6153 pub fn has_attr(tcx: &ctxt, did: DefId, attr: &str) -> bool {
6154 get_attrs(tcx, did).iter().any(|item| item.check_name(attr))
6155 }
6156
6157 /// Determine whether an item is annotated with `#[repr(packed)]`
6158 pub fn lookup_packed(tcx: &ctxt, did: DefId) -> bool {
6159 lookup_repr_hints(tcx, did).contains(&attr::ReprPacked)
6160 }
6161
6162 /// Determine whether an item is annotated with `#[simd]`
6163 pub fn lookup_simd(tcx: &ctxt, did: DefId) -> bool {
6164 has_attr(tcx, did, "simd")
6165 }
6166
6167 /// Obtain the representation annotation for a struct definition.
6168 pub fn lookup_repr_hints(tcx: &ctxt, did: DefId) -> Rc<Vec<attr::ReprAttr>> {
6169 memoized(&tcx.repr_hint_cache, did, |did: DefId| {
6170 Rc::new(if did.krate == LOCAL_CRATE {
6171 get_attrs(tcx, did).iter().flat_map(|meta| {
6172 attr::find_repr_attrs(tcx.sess.diagnostic(), meta).into_iter()
6173 }).collect()
6174 } else {
6175 csearch::get_repr_attrs(&tcx.sess.cstore, did)
6176 })
6177 })
6178 }
6179
6180 // Look up a field ID, whether or not it's local
6181 pub fn lookup_field_type_unsubstituted<'tcx>(tcx: &ctxt<'tcx>,
6182 struct_id: DefId,
6183 id: DefId)
6184 -> Ty<'tcx> {
6185 if id.krate == ast::LOCAL_CRATE {
6186 node_id_to_type(tcx, id.node)
6187 } else {
6188 let mut tcache = tcx.tcache.borrow_mut();
6189 tcache.entry(id).or_insert_with(|| csearch::get_field_type(tcx, struct_id, id)).ty
6190 }
6191 }
6192
6193
6194 // Look up a field ID, whether or not it's local
6195 // Takes a list of type substs in case the struct is generic
6196 pub fn lookup_field_type<'tcx>(tcx: &ctxt<'tcx>,
6197 struct_id: DefId,
6198 id: DefId,
6199 substs: &Substs<'tcx>)
6200 -> Ty<'tcx> {
6201 lookup_field_type_unsubstituted(tcx, struct_id, id).subst(tcx, substs)
6202 }
6203
6204 // Look up the list of field names and IDs for a given struct.
6205 // Panics if the id is not bound to a struct.
6206 pub fn lookup_struct_fields(cx: &ctxt, did: ast::DefId) -> Vec<field_ty> {
6207 if did.krate == ast::LOCAL_CRATE {
6208 let struct_fields = cx.struct_fields.borrow();
6209 match struct_fields.get(&did) {
6210 Some(fields) => (**fields).clone(),
6211 _ => {
6212 cx.sess.bug(
6213 &format!("ID not mapped to struct fields: {}",
6214 cx.map.node_to_string(did.node)));
6215 }
6216 }
6217 } else {
6218 csearch::get_struct_fields(&cx.sess.cstore, did)
6219 }
6220 }
6221
6222 pub fn is_tuple_struct(cx: &ctxt, did: ast::DefId) -> bool {
6223 let fields = lookup_struct_fields(cx, did);
6224 !fields.is_empty() && fields.iter().all(|f| f.name == token::special_names::unnamed_field)
6225 }
6226
6227 // Returns a list of fields corresponding to the struct's items. trans uses
6228 // this. Takes a list of substs with which to instantiate field types.
6229 pub fn struct_fields<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId, substs: &Substs<'tcx>)
6230 -> Vec<field<'tcx>> {
6231 lookup_struct_fields(cx, did).iter().map(|f| {
6232 field {
6233 name: f.name,
6234 mt: mt {
6235 ty: lookup_field_type(cx, did, f.id, substs),
6236 mutbl: MutImmutable
6237 }
6238 }
6239 }).collect()
6240 }
6241
6242 // Returns a list of fields corresponding to the tuple's items. trans uses
6243 // this.
6244 pub fn tup_fields<'tcx>(v: &[Ty<'tcx>]) -> Vec<field<'tcx>> {
6245 v.iter().enumerate().map(|(i, &f)| {
6246 field {
6247 name: token::intern(&i.to_string()),
6248 mt: mt {
6249 ty: f,
6250 mutbl: MutImmutable
6251 }
6252 }
6253 }).collect()
6254 }
6255
6256 /// Returns the deeply last field of nested structures, or the same type,
6257 /// if not a structure at all. Corresponds to the only possible unsized
6258 /// field, and its type can be used to determine unsizing strategy.
6259 pub fn struct_tail<'tcx>(cx: &ctxt<'tcx>, mut ty: Ty<'tcx>) -> Ty<'tcx> {
6260 while let TyStruct(def_id, substs) = ty.sty {
6261 match struct_fields(cx, def_id, substs).last() {
6262 Some(f) => ty = f.mt.ty,
6263 None => break
6264 }
6265 }
6266 ty
6267 }
6268
6269 /// Same as applying struct_tail on `source` and `target`, but only
6270 /// keeps going as long as the two types are instances of the same
6271 /// structure definitions.
6272 /// For `(Foo<Foo<T>>, Foo<Trait>)`, the result will be `(Foo<T>, Trait)`,
6273 /// whereas struct_tail produces `T`, and `Trait`, respectively.
6274 pub fn struct_lockstep_tails<'tcx>(cx: &ctxt<'tcx>,
6275 source: Ty<'tcx>,
6276 target: Ty<'tcx>)
6277 -> (Ty<'tcx>, Ty<'tcx>) {
6278 let (mut a, mut b) = (source, target);
6279 while let (&TyStruct(a_did, a_substs), &TyStruct(b_did, b_substs)) = (&a.sty, &b.sty) {
6280 if a_did != b_did {
6281 continue;
6282 }
6283 if let Some(a_f) = struct_fields(cx, a_did, a_substs).last() {
6284 if let Some(b_f) = struct_fields(cx, b_did, b_substs).last() {
6285 a = a_f.mt.ty;
6286 b = b_f.mt.ty;
6287 } else {
6288 break;
6289 }
6290 } else {
6291 break;
6292 }
6293 }
6294 (a, b)
6295 }
6296
6297 #[derive(Copy, Clone)]
6298 pub struct ClosureUpvar<'tcx> {
6299 pub def: def::Def,
6300 pub span: Span,
6301 pub ty: Ty<'tcx>,
6302 }
6303
6304 // Returns a list of `ClosureUpvar`s for each upvar.
6305 pub fn closure_upvars<'tcx>(typer: &mc::Typer<'tcx>,
6306 closure_id: ast::DefId,
6307 substs: &Substs<'tcx>)
6308 -> Option<Vec<ClosureUpvar<'tcx>>>
6309 {
6310 // Presently an unboxed closure type cannot "escape" out of a
6311 // function, so we will only encounter ones that originated in the
6312 // local crate or were inlined into it along with some function.
6313 // This may change if abstract return types of some sort are
6314 // implemented.
6315 assert!(closure_id.krate == ast::LOCAL_CRATE);
6316 let tcx = typer.tcx();
6317 match tcx.freevars.borrow().get(&closure_id.node) {
6318 None => Some(vec![]),
6319 Some(ref freevars) => {
6320 freevars.iter()
6321 .map(|freevar| {
6322 let freevar_def_id = freevar.def.def_id();
6323 let freevar_ty = match typer.node_ty(freevar_def_id.node) {
6324 Ok(t) => { t }
6325 Err(()) => { return None; }
6326 };
6327 let freevar_ty = freevar_ty.subst(tcx, substs);
6328
6329 let upvar_id = ty::UpvarId {
6330 var_id: freevar_def_id.node,
6331 closure_expr_id: closure_id.node
6332 };
6333
6334 typer.upvar_capture(upvar_id).map(|capture| {
6335 let freevar_ref_ty = match capture {
6336 UpvarCapture::ByValue => {
6337 freevar_ty
6338 }
6339 UpvarCapture::ByRef(borrow) => {
6340 mk_rptr(tcx,
6341 tcx.mk_region(borrow.region),
6342 ty::mt {
6343 ty: freevar_ty,
6344 mutbl: borrow.kind.to_mutbl_lossy(),
6345 })
6346 }
6347 };
6348
6349 ClosureUpvar {
6350 def: freevar.def,
6351 span: freevar.span,
6352 ty: freevar_ref_ty,
6353 }
6354 })
6355 })
6356 .collect()
6357 }
6358 }
6359 }
6360
6361 // Returns the repeat count for a repeating vector expression.
6362 pub fn eval_repeat_count(tcx: &ctxt, count_expr: &ast::Expr) -> usize {
6363 match const_eval::eval_const_expr_partial(tcx, count_expr, Some(tcx.types.usize)) {
6364 Ok(val) => {
6365 let found = match val {
6366 ConstVal::Uint(count) => return count as usize,
6367 ConstVal::Int(count) if count >= 0 => return count as usize,
6368 ConstVal::Int(_) => "negative integer",
6369 ConstVal::Float(_) => "float",
6370 ConstVal::Str(_) => "string",
6371 ConstVal::Bool(_) => "boolean",
6372 ConstVal::Binary(_) => "binary array",
6373 ConstVal::Struct(..) => "struct",
6374 ConstVal::Tuple(_) => "tuple"
6375 };
6376 span_err!(tcx.sess, count_expr.span, E0306,
6377 "expected positive integer for repeat count, found {}",
6378 found);
6379 }
6380 Err(err) => {
6381 let err_description = err.description();
6382 let found = match count_expr.node {
6383 ast::ExprPath(None, ast::Path {
6384 global: false,
6385 ref segments,
6386 ..
6387 }) if segments.len() == 1 =>
6388 format!("{}", "found variable"),
6389 _ =>
6390 format!("but {}", err_description),
6391 };
6392 span_err!(tcx.sess, count_expr.span, E0307,
6393 "expected constant integer for repeat count, {}",
6394 found);
6395 }
6396 }
6397 0
6398 }
6399
6400 // Iterate over a type parameter's bounded traits and any supertraits
6401 // of those traits, ignoring kinds.
6402 // Here, the supertraits are the transitive closure of the supertrait
6403 // relation on the supertraits from each bounded trait's constraint
6404 // list.
6405 pub fn each_bound_trait_and_supertraits<'tcx, F>(tcx: &ctxt<'tcx>,
6406 bounds: &[PolyTraitRef<'tcx>],
6407 mut f: F)
6408 -> bool where
6409 F: FnMut(PolyTraitRef<'tcx>) -> bool,
6410 {
6411 for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
6412 if !f(bound_trait_ref) {
6413 return false;
6414 }
6415 }
6416 return true;
6417 }
6418
6419 /// Given a set of predicates that apply to an object type, returns
6420 /// the region bounds that the (erased) `Self` type must
6421 /// outlive. Precisely *because* the `Self` type is erased, the
6422 /// parameter `erased_self_ty` must be supplied to indicate what type
6423 /// has been used to represent `Self` in the predicates
6424 /// themselves. This should really be a unique type; `FreshTy(0)` is a
6425 /// popular choice.
6426 ///
6427 /// Requires that trait definitions have been processed so that we can
6428 /// elaborate predicates and walk supertraits.
6429 pub fn required_region_bounds<'tcx>(tcx: &ctxt<'tcx>,
6430 erased_self_ty: Ty<'tcx>,
6431 predicates: Vec<ty::Predicate<'tcx>>)
6432 -> Vec<ty::Region>
6433 {
6434 debug!("required_region_bounds(erased_self_ty={:?}, predicates={:?})",
6435 erased_self_ty,
6436 predicates);
6437
6438 assert!(!erased_self_ty.has_escaping_regions());
6439
6440 traits::elaborate_predicates(tcx, predicates)
6441 .filter_map(|predicate| {
6442 match predicate {
6443 ty::Predicate::Projection(..) |
6444 ty::Predicate::Trait(..) |
6445 ty::Predicate::Equate(..) |
6446 ty::Predicate::RegionOutlives(..) => {
6447 None
6448 }
6449 ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(t, r))) => {
6450 // Search for a bound of the form `erased_self_ty
6451 // : 'a`, but be wary of something like `for<'a>
6452 // erased_self_ty : 'a` (we interpret a
6453 // higher-ranked bound like that as 'static,
6454 // though at present the code in `fulfill.rs`
6455 // considers such bounds to be unsatisfiable, so
6456 // it's kind of a moot point since you could never
6457 // construct such an object, but this seems
6458 // correct even if that code changes).
6459 if t == erased_self_ty && !r.has_escaping_regions() {
6460 if r.has_escaping_regions() {
6461 Some(ty::ReStatic)
6462 } else {
6463 Some(r)
6464 }
6465 } else {
6466 None
6467 }
6468 }
6469 }
6470 })
6471 .collect()
6472 }
6473
6474 pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc<ItemVariances> {
6475 lookup_locally_or_in_crate_store(
6476 "item_variance_map", item_id, &tcx.item_variance_map,
6477 || Rc::new(csearch::get_item_variances(&tcx.sess.cstore, item_id)))
6478 }
6479
6480 pub fn trait_has_default_impl(tcx: &ctxt, trait_def_id: DefId) -> bool {
6481 populate_implementations_for_trait_if_necessary(tcx, trait_def_id);
6482
6483 let def = lookup_trait_def(tcx, trait_def_id);
6484 def.flags.get().intersects(TraitFlags::HAS_DEFAULT_IMPL)
6485 }
6486
6487 /// Records a trait-to-implementation mapping.
6488 pub fn record_trait_has_default_impl(tcx: &ctxt, trait_def_id: DefId) {
6489 let def = lookup_trait_def(tcx, trait_def_id);
6490 def.flags.set(def.flags.get() | TraitFlags::HAS_DEFAULT_IMPL)
6491 }
6492
6493 /// Load primitive inherent implementations if necessary
6494 pub fn populate_implementations_for_primitive_if_necessary(tcx: &ctxt,
6495 primitive_def_id: ast::DefId) {
6496 if primitive_def_id.krate == LOCAL_CRATE {
6497 return
6498 }
6499
6500 if tcx.populated_external_primitive_impls.borrow().contains(&primitive_def_id) {
6501 return
6502 }
6503
6504 debug!("populate_implementations_for_primitive_if_necessary: searching for {:?}",
6505 primitive_def_id);
6506
6507 let impl_items = csearch::get_impl_items(&tcx.sess.cstore, primitive_def_id);
6508
6509 // Store the implementation info.
6510 tcx.impl_items.borrow_mut().insert(primitive_def_id, impl_items);
6511 tcx.populated_external_primitive_impls.borrow_mut().insert(primitive_def_id);
6512 }
6513
6514 /// Populates the type context with all the inherent implementations for
6515 /// the given type if necessary.
6516 pub fn populate_inherent_implementations_for_type_if_necessary(tcx: &ctxt,
6517 type_id: ast::DefId) {
6518 if type_id.krate == LOCAL_CRATE {
6519 return
6520 }
6521
6522 if tcx.populated_external_types.borrow().contains(&type_id) {
6523 return
6524 }
6525
6526 debug!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}", type_id);
6527
6528 let mut inherent_impls = Vec::new();
6529 csearch::each_inherent_implementation_for_type(&tcx.sess.cstore, type_id, |impl_def_id| {
6530 // Record the implementation.
6531 inherent_impls.push(impl_def_id);
6532
6533 // Store the implementation info.
6534 let impl_items = csearch::get_impl_items(&tcx.sess.cstore, impl_def_id);
6535 tcx.impl_items.borrow_mut().insert(impl_def_id, impl_items);
6536 });
6537
6538 tcx.inherent_impls.borrow_mut().insert(type_id, Rc::new(inherent_impls));
6539 tcx.populated_external_types.borrow_mut().insert(type_id);
6540 }
6541
6542 /// Populates the type context with all the implementations for the given
6543 /// trait if necessary.
6544 pub fn populate_implementations_for_trait_if_necessary(tcx: &ctxt, trait_id: ast::DefId) {
6545 if trait_id.krate == LOCAL_CRATE {
6546 return
6547 }
6548
6549 let def = lookup_trait_def(tcx, trait_id);
6550 if def.flags.get().intersects(TraitFlags::IMPLS_VALID) {
6551 return;
6552 }
6553
6554 debug!("populate_implementations_for_trait_if_necessary: searching for {:?}", def);
6555
6556 if csearch::is_defaulted_trait(&tcx.sess.cstore, trait_id) {
6557 record_trait_has_default_impl(tcx, trait_id);
6558 }
6559
6560 csearch::each_implementation_for_trait(&tcx.sess.cstore, trait_id, |implementation_def_id| {
6561 let impl_items = csearch::get_impl_items(&tcx.sess.cstore, implementation_def_id);
6562 let trait_ref = impl_trait_ref(tcx, implementation_def_id).unwrap();
6563 // Record the trait->implementation mapping.
6564 def.record_impl(tcx, implementation_def_id, trait_ref);
6565
6566 // For any methods that use a default implementation, add them to
6567 // the map. This is a bit unfortunate.
6568 for impl_item_def_id in &impl_items {
6569 let method_def_id = impl_item_def_id.def_id();
6570 match impl_or_trait_item(tcx, method_def_id) {
6571 MethodTraitItem(method) => {
6572 if let Some(source) = method.provided_source {
6573 tcx.provided_method_sources
6574 .borrow_mut()
6575 .insert(method_def_id, source);
6576 }
6577 }
6578 _ => {}
6579 }
6580 }
6581
6582 // Store the implementation info.
6583 tcx.impl_items.borrow_mut().insert(implementation_def_id, impl_items);
6584 });
6585
6586 def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID);
6587 }
6588
6589 /// Given the def_id of an impl, return the def_id of the trait it implements.
6590 /// If it implements no trait, return `None`.
6591 pub fn trait_id_of_impl(tcx: &ctxt,
6592 def_id: ast::DefId)
6593 -> Option<ast::DefId> {
6594 ty::impl_trait_ref(tcx, def_id).map(|tr| tr.def_id)
6595 }
6596
6597 /// If the given def ID describes a method belonging to an impl, return the
6598 /// ID of the impl that the method belongs to. Otherwise, return `None`.
6599 pub fn impl_of_method(tcx: &ctxt, def_id: ast::DefId)
6600 -> Option<ast::DefId> {
6601 if def_id.krate != LOCAL_CRATE {
6602 return match csearch::get_impl_or_trait_item(tcx,
6603 def_id).container() {
6604 TraitContainer(_) => None,
6605 ImplContainer(def_id) => Some(def_id),
6606 };
6607 }
6608 match tcx.impl_or_trait_items.borrow().get(&def_id).cloned() {
6609 Some(trait_item) => {
6610 match trait_item.container() {
6611 TraitContainer(_) => None,
6612 ImplContainer(def_id) => Some(def_id),
6613 }
6614 }
6615 None => None
6616 }
6617 }
6618
6619 /// If the given def ID describes an item belonging to a trait (either a
6620 /// default method or an implementation of a trait method), return the ID of
6621 /// the trait that the method belongs to. Otherwise, return `None`.
6622 pub fn trait_of_item(tcx: &ctxt, def_id: ast::DefId) -> Option<ast::DefId> {
6623 if def_id.krate != LOCAL_CRATE {
6624 return csearch::get_trait_of_item(&tcx.sess.cstore, def_id, tcx);
6625 }
6626 match tcx.impl_or_trait_items.borrow().get(&def_id).cloned() {
6627 Some(impl_or_trait_item) => {
6628 match impl_or_trait_item.container() {
6629 TraitContainer(def_id) => Some(def_id),
6630 ImplContainer(def_id) => trait_id_of_impl(tcx, def_id),
6631 }
6632 }
6633 None => None
6634 }
6635 }
6636
6637 /// If the given def ID describes an item belonging to a trait, (either a
6638 /// default method or an implementation of a trait method), return the ID of
6639 /// the method inside trait definition (this means that if the given def ID
6640 /// is already that of the original trait method, then the return value is
6641 /// the same).
6642 /// Otherwise, return `None`.
6643 pub fn trait_item_of_item(tcx: &ctxt, def_id: ast::DefId)
6644 -> Option<ImplOrTraitItemId> {
6645 let impl_item = match tcx.impl_or_trait_items.borrow().get(&def_id) {
6646 Some(m) => m.clone(),
6647 None => return None,
6648 };
6649 let name = impl_item.name();
6650 match trait_of_item(tcx, def_id) {
6651 Some(trait_did) => {
6652 let trait_items = ty::trait_items(tcx, trait_did);
6653 trait_items.iter()
6654 .position(|m| m.name() == name)
6655 .map(|idx| ty::trait_item(tcx, trait_did, idx).id())
6656 }
6657 None => None
6658 }
6659 }
6660
6661 /// Creates a hash of the type `Ty` which will be the same no matter what crate
6662 /// context it's calculated within. This is used by the `type_id` intrinsic.
6663 pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -> u64 {
6664 let mut state = SipHasher::new();
6665 helper(tcx, ty, svh, &mut state);
6666 return state.finish();
6667
6668 fn helper<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh,
6669 state: &mut SipHasher) {
6670 macro_rules! byte { ($b:expr) => { ($b as u8).hash(state) } }
6671 macro_rules! hash { ($e:expr) => { $e.hash(state) } }
6672
6673 let region = |state: &mut SipHasher, r: Region| {
6674 match r {
6675 ReStatic => {}
6676 ReLateBound(db, BrAnon(i)) => {
6677 db.hash(state);
6678 i.hash(state);
6679 }
6680 ReEmpty |
6681 ReEarlyBound(..) |
6682 ReLateBound(..) |
6683 ReFree(..) |
6684 ReScope(..) |
6685 ReInfer(..) => {
6686 tcx.sess.bug("unexpected region found when hashing a type")
6687 }
6688 }
6689 };
6690 let did = |state: &mut SipHasher, did: DefId| {
6691 let h = if ast_util::is_local(did) {
6692 svh.clone()
6693 } else {
6694 tcx.sess.cstore.get_crate_hash(did.krate)
6695 };
6696 h.as_str().hash(state);
6697 did.node.hash(state);
6698 };
6699 let mt = |state: &mut SipHasher, mt: mt| {
6700 mt.mutbl.hash(state);
6701 };
6702 let fn_sig = |state: &mut SipHasher, sig: &Binder<FnSig<'tcx>>| {
6703 let sig = anonymize_late_bound_regions(tcx, sig).0;
6704 for a in &sig.inputs { helper(tcx, *a, svh, state); }
6705 if let ty::FnConverging(output) = sig.output {
6706 helper(tcx, output, svh, state);
6707 }
6708 };
6709 maybe_walk_ty(ty, |ty| {
6710 match ty.sty {
6711 TyBool => byte!(2),
6712 TyChar => byte!(3),
6713 TyInt(i) => {
6714 byte!(4);
6715 hash!(i);
6716 }
6717 TyUint(u) => {
6718 byte!(5);
6719 hash!(u);
6720 }
6721 TyFloat(f) => {
6722 byte!(6);
6723 hash!(f);
6724 }
6725 TyStr => {
6726 byte!(7);
6727 }
6728 TyEnum(d, _) => {
6729 byte!(8);
6730 did(state, d);
6731 }
6732 TyBox(_) => {
6733 byte!(9);
6734 }
6735 TyArray(_, n) => {
6736 byte!(10);
6737 n.hash(state);
6738 }
6739 TySlice(_) => {
6740 byte!(11);
6741 }
6742 TyRawPtr(m) => {
6743 byte!(12);
6744 mt(state, m);
6745 }
6746 TyRef(r, m) => {
6747 byte!(13);
6748 region(state, *r);
6749 mt(state, m);
6750 }
6751 TyBareFn(opt_def_id, ref b) => {
6752 byte!(14);
6753 hash!(opt_def_id);
6754 hash!(b.unsafety);
6755 hash!(b.abi);
6756 fn_sig(state, &b.sig);
6757 return false;
6758 }
6759 TyTrait(ref data) => {
6760 byte!(17);
6761 did(state, data.principal_def_id());
6762 hash!(data.bounds);
6763
6764 let principal = anonymize_late_bound_regions(tcx, &data.principal).0;
6765 for subty in &principal.substs.types {
6766 helper(tcx, subty, svh, state);
6767 }
6768
6769 return false;
6770 }
6771 TyStruct(d, _) => {
6772 byte!(18);
6773 did(state, d);
6774 }
6775 TyTuple(ref inner) => {
6776 byte!(19);
6777 hash!(inner.len());
6778 }
6779 TyParam(p) => {
6780 byte!(20);
6781 hash!(p.space);
6782 hash!(p.idx);
6783 hash!(token::get_name(p.name));
6784 }
6785 TyInfer(_) => unreachable!(),
6786 TyError => byte!(21),
6787 TyClosure(d, _) => {
6788 byte!(22);
6789 did(state, d);
6790 }
6791 TyProjection(ref data) => {
6792 byte!(23);
6793 did(state, data.trait_ref.def_id);
6794 hash!(token::get_name(data.item_name));
6795 }
6796 }
6797 true
6798 });
6799 }
6800 }
6801
6802 impl fmt::Debug for Variance {
6803 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6804 f.write_str(match *self {
6805 Covariant => "+",
6806 Contravariant => "-",
6807 Invariant => "o",
6808 Bivariant => "*",
6809 })
6810 }
6811 }
6812
6813 /// Construct a parameter environment suitable for static contexts or other contexts where there
6814 /// are no free type/lifetime parameters in scope.
6815 pub fn empty_parameter_environment<'a,'tcx>(cx: &'a ctxt<'tcx>) -> ParameterEnvironment<'a,'tcx> {
6816 ty::ParameterEnvironment { tcx: cx,
6817 free_substs: Substs::empty(),
6818 caller_bounds: Vec::new(),
6819 implicit_region_bound: ty::ReEmpty,
6820 selection_cache: traits::SelectionCache::new(), }
6821 }
6822
6823 /// Constructs and returns a substitution that can be applied to move from
6824 /// the "outer" view of a type or method to the "inner" view.
6825 /// In general, this means converting from bound parameters to
6826 /// free parameters. Since we currently represent bound/free type
6827 /// parameters in the same way, this only has an effect on regions.
6828 pub fn construct_free_substs<'a,'tcx>(
6829 tcx: &'a ctxt<'tcx>,
6830 generics: &Generics<'tcx>,
6831 free_id: ast::NodeId)
6832 -> Substs<'tcx>
6833 {
6834 // map T => T
6835 let mut types = VecPerParamSpace::empty();
6836 push_types_from_defs(tcx, &mut types, generics.types.as_slice());
6837
6838 let free_id_outlive = region::DestructionScopeData::new(free_id);
6839
6840 // map bound 'a => free 'a
6841 let mut regions = VecPerParamSpace::empty();
6842 push_region_params(&mut regions, free_id_outlive, generics.regions.as_slice());
6843
6844 return Substs {
6845 types: types,
6846 regions: subst::NonerasedRegions(regions)
6847 };
6848
6849 fn push_region_params(regions: &mut VecPerParamSpace<ty::Region>,
6850 all_outlive_extent: region::DestructionScopeData,
6851 region_params: &[RegionParameterDef])
6852 {
6853 for r in region_params {
6854 regions.push(r.space, ty::free_region_from_def(all_outlive_extent, r));
6855 }
6856 }
6857
6858 fn push_types_from_defs<'tcx>(tcx: &ty::ctxt<'tcx>,
6859 types: &mut VecPerParamSpace<Ty<'tcx>>,
6860 defs: &[TypeParameterDef<'tcx>]) {
6861 for def in defs {
6862 debug!("construct_parameter_environment(): push_types_from_defs: def={:?}",
6863 def);
6864 let ty = ty::mk_param_from_def(tcx, def);
6865 types.push(def.space, ty);
6866 }
6867 }
6868 }
6869
6870 /// See `ParameterEnvironment` struct def'n for details
6871 pub fn construct_parameter_environment<'a,'tcx>(
6872 tcx: &'a ctxt<'tcx>,
6873 span: Span,
6874 generics: &ty::Generics<'tcx>,
6875 generic_predicates: &ty::GenericPredicates<'tcx>,
6876 free_id: ast::NodeId)
6877 -> ParameterEnvironment<'a, 'tcx>
6878 {
6879 //
6880 // Construct the free substs.
6881 //
6882
6883 let free_substs = construct_free_substs(tcx, generics, free_id);
6884 let free_id_outlive = region::DestructionScopeData::new(free_id);
6885
6886 //
6887 // Compute the bounds on Self and the type parameters.
6888 //
6889
6890 let bounds = generic_predicates.instantiate(tcx, &free_substs);
6891 let bounds = liberate_late_bound_regions(tcx, free_id_outlive, &ty::Binder(bounds));
6892 let predicates = bounds.predicates.into_vec();
6893
6894 debug!("construct_parameter_environment: free_id={:?} free_subst={:?} predicates={:?}",
6895 free_id,
6896 free_substs,
6897 predicates);
6898
6899 //
6900 // Finally, we have to normalize the bounds in the environment, in
6901 // case they contain any associated type projections. This process
6902 // can yield errors if the put in illegal associated types, like
6903 // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
6904 // report these errors right here; this doesn't actually feel
6905 // right to me, because constructing the environment feels like a
6906 // kind of a "idempotent" action, but I'm not sure where would be
6907 // a better place. In practice, we construct environments for
6908 // every fn once during type checking, and we'll abort if there
6909 // are any errors at that point, so after type checking you can be
6910 // sure that this will succeed without errors anyway.
6911 //
6912
6913 let unnormalized_env = ty::ParameterEnvironment {
6914 tcx: tcx,
6915 free_substs: free_substs,
6916 implicit_region_bound: ty::ReScope(free_id_outlive.to_code_extent()),
6917 caller_bounds: predicates,
6918 selection_cache: traits::SelectionCache::new(),
6919 };
6920
6921 let cause = traits::ObligationCause::misc(span, free_id);
6922 traits::normalize_param_env_or_error(unnormalized_env, cause)
6923 }
6924
6925 impl BorrowKind {
6926 pub fn from_mutbl(m: ast::Mutability) -> BorrowKind {
6927 match m {
6928 ast::MutMutable => MutBorrow,
6929 ast::MutImmutable => ImmBorrow,
6930 }
6931 }
6932
6933 /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow
6934 /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a
6935 /// mutability that is stronger than necessary so that it at least *would permit* the borrow in
6936 /// question.
6937 pub fn to_mutbl_lossy(self) -> ast::Mutability {
6938 match self {
6939 MutBorrow => ast::MutMutable,
6940 ImmBorrow => ast::MutImmutable,
6941
6942 // We have no type corresponding to a unique imm borrow, so
6943 // use `&mut`. It gives all the capabilities of an `&uniq`
6944 // and hence is a safe "over approximation".
6945 UniqueImmBorrow => ast::MutMutable,
6946 }
6947 }
6948
6949 pub fn to_user_str(&self) -> &'static str {
6950 match *self {
6951 MutBorrow => "mutable",
6952 ImmBorrow => "immutable",
6953 UniqueImmBorrow => "uniquely immutable",
6954 }
6955 }
6956 }
6957
6958 impl<'tcx> ctxt<'tcx> {
6959 pub fn is_method_call(&self, expr_id: ast::NodeId) -> bool {
6960 self.method_map.borrow().contains_key(&MethodCall::expr(expr_id))
6961 }
6962
6963 pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
6964 Some(self.upvar_capture_map.borrow().get(&upvar_id).unwrap().clone())
6965 }
6966 }
6967
6968 impl<'a,'tcx> mc::Typer<'tcx> for ParameterEnvironment<'a,'tcx> {
6969 fn node_ty(&self, id: ast::NodeId) -> mc::McResult<Ty<'tcx>> {
6970 Ok(ty::node_id_to_type(self.tcx, id))
6971 }
6972
6973 fn expr_ty_adjusted(&self, expr: &ast::Expr) -> mc::McResult<Ty<'tcx>> {
6974 Ok(ty::expr_ty_adjusted(self.tcx, expr))
6975 }
6976
6977 fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
6978 self.tcx.method_map.borrow().get(&method_call).map(|method| method.ty)
6979 }
6980
6981 fn node_method_origin(&self, method_call: ty::MethodCall)
6982 -> Option<ty::MethodOrigin<'tcx>>
6983 {
6984 self.tcx.method_map.borrow().get(&method_call).map(|method| method.origin.clone())
6985 }
6986
6987 fn adjustments(&self) -> &RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> {
6988 &self.tcx.adjustments
6989 }
6990
6991 fn is_method_call(&self, id: ast::NodeId) -> bool {
6992 self.tcx.is_method_call(id)
6993 }
6994
6995 fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent> {
6996 self.tcx.region_maps.temporary_scope(rvalue_id)
6997 }
6998
6999 fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
7000 self.tcx.upvar_capture(upvar_id)
7001 }
7002
7003 fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool {
7004 type_moves_by_default(self, span, ty)
7005 }
7006 }
7007
7008 impl<'a,'tcx> ClosureTyper<'tcx> for ty::ParameterEnvironment<'a,'tcx> {
7009 fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
7010 self
7011 }
7012
7013 fn closure_kind(&self,
7014 def_id: ast::DefId)
7015 -> Option<ty::ClosureKind>
7016 {
7017 Some(self.tcx.closure_kind(def_id))
7018 }
7019
7020 fn closure_type(&self,
7021 def_id: ast::DefId,
7022 substs: &subst::Substs<'tcx>)
7023 -> ty::ClosureTy<'tcx>
7024 {
7025 self.tcx.closure_type(def_id, substs)
7026 }
7027
7028 fn closure_upvars(&self,
7029 def_id: ast::DefId,
7030 substs: &Substs<'tcx>)
7031 -> Option<Vec<ClosureUpvar<'tcx>>>
7032 {
7033 closure_upvars(self, def_id, substs)
7034 }
7035 }
7036
7037
7038 /// The category of explicit self.
7039 #[derive(Clone, Copy, Eq, PartialEq, Debug)]
7040 pub enum ExplicitSelfCategory {
7041 StaticExplicitSelfCategory,
7042 ByValueExplicitSelfCategory,
7043 ByReferenceExplicitSelfCategory(Region, ast::Mutability),
7044 ByBoxExplicitSelfCategory,
7045 }
7046
7047 /// Pushes all the lifetimes in the given type onto the given list. A
7048 /// "lifetime in a type" is a lifetime specified by a reference or a lifetime
7049 /// in a list of type substitutions. This does *not* traverse into nominal
7050 /// types, nor does it resolve fictitious types.
7051 pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
7052 ty: Ty) {
7053 walk_ty(ty, |ty| {
7054 match ty.sty {
7055 TyRef(region, _) => {
7056 accumulator.push(*region)
7057 }
7058 TyTrait(ref t) => {
7059 accumulator.push_all(t.principal.0.substs.regions().as_slice());
7060 }
7061 TyEnum(_, substs) |
7062 TyStruct(_, substs) => {
7063 accum_substs(accumulator, substs);
7064 }
7065 TyClosure(_, substs) => {
7066 accum_substs(accumulator, substs);
7067 }
7068 TyBool |
7069 TyChar |
7070 TyInt(_) |
7071 TyUint(_) |
7072 TyFloat(_) |
7073 TyBox(_) |
7074 TyStr |
7075 TyArray(_, _) |
7076 TySlice(_) |
7077 TyRawPtr(_) |
7078 TyBareFn(..) |
7079 TyTuple(_) |
7080 TyProjection(_) |
7081 TyParam(_) |
7082 TyInfer(_) |
7083 TyError => {
7084 }
7085 }
7086 });
7087
7088 fn accum_substs(accumulator: &mut Vec<Region>, substs: &Substs) {
7089 match substs.regions {
7090 subst::ErasedRegions => {}
7091 subst::NonerasedRegions(ref regions) => {
7092 for region in regions {
7093 accumulator.push(*region)
7094 }
7095 }
7096 }
7097 }
7098 }
7099
7100 /// A free variable referred to in a function.
7101 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
7102 pub struct Freevar {
7103 /// The variable being accessed free.
7104 pub def: def::Def,
7105
7106 // First span where it is accessed (there can be multiple).
7107 pub span: Span
7108 }
7109
7110 pub type FreevarMap = NodeMap<Vec<Freevar>>;
7111
7112 pub type CaptureModeMap = NodeMap<ast::CaptureClause>;
7113
7114 // Trait method resolution
7115 pub type TraitMap = NodeMap<Vec<DefId>>;
7116
7117 // Map from the NodeId of a glob import to a list of items which are actually
7118 // imported.
7119 pub type GlobMap = HashMap<NodeId, HashSet<Name>>;
7120
7121 pub fn with_freevars<T, F>(tcx: &ty::ctxt, fid: ast::NodeId, f: F) -> T where
7122 F: FnOnce(&[Freevar]) -> T,
7123 {
7124 match tcx.freevars.borrow().get(&fid) {
7125 None => f(&[]),
7126 Some(d) => f(&d[..])
7127 }
7128 }
7129
7130 impl<'tcx> AutoAdjustment<'tcx> {
7131 pub fn is_identity(&self) -> bool {
7132 match *self {
7133 AdjustReifyFnPointer |
7134 AdjustUnsafeFnPointer => false,
7135 AdjustDerefRef(ref r) => r.is_identity(),
7136 }
7137 }
7138 }
7139
7140 impl<'tcx> AutoDerefRef<'tcx> {
7141 pub fn is_identity(&self) -> bool {
7142 self.autoderefs == 0 && self.unsize.is_none() && self.autoref.is_none()
7143 }
7144 }
7145
7146 /// Replace any late-bound regions bound in `value` with free variants attached to scope-id
7147 /// `scope_id`.
7148 pub fn liberate_late_bound_regions<'tcx, T>(
7149 tcx: &ty::ctxt<'tcx>,
7150 all_outlive_scope: region::DestructionScopeData,
7151 value: &Binder<T>)
7152 -> T
7153 where T : TypeFoldable<'tcx>
7154 {
7155 ty_fold::replace_late_bound_regions(
7156 tcx, value,
7157 |br| ty::ReFree(ty::FreeRegion{scope: all_outlive_scope, bound_region: br})).0
7158 }
7159
7160 pub fn count_late_bound_regions<'tcx, T>(
7161 tcx: &ty::ctxt<'tcx>,
7162 value: &Binder<T>)
7163 -> usize
7164 where T : TypeFoldable<'tcx>
7165 {
7166 let (_, skol_map) = ty_fold::replace_late_bound_regions(tcx, value, |_| ty::ReStatic);
7167 skol_map.len()
7168 }
7169
7170 pub fn binds_late_bound_regions<'tcx, T>(
7171 tcx: &ty::ctxt<'tcx>,
7172 value: &Binder<T>)
7173 -> bool
7174 where T : TypeFoldable<'tcx>
7175 {
7176 count_late_bound_regions(tcx, value) > 0
7177 }
7178
7179 /// Flattens two binding levels into one. So `for<'a> for<'b> Foo`
7180 /// becomes `for<'a,'b> Foo`.
7181 pub fn flatten_late_bound_regions<'tcx, T>(
7182 tcx: &ty::ctxt<'tcx>,
7183 bound2_value: &Binder<Binder<T>>)
7184 -> Binder<T>
7185 where T: TypeFoldable<'tcx>
7186 {
7187 let bound0_value = bound2_value.skip_binder().skip_binder();
7188 let value = ty_fold::fold_regions(tcx, bound0_value, |region, current_depth| {
7189 match region {
7190 ty::ReLateBound(debruijn, br) if debruijn.depth >= current_depth => {
7191 // should be true if no escaping regions from bound2_value
7192 assert!(debruijn.depth - current_depth <= 1);
7193 ty::ReLateBound(DebruijnIndex::new(current_depth), br)
7194 }
7195 _ => {
7196 region
7197 }
7198 }
7199 });
7200 Binder(value)
7201 }
7202
7203 pub fn no_late_bound_regions<'tcx, T>(
7204 tcx: &ty::ctxt<'tcx>,
7205 value: &Binder<T>)
7206 -> Option<T>
7207 where T : TypeFoldable<'tcx>
7208 {
7209 if binds_late_bound_regions(tcx, value) {
7210 None
7211 } else {
7212 Some(value.0.clone())
7213 }
7214 }
7215
7216 /// Replace any late-bound regions bound in `value` with `'static`. Useful in trans but also
7217 /// method lookup and a few other places where precise region relationships are not required.
7218 pub fn erase_late_bound_regions<'tcx, T>(
7219 tcx: &ty::ctxt<'tcx>,
7220 value: &Binder<T>)
7221 -> T
7222 where T : TypeFoldable<'tcx>
7223 {
7224 ty_fold::replace_late_bound_regions(tcx, value, |_| ty::ReStatic).0
7225 }
7226
7227 /// Rewrite any late-bound regions so that they are anonymous. Region numbers are
7228 /// assigned starting at 1 and increasing monotonically in the order traversed
7229 /// by the fold operation.
7230 ///
7231 /// The chief purpose of this function is to canonicalize regions so that two
7232 /// `FnSig`s or `TraitRef`s which are equivalent up to region naming will become
7233 /// structurally identical. For example, `for<'a, 'b> fn(&'a isize, &'b isize)` and
7234 /// `for<'a, 'b> fn(&'b isize, &'a isize)` will become identical after anonymization.
7235 pub fn anonymize_late_bound_regions<'tcx, T>(
7236 tcx: &ctxt<'tcx>,
7237 sig: &Binder<T>)
7238 -> Binder<T>
7239 where T : TypeFoldable<'tcx>,
7240 {
7241 let mut counter = 0;
7242 ty::Binder(ty_fold::replace_late_bound_regions(tcx, sig, |_| {
7243 counter += 1;
7244 ReLateBound(ty::DebruijnIndex::new(1), BrAnon(counter))
7245 }).0)
7246 }
7247
7248 impl DebruijnIndex {
7249 pub fn new(depth: u32) -> DebruijnIndex {
7250 assert!(depth > 0);
7251 DebruijnIndex { depth: depth }
7252 }
7253
7254 pub fn shifted(&self, amount: u32) -> DebruijnIndex {
7255 DebruijnIndex { depth: self.depth + amount }
7256 }
7257 }
7258
7259 impl<'tcx> fmt::Debug for AutoAdjustment<'tcx> {
7260 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7261 match *self {
7262 AdjustReifyFnPointer => {
7263 write!(f, "AdjustReifyFnPointer")
7264 }
7265 AdjustUnsafeFnPointer => {
7266 write!(f, "AdjustUnsafeFnPointer")
7267 }
7268 AdjustDerefRef(ref data) => {
7269 write!(f, "{:?}", data)
7270 }
7271 }
7272 }
7273 }
7274
7275 impl<'tcx> fmt::Debug for AutoDerefRef<'tcx> {
7276 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7277 write!(f, "AutoDerefRef({}, unsize={:?}, {:?})",
7278 self.autoderefs, self.unsize, self.autoref)
7279 }
7280 }
7281
7282 impl<'tcx> fmt::Debug for TraitTy<'tcx> {
7283 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7284 write!(f, "TraitTy({:?},{:?})",
7285 self.principal,
7286 self.bounds)
7287 }
7288 }
7289
7290 impl<'tcx> fmt::Debug for ty::Predicate<'tcx> {
7291 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7292 match *self {
7293 Predicate::Trait(ref a) => write!(f, "{:?}", a),
7294 Predicate::Equate(ref pair) => write!(f, "{:?}", pair),
7295 Predicate::RegionOutlives(ref pair) => write!(f, "{:?}", pair),
7296 Predicate::TypeOutlives(ref pair) => write!(f, "{:?}", pair),
7297 Predicate::Projection(ref pair) => write!(f, "{:?}", pair),
7298 }
7299 }
7300 }
7301
7302 pub fn make_substs_for_receiver_types<'tcx>(tcx: &ty::ctxt<'tcx>,
7303 trait_ref: &ty::TraitRef<'tcx>,
7304 method: &ty::Method<'tcx>)
7305 -> subst::Substs<'tcx>
7306 {
7307 /*!
7308 * Substitutes the values for the receiver's type parameters
7309 * that are found in method, leaving the method's type parameters
7310 * intact.
7311 */
7312
7313 let meth_tps: Vec<Ty> =
7314 method.generics.types.get_slice(subst::FnSpace)
7315 .iter()
7316 .map(|def| ty::mk_param_from_def(tcx, def))
7317 .collect();
7318 let meth_regions: Vec<ty::Region> =
7319 method.generics.regions.get_slice(subst::FnSpace)
7320 .iter()
7321 .map(|def| def.to_early_bound_region())
7322 .collect();
7323 trait_ref.substs.clone().with_method(meth_tps, meth_regions)
7324 }
7325
7326 #[derive(Copy, Clone)]
7327 pub enum CopyImplementationError {
7328 FieldDoesNotImplementCopy(ast::Name),
7329 VariantDoesNotImplementCopy(ast::Name),
7330 TypeIsStructural,
7331 TypeHasDestructor,
7332 }
7333
7334 pub fn can_type_implement_copy<'a,'tcx>(param_env: &ParameterEnvironment<'a, 'tcx>,
7335 span: Span,
7336 self_type: Ty<'tcx>)
7337 -> Result<(),CopyImplementationError>
7338 {
7339 let tcx = param_env.tcx;
7340
7341 let did = match self_type.sty {
7342 ty::TyStruct(struct_did, substs) => {
7343 let fields = ty::struct_fields(tcx, struct_did, substs);
7344 for field in &fields {
7345 if type_moves_by_default(param_env, span, field.mt.ty) {
7346 return Err(FieldDoesNotImplementCopy(field.name))
7347 }
7348 }
7349 struct_did
7350 }
7351 ty::TyEnum(enum_did, substs) => {
7352 let enum_variants = ty::enum_variants(tcx, enum_did);
7353 for variant in enum_variants.iter() {
7354 for variant_arg_type in &variant.args {
7355 let substd_arg_type =
7356 variant_arg_type.subst(tcx, substs);
7357 if type_moves_by_default(param_env, span, substd_arg_type) {
7358 return Err(VariantDoesNotImplementCopy(variant.name))
7359 }
7360 }
7361 }
7362 enum_did
7363 }
7364 _ => return Err(TypeIsStructural),
7365 };
7366
7367 if ty::has_dtor(tcx, did) {
7368 return Err(TypeHasDestructor)
7369 }
7370
7371 Ok(())
7372 }
7373
7374 // FIXME(#20298) -- all of these types basically walk various
7375 // structures to test whether types/regions are reachable with various
7376 // properties. It should be possible to express them in terms of one
7377 // common "walker" trait or something.
7378
7379 pub trait RegionEscape {
7380 fn has_escaping_regions(&self) -> bool {
7381 self.has_regions_escaping_depth(0)
7382 }
7383
7384 fn has_regions_escaping_depth(&self, depth: u32) -> bool;
7385 }
7386
7387 impl<'tcx> RegionEscape for Ty<'tcx> {
7388 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7389 ty::type_escapes_depth(*self, depth)
7390 }
7391 }
7392
7393 impl<'tcx> RegionEscape for Substs<'tcx> {
7394 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7395 self.types.has_regions_escaping_depth(depth) ||
7396 self.regions.has_regions_escaping_depth(depth)
7397 }
7398 }
7399
7400 impl<'tcx,T:RegionEscape> RegionEscape for VecPerParamSpace<T> {
7401 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7402 self.iter_enumerated().any(|(space, _, t)| {
7403 if space == subst::FnSpace {
7404 t.has_regions_escaping_depth(depth+1)
7405 } else {
7406 t.has_regions_escaping_depth(depth)
7407 }
7408 })
7409 }
7410 }
7411
7412 impl<'tcx> RegionEscape for TypeScheme<'tcx> {
7413 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7414 self.ty.has_regions_escaping_depth(depth)
7415 }
7416 }
7417
7418 impl RegionEscape for Region {
7419 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7420 self.escapes_depth(depth)
7421 }
7422 }
7423
7424 impl<'tcx> RegionEscape for GenericPredicates<'tcx> {
7425 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7426 self.predicates.has_regions_escaping_depth(depth)
7427 }
7428 }
7429
7430 impl<'tcx> RegionEscape for Predicate<'tcx> {
7431 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7432 match *self {
7433 Predicate::Trait(ref data) => data.has_regions_escaping_depth(depth),
7434 Predicate::Equate(ref data) => data.has_regions_escaping_depth(depth),
7435 Predicate::RegionOutlives(ref data) => data.has_regions_escaping_depth(depth),
7436 Predicate::TypeOutlives(ref data) => data.has_regions_escaping_depth(depth),
7437 Predicate::Projection(ref data) => data.has_regions_escaping_depth(depth),
7438 }
7439 }
7440 }
7441
7442 impl<'tcx,P:RegionEscape> RegionEscape for traits::Obligation<'tcx,P> {
7443 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7444 self.predicate.has_regions_escaping_depth(depth)
7445 }
7446 }
7447
7448 impl<'tcx> RegionEscape for TraitRef<'tcx> {
7449 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7450 self.substs.types.iter().any(|t| t.has_regions_escaping_depth(depth)) ||
7451 self.substs.regions.has_regions_escaping_depth(depth)
7452 }
7453 }
7454
7455 impl<'tcx> RegionEscape for subst::RegionSubsts {
7456 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7457 match *self {
7458 subst::ErasedRegions => false,
7459 subst::NonerasedRegions(ref r) => {
7460 r.iter().any(|t| t.has_regions_escaping_depth(depth))
7461 }
7462 }
7463 }
7464 }
7465
7466 impl<'tcx,T:RegionEscape> RegionEscape for Binder<T> {
7467 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7468 self.0.has_regions_escaping_depth(depth + 1)
7469 }
7470 }
7471
7472 impl<'tcx> RegionEscape for EquatePredicate<'tcx> {
7473 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7474 self.0.has_regions_escaping_depth(depth) || self.1.has_regions_escaping_depth(depth)
7475 }
7476 }
7477
7478 impl<'tcx> RegionEscape for TraitPredicate<'tcx> {
7479 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7480 self.trait_ref.has_regions_escaping_depth(depth)
7481 }
7482 }
7483
7484 impl<T:RegionEscape,U:RegionEscape> RegionEscape for OutlivesPredicate<T,U> {
7485 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7486 self.0.has_regions_escaping_depth(depth) || self.1.has_regions_escaping_depth(depth)
7487 }
7488 }
7489
7490 impl<'tcx> RegionEscape for ProjectionPredicate<'tcx> {
7491 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7492 self.projection_ty.has_regions_escaping_depth(depth) ||
7493 self.ty.has_regions_escaping_depth(depth)
7494 }
7495 }
7496
7497 impl<'tcx> RegionEscape for ProjectionTy<'tcx> {
7498 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7499 self.trait_ref.has_regions_escaping_depth(depth)
7500 }
7501 }
7502
7503 pub trait HasProjectionTypes {
7504 fn has_projection_types(&self) -> bool;
7505 }
7506
7507 impl<'tcx,T:HasProjectionTypes> HasProjectionTypes for Vec<T> {
7508 fn has_projection_types(&self) -> bool {
7509 self.iter().any(|p| p.has_projection_types())
7510 }
7511 }
7512
7513 impl<'tcx,T:HasProjectionTypes> HasProjectionTypes for VecPerParamSpace<T> {
7514 fn has_projection_types(&self) -> bool {
7515 self.iter().any(|p| p.has_projection_types())
7516 }
7517 }
7518
7519 impl<'tcx> HasProjectionTypes for ClosureTy<'tcx> {
7520 fn has_projection_types(&self) -> bool {
7521 self.sig.has_projection_types()
7522 }
7523 }
7524
7525 impl<'tcx> HasProjectionTypes for ClosureUpvar<'tcx> {
7526 fn has_projection_types(&self) -> bool {
7527 self.ty.has_projection_types()
7528 }
7529 }
7530
7531 impl<'tcx> HasProjectionTypes for ty::InstantiatedPredicates<'tcx> {
7532 fn has_projection_types(&self) -> bool {
7533 self.predicates.has_projection_types()
7534 }
7535 }
7536
7537 impl<'tcx> HasProjectionTypes for Predicate<'tcx> {
7538 fn has_projection_types(&self) -> bool {
7539 match *self {
7540 Predicate::Trait(ref data) => data.has_projection_types(),
7541 Predicate::Equate(ref data) => data.has_projection_types(),
7542 Predicate::RegionOutlives(ref data) => data.has_projection_types(),
7543 Predicate::TypeOutlives(ref data) => data.has_projection_types(),
7544 Predicate::Projection(ref data) => data.has_projection_types(),
7545 }
7546 }
7547 }
7548
7549 impl<'tcx> HasProjectionTypes for TraitPredicate<'tcx> {
7550 fn has_projection_types(&self) -> bool {
7551 self.trait_ref.has_projection_types()
7552 }
7553 }
7554
7555 impl<'tcx> HasProjectionTypes for EquatePredicate<'tcx> {
7556 fn has_projection_types(&self) -> bool {
7557 self.0.has_projection_types() || self.1.has_projection_types()
7558 }
7559 }
7560
7561 impl HasProjectionTypes for Region {
7562 fn has_projection_types(&self) -> bool {
7563 false
7564 }
7565 }
7566
7567 impl<T:HasProjectionTypes,U:HasProjectionTypes> HasProjectionTypes for OutlivesPredicate<T,U> {
7568 fn has_projection_types(&self) -> bool {
7569 self.0.has_projection_types() || self.1.has_projection_types()
7570 }
7571 }
7572
7573 impl<'tcx> HasProjectionTypes for ProjectionPredicate<'tcx> {
7574 fn has_projection_types(&self) -> bool {
7575 self.projection_ty.has_projection_types() || self.ty.has_projection_types()
7576 }
7577 }
7578
7579 impl<'tcx> HasProjectionTypes for ProjectionTy<'tcx> {
7580 fn has_projection_types(&self) -> bool {
7581 self.trait_ref.has_projection_types()
7582 }
7583 }
7584
7585 impl<'tcx> HasProjectionTypes for Ty<'tcx> {
7586 fn has_projection_types(&self) -> bool {
7587 ty::type_has_projection(*self)
7588 }
7589 }
7590
7591 impl<'tcx> HasProjectionTypes for TraitRef<'tcx> {
7592 fn has_projection_types(&self) -> bool {
7593 self.substs.has_projection_types()
7594 }
7595 }
7596
7597 impl<'tcx> HasProjectionTypes for subst::Substs<'tcx> {
7598 fn has_projection_types(&self) -> bool {
7599 self.types.iter().any(|t| t.has_projection_types())
7600 }
7601 }
7602
7603 impl<'tcx,T> HasProjectionTypes for Option<T>
7604 where T : HasProjectionTypes
7605 {
7606 fn has_projection_types(&self) -> bool {
7607 self.iter().any(|t| t.has_projection_types())
7608 }
7609 }
7610
7611 impl<'tcx,T> HasProjectionTypes for Rc<T>
7612 where T : HasProjectionTypes
7613 {
7614 fn has_projection_types(&self) -> bool {
7615 (**self).has_projection_types()
7616 }
7617 }
7618
7619 impl<'tcx,T> HasProjectionTypes for Box<T>
7620 where T : HasProjectionTypes
7621 {
7622 fn has_projection_types(&self) -> bool {
7623 (**self).has_projection_types()
7624 }
7625 }
7626
7627 impl<T> HasProjectionTypes for Binder<T>
7628 where T : HasProjectionTypes
7629 {
7630 fn has_projection_types(&self) -> bool {
7631 self.0.has_projection_types()
7632 }
7633 }
7634
7635 impl<'tcx> HasProjectionTypes for FnOutput<'tcx> {
7636 fn has_projection_types(&self) -> bool {
7637 match *self {
7638 FnConverging(t) => t.has_projection_types(),
7639 FnDiverging => false,
7640 }
7641 }
7642 }
7643
7644 impl<'tcx> HasProjectionTypes for FnSig<'tcx> {
7645 fn has_projection_types(&self) -> bool {
7646 self.inputs.iter().any(|t| t.has_projection_types()) ||
7647 self.output.has_projection_types()
7648 }
7649 }
7650
7651 impl<'tcx> HasProjectionTypes for field<'tcx> {
7652 fn has_projection_types(&self) -> bool {
7653 self.mt.ty.has_projection_types()
7654 }
7655 }
7656
7657 impl<'tcx> HasProjectionTypes for BareFnTy<'tcx> {
7658 fn has_projection_types(&self) -> bool {
7659 self.sig.has_projection_types()
7660 }
7661 }
7662
7663 pub trait ReferencesError {
7664 fn references_error(&self) -> bool;
7665 }
7666
7667 impl<T:ReferencesError> ReferencesError for Binder<T> {
7668 fn references_error(&self) -> bool {
7669 self.0.references_error()
7670 }
7671 }
7672
7673 impl<T:ReferencesError> ReferencesError for Rc<T> {
7674 fn references_error(&self) -> bool {
7675 (&**self).references_error()
7676 }
7677 }
7678
7679 impl<'tcx> ReferencesError for TraitPredicate<'tcx> {
7680 fn references_error(&self) -> bool {
7681 self.trait_ref.references_error()
7682 }
7683 }
7684
7685 impl<'tcx> ReferencesError for ProjectionPredicate<'tcx> {
7686 fn references_error(&self) -> bool {
7687 self.projection_ty.trait_ref.references_error() || self.ty.references_error()
7688 }
7689 }
7690
7691 impl<'tcx> ReferencesError for TraitRef<'tcx> {
7692 fn references_error(&self) -> bool {
7693 self.input_types().iter().any(|t| t.references_error())
7694 }
7695 }
7696
7697 impl<'tcx> ReferencesError for Ty<'tcx> {
7698 fn references_error(&self) -> bool {
7699 type_is_error(*self)
7700 }
7701 }
7702
7703 impl<'tcx> ReferencesError for Predicate<'tcx> {
7704 fn references_error(&self) -> bool {
7705 match *self {
7706 Predicate::Trait(ref data) => data.references_error(),
7707 Predicate::Equate(ref data) => data.references_error(),
7708 Predicate::RegionOutlives(ref data) => data.references_error(),
7709 Predicate::TypeOutlives(ref data) => data.references_error(),
7710 Predicate::Projection(ref data) => data.references_error(),
7711 }
7712 }
7713 }
7714
7715 impl<A,B> ReferencesError for OutlivesPredicate<A,B>
7716 where A : ReferencesError, B : ReferencesError
7717 {
7718 fn references_error(&self) -> bool {
7719 self.0.references_error() || self.1.references_error()
7720 }
7721 }
7722
7723 impl<'tcx> ReferencesError for EquatePredicate<'tcx>
7724 {
7725 fn references_error(&self) -> bool {
7726 self.0.references_error() || self.1.references_error()
7727 }
7728 }
7729
7730 impl ReferencesError for Region
7731 {
7732 fn references_error(&self) -> bool {
7733 false
7734 }
7735 }
7736
7737 impl<'tcx> fmt::Debug for ClosureTy<'tcx> {
7738 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7739 write!(f, "ClosureTy({},{:?},{})",
7740 self.unsafety,
7741 self.sig,
7742 self.abi)
7743 }
7744 }
7745
7746 impl<'tcx> fmt::Debug for ClosureUpvar<'tcx> {
7747 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7748 write!(f, "ClosureUpvar({:?},{:?})",
7749 self.def,
7750 self.ty)
7751 }
7752 }
7753
7754 impl<'tcx> fmt::Debug for field<'tcx> {
7755 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7756 write!(f, "field({},{})", self.name, self.mt)
7757 }
7758 }
7759
7760 impl<'a, 'tcx> fmt::Debug for ParameterEnvironment<'a, 'tcx> {
7761 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7762 write!(f, "ParameterEnvironment(\
7763 free_substs={:?}, \
7764 implicit_region_bound={:?}, \
7765 caller_bounds={:?})",
7766 self.free_substs,
7767 self.implicit_region_bound,
7768 self.caller_bounds)
7769 }
7770 }
7771
7772 impl<'tcx> fmt::Debug for ObjectLifetimeDefault {
7773 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7774 match *self {
7775 ObjectLifetimeDefault::Ambiguous => write!(f, "Ambiguous"),
7776 ObjectLifetimeDefault::BaseDefault => write!(f, "BaseDefault"),
7777 ObjectLifetimeDefault::Specific(ref r) => write!(f, "{:?}", r),
7778 }
7779 }
7780 }