]> git.proxmox.com Git - rustc.git/blame - src/librustc/middle/ty.rs
Imported Upstream version 1.2.0+dfsg1
[rustc.git] / src / librustc / middle / ty.rs
CommitLineData
1a4d82fc 1// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
223e47cc
LB
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
1a4d82fc
JJ
11#![allow(non_camel_case_types)]
12
13pub use self::terr_vstore_kind::*;
14pub use self::type_err::*;
1a4d82fc
JJ
15pub use self::InferTy::*;
16pub use self::InferRegion::*;
17pub use self::ImplOrTraitItemId::*;
85aaf69f 18pub use self::ClosureKind::*;
1a4d82fc
JJ
19pub use self::Variance::*;
20pub use self::AutoAdjustment::*;
21pub use self::Representability::*;
1a4d82fc 22pub use self::AutoRef::*;
1a4d82fc
JJ
23pub use self::DtorKind::*;
24pub use self::ExplicitSelfCategory::*;
25pub use self::FnOutput::*;
26pub use self::Region::*;
27pub use self::ImplOrTraitItemContainer::*;
28pub use self::BorrowKind::*;
29pub use self::ImplOrTraitItem::*;
30pub use self::BoundRegion::*;
62682a34 31pub use self::TypeVariants::*;
1a4d82fc 32pub use self::IntVarValue::*;
1a4d82fc
JJ
33pub use self::MethodOrigin::*;
34pub use self::CopyImplementationError::*;
35
62682a34
SL
36pub use self::BuiltinBound::Send as BoundSend;
37pub use self::BuiltinBound::Sized as BoundSized;
38pub use self::BuiltinBound::Copy as BoundCopy;
39pub use self::BuiltinBound::Sync as BoundSync;
40
41use ast_map::{self, LinkedPath};
1a4d82fc
JJ
42use back::svh::Svh;
43use session::Session;
44use lint;
223e47cc 45use metadata::csearch;
1a4d82fc 46use middle;
62682a34 47use middle::cast;
85aaf69f 48use middle::check_const;
62682a34 49use middle::const_eval::{self, ConstVal};
1a4d82fc
JJ
50use middle::def::{self, DefMap, ExportMap};
51use middle::dependency_format;
d9579d0f 52use middle::fast_reject;
bd371182 53use middle::free_region::FreeRegionMap;
62682a34 54use middle::infer::error_reporting::note_and_explain_region;
c34b1796 55use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
1a4d82fc
JJ
56use middle::mem_categorization as mc;
57use middle::region;
58use middle::resolve_lifetime;
59use middle::infer;
c34b1796 60use middle::pat_util;
bd371182 61use middle::region::RegionMaps;
1a4d82fc 62use middle::stability;
c34b1796 63use middle::subst::{self, ParamSpace, Subst, Substs, VecPerParamSpace};
1a4d82fc 64use middle::traits;
223e47cc 65use middle::ty;
1a4d82fc 66use middle::ty_fold::{self, TypeFoldable, TypeFolder};
c34b1796 67use middle::ty_walk::{self, TypeWalker};
1a4d82fc
JJ
68use util::common::{memoized, ErrorReported};
69use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
c34b1796 70use util::nodemap::FnvHashMap;
9346a6ac 71use util::num::ToPrimitive;
1a4d82fc
JJ
72
73use arena::TypedArena;
85aaf69f 74use std::borrow::{Borrow, Cow};
c34b1796 75use std::cell::{Cell, RefCell, Ref};
85aaf69f
SL
76use std::cmp;
77use std::fmt;
78use std::hash::{Hash, SipHasher, Hasher};
1a4d82fc 79use std::mem;
970d7e83 80use std::ops;
1a4d82fc 81use std::rc::Rc;
c34b1796 82use std::vec::IntoIter;
62682a34 83use collections::enum_set::{self, EnumSet, CLike};
1a4d82fc
JJ
84use std::collections::{HashMap, HashSet};
85use syntax::abi;
d9579d0f 86use syntax::ast::{CrateNum, DefId, ItemImpl, ItemTrait, LOCAL_CRATE};
1a4d82fc 87use syntax::ast::{MutImmutable, MutMutable, Name, NamedField, NodeId};
85aaf69f 88use syntax::ast::{StmtExpr, StmtSemi, StructField, UnnamedField, Visibility};
62682a34 89use syntax::ast_util::{self, is_local, local_def};
c34b1796 90use syntax::attr::{self, AttrMetaMethods, SignedInt, UnsignedInt};
1a4d82fc
JJ
91use syntax::codemap::Span;
92use syntax::parse::token::{self, InternedString, special_idents};
c34b1796
AL
93use syntax::print::pprust;
94use syntax::ptr::P;
95use syntax::ast;
1a4d82fc
JJ
96
97pub type Disr = u64;
98
99pub const INITIAL_DISCRIMINANT_VALUE: Disr = 0;
223e47cc
LB
100
101// Data types
102
1a4d82fc
JJ
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.
62682a34 105pub struct CrateAnalysis {
1a4d82fc
JJ
106 pub export_map: ExportMap,
107 pub exported_items: middle::privacy::ExportedItems,
108 pub public_items: middle::privacy::PublicItems,
1a4d82fc
JJ
109 pub reachable: NodeSet,
110 pub name: String,
111 pub glob_map: Option<GlobMap>,
112}
113
114#[derive(Copy, Clone, PartialEq, Eq, Hash)]
115pub struct field<'tcx> {
116 pub name: ast::Name,
117 pub mt: mt<'tcx>
118}
119
85aaf69f 120#[derive(Clone, Copy, Debug)]
1a4d82fc
JJ
121pub enum ImplOrTraitItemContainer {
122 TraitContainer(ast::DefId),
123 ImplContainer(ast::DefId),
124}
125
126impl ImplOrTraitItemContainer {
127 pub fn id(&self) -> ast::DefId {
128 match *self {
129 TraitContainer(id) => id,
130 ImplContainer(id) => id,
131 }
132 }
133}
134
62682a34 135#[derive(Clone)]
1a4d82fc 136pub enum ImplOrTraitItem<'tcx> {
d9579d0f 137 ConstTraitItem(Rc<AssociatedConst<'tcx>>),
1a4d82fc 138 MethodTraitItem(Rc<Method<'tcx>>),
62682a34 139 TypeTraitItem(Rc<AssociatedType<'tcx>>),
1a4d82fc
JJ
140}
141
142impl<'tcx> ImplOrTraitItem<'tcx> {
143 fn id(&self) -> ImplOrTraitItemId {
144 match *self {
d9579d0f
AL
145 ConstTraitItem(ref associated_const) => {
146 ConstTraitItemId(associated_const.def_id)
147 }
1a4d82fc
JJ
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 {
d9579d0f 157 ConstTraitItem(ref associated_const) => associated_const.def_id,
1a4d82fc
JJ
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 {
d9579d0f 165 ConstTraitItem(ref associated_const) => associated_const.name,
1a4d82fc
JJ
166 MethodTraitItem(ref method) => method.name,
167 TypeTraitItem(ref associated_type) => associated_type.name,
168 }
169 }
170
d9579d0f
AL
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
1a4d82fc
JJ
179 pub fn container(&self) -> ImplOrTraitItemContainer {
180 match *self {
d9579d0f 181 ConstTraitItem(ref associated_const) => associated_const.container,
1a4d82fc
JJ
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()),
d9579d0f 190 _ => None,
1a4d82fc
JJ
191 }
192 }
193}
194
85aaf69f 195#[derive(Clone, Copy, Debug)]
1a4d82fc 196pub enum ImplOrTraitItemId {
d9579d0f 197 ConstTraitItemId(ast::DefId),
1a4d82fc
JJ
198 MethodTraitItemId(ast::DefId),
199 TypeTraitItemId(ast::DefId),
200}
201
202impl ImplOrTraitItemId {
203 pub fn def_id(&self) -> ast::DefId {
204 match *self {
d9579d0f 205 ConstTraitItemId(def_id) => def_id,
1a4d82fc
JJ
206 MethodTraitItemId(def_id) => def_id,
207 TypeTraitItemId(def_id) => def_id,
970d7e83 208 }
1a4d82fc
JJ
209 }
210}
211
85aaf69f 212#[derive(Clone, Debug)]
1a4d82fc
JJ
213pub struct Method<'tcx> {
214 pub name: ast::Name,
85aaf69f
SL
215 pub generics: Generics<'tcx>,
216 pub predicates: GenericPredicates<'tcx>,
1a4d82fc
JJ
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,
970d7e83 222
1a4d82fc
JJ
223 // If this method is provided, we need to know where it came from
224 pub provided_source: Option<ast::DefId>
225}
226
227impl<'tcx> Method<'tcx> {
228 pub fn new(name: ast::Name,
229 generics: ty::Generics<'tcx>,
85aaf69f 230 predicates: GenericPredicates<'tcx>,
1a4d82fc
JJ
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> {
970d7e83 238 Method {
1a4d82fc 239 name: name,
970d7e83 240 generics: generics,
85aaf69f 241 predicates: predicates,
970d7e83
LB
242 fty: fty,
243 explicit_self: explicit_self,
244 vis: vis,
1a4d82fc
JJ
245 def_id: def_id,
246 container: container,
247 provided_source: provided_source
970d7e83
LB
248 }
249 }
970d7e83 250
1a4d82fc
JJ
251 pub fn container_id(&self) -> ast::DefId {
252 match self.container {
253 TraitContainer(id) => id,
254 ImplContainer(id) => id,
255 }
256 }
223e47cc
LB
257}
258
d9579d0f
AL
259#[derive(Clone, Copy, Debug)]
260pub 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
85aaf69f 269#[derive(Clone, Copy, Debug)]
62682a34 270pub struct AssociatedType<'tcx> {
1a4d82fc 271 pub name: ast::Name,
62682a34 272 pub ty: Option<Ty<'tcx>>,
1a4d82fc
JJ
273 pub vis: ast::Visibility,
274 pub def_id: ast::DefId,
275 pub container: ImplOrTraitItemContainer,
223e47cc
LB
276}
277
85aaf69f 278#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1a4d82fc
JJ
279pub struct mt<'tcx> {
280 pub ty: Ty<'tcx>,
281 pub mutbl: ast::Mutability,
223e47cc
LB
282}
283
85aaf69f 284#[derive(Clone, Copy, Debug)]
223e47cc 285pub struct field_ty {
1a4d82fc
JJ
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.
223e47cc
LB
290}
291
1a4d82fc
JJ
292#[derive(Clone, PartialEq, RustcDecodable, RustcEncodable)]
293pub struct ItemVariances {
294 pub types: VecPerParamSpace<Variance>,
295 pub regions: VecPerParamSpace<Variance>,
296}
297
62682a34 298#[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Copy)]
1a4d82fc
JJ
299pub 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
62682a34 306#[derive(Copy, Clone)]
1a4d82fc 307pub enum AutoAdjustment<'tcx> {
9346a6ac
AL
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>),
1a4d82fc 311}
223e47cc 312
9346a6ac
AL
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/// ```
62682a34 375#[derive(Copy, Clone)]
1a4d82fc 376pub struct AutoDerefRef<'tcx> {
9346a6ac 377 /// Step 1. Apply a number of dereferences, producing an lvalue.
c34b1796 378 pub autoderefs: usize,
223e47cc 379
9346a6ac
AL
380 /// Step 2. Optionally produce a pointer/reference from the value.
381 pub autoref: Option<AutoRef<'tcx>>,
1a4d82fc 382
9346a6ac
AL
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>>,
223e47cc
LB
387}
388
9346a6ac
AL
389#[derive(Copy, Clone, PartialEq, Debug)]
390pub enum AutoRef<'tcx> {
391 /// Convert from T to &T.
392 AutoPtr(&'tcx Region, ast::Mutability),
223e47cc 393
9346a6ac
AL
394 /// Convert from T to *T.
395 /// Value to thin pointer.
396 AutoUnsafe(ast::Mutability),
223e47cc
LB
397}
398
d9579d0f
AL
399#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
400pub enum CustomCoerceUnsized {
401 /// Records the index of the field being coerced.
402 Struct(usize)
403}
404
62682a34 405#[derive(Clone)]
1a4d82fc
JJ
406pub enum MethodOrigin<'tcx> {
407 // fully statically resolved method
408 MethodStatic(ast::DefId),
223e47cc 409
85aaf69f
SL
410 // fully statically resolved closure invocation
411 MethodStaticClosure(ast::DefId),
223e47cc 412
1a4d82fc
JJ
413 // method invoked on a type parameter with a bounded trait
414 MethodTypeParam(MethodParam<'tcx>),
223e47cc 415
1a4d82fc
JJ
416 // method invoked on a trait instance
417 MethodTraitObject(MethodObject<'tcx>),
970d7e83 418
223e47cc
LB
419}
420
1a4d82fc
JJ
421// details for a method invoked with a receiver whose type is a type parameter
422// with a bounded trait.
62682a34 423#[derive(Clone)]
1a4d82fc
JJ
424pub 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.
d9579d0f 429 pub trait_ref: ty::TraitRef<'tcx>,
1a4d82fc 430
c34b1796 431 // index of usize in the list of trait items. Note that this is NOT
85aaf69f
SL
432 // the index into the vtable, because the list of trait items
433 // includes associated types.
c34b1796 434 pub method_num: usize,
85aaf69f
SL
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>,
1a4d82fc
JJ
441}
442
443// details for a method invoked with a receiver whose type is an object
62682a34 444#[derive(Clone)]
1a4d82fc
JJ
445pub struct MethodObject<'tcx> {
446 // the (super)trait containing the method to be invoked
d9579d0f 447 pub trait_ref: TraitRef<'tcx>,
223e47cc 448
1a4d82fc
JJ
449 // the actual base trait id of the object
450 pub object_trait_id: ast::DefId,
223e47cc 451
85aaf69f 452 // index of the method to be invoked amongst the trait's items
c34b1796 453 pub method_num: usize,
1a4d82fc
JJ
454
455 // index into the actual runtime vtable.
456 // the vtable is formed by concatenating together the method lists of
85aaf69f 457 // the base object trait and all supertraits; this is the index into
1a4d82fc 458 // that vtable
c34b1796 459 pub vtable_index: usize,
223e47cc 460}
1a4d82fc 461
d9579d0f 462#[derive(Clone, Debug)]
1a4d82fc
JJ
463pub struct MethodCallee<'tcx> {
464 pub origin: MethodOrigin<'tcx>,
465 pub ty: Ty<'tcx>,
466 pub substs: subst::Substs<'tcx>
223e47cc 467}
1a4d82fc
JJ
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.
85aaf69f 481#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1a4d82fc
JJ
482pub struct MethodCall {
483 pub expr_id: ast::NodeId,
9346a6ac 484 pub autoderef: u32
223e47cc
LB
485}
486
1a4d82fc
JJ
487impl MethodCall {
488 pub fn expr(id: ast::NodeId) -> MethodCall {
489 MethodCall {
490 expr_id: id,
9346a6ac 491 autoderef: 0
1a4d82fc
JJ
492 }
493 }
494
9346a6ac 495 pub fn autoderef(expr_id: ast::NodeId, autoderef: u32) -> MethodCall {
1a4d82fc
JJ
496 MethodCall {
497 expr_id: expr_id,
9346a6ac 498 autoderef: 1 + autoderef
1a4d82fc
JJ
499 }
500 }
223e47cc
LB
501}
502
1a4d82fc
JJ
503// maps from an expression id that corresponds to a method call to the details
504// of the method to be invoked
505pub type MethodMap<'tcx> = RefCell<FnvHashMap<MethodCall, MethodCallee<'tcx>>>;
223e47cc 506
62682a34
SL
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)]
510pub struct creader_cache_key {
511 pub cnum: CrateNum,
512 pub pos: usize,
513 pub len: usize
970d7e83
LB
514}
515
1a4d82fc
JJ
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`.
c34b1796 522#[derive(Copy, Clone)]
1a4d82fc
JJ
523pub struct TransmuteRestriction<'tcx> {
524 /// The span whence the restriction comes.
525 pub span: Span,
970d7e83 526
1a4d82fc
JJ
527 /// The type being transmuted from.
528 pub original_from: Ty<'tcx>,
970d7e83 529
1a4d82fc
JJ
530 /// The type being transmuted to.
531 pub original_to: Ty<'tcx>,
970d7e83 532
1a4d82fc
JJ
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>,
223e47cc 537
1a4d82fc
JJ
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>,
223e47cc 542
1a4d82fc
JJ
543 /// NodeId of the transmute intrinsic.
544 pub id: ast::NodeId,
223e47cc
LB
545}
546
1a4d82fc
JJ
547/// Internal storage
548pub struct CtxtArenas<'tcx> {
d9579d0f 549 // internings
1a4d82fc
JJ
550 type_: TypedArena<TyS<'tcx>>,
551 substs: TypedArena<Substs<'tcx>>,
552 bare_fn: TypedArena<BareFnTy<'tcx>>,
553 region: TypedArena<Region>,
62682a34 554 stability: TypedArena<attr::Stability>,
d9579d0f
AL
555
556 // references
62682a34 557 trait_defs: TypedArena<TraitDef<'tcx>>,
970d7e83
LB
558}
559
1a4d82fc
JJ
560impl<'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(),
62682a34 567 stability: TypedArena::new(),
d9579d0f
AL
568
569 trait_defs: TypedArena::new()
1a4d82fc
JJ
570 }
571 }
223e47cc
LB
572}
573
1a4d82fc
JJ
574pub struct CommonTypes<'tcx> {
575 pub bool: Ty<'tcx>,
576 pub char: Ty<'tcx>,
c34b1796 577 pub isize: Ty<'tcx>,
1a4d82fc
JJ
578 pub i8: Ty<'tcx>,
579 pub i16: Ty<'tcx>,
580 pub i32: Ty<'tcx>,
581 pub i64: Ty<'tcx>,
c34b1796 582 pub usize: Ty<'tcx>,
1a4d82fc
JJ
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.
595pub 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>>,
62682a34 609 stability_interner: RefCell<FnvHashMap<&'tcx attr::Stability, &'tcx attr::Stability>>,
1a4d82fc
JJ
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
bd371182
AL
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>>,
1a4d82fc
JJ
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.
c34b1796 631 node_types: RefCell<NodeMap<Ty<'tcx>>>,
1a4d82fc
JJ
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
62682a34 648 pub impl_trait_refs: RefCell<DefIdMap<Option<TraitRef<'tcx>>>>,
d9579d0f 649 pub trait_defs: RefCell<DefIdMap<&'tcx TraitDef<'tcx>>>,
1a4d82fc 650
85aaf69f
SL
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
c34b1796
AL
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
1a4d82fc 663 pub map: ast_map::Map<'tcx>,
1a4d82fc
JJ
664 pub freevars: RefCell<FreevarMap>,
665 pub tcache: RefCell<DefIdMap<TypeScheme<'tcx>>>,
666 pub rcache: RefCell<FnvHashMap<creader_cache_key, Ty<'tcx>>>,
1a4d82fc 667 pub tc_cache: RefCell<FnvHashMap<Ty<'tcx>, TypeContents>>,
c34b1796 668 pub ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
1a4d82fc
JJ
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
1a4d82fc
JJ
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>,
d9579d0f
AL
717 /// The set of external primitive types whose implementations have been read.
718 /// FIXME(arielb1): why is this separate from populated_external_types?
c34b1796
AL
719 pub populated_external_primitive_impls: RefCell<DefIdSet>,
720
1a4d82fc 721 /// Borrows
85aaf69f 722 pub upvar_capture_map: RefCell<UpvarCaptureMap>,
1a4d82fc 723
62682a34 724 /// These caches are used by const_eval when decoding external constants.
1a4d82fc
JJ
725 pub extern_const_statics: RefCell<DefIdMap<ast::NodeId>>,
726 pub extern_const_variants: RefCell<DefIdMap<ast::NodeId>>,
62682a34 727 pub extern_const_fns: RefCell<DefIdMap<ast::NodeId>>,
1a4d82fc
JJ
728
729 pub method_map: MethodMap<'tcx>,
730
731 pub dependency_formats: RefCell<dependency_format::Dependencies>,
732
85aaf69f
SL
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>>>,
1a4d82fc
JJ
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.
62682a34 750 pub stability: RefCell<stability::Index<'tcx>>,
1a4d82fc
JJ
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
62682a34
SL
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
1a4d82fc
JJ
762 /// Caches the representation hints for struct definitions.
763 pub repr_hint_cache: RefCell<DefIdMap<Rc<Vec<attr::ReprAttr>>>>,
764
85aaf69f
SL
765 /// Maps Expr NodeId's to their constant qualification.
766 pub const_qualif_map: RefCell<NodeMap<check_const::ConstQualif>>,
d9579d0f
AL
767
768 /// Caches CoerceUnsized kinds for impls on custom types.
769 pub custom_coerce_unsized_kinds: RefCell<DefIdMap<CustomCoerceUnsized>>,
62682a34
SL
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>>,
1a4d82fc
JJ
774}
775
c34b1796
AL
776impl<'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 }
bd371182 781
d9579d0f
AL
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
62682a34
SL
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
bd371182
AL
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 }
62682a34
SL
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.
824pub trait Lift<'tcx> {
825 type Lifted;
826 fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<Self::Lifted>;
827}
828
829impl<'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
836impl<'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
851impl<'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
858impl<'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
870impl<'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
882impl<'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
892impl<'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
901impl<'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
908impl<'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
915impl<'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
930impl<'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
937pub 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 }
c34b1796
AL
1002}
1003
1a4d82fc
JJ
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.
1008bitflags! {
1009 flags TypeFlags: u32 {
62682a34
SL
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 |
d9579d0f 1032 TypeFlags::HAS_SELF.bits |
62682a34
SL
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,
1a4d82fc
JJ
1047 }
1048}
1049
1050macro_rules! sty_debug_print {
1051 ($ctxt: expr, $($variant: ident),*) => {{
1052 // curious inner module to allow variant names to be used as
1053 // variable names.
62682a34 1054 #[allow(non_snake_case)]
1a4d82fc
JJ
1055 mod inner {
1056 use middle::ty;
c34b1796 1057 #[derive(Copy, Clone)]
1a4d82fc 1058 struct DebugStat {
c34b1796
AL
1059 total: usize,
1060 region_infer: usize,
1061 ty_infer: usize,
1062 both_infer: usize,
1a4d82fc 1063 }
223e47cc 1064
1a4d82fc
JJ
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
62682a34 1073 for (_, t) in tcx.interner.borrow().iter() {
1a4d82fc 1074 let variant = match t.sty {
62682a34
SL
1075 ty::TyBool | ty::TyChar | ty::TyInt(..) | ty::TyUint(..) |
1076 ty::TyFloat(..) | ty::TyStr => continue,
1077 ty::TyError => /* unimportant */ continue,
1a4d82fc
JJ
1078 $(ty::$variant(..) => &mut $variant,)*
1079 };
62682a34
SL
1080 let region = t.flags.get().intersects(ty::TypeFlags::HAS_RE_INFER);
1081 let ty = t.flags.get().intersects(ty::TypeFlags::HAS_TY_INFER);
1a4d82fc
JJ
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 }
223e47cc 1107
1a4d82fc
JJ
1108 inner::go($ctxt)
1109 }}
223e47cc
LB
1110}
1111
1a4d82fc
JJ
1112impl<'tcx> ctxt<'tcx> {
1113 pub fn print_debug_stats(&self) {
1114 sty_debug_print!(
1115 self,
62682a34
SL
1116 TyEnum, TyBox, TyArray, TySlice, TyRawPtr, TyRef, TyBareFn, TyTrait,
1117 TyStruct, TyClosure, TyTuple, TyParam, TyInfer, TyProjection);
1a4d82fc
JJ
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());
62682a34 1122 println!("Stability interner: #{}", self.stability_interner.borrow().len());
1a4d82fc 1123 }
223e47cc
LB
1124}
1125
1a4d82fc 1126pub struct TyS<'tcx> {
62682a34
SL
1127 pub sty: TypeVariants<'tcx>,
1128 pub flags: Cell<TypeFlags>,
970d7e83 1129
1a4d82fc
JJ
1130 // the maximal depth of any bound regions appearing in this type.
1131 region_depth: u32,
970d7e83
LB
1132}
1133
85aaf69f 1134impl fmt::Debug for TypeFlags {
1a4d82fc
JJ
1135 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1136 write!(f, "{}", self.bits)
1137 }
970d7e83
LB
1138}
1139
1a4d82fc 1140impl<'tcx> PartialEq for TyS<'tcx> {
d9579d0f 1141 #[inline]
1a4d82fc 1142 fn eq(&self, other: &TyS<'tcx>) -> bool {
85aaf69f
SL
1143 // (self as *const _) == (other as *const _)
1144 (self as *const TyS<'tcx>) == (other as *const TyS<'tcx>)
1a4d82fc 1145 }
970d7e83 1146}
1a4d82fc 1147impl<'tcx> Eq for TyS<'tcx> {}
970d7e83 1148
85aaf69f
SL
1149impl<'tcx> Hash for TyS<'tcx> {
1150 fn hash<H: Hasher>(&self, s: &mut H) {
c34b1796 1151 (self as *const TyS).hash(s)
970d7e83
LB
1152 }
1153}
1154
1a4d82fc 1155pub type Ty<'tcx> = &'tcx TyS<'tcx>;
223e47cc 1156
1a4d82fc
JJ
1157/// An entry in the type interner.
1158pub struct InternedTy<'tcx> {
1159 ty: Ty<'tcx>
223e47cc
LB
1160}
1161
1a4d82fc
JJ
1162// NB: An InternedTy compares and hashes as a sty.
1163impl<'tcx> PartialEq for InternedTy<'tcx> {
1164 fn eq(&self, other: &InternedTy<'tcx>) -> bool {
1165 self.ty.sty == other.ty.sty
1166 }
223e47cc
LB
1167}
1168
1a4d82fc 1169impl<'tcx> Eq for InternedTy<'tcx> {}
223e47cc 1170
85aaf69f
SL
1171impl<'tcx> Hash for InternedTy<'tcx> {
1172 fn hash<H: Hasher>(&self, s: &mut H) {
1173 self.ty.sty.hash(s)
1174 }
1175}
223e47cc 1176
62682a34
SL
1177impl<'tcx> Borrow<TypeVariants<'tcx>> for InternedTy<'tcx> {
1178 fn borrow<'a>(&'a self) -> &'a TypeVariants<'tcx> {
85aaf69f 1179 &self.ty.sty
1a4d82fc 1180 }
223e47cc
LB
1181}
1182
1a4d82fc 1183pub fn type_has_params(ty: Ty) -> bool {
62682a34 1184 ty.flags.get().intersects(TypeFlags::HAS_PARAMS)
223e47cc 1185}
1a4d82fc 1186pub fn type_has_self(ty: Ty) -> bool {
62682a34 1187 ty.flags.get().intersects(TypeFlags::HAS_SELF)
1a4d82fc
JJ
1188}
1189pub fn type_has_ty_infer(ty: Ty) -> bool {
62682a34 1190 ty.flags.get().intersects(TypeFlags::HAS_TY_INFER)
1a4d82fc
JJ
1191}
1192pub fn type_needs_infer(ty: Ty) -> bool {
62682a34
SL
1193 ty.flags.get().intersects(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER)
1194}
1195pub fn type_is_global(ty: Ty) -> bool {
1196 !ty.flags.get().intersects(TypeFlags::HAS_LOCAL_NAMES)
1a4d82fc
JJ
1197}
1198pub fn type_has_projection(ty: Ty) -> bool {
62682a34
SL
1199 ty.flags.get().intersects(TypeFlags::HAS_PROJECTION)
1200}
1201pub fn type_has_ty_closure(ty: Ty) -> bool {
1202 ty.flags.get().intersects(TypeFlags::HAS_TY_CLOSURE)
223e47cc
LB
1203}
1204
62682a34
SL
1205pub 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)
223e47cc
LB
1209}
1210
1a4d82fc
JJ
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///
c34b1796 1215/// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize))
1a4d82fc
JJ
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.
1233pub fn type_has_escaping_regions(ty: Ty) -> bool {
1234 type_escapes_depth(ty, 0)
223e47cc
LB
1235}
1236
1a4d82fc
JJ
1237pub fn type_escapes_depth(ty: Ty, depth: u32) -> bool {
1238 ty.region_depth > depth
223e47cc
LB
1239}
1240
85aaf69f 1241#[derive(Clone, PartialEq, Eq, Hash, Debug)]
1a4d82fc
JJ
1242pub struct BareFnTy<'tcx> {
1243 pub unsafety: ast::Unsafety,
1244 pub abi: abi::Abi,
1245 pub sig: PolyFnSig<'tcx>,
223e47cc
LB
1246}
1247
62682a34 1248#[derive(Clone, PartialEq, Eq, Hash)]
1a4d82fc
JJ
1249pub struct ClosureTy<'tcx> {
1250 pub unsafety: ast::Unsafety,
1a4d82fc 1251 pub abi: abi::Abi,
85aaf69f 1252 pub sig: PolyFnSig<'tcx>,
223e47cc
LB
1253}
1254
85aaf69f 1255#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1a4d82fc
JJ
1256pub enum FnOutput<'tcx> {
1257 FnConverging(Ty<'tcx>),
1258 FnDiverging
223e47cc
LB
1259}
1260
1a4d82fc
JJ
1261impl<'tcx> FnOutput<'tcx> {
1262 pub fn diverges(&self) -> bool {
1263 *self == FnDiverging
223e47cc 1264 }
223e47cc 1265
1a4d82fc
JJ
1266 pub fn unwrap(self) -> Ty<'tcx> {
1267 match self {
1268 ty::FnConverging(t) => t,
1269 ty::FnDiverging => unreachable!()
223e47cc
LB
1270 }
1271 }
9346a6ac
AL
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 }
223e47cc
LB
1279}
1280
1a4d82fc
JJ
1281pub type PolyFnOutput<'tcx> = Binder<FnOutput<'tcx>>;
1282
1283impl<'tcx> PolyFnOutput<'tcx> {
1284 pub fn diverges(&self) -> bool {
1285 self.0.diverges()
223e47cc
LB
1286 }
1287}
1288
1a4d82fc
JJ
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)]
1296pub struct FnSig<'tcx> {
1297 pub inputs: Vec<Ty<'tcx>>,
1298 pub output: FnOutput<'tcx>,
1299 pub variadic: bool
223e47cc
LB
1300}
1301
1a4d82fc 1302pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;
223e47cc 1303
1a4d82fc
JJ
1304impl<'tcx> PolyFnSig<'tcx> {
1305 pub fn inputs(&self) -> ty::Binder<Vec<Ty<'tcx>>> {
c34b1796 1306 self.map_bound_ref(|fn_sig| fn_sig.inputs.clone())
223e47cc 1307 }
c34b1796
AL
1308 pub fn input(&self, index: usize) -> ty::Binder<Ty<'tcx>> {
1309 self.map_bound_ref(|fn_sig| fn_sig.inputs[index])
1a4d82fc
JJ
1310 }
1311 pub fn output(&self) -> ty::Binder<FnOutput<'tcx>> {
c34b1796 1312 self.map_bound_ref(|fn_sig| fn_sig.output.clone())
1a4d82fc
JJ
1313 }
1314 pub fn variadic(&self) -> bool {
c34b1796 1315 self.skip_binder().variadic
1a4d82fc
JJ
1316 }
1317}
1318
62682a34 1319#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1a4d82fc
JJ
1320pub struct ParamTy {
1321 pub space: subst::ParamSpace,
1322 pub idx: u32,
1323 pub name: ast::Name,
223e47cc
LB
1324}
1325
1a4d82fc
JJ
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///
c34b1796 1330/// for<'a> fn(for<'b> fn(&'b isize, &'a isize), &'a char)
1a4d82fc
JJ
1331/// ^ ^ | | |
1332/// | | | | |
1333/// | +------------+ 1 | |
1334/// | | |
1335/// +--------------------------------+ 2 |
1336/// | |
1337/// +------------------------------------------+ 1
223e47cc 1338///
1a4d82fc
JJ
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.
223e47cc 1346///
c34b1796 1347/// Let's start with the reference type `&'b isize` that is the first
1a4d82fc
JJ
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
c34b1796 1351/// isize`) would then be assigned a De Bruijn index of 2, meaning "the
1a4d82fc
JJ
1352/// second-innermost binder". (These indices are written on the arrays
1353/// in the diagram).
223e47cc 1354///
1a4d82fc
JJ
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
85aaf69f 1365#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, Copy)]
1a4d82fc
JJ
1366pub 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,
223e47cc
LB
1370}
1371
1a4d82fc 1372/// Representation of regions:
62682a34 1373#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Copy)]
1a4d82fc
JJ
1374pub 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.
9346a6ac 1378 ReEarlyBound(EarlyBoundRegion),
1a4d82fc
JJ
1379
1380 // Region bound in a function scope, which will be substituted when the
1381 // function is called.
1382 ReLateBound(DebruijnIndex, BoundRegion),
970d7e83 1383
1a4d82fc
JJ
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),
223e47cc 1388
85aaf69f
SL
1389 /// A concrete region naming some statically determined extent
1390 /// (e.g. an expression or sequence of statements) within the
1391 /// current function.
1a4d82fc 1392 ReScope(region::CodeExtent),
223e47cc 1393
1a4d82fc
JJ
1394 /// Static data that has an "infinite" lifetime. Top in the region lattice.
1395 ReStatic,
223e47cc 1396
1a4d82fc
JJ
1397 /// A region variable. Should not exist after typeck.
1398 ReInfer(InferRegion),
970d7e83 1399
1a4d82fc
JJ
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
9346a6ac
AL
1410#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
1411pub struct EarlyBoundRegion {
1412 pub param_id: ast::NodeId,
1413 pub space: subst::ParamSpace,
1414 pub index: u32,
1415 pub name: ast::Name,
1416}
1417
1a4d82fc
JJ
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.
62682a34 1421#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1a4d82fc
JJ
1422pub struct UpvarId {
1423 pub var_id: ast::NodeId,
1424 pub closure_expr_id: ast::NodeId,
1425}
1426
85aaf69f 1427#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)]
1a4d82fc
JJ
1428pub 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 ///
c34b1796 1437 /// let x: &mut isize = ...;
1a4d82fc
JJ
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 ///
c34b1796
AL
1443 /// struct Env { x: & &mut isize }
1444 /// let x: &mut isize = ...;
1a4d82fc
JJ
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 ///
c34b1796
AL
1452 /// struct Env { x: & &mut isize }
1453 /// let x: &mut isize = ...;
1a4d82fc
JJ
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
85aaf69f
SL
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)]
1476pub 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
62682a34 1486#[derive(PartialEq, Clone, RustcEncodable, RustcDecodable, Copy)]
1a4d82fc 1487pub struct UpvarBorrow {
85aaf69f
SL
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.
1a4d82fc 1491 pub kind: BorrowKind,
85aaf69f
SL
1492
1493 /// Region of the resulting reference.
1a4d82fc
JJ
1494 pub region: ty::Region,
1495}
1496
85aaf69f 1497pub type UpvarCaptureMap = FnvHashMap<UpvarId, UpvarCapture>;
223e47cc 1498
1a4d82fc 1499impl Region {
62682a34
SL
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
1a4d82fc
JJ
1509 pub fn is_bound(&self) -> bool {
1510 match *self {
1511 ty::ReEarlyBound(..) => true,
1512 ty::ReLateBound(..) => true,
1513 _ => false
223e47cc
LB
1514 }
1515 }
223e47cc 1516
1a4d82fc
JJ
1517 pub fn escapes_depth(&self, depth: u32) -> bool {
1518 match *self {
1519 ty::ReLateBound(debruijn, _) => debruijn.depth > depth,
1520 _ => false,
1521 }
970d7e83
LB
1522 }
1523}
1524
1a4d82fc 1525#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash,
62682a34 1526 RustcEncodable, RustcDecodable, Copy)]
1a4d82fc
JJ
1527/// A "free" region `fr` can be interpreted as "some region
1528/// at least as big as the scope `fr.scope`".
1529pub struct FreeRegion {
85aaf69f 1530 pub scope: region::DestructionScopeData,
1a4d82fc 1531 pub bound_region: BoundRegion
223e47cc
LB
1532}
1533
1a4d82fc 1534#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash,
62682a34 1535 RustcEncodable, RustcDecodable, Copy, Debug)]
1a4d82fc
JJ
1536pub enum BoundRegion {
1537 /// An anonymous region parameter for a given fn (&T)
1538 BrAnon(u32),
223e47cc 1539
1a4d82fc
JJ
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),
223e47cc 1545
1a4d82fc
JJ
1546 /// Fresh bound identifiers created during GLB computations.
1547 BrFresh(u32),
223e47cc 1548
1a4d82fc
JJ
1549 // Anonymous region for the implicit env pointer parameter
1550 // to a closure
1551 BrEnv
1552}
223e47cc 1553
1a4d82fc
JJ
1554// NB: If you change this, you'll probably want to change the corresponding
1555// AST structure in libsyntax/ast.rs as well.
85aaf69f 1556#[derive(Clone, PartialEq, Eq, Hash, Debug)]
62682a34
SL
1557pub 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.
1a4d82fc 1577 /// That is, even after substitution it is possible that there are type
62682a34
SL
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`
1a4d82fc 1580 /// from the tcx, use the `NodeId` from the `ast::Ty` and look it up in
62682a34 1581 /// the `ast_ty_to_ty_cache`. This is probably true for `TyStruct` as
c34b1796 1582 /// well.
62682a34 1583 TyEnum(DefId, &'tcx Substs<'tcx>),
1a4d82fc 1584
62682a34
SL
1585 /// A structure type, defined with `struct`.
1586 ///
1587 /// See warning about substitutions for enumerated types.
1588 TyStruct(DefId, &'tcx Substs<'tcx>),
1a4d82fc 1589
62682a34
SL
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>),
1a4d82fc 1595
62682a34
SL
1596 /// The pointee of a string slice. Written as `str`.
1597 TyStr,
1a4d82fc 1598
62682a34
SL
1599 /// An array with the given length. Written as `[T; n]`.
1600 TyArray(Ty<'tcx>, usize),
1a4d82fc 1601
62682a34
SL
1602 /// The pointee of an array slice. Written as `[T]`.
1603 TySlice(Ty<'tcx>),
1a4d82fc 1604
62682a34
SL
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,
1a4d82fc 1644}
223e47cc 1645
62682a34
SL
1646#[derive(Clone, PartialEq, Eq, Hash)]
1647pub struct TraitTy<'tcx> {
1a4d82fc
JJ
1648 pub principal: ty::PolyTraitRef<'tcx>,
1649 pub bounds: ExistentialBounds<'tcx>,
1650}
223e47cc 1651
62682a34 1652impl<'tcx> TraitTy<'tcx> {
1a4d82fc
JJ
1653 pub fn principal_def_id(&self) -> ast::DefId {
1654 self.principal.0.def_id
1655 }
223e47cc 1656
1a4d82fc
JJ
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());
223e47cc 1668
d9579d0f 1669 ty::Binder(TraitRef {
1a4d82fc
JJ
1670 def_id: self.principal.0.def_id,
1671 substs: tcx.mk_substs(self.principal.0.substs.with_self_ty(self_ty)),
d9579d0f 1672 })
1a4d82fc 1673 }
223e47cc 1674
1a4d82fc
JJ
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));
d9579d0f
AL
1687 let trait_ref = ty::TraitRef::new(in_projection_ty.trait_ref.def_id,
1688 substs);
1a4d82fc
JJ
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}
223e47cc 1701
1a4d82fc
JJ
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.
62682a34 1717#[derive(Copy, Clone, PartialEq, Eq, Hash)]
1a4d82fc
JJ
1718pub struct TraitRef<'tcx> {
1719 pub def_id: DefId,
1720 pub substs: &'tcx Substs<'tcx>,
1721}
223e47cc 1722
d9579d0f 1723pub type PolyTraitRef<'tcx> = Binder<TraitRef<'tcx>>;
223e47cc 1724
1a4d82fc
JJ
1725impl<'tcx> PolyTraitRef<'tcx> {
1726 pub fn self_ty(&self) -> Ty<'tcx> {
1727 self.0.self_ty()
1728 }
223e47cc 1729
1a4d82fc
JJ
1730 pub fn def_id(&self) -> ast::DefId {
1731 self.0.def_id
1732 }
223e47cc 1733
1a4d82fc
JJ
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
970d7e83 1737 }
223e47cc 1738
1a4d82fc
JJ
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()
970d7e83 1742 }
223e47cc 1743
1a4d82fc
JJ
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() })
970d7e83 1747 }
223e47cc
LB
1748}
1749
1a4d82fc 1750/// Binder is a binder for higher-ranked lifetimes. It is part of the
c34b1796 1751/// compiler's representation for things like `for<'a> Fn(&'a isize)`
1a4d82fc
JJ
1752/// (which would be represented by the type `PolyTraitRef ==
1753/// Binder<TraitRef>`). Note that when we skolemize, instantiate,
85aaf69f 1754/// erase, or otherwise "discharge" these bound regions, we change the
1a4d82fc
JJ
1755/// type from `Binder<T>` to just `T` (see
1756/// e.g. `liberate_late_bound_regions`).
85aaf69f 1757#[derive(Clone, PartialEq, Eq, Hash, Debug)]
1a4d82fc 1758pub struct Binder<T>(pub T);
223e47cc 1759
c34b1796
AL
1760impl<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
1a4d82fc
JJ
1797#[derive(Clone, Copy, PartialEq)]
1798pub enum IntVarValue {
1799 IntType(ast::IntTy),
1800 UintType(ast::UintTy),
223e47cc
LB
1801}
1802
85aaf69f 1803#[derive(Clone, Copy, Debug)]
1a4d82fc
JJ
1804pub enum terr_vstore_kind {
1805 terr_vec,
1806 terr_str,
1807 terr_fn,
1808 terr_trait
223e47cc
LB
1809}
1810
85aaf69f 1811#[derive(Clone, Copy, Debug)]
1a4d82fc
JJ
1812pub struct expected_found<T> {
1813 pub expected: T,
1814 pub found: T
223e47cc
LB
1815}
1816
1a4d82fc 1817// Data structures used in type unification
85aaf69f 1818#[derive(Clone, Copy, Debug)]
1a4d82fc
JJ
1819pub enum type_err<'tcx> {
1820 terr_mismatch,
1821 terr_unsafety_mismatch(expected_found<ast::Unsafety>),
1a4d82fc
JJ
1822 terr_abi_mismatch(expected_found<abi::Abi>),
1823 terr_mutability,
1a4d82fc
JJ
1824 terr_box_mutability,
1825 terr_ptr_mutability,
1826 terr_ref_mutability,
1827 terr_vec_mutability,
c34b1796
AL
1828 terr_tuple_size(expected_found<usize>),
1829 terr_fixed_array_size(expected_found<usize>),
1830 terr_ty_param_size(expected_found<usize>),
1a4d82fc
JJ
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),
1a4d82fc
JJ
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>),
c34b1796 1847 terr_projection_bounds_length(expected_found<usize>),
1a4d82fc
JJ
1848}
1849
1a4d82fc 1850/// Bounds suitable for an existentially quantified type parameter
62682a34
SL
1851/// such as those that appear in object types or closure types.
1852#[derive(PartialEq, Eq, Hash, Clone)]
1a4d82fc
JJ
1853pub struct ExistentialBounds<'tcx> {
1854 pub region_bound: ty::Region,
1855 pub builtin_bounds: BuiltinBounds,
1856 pub projection_bounds: Vec<PolyProjectionPredicate<'tcx>>,
62682a34
SL
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,
223e47cc
LB
1862}
1863
62682a34
SL
1864#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1865pub struct BuiltinBounds(EnumSet<BuiltinBound>);
223e47cc 1866
62682a34
SL
1867impl 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
1888impl ops::Deref for BuiltinBounds {
1889 type Target = EnumSet<BuiltinBound>;
1890 fn deref(&self) -> &Self::Target { &self.0 }
1891}
1892
1893impl ops::DerefMut for BuiltinBounds {
1894 fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
223e47cc
LB
1895}
1896
62682a34
SL
1897impl<'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 }
223e47cc
LB
1903}
1904
62682a34
SL
1905#[derive(Clone, RustcEncodable, PartialEq, Eq, RustcDecodable, Hash,
1906 Debug, Copy)]
1907#[repr(usize)]
1908pub enum BuiltinBound {
1909 Send,
1910 Sized,
1911 Copy,
1912 Sync,
223e47cc
LB
1913}
1914
1a4d82fc
JJ
1915/// An existential bound that does not implement any traits.
1916pub fn region_existential_bound<'tcx>(r: ty::Region) -> ExistentialBounds<'tcx> {
1917 ty::ExistentialBounds { region_bound: r,
62682a34
SL
1918 builtin_bounds: BuiltinBounds::empty(),
1919 projection_bounds: Vec::new(),
1920 region_bound_will_change: false, }
223e47cc
LB
1921}
1922
1a4d82fc 1923impl CLike for BuiltinBound {
c34b1796
AL
1924 fn to_usize(&self) -> usize {
1925 *self as usize
1a4d82fc 1926 }
c34b1796 1927 fn from_usize(v: usize) -> BuiltinBound {
1a4d82fc
JJ
1928 unsafe { mem::transmute(v) }
1929 }
223e47cc
LB
1930}
1931
1a4d82fc
JJ
1932#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1933pub struct TyVid {
1934 pub index: u32
223e47cc 1935}
223e47cc 1936
1a4d82fc
JJ
1937#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1938pub struct IntVid {
1939 pub index: u32
223e47cc
LB
1940}
1941
1a4d82fc
JJ
1942#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1943pub struct FloatVid {
1944 pub index: u32
223e47cc
LB
1945}
1946
1a4d82fc
JJ
1947#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1948pub struct RegionVid {
1949 pub index: u32
223e47cc
LB
1950}
1951
1a4d82fc
JJ
1952#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1953pub enum InferTy {
1954 TyVar(TyVid),
1955 IntVar(IntVid),
1956 FloatVar(FloatVid),
223e47cc 1957
1a4d82fc
JJ
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),
1a4d82fc 1962 FreshIntTy(u32),
d9579d0f 1963 FreshFloatTy(u32)
223e47cc
LB
1964}
1965
85aaf69f 1966#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)]
1a4d82fc
JJ
1967pub enum UnconstrainedNumeric {
1968 UnconstrainedFloat,
1969 UnconstrainedInt,
1970 Neither,
1971}
223e47cc 1972
223e47cc 1973
85aaf69f 1974#[derive(Clone, RustcEncodable, RustcDecodable, Eq, Hash, Debug, Copy)]
1a4d82fc
JJ
1975pub enum InferRegion {
1976 ReVar(RegionVid),
1977 ReSkolemized(u32, BoundRegion)
1978}
223e47cc 1979
1a4d82fc
JJ
1980impl 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}
223e47cc 1996
85aaf69f 1997impl fmt::Debug for TyVid {
62682a34 1998 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1a4d82fc
JJ
1999 write!(f, "_#{}t", self.index)
2000 }
223e47cc
LB
2001}
2002
85aaf69f 2003impl fmt::Debug for IntVid {
1a4d82fc
JJ
2004 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2005 write!(f, "_#{}i", self.index)
2006 }
2007}
223e47cc 2008
85aaf69f 2009impl fmt::Debug for FloatVid {
1a4d82fc
JJ
2010 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2011 write!(f, "_#{}f", self.index)
2012 }
223e47cc
LB
2013}
2014
85aaf69f 2015impl fmt::Debug for RegionVid {
1a4d82fc
JJ
2016 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2017 write!(f, "'_#{}r", self.index)
2018 }
2019}
223e47cc 2020
85aaf69f 2021impl<'tcx> fmt::Debug for FnSig<'tcx> {
1a4d82fc
JJ
2022 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2023 write!(f, "({:?}; variadic: {})->{:?}", self.inputs, self.variadic, self.output)
2024 }
223e47cc
LB
2025}
2026
85aaf69f 2027impl fmt::Debug for InferTy {
1a4d82fc
JJ
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),
d9579d0f 2035 FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v)
1a4d82fc 2036 }
970d7e83 2037 }
1a4d82fc
JJ
2038}
2039
85aaf69f 2040impl fmt::Debug for IntVarValue {
1a4d82fc
JJ
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 }
223e47cc
LB
2046 }
2047}
2048
85aaf69f
SL
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.
62682a34 2054#[derive(Copy, Clone)]
85aaf69f
SL
2055pub enum ObjectLifetimeDefault {
2056 /// Require an explicit annotation. Occurs when multiple
2057 /// `T:'a` constraints are found.
2058 Ambiguous,
2059
62682a34
SL
2060 /// Use the base default, typically 'static, but in a fn body it is a fresh variable
2061 BaseDefault,
2062
85aaf69f
SL
2063 /// Use the given region as the default.
2064 Specific(Region),
2065}
2066
62682a34 2067#[derive(Clone)]
1a4d82fc
JJ
2068pub struct TypeParameterDef<'tcx> {
2069 pub name: ast::Name,
2070 pub def_id: ast::DefId,
2071 pub space: subst::ParamSpace,
2072 pub index: u32,
1a4d82fc 2073 pub default: Option<Ty<'tcx>>,
62682a34 2074 pub object_lifetime_default: ObjectLifetimeDefault,
223e47cc
LB
2075}
2076
85aaf69f 2077#[derive(RustcEncodable, RustcDecodable, Clone, Debug)]
1a4d82fc
JJ
2078pub 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}
223e47cc 2085
1a4d82fc
JJ
2086impl RegionParameterDef {
2087 pub fn to_early_bound_region(&self) -> ty::Region {
9346a6ac
AL
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 })
223e47cc 2094 }
c34b1796
AL
2095 pub fn to_bound_region(&self) -> ty::BoundRegion {
2096 ty::BoundRegion::BrNamed(self.def_id, self.name)
2097 }
223e47cc
LB
2098}
2099
1a4d82fc
JJ
2100/// Information about the formal type/lifetime parameters associated
2101/// with an item or method. Analogous to ast::Generics.
85aaf69f 2102#[derive(Clone, Debug)]
1a4d82fc
JJ
2103pub struct Generics<'tcx> {
2104 pub types: VecPerParamSpace<TypeParameterDef<'tcx>>,
2105 pub regions: VecPerParamSpace<RegionParameterDef>,
970d7e83
LB
2106}
2107
1a4d82fc
JJ
2108impl<'tcx> Generics<'tcx> {
2109 pub fn empty() -> Generics<'tcx> {
2110 Generics {
2111 types: VecPerParamSpace::empty(),
2112 regions: VecPerParamSpace::empty(),
1a4d82fc 2113 }
223e47cc
LB
2114 }
2115
85aaf69f
SL
2116 pub fn is_empty(&self) -> bool {
2117 self.types.is_empty() && self.regions.is_empty()
2118 }
2119
1a4d82fc
JJ
2120 pub fn has_type_params(&self, space: subst::ParamSpace) -> bool {
2121 !self.types.is_empty_in(space)
223e47cc 2122 }
223e47cc 2123
1a4d82fc
JJ
2124 pub fn has_region_params(&self, space: subst::ParamSpace) -> bool {
2125 !self.regions.is_empty_in(space)
223e47cc 2126 }
85aaf69f 2127}
223e47cc 2128
85aaf69f 2129/// Bounds on generics.
62682a34 2130#[derive(Clone)]
85aaf69f
SL
2131pub struct GenericPredicates<'tcx> {
2132 pub predicates: VecPerParamSpace<Predicate<'tcx>>,
2133}
2134
2135impl<'tcx> GenericPredicates<'tcx> {
2136 pub fn empty() -> GenericPredicates<'tcx> {
2137 GenericPredicates {
2138 predicates: VecPerParamSpace::empty(),
2139 }
1a4d82fc
JJ
2140 }
2141
85aaf69f
SL
2142 pub fn instantiate(&self, tcx: &ty::ctxt<'tcx>, substs: &Substs<'tcx>)
2143 -> InstantiatedPredicates<'tcx> {
2144 InstantiatedPredicates {
1a4d82fc 2145 predicates: self.predicates.subst(tcx, substs),
223e47cc
LB
2146 }
2147 }
c34b1796
AL
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 }
223e47cc
LB
2158}
2159
62682a34 2160#[derive(Clone, PartialEq, Eq, Hash)]
1a4d82fc
JJ
2161pub 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>),
223e47cc 2175
1a4d82fc
JJ
2176 /// where <T as TraitRef>::Name == X, approximately.
2177 /// See `ProjectionPredicate` struct for details.
2178 Projection(PolyProjectionPredicate<'tcx>),
223e47cc
LB
2179}
2180
c34b1796 2181impl<'tcx> Predicate<'tcx> {
d9579d0f 2182 /// Performs a substitution suitable for going from a
c34b1796
AL
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 }
62682a34
SL
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 }
c34b1796
AL
2289}
2290
62682a34 2291#[derive(Clone, PartialEq, Eq, Hash)]
1a4d82fc 2292pub struct TraitPredicate<'tcx> {
d9579d0f 2293 pub trait_ref: TraitRef<'tcx>
223e47cc 2294}
1a4d82fc 2295pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;
223e47cc 2296
1a4d82fc
JJ
2297impl<'tcx> TraitPredicate<'tcx> {
2298 pub fn def_id(&self) -> ast::DefId {
2299 self.trait_ref.def_id
2300 }
223e47cc 2301
1a4d82fc
JJ
2302 pub fn input_types(&self) -> &[Ty<'tcx>] {
2303 self.trait_ref.substs.types.as_slice()
2304 }
223e47cc 2305
1a4d82fc
JJ
2306 pub fn self_ty(&self) -> Ty<'tcx> {
2307 self.trait_ref.self_ty()
2308 }
223e47cc
LB
2309}
2310
1a4d82fc
JJ
2311impl<'tcx> PolyTraitPredicate<'tcx> {
2312 pub fn def_id(&self) -> ast::DefId {
2313 self.0.def_id()
2314 }
223e47cc
LB
2315}
2316
85aaf69f 2317#[derive(Clone, PartialEq, Eq, Hash, Debug)]
1a4d82fc
JJ
2318pub struct EquatePredicate<'tcx>(pub Ty<'tcx>, pub Ty<'tcx>); // `0 == 1`
2319pub type PolyEquatePredicate<'tcx> = ty::Binder<EquatePredicate<'tcx>>;
970d7e83 2320
85aaf69f 2321#[derive(Clone, PartialEq, Eq, Hash, Debug)]
1a4d82fc
JJ
2322pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
2323pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
2324pub type PolyRegionOutlivesPredicate = PolyOutlivesPredicate<ty::Region, ty::Region>;
2325pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate<Ty<'tcx>, ty::Region>;
970d7e83 2326
1a4d82fc
JJ
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.
62682a34 2339#[derive(Clone, PartialEq, Eq, Hash)]
1a4d82fc
JJ
2340pub struct ProjectionPredicate<'tcx> {
2341 pub projection_ty: ProjectionTy<'tcx>,
2342 pub ty: Ty<'tcx>,
223e47cc
LB
2343}
2344
1a4d82fc 2345pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;
223e47cc 2346
1a4d82fc
JJ
2347impl<'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
970d7e83 2350 }
970d7e83 2351
1a4d82fc
JJ
2352 pub fn sort_key(&self) -> (ast::DefId, ast::Name) {
2353 self.0.projection_ty.sort_key()
223e47cc
LB
2354 }
2355}
2356
1a4d82fc
JJ
2357/// Represents the projection of an associated type. In explicit UFCS
2358/// form this would be written `<T as Trait<..>>::N`.
85aaf69f 2359#[derive(Clone, PartialEq, Eq, Hash, Debug)]
1a4d82fc
JJ
2360pub struct ProjectionTy<'tcx> {
2361 /// The trait reference `T as Trait<..>`.
d9579d0f 2362 pub trait_ref: ty::TraitRef<'tcx>,
1a4d82fc
JJ
2363
2364 /// The name `N` of the associated type.
2365 pub item_name: ast::Name,
223e47cc
LB
2366}
2367
1a4d82fc
JJ
2368impl<'tcx> ProjectionTy<'tcx> {
2369 pub fn sort_key(&self) -> (ast::DefId, ast::Name) {
2370 (self.trait_ref.def_id, self.item_name)
970d7e83
LB
2371 }
2372}
2373
1a4d82fc
JJ
2374pub trait ToPolyTraitRef<'tcx> {
2375 fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
223e47cc
LB
2376}
2377
d9579d0f 2378impl<'tcx> ToPolyTraitRef<'tcx> for TraitRef<'tcx> {
1a4d82fc
JJ
2379 fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
2380 assert!(!self.has_escaping_regions());
2381 ty::Binder(self.clone())
970d7e83
LB
2382 }
2383}
2384
1a4d82fc
JJ
2385impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
2386 fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
c34b1796 2387 self.map_bound_ref(|trait_pred| trait_pred.trait_ref.clone())
970d7e83
LB
2388 }
2389}
2390
1a4d82fc
JJ
2391impl<'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())
223e47cc
LB
2399 }
2400}
2401
1a4d82fc
JJ
2402pub trait AsPredicate<'tcx> {
2403 fn as_predicate(&self) -> Predicate<'tcx>;
223e47cc
LB
2404}
2405
d9579d0f 2406impl<'tcx> AsPredicate<'tcx> for TraitRef<'tcx> {
1a4d82fc
JJ
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 }))
223e47cc
LB
2416 }
2417}
2418
1a4d82fc
JJ
2419impl<'tcx> AsPredicate<'tcx> for PolyTraitRef<'tcx> {
2420 fn as_predicate(&self) -> Predicate<'tcx> {
2421 ty::Predicate::Trait(self.to_poly_trait_predicate())
223e47cc
LB
2422 }
2423}
2424
1a4d82fc
JJ
2425impl<'tcx> AsPredicate<'tcx> for PolyEquatePredicate<'tcx> {
2426 fn as_predicate(&self) -> Predicate<'tcx> {
2427 Predicate::Equate(self.clone())
223e47cc
LB
2428 }
2429}
2430
1a4d82fc
JJ
2431impl<'tcx> AsPredicate<'tcx> for PolyRegionOutlivesPredicate {
2432 fn as_predicate(&self) -> Predicate<'tcx> {
2433 Predicate::RegionOutlives(self.clone())
223e47cc
LB
2434 }
2435}
2436
1a4d82fc
JJ
2437impl<'tcx> AsPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
2438 fn as_predicate(&self) -> Predicate<'tcx> {
2439 Predicate::TypeOutlives(self.clone())
223e47cc
LB
2440 }
2441}
2442
1a4d82fc
JJ
2443impl<'tcx> AsPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
2444 fn as_predicate(&self) -> Predicate<'tcx> {
2445 Predicate::Projection(self.clone())
223e47cc
LB
2446 }
2447}
2448
1a4d82fc 2449impl<'tcx> Predicate<'tcx> {
85aaf69f
SL
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()
62682a34 2471 .chain(Some(data.0.ty))
85aaf69f
SL
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
1a4d82fc
JJ
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 }
223e47cc 2492 }
223e47cc 2493
1a4d82fc
JJ
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 }
223e47cc
LB
2506 }
2507}
2508
1a4d82fc
JJ
2509/// Represents the bounds declared on a particular set of type
2510/// parameters. Should eventually be generalized into a flag list of
85aaf69f
SL
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
1a4d82fc
JJ
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///
85aaf69f 2524/// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
1a4d82fc 2525/// `[[], [U:Bar<T>]]`. Now if there were some particular reference
c34b1796
AL
2526/// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
2527/// [usize:Bar<isize>]]`.
62682a34 2528#[derive(Clone)]
85aaf69f 2529pub struct InstantiatedPredicates<'tcx> {
1a4d82fc 2530 pub predicates: VecPerParamSpace<Predicate<'tcx>>,
223e47cc
LB
2531}
2532
85aaf69f
SL
2533impl<'tcx> InstantiatedPredicates<'tcx> {
2534 pub fn empty() -> InstantiatedPredicates<'tcx> {
2535 InstantiatedPredicates { predicates: VecPerParamSpace::empty() }
223e47cc
LB
2536 }
2537
1a4d82fc
JJ
2538 pub fn has_escaping_regions(&self) -> bool {
2539 self.predicates.any(|p| p.has_escaping_regions())
223e47cc
LB
2540 }
2541
1a4d82fc
JJ
2542 pub fn is_empty(&self) -> bool {
2543 self.predicates.is_empty()
223e47cc 2544 }
223e47cc
LB
2545}
2546
1a4d82fc
JJ
2547impl<'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 }
970d7e83
LB
2550 }
2551
1a4d82fc
JJ
2552 pub fn self_ty(&self) -> Ty<'tcx> {
2553 self.substs.self_ty().unwrap()
970d7e83
LB
2554 }
2555
1a4d82fc
JJ
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()
223e47cc 2562 }
1a4d82fc 2563}
223e47cc 2564
1a4d82fc
JJ
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)]
2578pub struct ParameterEnvironment<'a, 'tcx:'a> {
2579 pub tcx: &'a ctxt<'tcx>,
2580
85aaf69f 2581 /// See `construct_free_substs` for details.
1a4d82fc
JJ
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
62682a34 2592 /// into Obligations, and elaborated and normalized.
85aaf69f 2593 pub caller_bounds: Vec<ty::Predicate<'tcx>>,
1a4d82fc
JJ
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
2600impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
85aaf69f
SL
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
1a4d82fc
JJ
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)) => {
c34b1796 2617 match impl_item.node {
d9579d0f
AL
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 }
c34b1796 2628 ast::MethodImplItem(_, ref body) => {
1a4d82fc
JJ
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;
85aaf69f 2633 let method_bounds = &method_ty.predicates;
1a4d82fc
JJ
2634 construct_parameter_environment(
2635 cx,
c34b1796 2636 impl_item.span,
1a4d82fc 2637 method_generics,
85aaf69f 2638 method_bounds,
c34b1796 2639 body.id)
1a4d82fc 2640 }
d9579d0f 2641 _ => {
1a4d82fc
JJ
2642 cx.sess
2643 .bug("ParameterEnvironment::for_item(): \
d9579d0f 2644 got non-method item from impl method?!")
1a4d82fc
JJ
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 }
c34b1796 2653 ast::MacImplItem(_) => cx.sess.bug("unexpanded macro")
1a4d82fc
JJ
2654 }
2655 }
c34b1796
AL
2656 Some(ast_map::NodeTraitItem(trait_item)) => {
2657 match trait_item.node {
d9579d0f
AL
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 }
c34b1796
AL
2677 ast::MethodTraitItem(_, None) => {
2678 cx.sess.span_bug(trait_item.span,
1a4d82fc
JJ
2679 "ParameterEnvironment::for_item():
2680 can't create a parameter \
2681 environment for required trait \
2682 methods")
2683 }
c34b1796 2684 ast::MethodTraitItem(_, Some(ref body)) => {
1a4d82fc
JJ
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;
85aaf69f 2689 let method_bounds = &method_ty.predicates;
1a4d82fc
JJ
2690 construct_parameter_environment(
2691 cx,
c34b1796 2692 trait_item.span,
1a4d82fc 2693 method_generics,
85aaf69f 2694 method_bounds,
c34b1796 2695 body.id)
1a4d82fc 2696 }
d9579d0f 2697 _ => {
1a4d82fc
JJ
2698 cx.sess
2699 .bug("ParameterEnvironment::for_item(): \
d9579d0f
AL
2700 got non-method item from provided \
2701 method?!")
1a4d82fc
JJ
2702 }
2703 }
2704 }
c34b1796 2705 ast::TypeTraitItem(..) => {
1a4d82fc
JJ
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 {
62682a34 2714 ast::ItemFn(_, _, _, _, _, ref body) => {
1a4d82fc
JJ
2715 // We assume this is a function.
2716 let fn_def_id = ast_util::local_def(id);
85aaf69f
SL
2717 let fn_scheme = lookup_item_type(cx, fn_def_id);
2718 let fn_predicates = lookup_predicates(cx, fn_def_id);
1a4d82fc
JJ
2719
2720 construct_parameter_environment(cx,
85aaf69f
SL
2721 item.span,
2722 &fn_scheme.generics,
2723 &fn_predicates,
1a4d82fc
JJ
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);
85aaf69f
SL
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)
1a4d82fc
JJ
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",
c34b1796 2755 cx.map.node_to_string(id)))
1a4d82fc
JJ
2756 }
2757 }
223e47cc 2758 }
1a4d82fc 2759}
223e47cc 2760
1a4d82fc
JJ
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`.
85aaf69f
SL
2777///
2778/// Note that each item also comes with predicates, see
2779/// `lookup_predicates`.
2780#[derive(Clone, Debug)]
1a4d82fc
JJ
2781pub struct TypeScheme<'tcx> {
2782 pub generics: Generics<'tcx>,
85aaf69f 2783 pub ty: Ty<'tcx>,
1a4d82fc
JJ
2784}
2785
d9579d0f
AL
2786bitflags! {
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
1a4d82fc
JJ
2796/// As `TypeScheme` but for a trait ref.
2797pub struct TraitDef<'tcx> {
2798 pub unsafety: ast::Unsafety,
2799
85aaf69f
SL
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
1a4d82fc
JJ
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
d9579d0f 2813 pub trait_ref: TraitRef<'tcx>,
1a4d82fc
JJ
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>,
d9579d0f
AL
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
2836impl<'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>) {
62682a34
SL
2862 debug!("TraitDef::record_impl for {:?}, from {:?}",
2863 self, impl_trait_ref);
d9579d0f
AL
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
1a4d82fc
JJ
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)]
2931pub struct ItemSubsts<'tcx> {
2932 pub substs: Substs<'tcx>,
2933}
2934
c34b1796 2935#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
85aaf69f 2936pub enum ClosureKind {
c34b1796
AL
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.
85aaf69f
SL
2940 FnClosureKind,
2941 FnMutClosureKind,
2942 FnOnceClosureKind,
1a4d82fc
JJ
2943}
2944
85aaf69f 2945impl ClosureKind {
1a4d82fc
JJ
2946 pub fn trait_did(&self, cx: &ctxt) -> ast::DefId {
2947 let result = match *self {
85aaf69f
SL
2948 FnClosureKind => cx.lang_items.require(FnTraitLangItem),
2949 FnMutClosureKind => {
1a4d82fc
JJ
2950 cx.lang_items.require(FnMutTraitLangItem)
2951 }
85aaf69f 2952 FnOnceClosureKind => {
1a4d82fc
JJ
2953 cx.lang_items.require(FnOnceTraitLangItem)
2954 }
2955 };
2956 match result {
2957 Ok(trait_did) => trait_did,
85aaf69f 2958 Err(err) => cx.sess.fatal(&err[..]),
1a4d82fc 2959 }
223e47cc 2960 }
c34b1796
AL
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 }
1a4d82fc 2975}
223e47cc 2976
85aaf69f
SL
2977pub trait ClosureTyper<'tcx> {
2978 fn tcx(&self) -> &ty::ctxt<'tcx> {
2979 self.param_env().tcx
2980 }
2981
1a4d82fc 2982 fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx>;
223e47cc 2983
85aaf69f
SL
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>;
223e47cc 2990
85aaf69f
SL
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>;
223e47cc 2996
85aaf69f
SL
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>>>;
1a4d82fc 3004}
223e47cc 3005
1a4d82fc
JJ
3006impl<'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 {
62682a34
SL
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.
3035pub 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
1a4d82fc 3046{
85aaf69f 3047 let mut interner = FnvHashMap();
1a4d82fc
JJ
3048 let common_types = CommonTypes::new(&arenas.type_, &mut interner);
3049
62682a34 3050 tls::enter(ctxt {
1a4d82fc
JJ
3051 arenas: arenas,
3052 interner: RefCell::new(interner),
85aaf69f
SL
3053 substs_interner: RefCell::new(FnvHashMap()),
3054 bare_fn_interner: RefCell::new(FnvHashMap()),
3055 region_interner: RefCell::new(FnvHashMap()),
62682a34 3056 stability_interner: RefCell::new(FnvHashMap()),
1a4d82fc
JJ
3057 types: common_types,
3058 named_region_map: named_region_map,
bd371182
AL
3059 region_maps: region_maps,
3060 free_region_maps: RefCell::new(FnvHashMap()),
85aaf69f 3061 item_variance_map: RefCell::new(DefIdMap()),
1a4d82fc
JJ
3062 variance_computed: Cell::new(false),
3063 sess: s,
c34b1796 3064 def_map: def_map,
85aaf69f
SL
3065 node_types: RefCell::new(FnvHashMap()),
3066 item_substs: RefCell::new(NodeMap()),
62682a34 3067 impl_trait_refs: RefCell::new(DefIdMap()),
85aaf69f
SL
3068 trait_defs: RefCell::new(DefIdMap()),
3069 predicates: RefCell::new(DefIdMap()),
c34b1796 3070 super_predicates: RefCell::new(DefIdMap()),
62682a34 3071 fulfilled_predicates: RefCell::new(traits::FulfilledPredicates::new()),
1a4d82fc 3072 map: map,
1a4d82fc 3073 freevars: freevars,
85aaf69f
SL
3074 tcache: RefCell::new(DefIdMap()),
3075 rcache: RefCell::new(FnvHashMap()),
85aaf69f
SL
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()),
85aaf69f
SL
3082 ty_param_defs: RefCell::new(NodeMap()),
3083 adjustments: RefCell::new(NodeMap()),
3084 normalized_cache: RefCell::new(FnvHashMap()),
1a4d82fc 3085 lang_items: lang_items,
85aaf69f
SL
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()),
85aaf69f
SL
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()),
c34b1796 3095 populated_external_primitive_impls: RefCell::new(DefIdSet()),
85aaf69f
SL
3096 upvar_capture_map: RefCell::new(FnvHashMap()),
3097 extern_const_statics: RefCell::new(DefIdMap()),
3098 extern_const_variants: RefCell::new(DefIdMap()),
62682a34 3099 extern_const_fns: RefCell::new(DefIdMap()),
85aaf69f
SL
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()),
1a4d82fc
JJ
3105 transmute_restrictions: RefCell::new(Vec::new()),
3106 stability: RefCell::new(stability),
1a4d82fc 3107 selection_cache: traits::SelectionCache::new(),
85aaf69f 3108 repr_hint_cache: RefCell::new(DefIdMap()),
85aaf69f 3109 const_qualif_map: RefCell::new(NodeMap()),
d9579d0f 3110 custom_coerce_unsized_kinds: RefCell::new(DefIdMap()),
62682a34
SL
3111 cast_kinds: RefCell::new(NodeMap()),
3112 }, f)
1a4d82fc 3113}
223e47cc 3114
1a4d82fc 3115// Type constructors
223e47cc 3116
1a4d82fc
JJ
3117impl<'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 }
223e47cc 3122
1a4d82fc
JJ
3123 let substs = self.arenas.substs.alloc(substs);
3124 self.substs_interner.borrow_mut().insert(substs, substs);
3125 substs
223e47cc
LB
3126 }
3127
c34b1796
AL
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
1a4d82fc
JJ
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 }
223e47cc 3143
1a4d82fc
JJ
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
223e47cc
LB
3147 }
3148
1a4d82fc
JJ
3149 pub fn mk_region(&self, region: Region) -> &'tcx Region {
3150 if let Some(region) = self.region_interner.borrow().get(&region) {
3151 return *region;
970d7e83 3152 }
223e47cc 3153
1a4d82fc
JJ
3154 let region = self.arenas.region.alloc(region);
3155 self.region_interner.borrow_mut().insert(region, region);
3156 region
223e47cc 3157 }
223e47cc 3158
85aaf69f 3159 pub fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
c34b1796 3160 *self.closure_kinds.borrow().get(&def_id).unwrap()
223e47cc 3161 }
223e47cc 3162
85aaf69f
SL
3163 pub fn closure_type(&self,
3164 def_id: ast::DefId,
3165 substs: &subst::Substs<'tcx>)
3166 -> ty::ClosureTy<'tcx>
1a4d82fc 3167 {
c34b1796
AL
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
62682a34 3178 pub fn pat_contains_ref_binding(&self, pat: &ast::Pat) -> Option<ast::Mutability> {
c34b1796
AL
3179 pat_util::pat_contains_ref_binding(&self.def_map, pat)
3180 }
3181
62682a34 3182 pub fn arm_contains_ref_binding(&self, arm: &ast::Arm) -> Option<ast::Mutability> {
c34b1796 3183 pat_util::arm_contains_ref_binding(&self.def_map, arm)
223e47cc
LB
3184 }
3185}
3186
1a4d82fc
JJ
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).
62682a34 3189pub fn mk_t<'tcx>(cx: &ctxt<'tcx>, st: TypeVariants<'tcx>) -> Ty<'tcx> {
1a4d82fc
JJ
3190 let mut interner = cx.interner.borrow_mut();
3191 intern_ty(&cx.arenas.type_, &mut *interner, st)
223e47cc
LB
3192}
3193
1a4d82fc
JJ
3194fn intern_ty<'tcx>(type_arena: &'tcx TypedArena<TyS<'tcx>>,
3195 interner: &mut FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>,
62682a34 3196 st: TypeVariants<'tcx>)
1a4d82fc
JJ
3197 -> Ty<'tcx>
3198{
3199 match interner.get(&st) {
3200 Some(ty) => return *ty,
3201 _ => ()
3202 }
223e47cc 3203
1a4d82fc 3204 let flags = FlagComputation::for_sty(&st);
970d7e83 3205
85aaf69f
SL
3206 let ty = match () {
3207 () => type_arena.alloc(TyS { sty: st,
62682a34 3208 flags: Cell::new(flags.flags),
85aaf69f
SL
3209 region_depth: flags.depth, }),
3210 };
970d7e83 3211
1a4d82fc 3212 debug!("Interned type: {:?} Pointer: {:?}",
c34b1796 3213 ty, ty as *const TyS);
223e47cc 3214
1a4d82fc 3215 interner.insert(InternedTy { ty: ty }, ty);
223e47cc 3216
1a4d82fc 3217 ty
223e47cc
LB
3218}
3219
1a4d82fc
JJ
3220struct FlagComputation {
3221 flags: TypeFlags,
223e47cc 3222
1a4d82fc
JJ
3223 // maximum depth of any bound region that we have seen thus far
3224 depth: u32,
223e47cc
LB
3225}
3226
1a4d82fc
JJ
3227impl FlagComputation {
3228 fn new() -> FlagComputation {
d9579d0f 3229 FlagComputation { flags: TypeFlags::empty(), depth: 0 }
1a4d82fc 3230 }
223e47cc 3231
62682a34 3232 fn for_sty(st: &TypeVariants) -> FlagComputation {
1a4d82fc
JJ
3233 let mut result = FlagComputation::new();
3234 result.add_sty(st);
3235 result
223e47cc
LB
3236 }
3237
1a4d82fc 3238 fn add_flags(&mut self, flags: TypeFlags) {
62682a34 3239 self.flags = self.flags | (flags & TypeFlags::NOMINAL_FLAGS);
1a4d82fc 3240 }
223e47cc 3241
1a4d82fc
JJ
3242 fn add_depth(&mut self, depth: u32) {
3243 if depth > self.depth {
3244 self.depth = depth;
223e47cc 3245 }
1a4d82fc 3246 }
223e47cc 3247
1a4d82fc
JJ
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);
223e47cc 3252
85aaf69f 3253 // The types that contributed to `computation` occurred within
1a4d82fc
JJ
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 }
223e47cc 3261
62682a34 3262 fn add_sty(&mut self, st: &TypeVariants) {
1a4d82fc 3263 match st {
62682a34
SL
3264 &TyBool |
3265 &TyChar |
3266 &TyInt(_) |
3267 &TyFloat(_) |
3268 &TyUint(_) |
3269 &TyStr => {
223e47cc
LB
3270 }
3271
62682a34
SL
3272 // You might think that we could just return TyError for
3273 // any type containing TyError as a component, and get
d9579d0f 3274 // rid of the TypeFlags::HAS_TY_ERR flag -- likewise for ty_bot (with
1a4d82fc
JJ
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.
62682a34 3279 &TyError => {
d9579d0f 3280 self.add_flags(TypeFlags::HAS_TY_ERR)
223e47cc
LB
3281 }
3282
62682a34
SL
3283 &TyParam(ref p) => {
3284 self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
1a4d82fc 3285 if p.space == subst::SelfSpace {
d9579d0f 3286 self.add_flags(TypeFlags::HAS_SELF);
1a4d82fc 3287 } else {
d9579d0f 3288 self.add_flags(TypeFlags::HAS_PARAMS);
1a4d82fc 3289 }
223e47cc
LB
3290 }
3291
62682a34
SL
3292 &TyClosure(_, substs) => {
3293 self.add_flags(TypeFlags::HAS_TY_CLOSURE);
3294 self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
1a4d82fc 3295 self.add_substs(substs);
223e47cc
LB
3296 }
3297
62682a34
SL
3298 &TyInfer(_) => {
3299 self.add_flags(TypeFlags::HAS_LOCAL_NAMES); // it might, right?
d9579d0f 3300 self.add_flags(TypeFlags::HAS_TY_INFER)
223e47cc
LB
3301 }
3302
62682a34 3303 &TyEnum(_, substs) | &TyStruct(_, substs) => {
1a4d82fc 3304 self.add_substs(substs);
223e47cc
LB
3305 }
3306
62682a34 3307 &TyProjection(ref data) => {
d9579d0f 3308 self.add_flags(TypeFlags::HAS_PROJECTION);
85aaf69f 3309 self.add_projection_ty(data);
223e47cc
LB
3310 }
3311
62682a34 3312 &TyTrait(box TraitTy { ref principal, ref bounds }) => {
1a4d82fc
JJ
3313 let mut computation = FlagComputation::new();
3314 computation.add_substs(principal.0.substs);
85aaf69f
SL
3315 for projection_bound in &bounds.projection_bounds {
3316 let mut proj_computation = FlagComputation::new();
3317 proj_computation.add_projection_predicate(&projection_bound.0);
62682a34 3318 self.add_bound_computation(&proj_computation);
85aaf69f 3319 }
1a4d82fc 3320 self.add_bound_computation(&computation);
223e47cc 3321
1a4d82fc 3322 self.add_bounds(bounds);
223e47cc
LB
3323 }
3324
62682a34 3325 &TyBox(tt) | &TyArray(tt, _) | &TySlice(tt) => {
1a4d82fc 3326 self.add_ty(tt)
223e47cc
LB
3327 }
3328
62682a34 3329 &TyRawPtr(ref m) => {
1a4d82fc 3330 self.add_ty(m.ty);
223e47cc
LB
3331 }
3332
62682a34 3333 &TyRef(r, ref m) => {
1a4d82fc
JJ
3334 self.add_region(*r);
3335 self.add_ty(m.ty);
223e47cc
LB
3336 }
3337
62682a34 3338 &TyTuple(ref ts) => {
85aaf69f 3339 self.add_tys(&ts[..]);
223e47cc
LB
3340 }
3341
62682a34 3342 &TyBareFn(_, ref f) => {
1a4d82fc 3343 self.add_fn_sig(&f.sig);
223e47cc 3344 }
1a4d82fc
JJ
3345 }
3346 }
223e47cc 3347
1a4d82fc 3348 fn add_ty(&mut self, ty: Ty) {
62682a34 3349 self.add_flags(ty.flags.get());
1a4d82fc
JJ
3350 self.add_depth(ty.region_depth);
3351 }
223e47cc 3352
1a4d82fc 3353 fn add_tys(&mut self, tys: &[Ty]) {
85aaf69f 3354 for &ty in tys {
1a4d82fc
JJ
3355 self.add_ty(ty);
3356 }
3357 }
223e47cc 3358
1a4d82fc
JJ
3359 fn add_fn_sig(&mut self, fn_sig: &PolyFnSig) {
3360 let mut computation = FlagComputation::new();
223e47cc 3361
c34b1796 3362 computation.add_tys(&fn_sig.0.inputs);
223e47cc 3363
1a4d82fc
JJ
3364 if let ty::FnConverging(output) = fn_sig.0.output {
3365 computation.add_ty(output);
3366 }
223e47cc 3367
1a4d82fc 3368 self.add_bound_computation(&computation);
223e47cc
LB
3369 }
3370
1a4d82fc 3371 fn add_region(&mut self, r: Region) {
1a4d82fc 3372 match r {
d9579d0f 3373 ty::ReInfer(_) => { self.add_flags(TypeFlags::HAS_RE_INFER); }
62682a34
SL
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);
1a4d82fc 3382 }
223e47cc
LB
3383 }
3384
85aaf69f
SL
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
1a4d82fc
JJ
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) => {
62682a34 3399 for &r in regions {
1a4d82fc
JJ
3400 self.add_region(r);
3401 }
3402 }
970d7e83 3403 }
970d7e83
LB
3404 }
3405
1a4d82fc
JJ
3406 fn add_bounds(&mut self, bounds: &ExistentialBounds) {
3407 self.add_region(bounds.region_bound);
970d7e83 3408 }
1a4d82fc 3409}
970d7e83 3410
1a4d82fc
JJ
3411pub fn mk_mach_int<'tcx>(tcx: &ctxt<'tcx>, tm: ast::IntTy) -> Ty<'tcx> {
3412 match tm {
c34b1796 3413 ast::TyIs => tcx.types.isize,
1a4d82fc
JJ
3414 ast::TyI8 => tcx.types.i8,
3415 ast::TyI16 => tcx.types.i16,
3416 ast::TyI32 => tcx.types.i32,
3417 ast::TyI64 => tcx.types.i64,
223e47cc 3418 }
1a4d82fc 3419}
223e47cc 3420
1a4d82fc
JJ
3421pub fn mk_mach_uint<'tcx>(tcx: &ctxt<'tcx>, tm: ast::UintTy) -> Ty<'tcx> {
3422 match tm {
c34b1796 3423 ast::TyUs => tcx.types.usize,
1a4d82fc
JJ
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}
223e47cc 3430
1a4d82fc
JJ
3431pub 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,
223e47cc 3435 }
970d7e83 3436}
223e47cc 3437
1a4d82fc 3438pub fn mk_str<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
62682a34 3439 mk_t(cx, TyStr)
223e47cc
LB
3440}
3441
1a4d82fc
JJ
3442pub fn mk_str_slice<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, m: ast::Mutability) -> Ty<'tcx> {
3443 mk_rptr(cx, r,
3444 mt {
62682a34 3445 ty: mk_t(cx, TyStr),
1a4d82fc
JJ
3446 mutbl: m
3447 })
3448}
223e47cc 3449
1a4d82fc
JJ
3450pub 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
62682a34 3452 mk_t(cx, TyEnum(did, substs))
1a4d82fc 3453}
223e47cc 3454
62682a34 3455pub fn mk_uniq<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { mk_t(cx, TyBox(ty)) }
223e47cc 3456
62682a34 3457pub fn mk_ptr<'tcx>(cx: &ctxt<'tcx>, tm: mt<'tcx>) -> Ty<'tcx> { mk_t(cx, TyRawPtr(tm)) }
223e47cc 3458
1a4d82fc 3459pub fn mk_rptr<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, tm: mt<'tcx>) -> Ty<'tcx> {
62682a34 3460 mk_t(cx, TyRef(r, tm))
1a4d82fc 3461}
223e47cc 3462
1a4d82fc
JJ
3463pub 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}
3466pub 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}
223e47cc 3469
1a4d82fc
JJ
3470pub fn mk_mut_ptr<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
3471 mk_ptr(cx, mt {ty: ty, mutbl: ast::MutMutable})
3472}
223e47cc 3473
1a4d82fc
JJ
3474pub fn mk_imm_ptr<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
3475 mk_ptr(cx, mt {ty: ty, mutbl: ast::MutImmutable})
3476}
223e47cc 3477
1a4d82fc
JJ
3478pub fn mk_nil_ptr<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
3479 mk_ptr(cx, mt {ty: mk_nil(cx), mutbl: ast::MutImmutable})
3480}
223e47cc 3481
c34b1796 3482pub fn mk_vec<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>, sz: Option<usize>) -> Ty<'tcx> {
62682a34
SL
3483 match sz {
3484 Some(n) => mk_t(cx, TyArray(ty, n)),
3485 None => mk_t(cx, TySlice(ty))
3486 }
1a4d82fc 3487}
223e47cc 3488
1a4d82fc
JJ
3489pub 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}
223e47cc 3496
1a4d82fc 3497pub fn mk_tup<'tcx>(cx: &ctxt<'tcx>, ts: Vec<Ty<'tcx>>) -> Ty<'tcx> {
62682a34 3498 mk_t(cx, TyTuple(ts))
1a4d82fc 3499}
223e47cc 3500
1a4d82fc
JJ
3501pub fn mk_nil<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
3502 mk_tup(cx, Vec::new())
3503}
223e47cc 3504
c34b1796 3505pub fn mk_bool<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
62682a34 3506 mk_t(cx, TyBool)
c34b1796
AL
3507}
3508
1a4d82fc
JJ
3509pub fn mk_bare_fn<'tcx>(cx: &ctxt<'tcx>,
3510 opt_def_id: Option<ast::DefId>,
3511 fty: &'tcx BareFnTy<'tcx>) -> Ty<'tcx> {
62682a34 3512 mk_t(cx, TyBareFn(opt_def_id, fty))
223e47cc
LB
3513}
3514
1a4d82fc
JJ
3515pub fn mk_ctor_fn<'tcx>(cx: &ctxt<'tcx>,
3516 def_id: ast::DefId,
3517 input_tys: &[Ty<'tcx>],
3518 output: Ty<'tcx>) -> Ty<'tcx> {
85aaf69f 3519 let input_args = input_tys.iter().cloned().collect();
1a4d82fc
JJ
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}
223e47cc 3532
1a4d82fc
JJ
3533pub fn mk_trait<'tcx>(cx: &ctxt<'tcx>,
3534 principal: ty::PolyTraitRef<'tcx>,
3535 bounds: ExistentialBounds<'tcx>)
3536 -> Ty<'tcx>
3537{
85aaf69f 3538 assert!(bound_list_is_sorted(&bounds.projection_bounds));
1a4d82fc 3539
62682a34 3540 let inner = box TraitTy {
1a4d82fc
JJ
3541 principal: principal,
3542 bounds: bounds
3543 };
62682a34 3544 mk_t(cx, TyTrait(inner))
223e47cc
LB
3545}
3546
1a4d82fc 3547fn bound_list_is_sorted(bounds: &[ty::PolyProjectionPredicate]) -> bool {
9346a6ac 3548 bounds.is_empty() ||
1a4d82fc
JJ
3549 bounds[1..].iter().enumerate().all(
3550 |(index, bound)| bounds[index].sort_key() <= bound.sort_key())
223e47cc
LB
3551}
3552
1a4d82fc
JJ
3553pub fn sort_bounds_list(bounds: &mut [ty::PolyProjectionPredicate]) {
3554 bounds.sort_by(|a, b| a.sort_key().cmp(&b.sort_key()))
223e47cc
LB
3555}
3556
1a4d82fc 3557pub fn mk_projection<'tcx>(cx: &ctxt<'tcx>,
d9579d0f 3558 trait_ref: TraitRef<'tcx>,
1a4d82fc
JJ
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 };
62682a34 3563 mk_t(cx, TyProjection(inner))
223e47cc
LB
3564}
3565
1a4d82fc
JJ
3566pub 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
62682a34 3569 mk_t(cx, TyStruct(struct_id, substs))
223e47cc
LB
3570}
3571
c34b1796 3572pub fn mk_closure<'tcx>(cx: &ctxt<'tcx>, closure_id: ast::DefId, substs: &'tcx Substs<'tcx>)
85aaf69f 3573 -> Ty<'tcx> {
62682a34 3574 mk_t(cx, TyClosure(closure_id, substs))
223e47cc
LB
3575}
3576
1a4d82fc
JJ
3577pub fn mk_var<'tcx>(cx: &ctxt<'tcx>, v: TyVid) -> Ty<'tcx> {
3578 mk_infer(cx, TyVar(v))
223e47cc
LB
3579}
3580
1a4d82fc
JJ
3581pub fn mk_int_var<'tcx>(cx: &ctxt<'tcx>, v: IntVid) -> Ty<'tcx> {
3582 mk_infer(cx, IntVar(v))
970d7e83
LB
3583}
3584
1a4d82fc
JJ
3585pub fn mk_float_var<'tcx>(cx: &ctxt<'tcx>, v: FloatVid) -> Ty<'tcx> {
3586 mk_infer(cx, FloatVar(v))
3587}
223e47cc 3588
1a4d82fc 3589pub fn mk_infer<'tcx>(cx: &ctxt<'tcx>, it: InferTy) -> Ty<'tcx> {
62682a34 3590 mk_t(cx, TyInfer(it))
1a4d82fc 3591}
223e47cc 3592
1a4d82fc
JJ
3593pub fn mk_param<'tcx>(cx: &ctxt<'tcx>,
3594 space: subst::ParamSpace,
3595 index: u32,
3596 name: ast::Name) -> Ty<'tcx> {
62682a34 3597 mk_t(cx, TyParam(ParamTy { space: space, idx: index, name: name }))
1a4d82fc 3598}
223e47cc 3599
1a4d82fc
JJ
3600pub fn mk_self_type<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
3601 mk_param(cx, subst::SelfSpace, 0, special_idents::type_self.name)
223e47cc
LB
3602}
3603
1a4d82fc
JJ
3604pub fn mk_param_from_def<'tcx>(cx: &ctxt<'tcx>, def: &TypeParameterDef) -> Ty<'tcx> {
3605 mk_param(cx, def.space, def.index, def.name)
223e47cc
LB
3606}
3607
1a4d82fc
JJ
3608impl<'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
c34b1796
AL
3615 /// isize => { isize }
3616 /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
3617 /// [isize] => { [isize], isize }
1a4d82fc
JJ
3618 /// ```
3619 pub fn walk(&'tcx self) -> TypeWalker<'tcx> {
3620 TypeWalker::new(self)
970d7e83 3621 }
970d7e83 3622
c34b1796
AL
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)
223e47cc 3628 }
85aaf69f
SL
3629
3630 pub fn as_opt_param_ty(&self) -> Option<ty::ParamTy> {
3631 match self.sty {
62682a34 3632 ty::TyParam(ref d) => Some(d.clone()),
85aaf69f
SL
3633 _ => None,
3634 }
3635 }
c34b1796
AL
3636
3637 pub fn is_param(&self, space: ParamSpace, index: u32) -> bool {
3638 match self.sty {
62682a34 3639 ty::TyParam(ref data) => data.space == space && data.idx == index,
c34b1796
AL
3640 _ => false,
3641 }
3642 }
223e47cc
LB
3643}
3644
1a4d82fc
JJ
3645pub 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);
223e47cc 3650 }
223e47cc
LB
3651}
3652
1a4d82fc
JJ
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.
3658pub 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 }
223e47cc
LB
3667}
3668
1a4d82fc
JJ
3669// Folds types from the bottom up.
3670pub 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}
223e47cc 3678
1a4d82fc
JJ
3679impl 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 }
223e47cc 3686
1a4d82fc
JJ
3687 pub fn for_self() -> ParamTy {
3688 ParamTy::new(subst::SelfSpace, 0, special_idents::type_self.name)
3689 }
223e47cc 3690
1a4d82fc
JJ
3691 pub fn for_def(def: &TypeParameterDef) -> ParamTy {
3692 ParamTy::new(def.space, def.index, def.name)
3693 }
223e47cc 3694
1a4d82fc
JJ
3695 pub fn to_ty<'tcx>(self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> {
3696 ty::mk_param(tcx, self.space, self.idx, self.name)
223e47cc 3697 }
223e47cc 3698
1a4d82fc
JJ
3699 pub fn is_self(&self) -> bool {
3700 self.space == subst::SelfSpace && self.idx == 0
223e47cc
LB
3701 }
3702}
3703
1a4d82fc
JJ
3704impl<'tcx> ItemSubsts<'tcx> {
3705 pub fn empty() -> ItemSubsts<'tcx> {
3706 ItemSubsts { substs: Substs::empty() }
3707 }
223e47cc 3708
1a4d82fc
JJ
3709 pub fn is_noop(&self) -> bool {
3710 self.substs.is_noop()
223e47cc
LB
3711 }
3712}
3713
1a4d82fc
JJ
3714// Type utilities
3715
3716pub fn type_is_nil(ty: Ty) -> bool {
3717 match ty.sty {
62682a34 3718 TyTuple(ref tys) => tys.is_empty(),
1a4d82fc 3719 _ => false
223e47cc
LB
3720 }
3721}
3722
1a4d82fc 3723pub fn type_is_error(ty: Ty) -> bool {
62682a34 3724 ty.flags.get().intersects(TypeFlags::HAS_TY_ERR)
1a4d82fc 3725}
970d7e83 3726
1a4d82fc 3727pub fn type_needs_subst(ty: Ty) -> bool {
62682a34 3728 ty.flags.get().intersects(TypeFlags::NEEDS_SUBST)
1a4d82fc 3729}
970d7e83 3730
1a4d82fc
JJ
3731pub fn trait_ref_contains_error(tref: &ty::TraitRef) -> bool {
3732 tref.substs.types.any(|&ty| type_is_error(ty))
3733}
970d7e83 3734
1a4d82fc
JJ
3735pub fn type_is_ty_var(ty: Ty) -> bool {
3736 match ty.sty {
62682a34 3737 TyInfer(TyVar(_)) => true,
1a4d82fc 3738 _ => false
223e47cc
LB
3739 }
3740}
3741
62682a34 3742pub fn type_is_bool(ty: Ty) -> bool { ty.sty == TyBool }
1a4d82fc
JJ
3743
3744pub fn type_is_self(ty: Ty) -> bool {
3745 match ty.sty {
62682a34 3746 TyParam(ref p) => p.space == subst::SelfSpace,
1a4d82fc 3747 _ => false
223e47cc
LB
3748 }
3749}
3750
1a4d82fc
JJ
3751fn type_is_slice(ty: Ty) -> bool {
3752 match ty.sty {
62682a34
SL
3753 TyRawPtr(mt) | TyRef(_, mt) => match mt.ty.sty {
3754 TySlice(_) | TyStr => true,
1a4d82fc
JJ
3755 _ => false,
3756 },
3757 _ => false
223e47cc
LB
3758 }
3759}
3760
1a4d82fc
JJ
3761pub fn type_is_structural(ty: Ty) -> bool {
3762 match ty.sty {
62682a34
SL
3763 TyStruct(..) | TyTuple(_) | TyEnum(..) |
3764 TyArray(..) | TyClosure(..) => true,
1a4d82fc 3765 _ => type_is_slice(ty) | type_is_trait(ty)
223e47cc
LB
3766 }
3767}
3768
1a4d82fc
JJ
3769pub fn type_is_simd(cx: &ctxt, ty: Ty) -> bool {
3770 match ty.sty {
62682a34 3771 TyStruct(did, _) => lookup_simd(cx, did),
1a4d82fc
JJ
3772 _ => false
3773 }
223e47cc
LB
3774}
3775
1a4d82fc
JJ
3776pub fn sequence_element_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
3777 match ty.sty {
62682a34
SL
3778 TyArray(ty, _) | TySlice(ty) => ty,
3779 TyStr => mk_mach_uint(cx, ast::TyU8),
1a4d82fc 3780 _ => cx.sess.bug(&format!("sequence_element_type called on non-sequence value: {}",
62682a34 3781 ty)),
970d7e83
LB
3782 }
3783}
3784
1a4d82fc
JJ
3785pub fn simd_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
3786 match ty.sty {
62682a34 3787 TyStruct(did, substs) => {
1a4d82fc
JJ
3788 let fields = lookup_struct_fields(cx, did);
3789 lookup_field_type(cx, did, fields[0].id, substs)
223e47cc 3790 }
1a4d82fc 3791 _ => panic!("simd_type called on invalid type")
223e47cc
LB
3792 }
3793}
3794
c34b1796 3795pub fn simd_size(cx: &ctxt, ty: Ty) -> usize {
1a4d82fc 3796 match ty.sty {
62682a34 3797 TyStruct(did, _) => {
1a4d82fc
JJ
3798 let fields = lookup_struct_fields(cx, did);
3799 fields.len()
223e47cc 3800 }
1a4d82fc 3801 _ => panic!("simd_size called on invalid type")
223e47cc
LB
3802 }
3803}
3804
1a4d82fc
JJ
3805pub fn type_is_region_ptr(ty: Ty) -> bool {
3806 match ty.sty {
62682a34 3807 TyRef(..) => true,
1a4d82fc 3808 _ => false
223e47cc
LB
3809 }
3810}
3811
1a4d82fc
JJ
3812pub fn type_is_unsafe_ptr(ty: Ty) -> bool {
3813 match ty.sty {
62682a34 3814 TyRawPtr(_) => return true,
1a4d82fc 3815 _ => return false
223e47cc
LB
3816 }
3817}
3818
1a4d82fc
JJ
3819pub fn type_is_unique(ty: Ty) -> bool {
3820 match ty.sty {
62682a34 3821 TyBox(_) => true,
223e47cc
LB
3822 _ => false
3823 }
3824}
3825
1a4d82fc
JJ
3826/*
3827 A scalar type is one that denotes an atomic datum, with no sub-components.
62682a34 3828 (A TyRawPtr is scalar because it represents a non-managed pointer, so its
1a4d82fc
JJ
3829 contents are abstract to rustc.)
3830*/
3831pub fn type_is_scalar(ty: Ty) -> bool {
3832 match ty.sty {
62682a34
SL
3833 TyBool | TyChar | TyInt(_) | TyFloat(_) | TyUint(_) |
3834 TyInfer(IntVar(_)) | TyInfer(FloatVar(_)) |
3835 TyBareFn(..) | TyRawPtr(_) => true,
1a4d82fc 3836 _ => false
223e47cc
LB
3837 }
3838}
3839
1a4d82fc
JJ
3840/// Returns true if this type is a floating point type and false otherwise.
3841pub fn type_is_floating_point(ty: Ty) -> bool {
3842 match ty.sty {
62682a34
SL
3843 TyFloat(_) |
3844 TyInfer(FloatVar(_)) =>
c34b1796
AL
3845 true,
3846
3847 _ =>
3848 false,
223e47cc
LB
3849 }
3850}
3851
1a4d82fc
JJ
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)]
3863pub struct TypeContents {
3864 pub bits: u64
3865}
3866
3867macro_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 )+
970d7e83
LB
3876 }
3877 }
3878}
3879
1a4d82fc
JJ
3880def_type_content_sets! {
3881 mod TC {
3882 None = 0b0000_0000__0000_0000__0000,
223e47cc 3883
1a4d82fc
JJ
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,
223e47cc 3889
1a4d82fc
JJ
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,
1a4d82fc 3893 OwnsAll = 0b0000_0000__1111_1111__0000,
223e47cc 3894
1a4d82fc
JJ
3895 // Things that are reachable by the value in any way (fourth nibble):
3896 ReachesBorrowed = 0b0000_0010__0000_0000__0000,
1a4d82fc
JJ
3897 ReachesMutable = 0b0000_1000__0000_0000__0000,
3898 ReachesFfiUnsafe = 0b0010_0000__0000_0000__0000,
3899 ReachesAll = 0b0011_1111__0000_0000__0000,
223e47cc 3900
1a4d82fc
JJ
3901 // Things that mean drop glue is necessary
3902 NeedsDrop = 0b0000_0000__0000_0111__0000,
223e47cc 3903
1a4d82fc
JJ
3904 // Things that prevent values from being considered sized
3905 Nonsized = 0b0000_0000__0000_0000__0001,
223e47cc 3906
1a4d82fc
JJ
3907 // All bits
3908 All = 0b1111_1111__1111_1111__1111
3909 }
223e47cc
LB
3910}
3911
1a4d82fc
JJ
3912impl TypeContents {
3913 pub fn when(&self, cond: bool) -> TypeContents {
3914 if cond {*self} else {TC::None}
3915 }
223e47cc 3916
1a4d82fc
JJ
3917 pub fn intersects(&self, tc: TypeContents) -> bool {
3918 (self.bits & tc.bits) != 0
3919 }
223e47cc 3920
1a4d82fc
JJ
3921 pub fn owns_owned(&self) -> bool {
3922 self.intersects(TC::OwnsOwned)
3923 }
223e47cc 3924
1a4d82fc
JJ
3925 pub fn is_sized(&self, _: &ctxt) -> bool {
3926 !self.intersects(TC::Nonsized)
3927 }
223e47cc 3928
1a4d82fc
JJ
3929 pub fn interior_param(&self) -> bool {
3930 self.intersects(TC::InteriorParam)
3931 }
223e47cc 3932
1a4d82fc
JJ
3933 pub fn interior_unsafe(&self) -> bool {
3934 self.intersects(TC::InteriorUnsafe)
3935 }
223e47cc 3936
1a4d82fc
JJ
3937 pub fn interior_unsized(&self) -> bool {
3938 self.intersects(TC::InteriorUnsized)
3939 }
223e47cc 3940
1a4d82fc
JJ
3941 pub fn needs_drop(&self, _: &ctxt) -> bool {
3942 self.intersects(TC::NeedsDrop)
3943 }
223e47cc 3944
1a4d82fc
JJ
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 }
970d7e83 3950
1a4d82fc
JJ
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 }
223e47cc 3956
62682a34 3957 /// Includes only those bits that still apply when indirected through a raw pointer (`*`)
1a4d82fc
JJ
3958 pub fn unsafe_pointer(&self) -> TypeContents {
3959 *self & TC::ReachesAll
3960 }
223e47cc 3961
1a4d82fc
JJ
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))
223e47cc
LB
3966 }
3967
1a4d82fc
JJ
3968 pub fn has_dtor(&self) -> bool {
3969 self.intersects(TC::OwnsDtor)
3970 }
3971}
223e47cc 3972
1a4d82fc
JJ
3973impl ops::BitOr for TypeContents {
3974 type Output = TypeContents;
3975
3976 fn bitor(self, other: TypeContents) -> TypeContents {
3977 TypeContents {bits: self.bits | other.bits}
223e47cc
LB
3978 }
3979}
3980
1a4d82fc
JJ
3981impl ops::BitAnd for TypeContents {
3982 type Output = TypeContents;
3983
3984 fn bitand(self, other: TypeContents) -> TypeContents {
3985 TypeContents {bits: self.bits & other.bits}
970d7e83
LB
3986 }
3987}
3988
1a4d82fc
JJ
3989impl ops::Sub for TypeContents {
3990 type Output = TypeContents;
3991
3992 fn sub(self, other: TypeContents) -> TypeContents {
3993 TypeContents {bits: self.bits & !other.bits}
3994 }
223e47cc
LB
3995}
3996
85aaf69f 3997impl fmt::Debug for TypeContents {
1a4d82fc
JJ
3998 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3999 write!(f, "TypeContents({:b})", self.bits)
223e47cc
LB
4000 }
4001}
4002
1a4d82fc
JJ
4003pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
4004 return memoized(&cx.tc_cache, ty, |ty| {
85aaf69f 4005 tc_ty(cx, ty, &mut FnvHashMap())
1a4d82fc
JJ
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 {
c34b1796 4044 // usize and isize are ffi-unsafe
62682a34 4045 TyUint(ast::TyUs) | TyInt(ast::TyIs) => {
1a4d82fc
JJ
4046 TC::ReachesFfiUnsafe
4047 }
4048
4049 // Scalar and unique types are sendable, and durable
62682a34
SL
4050 TyInfer(ty::FreshIntTy(_)) | TyInfer(ty::FreshFloatTy(_)) |
4051 TyBool | TyInt(_) | TyUint(_) | TyFloat(_) |
4052 TyBareFn(..) | ty::TyChar => {
1a4d82fc
JJ
4053 TC::None
4054 }
4055
62682a34 4056 TyBox(typ) => {
1a4d82fc 4057 TC::ReachesFfiUnsafe | match typ.sty {
62682a34 4058 TyStr => TC::OwnsOwned,
1a4d82fc
JJ
4059 _ => tc_ty(cx, typ, cache).owned_pointer(),
4060 }
4061 }
4062
62682a34 4063 TyTrait(box TraitTy { ref bounds, .. }) => {
1a4d82fc
JJ
4064 object_contents(bounds) | TC::ReachesFfiUnsafe | TC::Nonsized
4065 }
4066
62682a34 4067 TyRawPtr(ref mt) => {
1a4d82fc
JJ
4068 tc_ty(cx, mt.ty, cache).unsafe_pointer()
4069 }
4070
62682a34 4071 TyRef(r, ref mt) => {
1a4d82fc 4072 TC::ReachesFfiUnsafe | match mt.ty.sty {
62682a34
SL
4073 TyStr => borrowed_contents(*r, ast::MutImmutable),
4074 TyArray(..) |
4075 TySlice(_) => tc_ty(cx, mt.ty, cache).reference(borrowed_contents(*r,
1a4d82fc
JJ
4076 mt.mutbl)),
4077 _ => tc_ty(cx, mt.ty, cache).reference(borrowed_contents(*r, mt.mutbl)),
4078 }
4079 }
4080
62682a34 4081 TyArray(ty, _) => {
1a4d82fc
JJ
4082 tc_ty(cx, ty, cache)
4083 }
4084
62682a34 4085 TySlice(ty) => {
1a4d82fc
JJ
4086 tc_ty(cx, ty, cache) | TC::Nonsized
4087 }
62682a34 4088 TyStr => TC::Nonsized,
1a4d82fc 4089
62682a34 4090 TyStruct(did, substs) => {
1a4d82fc
JJ
4091 let flds = struct_fields(cx, did, substs);
4092 let mut res =
85aaf69f 4093 TypeContents::union(&flds[..],
1a4d82fc
JJ
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
62682a34 4106 TyClosure(did, substs) => {
85aaf69f 4107 // FIXME(#14449): `borrowed_contents` below assumes `&mut` closure.
1a4d82fc 4108 let param_env = ty::empty_parameter_environment(cx);
85aaf69f 4109 let upvars = closure_upvars(&param_env, did, substs).unwrap();
c34b1796 4110 TypeContents::union(&upvars, |f| tc_ty(cx, &f.ty, cache))
1a4d82fc
JJ
4111 }
4112
62682a34 4113 TyTuple(ref tys) => {
85aaf69f 4114 TypeContents::union(&tys[..],
1a4d82fc
JJ
4115 |ty| tc_ty(cx, *ty, cache))
4116 }
4117
62682a34 4118 TyEnum(did, substs) => {
1a4d82fc
JJ
4119 let variants = substd_enum_variants(cx, did, substs);
4120 let mut res =
85aaf69f 4121 TypeContents::union(&variants[..], |variant| {
c34b1796 4122 TypeContents::union(&variant.args,
1a4d82fc
JJ
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
9346a6ac 4132 if !variants.is_empty() {
1a4d82fc
JJ
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
9346a6ac 4154 if variants[0].args.is_empty() {
1a4d82fc
JJ
4155 data_idx = 1;
4156 }
4157
4158 if variants[data_idx].args.len() == 1 {
4159 match variants[data_idx].args[0].sty {
62682a34 4160 TyBareFn(..) => { res = res - TC::ReachesFfiUnsafe; }
1a4d82fc
JJ
4161 _ => { }
4162 }
4163 }
4164 }
4165 }
4166 }
4167 }
4168
4169
4170 apply_lang_items(cx, did, res)
4171 }
4172
62682a34
SL
4173 TyProjection(..) |
4174 TyParam(_) => {
1a4d82fc
JJ
4175 TC::All
4176 }
4177
62682a34
SL
4178 TyInfer(_) |
4179 TyError => {
1a4d82fc
JJ
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 {
d9579d0f 4198 if Some(did) == cx.lang_items.unsafe_cell_type() {
1a4d82fc
JJ
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;
85aaf69f 4221 for bound in &bounds.builtin_bounds {
1a4d82fc
JJ
4222 tc = tc - match bound {
4223 BoundSync | BoundSend | BoundCopy => TC::None,
4224 BoundSized => TC::Nonsized,
4225 };
4226 }
4227 return tc;
4228 }
4229}
4230
62682a34
SL
4231fn type_impls_bound<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'tcx>>,
4232 tcx: &ty::ctxt<'tcx>,
1a4d82fc
JJ
4233 ty: Ty<'tcx>,
4234 bound: ty::BuiltinBound,
4235 span: Span)
4236 -> bool
4237{
62682a34
SL
4238 let pe;
4239 let param_env = match param_env {
4240 Some(e) => e,
4241 None => {
4242 pe = empty_parameter_environment(tcx);
4243 &pe
1a4d82fc 4244 }
62682a34
SL
4245 };
4246 let infcx = infer::new_infer_ctxt(tcx);
1a4d82fc
JJ
4247
4248 let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env, ty, bound, span);
4249
62682a34
SL
4250 debug!("type_impls_bound({:?}, {:?}) = {:?}",
4251 ty,
1a4d82fc
JJ
4252 bound,
4253 is_impld);
4254
1a4d82fc
JJ
4255 is_impld
4256}
4257
4258pub fn type_moves_by_default<'a,'tcx>(param_env: &ParameterEnvironment<'a,'tcx>,
4259 span: Span,
4260 ty: Ty<'tcx>)
4261 -> bool
4262{
62682a34
SL
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
1a4d82fc
JJ
4298}
4299
62682a34
SL
4300#[inline]
4301pub fn type_is_sized<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'tcx>>,
4302 tcx: &ty::ctxt<'tcx>,
1a4d82fc
JJ
4303 span: Span,
4304 ty: Ty<'tcx>)
4305 -> bool
4306{
62682a34
SL
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
4315fn 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
1a4d82fc
JJ
4342}
4343
4344pub 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`.
4349pub 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({:?}, {:?})?",
62682a34 4353 r_ty, ty);
1a4d82fc
JJ
4354
4355 let r = r_ty == ty || subtypes_require(cx, seen, r_ty, ty);
4356
4357 debug!("type_requires({:?}, {:?})? {:?}",
62682a34 4358 r_ty, ty, r);
1a4d82fc
JJ
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({:?}, {:?})?",
62682a34 4365 r_ty, ty);
1a4d82fc
JJ
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.
62682a34
SL
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(_) => {
1a4d82fc
JJ
4384 false
4385 }
62682a34 4386 TyBox(typ) => {
1a4d82fc
JJ
4387 type_requires(cx, seen, r_ty, typ)
4388 }
62682a34 4389 TyRef(_, ref mt) => {
1a4d82fc
JJ
4390 type_requires(cx, seen, r_ty, mt.ty)
4391 }
4392
62682a34 4393 TyRawPtr(..) => {
1a4d82fc
JJ
4394 false // unsafe ptrs can always be NULL
4395 }
4396
62682a34 4397 TyTrait(..) => {
1a4d82fc
JJ
4398 false
4399 }
4400
62682a34 4401 TyStruct(ref did, _) if seen.contains(did) => {
1a4d82fc
JJ
4402 false
4403 }
4404
62682a34 4405 TyStruct(did, substs) => {
1a4d82fc
JJ
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
62682a34
SL
4413 TyError |
4414 TyInfer(_) |
4415 TyClosure(..) => {
1a4d82fc 4416 // this check is run on type definitions, so we don't expect to see
85aaf69f
SL
4417 // inference by-products or closure types
4418 cx.sess.bug(&format!("requires check invoked on inapplicable type: {:?}", ty))
1a4d82fc
JJ
4419 }
4420
62682a34 4421 TyTuple(ref ts) => {
1a4d82fc
JJ
4422 ts.iter().any(|ty| type_requires(cx, seen, r_ty, *ty))
4423 }
4424
62682a34 4425 TyEnum(ref did, _) if seen.contains(did) => {
1a4d82fc
JJ
4426 false
4427 }
4428
62682a34 4429 TyEnum(did, substs) => {
1a4d82fc
JJ
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({:?}, {:?})? {:?}",
62682a34 4444 r_ty, ty, r);
1a4d82fc
JJ
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.
c34b1796 4461#[derive(Copy, Clone, PartialOrd, Ord, Eq, PartialEq, Debug)]
1a4d82fc
JJ
4462pub 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.
4470pub 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 {
62682a34 4486 TyTuple(ref ts) => {
85aaf69f 4487 find_nonrepresentable(cx, sp, seen, ts.iter().cloned())
1a4d82fc
JJ
4488 }
4489 // Fixed-length vectors.
4490 // FIXME(#11924) Behavior undecided for zero-length vectors.
62682a34 4491 TyArray(ty, _) => {
1a4d82fc
JJ
4492 is_type_structurally_recursive(cx, sp, seen, ty)
4493 }
62682a34 4494 TyStruct(did, substs) => {
1a4d82fc
JJ
4495 let fields = struct_fields(cx, did, substs);
4496 find_nonrepresentable(cx, sp, seen, fields.iter().map(|f| f.mt.ty))
4497 }
62682a34 4498 TyEnum(did, substs) => {
1a4d82fc
JJ
4499 let vs = enum_variants(cx, did);
4500 let iter = vs.iter()
62682a34 4501 .flat_map(|variant| &variant.args)
1a4d82fc
JJ
4502 .map(|aty| { aty.subst_spanned(cx, substs, Some(sp)) });
4503
4504 find_nonrepresentable(cx, sp, seen, iter)
4505 }
62682a34 4506 TyClosure(..) => {
85aaf69f
SL
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))
1a4d82fc
JJ
4510 }
4511 _ => Representable,
4512 }
4513 }
4514
4515 fn same_struct_or_enum_def_id(ty: Ty, did: DefId) -> bool {
4516 match ty.sty {
62682a34 4517 TyStruct(ty_did, _) | TyEnum(ty_did, _) => {
1a4d82fc
JJ
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) {
62682a34
SL
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)) => {
1a4d82fc
JJ
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
62682a34 4535 let mut pairs = types_a.iter().zip(types_b);
1a4d82fc
JJ
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 {
62682a34 4550 debug!("is_type_structurally_recursive: {:?}", ty);
1a4d82fc
JJ
4551
4552 match ty.sty {
62682a34 4553 TyStruct(did, _) | TyEnum(did, _) => {
1a4d82fc
JJ
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 {:?}",
62682a34
SL
4570 seen_type,
4571 ty);
1a4d82fc
JJ
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 {:?}",
62682a34
SL
4590 seen_type,
4591 ty);
1a4d82fc
JJ
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
62682a34 4611 debug!("is_type_representable: {:?}", ty);
1a4d82fc
JJ
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);
62682a34 4618 debug!("is_type_representable: {:?} is {:?}", ty, r);
1a4d82fc
JJ
4619 r
4620}
4621
4622pub fn type_is_trait(ty: Ty) -> bool {
1a4d82fc 4623 match ty.sty {
62682a34
SL
4624 TyTrait(..) => true,
4625 _ => false
1a4d82fc
JJ
4626 }
4627}
4628
4629pub fn type_is_integral(ty: Ty) -> bool {
4630 match ty.sty {
62682a34 4631 TyInfer(IntVar(_)) | TyInt(_) | TyUint(_) => true,
1a4d82fc
JJ
4632 _ => false
4633 }
4634}
4635
4636pub fn type_is_fresh(ty: Ty) -> bool {
4637 match ty.sty {
62682a34
SL
4638 TyInfer(FreshTy(_)) => true,
4639 TyInfer(FreshIntTy(_)) => true,
4640 TyInfer(FreshFloatTy(_)) => true,
1a4d82fc
JJ
4641 _ => false
4642 }
4643}
4644
4645pub fn type_is_uint(ty: Ty) -> bool {
4646 match ty.sty {
62682a34 4647 TyInfer(IntVar(_)) | TyUint(ast::TyUs) => true,
1a4d82fc
JJ
4648 _ => false
4649 }
4650}
4651
4652pub fn type_is_char(ty: Ty) -> bool {
4653 match ty.sty {
62682a34 4654 TyChar => true,
1a4d82fc
JJ
4655 _ => false
4656 }
4657}
4658
4659pub fn type_is_bare_fn(ty: Ty) -> bool {
4660 match ty.sty {
62682a34 4661 TyBareFn(..) => true,
1a4d82fc
JJ
4662 _ => false
4663 }
4664}
4665
4666pub fn type_is_bare_fn_item(ty: Ty) -> bool {
4667 match ty.sty {
62682a34 4668 TyBareFn(Some(_), _) => true,
1a4d82fc
JJ
4669 _ => false
4670 }
4671}
4672
4673pub fn type_is_fp(ty: Ty) -> bool {
4674 match ty.sty {
62682a34 4675 TyInfer(FloatVar(_)) | TyFloat(_) => true,
1a4d82fc
JJ
4676 _ => false
4677 }
4678}
4679
4680pub fn type_is_numeric(ty: Ty) -> bool {
4681 return type_is_integral(ty) || type_is_fp(ty);
4682}
4683
4684pub fn type_is_signed(ty: Ty) -> bool {
4685 match ty.sty {
62682a34 4686 TyInt(_) => true,
1a4d82fc
JJ
4687 _ => false
4688 }
4689}
4690
4691pub fn type_is_machine(ty: Ty) -> bool {
4692 match ty.sty {
62682a34
SL
4693 TyInt(ast::TyIs) | TyUint(ast::TyUs) => false,
4694 TyInt(..) | TyUint(..) | TyFloat(..) => true,
1a4d82fc
JJ
4695 _ => false
4696 }
4697}
4698
4699// Whether a type is enum like, that is an enum type with only nullary
4700// constructors
4701pub fn type_is_c_like_enum(cx: &ctxt, ty: Ty) -> bool {
4702 match ty.sty {
62682a34 4703 TyEnum(did, _) => {
1a4d82fc 4704 let variants = enum_variants(cx, did);
9346a6ac 4705 if variants.is_empty() {
1a4d82fc
JJ
4706 false
4707 } else {
9346a6ac 4708 variants.iter().all(|v| v.args.is_empty())
1a4d82fc
JJ
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.
4719pub fn deref<'tcx>(ty: Ty<'tcx>, explicit: bool) -> Option<mt<'tcx>> {
4720 match ty.sty {
62682a34 4721 TyBox(ty) => {
1a4d82fc
JJ
4722 Some(mt {
4723 ty: ty,
4724 mutbl: ast::MutImmutable,
4725 })
4726 },
62682a34
SL
4727 TyRef(_, mt) => Some(mt),
4728 TyRawPtr(mt) if explicit => Some(mt),
1a4d82fc
JJ
4729 _ => None
4730 }
4731}
4732
1a4d82fc
JJ
4733pub fn type_content<'tcx>(ty: Ty<'tcx>) -> Ty<'tcx> {
4734 match ty.sty {
62682a34
SL
4735 TyBox(ty) => ty,
4736 TyRef(_, mt) | TyRawPtr(mt) => mt.ty,
1a4d82fc
JJ
4737 _ => ty
4738 }
4739}
4740
1a4d82fc
JJ
4741// Returns the type of ty[i]
4742pub fn index<'tcx>(ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
4743 match ty.sty {
62682a34 4744 TyArray(ty, _) | TySlice(ty) => Some(ty),
1a4d82fc
JJ
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.
4752pub fn array_element_ty<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
4753 match ty.sty {
62682a34
SL
4754 TyArray(ty, _) | TySlice(ty) => Some(ty),
4755 TyStr => Some(tcx.types.u8),
1a4d82fc
JJ
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.
4762pub fn positional_element_ty<'tcx>(cx: &ctxt<'tcx>,
4763 ty: Ty<'tcx>,
c34b1796 4764 i: usize,
1a4d82fc
JJ
4765 variant: Option<ast::DefId>) -> Option<Ty<'tcx>> {
4766
4767 match (&ty.sty, variant) {
62682a34 4768 (&TyTuple(ref v), None) => v.get(i).cloned(),
1a4d82fc
JJ
4769
4770
62682a34 4771 (&TyStruct(def_id, substs), None) => lookup_struct_fields(cx, def_id)
1a4d82fc
JJ
4772 .get(i)
4773 .map(|&t|lookup_item_type(cx, t.id).ty.subst(cx, substs)),
4774
62682a34 4775 (&TyEnum(def_id, substs), Some(variant_def_id)) => {
1a4d82fc
JJ
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
62682a34 4780 (&TyEnum(def_id, substs), None) => {
1a4d82fc
JJ
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.
4793pub 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) {
62682a34 4799 (&TyStruct(def_id, substs), None) => {
1a4d82fc
JJ
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 }
62682a34 4804 (&TyEnum(def_id, substs), Some(variant_def_id)) => {
1a4d82fc
JJ
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")
62682a34 4808 .iter().zip(&variant_info.args)
9346a6ac
AL
4809 .find(|&(&name, _)| name == n)
4810 .map(|(_name, arg_t)| arg_t.subst(cx, substs))
1a4d82fc
JJ
4811 }
4812 _ => None
4813 }
4814}
4815
1a4d82fc 4816pub fn node_id_to_type<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> Ty<'tcx> {
85aaf69f 4817 match node_id_to_type_opt(cx, id) {
1a4d82fc
JJ
4818 Some(ty) => ty,
4819 None => cx.sess.bug(
4820 &format!("node_id_to_type: no type for node `{}`",
c34b1796 4821 cx.map.node_to_string(id)))
1a4d82fc
JJ
4822 }
4823}
4824
4825pub 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
4832pub 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
4839pub fn fn_is_variadic(fty: Ty) -> bool {
4840 match fty.sty {
62682a34 4841 TyBareFn(_, ref f) => f.sig.0.variadic,
1a4d82fc
JJ
4842 ref s => {
4843 panic!("fn_is_variadic() called on non-fn type: {:?}", s)
4844 }
4845 }
4846}
4847
4848pub fn ty_fn_sig<'tcx>(fty: Ty<'tcx>) -> &'tcx PolyFnSig<'tcx> {
4849 match fty.sty {
62682a34 4850 TyBareFn(_, ref f) => &f.sig,
1a4d82fc
JJ
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.
4858pub fn ty_fn_abi(fty: Ty) -> abi::Abi {
4859 match fty.sty {
62682a34 4860 TyBareFn(_, ref f) => f.abi,
1a4d82fc
JJ
4861 _ => panic!("ty_fn_abi() called on non-fn type"),
4862 }
4863}
4864
4865// Type accessors for substructures of types
4866pub fn ty_fn_args<'tcx>(fty: Ty<'tcx>) -> ty::Binder<Vec<Ty<'tcx>>> {
4867 ty_fn_sig(fty).inputs()
4868}
4869
1a4d82fc
JJ
4870pub fn ty_fn_ret<'tcx>(fty: Ty<'tcx>) -> Binder<FnOutput<'tcx>> {
4871 match fty.sty {
62682a34 4872 TyBareFn(_, ref f) => f.sig.output(),
1a4d82fc
JJ
4873 ref s => {
4874 panic!("ty_fn_ret() called on non-fn type: {:?}", s)
4875 }
4876 }
4877}
4878
4879pub fn is_fn_ty(fty: Ty) -> bool {
4880 match fty.sty {
62682a34 4881 TyBareFn(..) => true,
1a4d82fc
JJ
4882 _ => false
4883 }
4884}
4885
4886pub fn ty_region(tcx: &ctxt,
4887 span: Span,
4888 ty: Ty) -> Region {
4889 match ty.sty {
62682a34 4890 TyRef(r, _) => *r,
1a4d82fc
JJ
4891 ref s => {
4892 tcx.sess.span_bug(
4893 span,
4894 &format!("ty_region() invoked on an inappropriate ty: {:?}",
c34b1796 4895 s));
1a4d82fc
JJ
4896 }
4897 }
4898}
4899
85aaf69f
SL
4900pub fn free_region_from_def(outlives_extent: region::DestructionScopeData,
4901 def: &RegionParameterDef)
1a4d82fc
JJ
4902 -> ty::Region
4903{
85aaf69f
SL
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
1a4d82fc
JJ
4910}
4911
4912// Returns the type of a pattern as a monotype. Like @expr_ty, this function
4913// doesn't provide type parameter substitutions.
4914pub fn pat_ty<'tcx>(cx: &ctxt<'tcx>, pat: &ast::Pat) -> Ty<'tcx> {
4915 return node_id_to_type(cx, pat.id);
4916}
c34b1796
AL
4917pub 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}
1a4d82fc
JJ
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
c34b1796
AL
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".
1a4d82fc
JJ
4932pub fn expr_ty<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr) -> Ty<'tcx> {
4933 return node_id_to_type(cx, expr.id);
4934}
4935
4936pub 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
bd371182 4948/// thread at hand! -nmatsakis
1a4d82fc
JJ
4949pub 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
4955pub 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,
c34b1796 4963 f));
1a4d82fc
JJ
4964 }
4965 None => {
4966 cx.sess.bug(&format!("Node id {} is not present \
c34b1796 4967 in the node map", id));
1a4d82fc
JJ
4968 }
4969 }
4970}
4971
4972pub 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,
c34b1796 4983 pat));
1a4d82fc
JJ
4984 }
4985 }
4986 }
4987 r => {
4988 cx.sess.bug(&format!("Variable id {} maps to {:?}, not local",
4989 id,
c34b1796 4990 r));
1a4d82fc
JJ
4991 }
4992 }
4993}
4994
4995/// See `expr_ty_adjusted`
4996pub 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{
62682a34 5005 if let TyError = unadjusted_ty.sty {
1a4d82fc
JJ
5006 return unadjusted_ty;
5007 }
5008
5009 return match adjustment {
5010 Some(adjustment) => {
5011 match *adjustment {
9346a6ac 5012 AdjustReifyFnPointer => {
1a4d82fc 5013 match unadjusted_ty.sty {
62682a34 5014 ty::TyBareFn(Some(_), b) => {
1a4d82fc
JJ
5015 ty::mk_bare_fn(cx, None, b)
5016 }
9346a6ac 5017 _ => {
1a4d82fc
JJ
5018 cx.sess.bug(
5019 &format!("AdjustReifyFnPointer adjustment on non-fn-item: \
62682a34 5020 {:?}", unadjusted_ty));
1a4d82fc
JJ
5021 }
5022 }
5023 }
5024
c34b1796
AL
5025 AdjustUnsafeFnPointer => {
5026 match unadjusted_ty.sty {
62682a34 5027 ty::TyBareFn(None, b) => cx.safe_to_unsafe_fn_ty(b),
c34b1796
AL
5028 ref b => {
5029 cx.sess.bug(
5030 &format!("AdjustReifyFnPointer adjustment on non-fn-item: \
5031 {:?}",
5032 b));
5033 }
5034 }
5035 }
5036
1a4d82fc
JJ
5037 AdjustDerefRef(ref adj) => {
5038 let mut adjusted_ty = unadjusted_ty;
5039
5040 if !ty::type_is_error(adjusted_ty) {
85aaf69f 5041 for i in 0..adj.autoderefs {
9346a6ac 5042 let method_call = MethodCall::autoderef(expr_id, i as u32);
1a4d82fc
JJ
5043 match method_type(method_call) {
5044 Some(method_ty) => {
9346a6ac
AL
5045 // Overloaded deref operators have all late-bound
5046 // regions fully instantiated and coverge.
1a4d82fc 5047 let fn_ret =
85aaf69f
SL
5048 ty::no_late_bound_regions(cx,
5049 &ty_fn_ret(method_ty)).unwrap();
1a4d82fc
JJ
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,
9346a6ac 5059 &format!("the {}th autoderef failed: {}",
1a4d82fc 5060 i,
62682a34 5061 adjusted_ty)
c34b1796 5062 );
1a4d82fc
JJ
5063 }
5064 }
5065 }
5066 }
5067
9346a6ac
AL
5068 if let Some(target) = adj.unsize {
5069 target
5070 } else {
5071 adjust_ty_for_autoref(cx, adjusted_ty, adj.autoref)
5072 }
1a4d82fc
JJ
5073 }
5074 }
5075 }
5076 None => unadjusted_ty
5077 };
5078}
5079
5080pub fn adjust_ty_for_autoref<'tcx>(cx: &ctxt<'tcx>,
1a4d82fc 5081 ty: Ty<'tcx>,
9346a6ac
AL
5082 autoref: Option<AutoRef<'tcx>>)
5083 -> Ty<'tcx> {
1a4d82fc
JJ
5084 match autoref {
5085 None => ty,
9346a6ac
AL
5086 Some(AutoPtr(r, m)) => {
5087 mk_rptr(cx, r, mt { ty: ty, mutbl: m })
1a4d82fc 5088 }
9346a6ac
AL
5089 Some(AutoUnsafe(m)) => {
5090 mk_ptr(cx, mt { ty: ty, mutbl: m })
c34b1796 5091 }
1a4d82fc
JJ
5092 }
5093}
5094
5095pub fn resolve_expr(tcx: &ctxt, expr: &ast::Expr) -> def::Def {
5096 match tcx.def_map.borrow().get(&expr.id) {
c34b1796 5097 Some(def) => def.full_def(),
223e47cc 5098 None => {
1a4d82fc 5099 tcx.sess.span_bug(expr.span, &format!(
c34b1796 5100 "no def-map entry for expr {}", expr.id));
1a4d82fc
JJ
5101 }
5102 }
5103}
5104
62682a34
SL
5105pub fn expr_is_lval(tcx: &ctxt, expr: &ast::Expr) -> bool {
5106 match expr.node {
c34b1796 5107 ast::ExprPath(..) => {
62682a34
SL
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
1a4d82fc
JJ
5120 }
5121
62682a34 5122 Some(..) => false,
1a4d82fc 5123
62682a34
SL
5124 None => tcx.sess.span_bug(expr.span, &format!(
5125 "no def for path {}", expr.id))
1a4d82fc
JJ
5126 }
5127 }
5128
5129 ast::ExprUnary(ast::UnDeref, _) |
5130 ast::ExprField(..) |
5131 ast::ExprTupField(..) |
5132 ast::ExprIndex(..) => {
62682a34 5133 true
1a4d82fc
JJ
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(..) |
62682a34 5146 ast::ExprVec(..) |
1a4d82fc
JJ
5147 ast::ExprBreak(..) |
5148 ast::ExprAgain(..) |
5149 ast::ExprRet(..) |
5150 ast::ExprWhile(..) |
5151 ast::ExprLoop(..) |
5152 ast::ExprAssign(..) |
5153 ast::ExprInlineAsm(..) |
62682a34
SL
5154 ast::ExprAssignOp(..) |
5155 ast::ExprLit(_) |
1a4d82fc 5156 ast::ExprUnary(..) |
62682a34 5157 ast::ExprBox(..) |
1a4d82fc 5158 ast::ExprAddrOf(..) |
c34b1796
AL
5159 ast::ExprBinary(..) |
5160 ast::ExprCast(..) => {
62682a34 5161 false
1a4d82fc
JJ
5162 }
5163
62682a34 5164 ast::ExprParen(ref e) => expr_is_lval(tcx, e),
1a4d82fc 5165
62682a34
SL
5166 ast::ExprIfLet(..) |
5167 ast::ExprWhileLet(..) |
5168 ast::ExprForLoop(..) |
1a4d82fc
JJ
5169 ast::ExprMac(..) => {
5170 tcx.sess.span_bug(
5171 expr.span,
5172 "macro expression remains after expansion");
5173 }
5174 }
5175}
5176
5177pub 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
5186pub fn field_idx_strict(tcx: &ctxt, name: ast::Name, fields: &[field])
c34b1796 5187 -> usize {
85aaf69f
SL
5188 let mut i = 0;
5189 for f in fields { if f.name == name { return i; } i += 1; }
1a4d82fc
JJ
5190 tcx.sess.bug(&format!(
5191 "no field named `{}` found in the list of fields `{:?}`",
5192 token::get_name(name),
5193 fields.iter()
85aaf69f 5194 .map(|f| token::get_name(f.name).to_string())
c34b1796 5195 .collect::<Vec<String>>()));
1a4d82fc
JJ
5196}
5197
5198pub fn impl_or_trait_item_idx(id: ast::Name, trait_items: &[ImplOrTraitItem])
c34b1796 5199 -> Option<usize> {
1a4d82fc
JJ
5200 trait_items.iter().position(|m| m.name() == id)
5201}
5202
62682a34 5203pub fn ty_sort_string(cx: &ctxt, ty: Ty) -> String {
1a4d82fc 5204 match ty.sty {
62682a34
SL
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) => {
1a4d82fc
JJ
5218 format!("trait {}", item_path_str(cx, inner.principal_def_id()))
5219 }
62682a34 5220 TyStruct(id, _) => {
85aaf69f 5221 format!("struct `{}`", item_path_str(cx, id))
1a4d82fc 5222 }
62682a34
SL
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) => {
1a4d82fc
JJ
5233 if p.space == subst::SelfSpace {
5234 "Self".to_string()
5235 } else {
5236 "type parameter".to_string()
5237 }
5238 }
62682a34 5239 TyError => "type error".to_string(),
1a4d82fc
JJ
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.
62682a34
SL
5247impl<'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 }
1a4d82fc 5335 }
62682a34
SL
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)
1a4d82fc 5368 }
1a4d82fc
JJ
5369 }
5370 }
5371}
5372
9346a6ac 5373pub fn note_and_explain_type_err<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>, sp: Span) {
1a4d82fc
JJ
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 }
9346a6ac
AL
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 }
1a4d82fc
JJ
5414 _ => {}
5415 }
5416}
5417
5418pub fn provided_source(cx: &ctxt, id: ast::DefId) -> Option<ast::DefId> {
85aaf69f 5419 cx.provided_method_sources.borrow().get(&id).cloned()
1a4d82fc
JJ
5420}
5421
5422pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
5423 -> Vec<Rc<Method<'tcx>>> {
5424 if is_local(id) {
c34b1796
AL
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),
d9579d0f 5430 _ => {
c34b1796 5431 cx.sess.bug("provided_trait_methods(): \
d9579d0f
AL
5432 non-method item found from \
5433 looking up provided method?!")
c34b1796 5434 }
1a4d82fc 5435 }
c34b1796
AL
5436 } else {
5437 None
1a4d82fc 5438 }
c34b1796
AL
5439 }).collect()
5440 } else {
5441 cx.sess.bug(&format!("provided_trait_methods: `{:?}` is not a trait", id))
1a4d82fc
JJ
5442 }
5443 } else {
5444 csearch::get_provided_trait_methods(cx, id)
5445 }
5446}
5447
d9579d0f
AL
5448pub 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
1a4d82fc
JJ
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).
5500fn lookup_locally_or_in_crate_store<V, F>(descr: &str,
5501 def_id: ast::DefId,
62682a34 5502 map: &RefCell<DefIdMap<V>>,
1a4d82fc
JJ
5503 load_external: F) -> V where
5504 V: Clone,
5505 F: FnOnce() -> V,
5506{
62682a34 5507 match map.borrow().get(&def_id).cloned() {
1a4d82fc
JJ
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();
62682a34 5516 map.borrow_mut().insert(def_id, v.clone());
1a4d82fc
JJ
5517 v
5518}
5519
c34b1796 5520pub fn trait_item<'tcx>(cx: &ctxt<'tcx>, trait_did: ast::DefId, idx: usize)
1a4d82fc
JJ
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
5526pub 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
85aaf69f
SL
5543pub 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
d9579d0f
AL
5560pub 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
1a4d82fc
JJ
5580pub fn impl_or_trait_item<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
5581 -> ImplOrTraitItem<'tcx> {
62682a34
SL
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))
1a4d82fc
JJ
5585}
5586
5587/// Returns the parameter index that the given associated type corresponds to.
5588pub fn associated_type_parameter_index(cx: &ctxt,
5589 trait_def: &TraitDef,
5590 associated_type_id: ast::DefId)
c34b1796 5591 -> usize {
62682a34 5592 for type_parameter_def in &trait_def.generics.types {
1a4d82fc 5593 if type_parameter_def.def_id == associated_type_id {
c34b1796 5594 return type_parameter_def.index as usize
1a4d82fc
JJ
5595 }
5596 }
5597 cx.sess.bug("couldn't find associated type parameter index")
5598}
5599
1a4d82fc
JJ
5600pub fn trait_item_def_ids(cx: &ctxt, id: ast::DefId)
5601 -> Rc<Vec<ImplOrTraitItemId>> {
62682a34
SL
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)))
1a4d82fc
JJ
5605}
5606
62682a34
SL
5607/// Returns the trait-ref corresponding to a given impl, or None if it is
5608/// an inherent impl.
1a4d82fc 5609pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
62682a34
SL
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
5618pub 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
1a4d82fc 5623 } else {
62682a34 5624 false
1a4d82fc 5625 }
62682a34
SL
5626 } else {
5627 csearch::is_impl(&cx.sess.cstore, id)
5628 }
1a4d82fc
JJ
5629}
5630
5631pub fn trait_ref_to_def_id(tcx: &ctxt, tr: &ast::TraitRef) -> ast::DefId {
c34b1796 5632 tcx.def_map.borrow().get(&tr.ref_id).expect("no def-map entry for trait").def_id()
1a4d82fc
JJ
5633}
5634
5635pub 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
5652pub fn ty_to_def_id(ty: Ty) -> Option<ast::DefId> {
5653 match ty.sty {
62682a34 5654 TyTrait(ref tt) =>
1a4d82fc 5655 Some(tt.principal_def_id()),
62682a34
SL
5656 TyStruct(id, _) |
5657 TyEnum(id, _) |
5658 TyClosure(id, _) =>
1a4d82fc
JJ
5659 Some(id),
5660 _ =>
5661 None
5662 }
5663}
5664
5665// Enum information
5666#[derive(Clone)]
5667pub struct VariantInfo<'tcx> {
5668 pub args: Vec<Ty<'tcx>>,
9346a6ac 5669 pub arg_names: Option<Vec<ast::Name>>,
1a4d82fc
JJ
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
5677impl<'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) => {
9346a6ac 5689 let arg_tys = if !args.is_empty() {
1a4d82fc
JJ
5690 // the regions in the argument types come from the
5691 // enum def'n, and hence will all be early bound
85aaf69f 5692 ty::no_late_bound_regions(cx, &ty_fn_args(ctor_ty)).unwrap()
1a4d82fc
JJ
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) => {
c34b1796 5708 let fields: &[StructField] = &struct_def.fields;
1a4d82fc 5709
9346a6ac 5710 assert!(!fields.is_empty());
1a4d82fc
JJ
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 {
9346a6ac 5716 NamedField(ident, _) => ident.name,
1a4d82fc
JJ
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
5736pub 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
5754pub 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
c34b1796 5758#[derive(Copy, Clone)]
1a4d82fc
JJ
5759pub enum DtorKind {
5760 NoDtor,
5761 TraitDtor(DefId, bool)
5762}
5763
5764impl 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
d9579d0f 5780/* If struct_id names a struct with a dtor. */
1a4d82fc
JJ
5781pub 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
5792pub fn has_dtor(cx: &ctxt, struct_id: DefId) -> bool {
5793 cx.destructor_for_type.borrow().contains_key(&struct_id)
5794}
5795
5796pub 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 {
c34b1796 5802 f(csearch::get_item_path(cx, id).iter().cloned().chain(LinkedPath::empty()))
1a4d82fc
JJ
5803 }
5804}
5805
5806pub fn enum_is_univariant(cx: &ctxt, id: ast::DefId) -> bool {
5807 enum_variants(cx, id).len() == 1
5808}
5809
5810pub fn type_is_empty(cx: &ctxt, ty: Ty) -> bool {
5811 match ty.sty {
62682a34 5812 TyEnum(did, _) => (*enum_variants(cx, did)).is_empty(),
1a4d82fc
JJ
5813 _ => false
5814 }
5815}
5816
c34b1796
AL
5817trait 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
5826impl 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`).
5941pub 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
5967fn 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);
62682a34 5975 let repr_type = repr_type.to_ty(cx);
c34b1796
AL
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`.
5985fn 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)) {
62682a34
SL
6025 Ok(ConstVal::Int(val)) => current_disr_val = val as Disr,
6026 Ok(ConstVal::Uint(val)) => current_disr_val = val as Disr,
c34b1796 6027 Ok(_) => {
d9579d0f 6028 let sign_desc = if repr_type.is_signed() { "signed" } else { "unsigned" };
c34b1796 6029 span_err!(cx.sess, e.span, E0079,
d9579d0f
AL
6030 "expected {} integer constant",
6031 sign_desc);
c34b1796
AL
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
1a4d82fc
JJ
6067pub 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 {
1a4d82fc
JJ
6073 match cx.map.get(id.node) {
6074 ast_map::NodeItem(ref item) => {
6075 match item.node {
6076 ast::ItemEnum(ref enum_definition, _) => {
c34b1796
AL
6077 Rc::new(compute_enum_variants(
6078 cx,
6079 &enum_definition.variants,
6080 lookup_repr_hints(cx, id).get(0)))
1a4d82fc
JJ
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:
6094pub 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.
6107pub fn lookup_item_type<'tcx>(cx: &ctxt<'tcx>,
6108 did: ast::DefId)
6109 -> TypeScheme<'tcx> {
6110 lookup_locally_or_in_crate_store(
62682a34 6111 "tcache", did, &cx.tcache,
1a4d82fc
JJ
6112 || csearch::get_type(cx, did))
6113}
6114
6115/// Given the did of a trait, returns its canonical trait ref.
6116pub fn lookup_trait_def<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
d9579d0f 6117 -> &'tcx TraitDef<'tcx> {
62682a34
SL
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 )
1a4d82fc
JJ
6122}
6123
c34b1796 6124/// Given the did of an item, returns its full set of predicates.
85aaf69f
SL
6125pub fn lookup_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
6126 -> GenericPredicates<'tcx>
6127{
62682a34
SL
6128 lookup_locally_or_in_crate_store(
6129 "predicates", did, &cx.predicates,
6130 || csearch::get_predicates(cx, did))
85aaf69f
SL
6131}
6132
c34b1796
AL
6133/// Given the did of a trait, returns its superpredicates.
6134pub fn lookup_super_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
6135 -> GenericPredicates<'tcx>
1a4d82fc 6136{
62682a34
SL
6137 lookup_locally_or_in_crate_store(
6138 "super_predicates", did, &cx.super_predicates,
6139 || csearch::get_super_predicates(cx, did))
1a4d82fc
JJ
6140}
6141
85aaf69f
SL
6142/// Get the attributes of a definition.
6143pub fn get_attrs<'tcx>(tcx: &'tcx ctxt, did: DefId)
c34b1796 6144 -> Cow<'tcx, [ast::Attribute]> {
1a4d82fc 6145 if is_local(did) {
c34b1796 6146 Cow::Borrowed(tcx.map.attrs(did.node))
1a4d82fc 6147 } else {
85aaf69f 6148 Cow::Owned(csearch::get_item_attrs(&tcx.sess.cstore, did))
1a4d82fc
JJ
6149 }
6150}
6151
6152/// Determine whether an item is annotated with an attribute
6153pub fn has_attr(tcx: &ctxt, did: DefId, attr: &str) -> bool {
85aaf69f 6154 get_attrs(tcx, did).iter().any(|item| item.check_name(attr))
1a4d82fc
JJ
6155}
6156
6157/// Determine whether an item is annotated with `#[repr(packed)]`
6158pub 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]`
6163pub 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.
6168pub 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 {
85aaf69f
SL
6171 get_attrs(tcx, did).iter().flat_map(|meta| {
6172 attr::find_repr_attrs(tcx.sess.diagnostic(), meta).into_iter()
6173 }).collect()
1a4d82fc
JJ
6174 } else {
6175 csearch::get_repr_attrs(&tcx.sess.cstore, did)
6176 })
6177 })
6178}
6179
d9579d0f
AL
6180// Look up a field ID, whether or not it's local
6181pub 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
1a4d82fc
JJ
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
6196pub fn lookup_field_type<'tcx>(tcx: &ctxt<'tcx>,
6197 struct_id: DefId,
6198 id: DefId,
6199 substs: &Substs<'tcx>)
6200 -> Ty<'tcx> {
d9579d0f 6201 lookup_field_type_unsubstituted(tcx, struct_id, id).subst(tcx, substs)
1a4d82fc
JJ
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.
6206pub 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: {}",
c34b1796 6214 cx.map.node_to_string(did.node)));
1a4d82fc
JJ
6215 }
6216 }
6217 } else {
6218 csearch::get_struct_fields(&cx.sess.cstore, did)
6219 }
6220}
6221
6222pub 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.
6229pub 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.
6244pub fn tup_fields<'tcx>(v: &[Ty<'tcx>]) -> Vec<field<'tcx>> {
6245 v.iter().enumerate().map(|(i, &f)| {
6246 field {
c34b1796 6247 name: token::intern(&i.to_string()),
1a4d82fc
JJ
6248 mt: mt {
6249 ty: f,
6250 mutbl: MutImmutable
6251 }
6252 }
6253 }).collect()
6254}
6255
9346a6ac
AL
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.
6259pub fn struct_tail<'tcx>(cx: &ctxt<'tcx>, mut ty: Ty<'tcx>) -> Ty<'tcx> {
62682a34 6260 while let TyStruct(def_id, substs) = ty.sty {
9346a6ac
AL
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.
6274pub 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);
62682a34 6279 while let (&TyStruct(a_did, a_substs), &TyStruct(b_did, b_substs)) = (&a.sty, &b.sty) {
9346a6ac
AL
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
1a4d82fc 6297#[derive(Copy, Clone)]
85aaf69f 6298pub struct ClosureUpvar<'tcx> {
1a4d82fc
JJ
6299 pub def: def::Def,
6300 pub span: Span,
6301 pub ty: Ty<'tcx>,
6302}
6303
85aaf69f
SL
6304// Returns a list of `ClosureUpvar`s for each upvar.
6305pub fn closure_upvars<'tcx>(typer: &mc::Typer<'tcx>,
6306 closure_id: ast::DefId,
6307 substs: &Substs<'tcx>)
6308 -> Option<Vec<ClosureUpvar<'tcx>>>
1a4d82fc
JJ
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();
1a4d82fc
JJ
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
85aaf69f
SL
6329 let upvar_id = ty::UpvarId {
6330 var_id: freevar_def_id.node,
6331 closure_expr_id: closure_id.node
6332 };
1a4d82fc 6333
85aaf69f
SL
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 };
1a4d82fc 6348
85aaf69f
SL
6349 ClosureUpvar {
6350 def: freevar.def,
6351 span: freevar.span,
6352 ty: freevar_ref_ty,
1a4d82fc 6353 }
85aaf69f 6354 })
1a4d82fc
JJ
6355 })
6356 .collect()
6357 }
6358 }
6359}
6360
1a4d82fc 6361// Returns the repeat count for a repeating vector expression.
c34b1796
AL
6362pub 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)) {
1a4d82fc
JJ
6364 Ok(val) => {
6365 let found = match val {
62682a34
SL
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"
1a4d82fc 6375 };
85aaf69f 6376 span_err!(tcx.sess, count_expr.span, E0306,
1a4d82fc 6377 "expected positive integer for repeat count, found {}",
85aaf69f 6378 found);
1a4d82fc 6379 }
c34b1796
AL
6380 Err(err) => {
6381 let err_description = err.description();
1a4d82fc 6382 let found = match count_expr.node {
c34b1796 6383 ast::ExprPath(None, ast::Path {
1a4d82fc
JJ
6384 global: false,
6385 ref segments,
6386 ..
6387 }) if segments.len() == 1 =>
c34b1796 6388 format!("{}", "found variable"),
1a4d82fc 6389 _ =>
c34b1796 6390 format!("but {}", err_description),
1a4d82fc 6391 };
85aaf69f 6392 span_err!(tcx.sess, count_expr.span, E0307,
c34b1796 6393 "expected constant integer for repeat count, {}",
85aaf69f 6394 found);
1a4d82fc
JJ
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.
6405pub 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
1a4d82fc
JJ
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
85aaf69f 6425/// popular choice.
1a4d82fc
JJ
6426///
6427/// Requires that trait definitions have been processed so that we can
6428/// elaborate predicates and walk supertraits.
6429pub 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={:?})",
62682a34
SL
6435 erased_self_ty,
6436 predicates);
1a4d82fc
JJ
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
1a4d82fc
JJ
6474pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc<ItemVariances> {
6475 lookup_locally_or_in_crate_store(
62682a34 6476 "item_variance_map", item_id, &tcx.item_variance_map,
1a4d82fc
JJ
6477 || Rc::new(csearch::get_item_variances(&tcx.sess.cstore, item_id)))
6478}
6479
c34b1796
AL
6480pub fn trait_has_default_impl(tcx: &ctxt, trait_def_id: DefId) -> bool {
6481 populate_implementations_for_trait_if_necessary(tcx, trait_def_id);
c34b1796 6482
d9579d0f
AL
6483 let def = lookup_trait_def(tcx, trait_def_id);
6484 def.flags.get().intersects(TraitFlags::HAS_DEFAULT_IMPL)
c34b1796
AL
6485}
6486
1a4d82fc 6487/// Records a trait-to-implementation mapping.
d9579d0f
AL
6488pub 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)
1a4d82fc
JJ
6491}
6492
c34b1796 6493/// Load primitive inherent implementations if necessary
d9579d0f
AL
6494pub fn populate_implementations_for_primitive_if_necessary(tcx: &ctxt,
6495 primitive_def_id: ast::DefId) {
6496 if primitive_def_id.krate == LOCAL_CRATE {
c34b1796
AL
6497 return
6498 }
d9579d0f
AL
6499
6500 if tcx.populated_external_primitive_impls.borrow().contains(&primitive_def_id) {
c34b1796
AL
6501 return
6502 }
6503
d9579d0f
AL
6504 debug!("populate_implementations_for_primitive_if_necessary: searching for {:?}",
6505 primitive_def_id);
c34b1796 6506
d9579d0f 6507 let impl_items = csearch::get_impl_items(&tcx.sess.cstore, primitive_def_id);
c34b1796
AL
6508
6509 // Store the implementation info.
d9579d0f
AL
6510 tcx.impl_items.borrow_mut().insert(primitive_def_id, impl_items);
6511 tcx.populated_external_primitive_impls.borrow_mut().insert(primitive_def_id);
c34b1796
AL
6512}
6513
d9579d0f
AL
6514/// Populates the type context with all the inherent implementations for
6515/// the given type if necessary.
6516pub fn populate_inherent_implementations_for_type_if_necessary(tcx: &ctxt,
6517 type_id: ast::DefId) {
1a4d82fc
JJ
6518 if type_id.krate == LOCAL_CRATE {
6519 return
6520 }
d9579d0f 6521
1a4d82fc
JJ
6522 if tcx.populated_external_types.borrow().contains(&type_id) {
6523 return
6524 }
6525
d9579d0f 6526 debug!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}", type_id);
1a4d82fc
JJ
6527
6528 let mut inherent_impls = Vec::new();
d9579d0f
AL
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);
1a4d82fc
JJ
6532
6533 // Store the implementation info.
d9579d0f 6534 let impl_items = csearch::get_impl_items(&tcx.sess.cstore, impl_def_id);
1a4d82fc 6535 tcx.impl_items.borrow_mut().insert(impl_def_id, impl_items);
1a4d82fc
JJ
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.
d9579d0f 6544pub fn populate_implementations_for_trait_if_necessary(tcx: &ctxt, trait_id: ast::DefId) {
1a4d82fc
JJ
6545 if trait_id.krate == LOCAL_CRATE {
6546 return
6547 }
c34b1796 6548
d9579d0f
AL
6549 let def = lookup_trait_def(tcx, trait_id);
6550 if def.flags.get().intersects(TraitFlags::IMPLS_VALID) {
6551 return;
1a4d82fc
JJ
6552 }
6553
62682a34 6554 debug!("populate_implementations_for_trait_if_necessary: searching for {:?}", def);
d9579d0f 6555
c34b1796
AL
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| {
1a4d82fc 6561 let impl_items = csearch::get_impl_items(&tcx.sess.cstore, implementation_def_id);
d9579d0f 6562 let trait_ref = impl_trait_ref(tcx, implementation_def_id).unwrap();
1a4d82fc 6563 // Record the trait->implementation mapping.
d9579d0f 6564 def.record_impl(tcx, implementation_def_id, trait_ref);
1a4d82fc
JJ
6565
6566 // For any methods that use a default implementation, add them to
6567 // the map. This is a bit unfortunate.
85aaf69f 6568 for impl_item_def_id in &impl_items {
1a4d82fc
JJ
6569 let method_def_id = impl_item_def_id.def_id();
6570 match impl_or_trait_item(tcx, method_def_id) {
6571 MethodTraitItem(method) => {
85aaf69f 6572 if let Some(source) = method.provided_source {
1a4d82fc 6573 tcx.provided_method_sources
c34b1796
AL
6574 .borrow_mut()
6575 .insert(method_def_id, source);
1a4d82fc
JJ
6576 }
6577 }
d9579d0f 6578 _ => {}
1a4d82fc
JJ
6579 }
6580 }
6581
6582 // Store the implementation info.
6583 tcx.impl_items.borrow_mut().insert(implementation_def_id, impl_items);
6584 });
6585
d9579d0f 6586 def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID);
1a4d82fc
JJ
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`.
6591pub 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`.
6599pub 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`.
6622pub 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`.
6643pub 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())
223e47cc 6656 }
1a4d82fc
JJ
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.
6663pub 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
85aaf69f 6673 let region = |state: &mut SipHasher, r: Region| {
1a4d82fc
JJ
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 };
85aaf69f 6690 let did = |state: &mut SipHasher, did: DefId| {
1a4d82fc
JJ
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 };
85aaf69f 6699 let mt = |state: &mut SipHasher, mt: mt| {
1a4d82fc
JJ
6700 mt.mutbl.hash(state);
6701 };
85aaf69f 6702 let fn_sig = |state: &mut SipHasher, sig: &Binder<FnSig<'tcx>>| {
1a4d82fc 6703 let sig = anonymize_late_bound_regions(tcx, sig).0;
85aaf69f 6704 for a in &sig.inputs { helper(tcx, *a, svh, state); }
1a4d82fc
JJ
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 {
62682a34
SL
6711 TyBool => byte!(2),
6712 TyChar => byte!(3),
6713 TyInt(i) => {
1a4d82fc
JJ
6714 byte!(4);
6715 hash!(i);
6716 }
62682a34 6717 TyUint(u) => {
1a4d82fc
JJ
6718 byte!(5);
6719 hash!(u);
6720 }
62682a34 6721 TyFloat(f) => {
1a4d82fc
JJ
6722 byte!(6);
6723 hash!(f);
6724 }
62682a34 6725 TyStr => {
1a4d82fc
JJ
6726 byte!(7);
6727 }
62682a34 6728 TyEnum(d, _) => {
1a4d82fc
JJ
6729 byte!(8);
6730 did(state, d);
6731 }
62682a34 6732 TyBox(_) => {
1a4d82fc
JJ
6733 byte!(9);
6734 }
62682a34 6735 TyArray(_, n) => {
1a4d82fc
JJ
6736 byte!(10);
6737 n.hash(state);
6738 }
62682a34 6739 TySlice(_) => {
1a4d82fc
JJ
6740 byte!(11);
6741 }
62682a34 6742 TyRawPtr(m) => {
1a4d82fc
JJ
6743 byte!(12);
6744 mt(state, m);
6745 }
62682a34 6746 TyRef(r, m) => {
1a4d82fc
JJ
6747 byte!(13);
6748 region(state, *r);
6749 mt(state, m);
6750 }
62682a34 6751 TyBareFn(opt_def_id, ref b) => {
1a4d82fc
JJ
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 }
62682a34 6759 TyTrait(ref data) => {
1a4d82fc
JJ
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;
62682a34
SL
6765 for subty in &principal.substs.types {
6766 helper(tcx, subty, svh, state);
1a4d82fc
JJ
6767 }
6768
6769 return false;
6770 }
62682a34 6771 TyStruct(d, _) => {
1a4d82fc
JJ
6772 byte!(18);
6773 did(state, d);
6774 }
62682a34 6775 TyTuple(ref inner) => {
1a4d82fc
JJ
6776 byte!(19);
6777 hash!(inner.len());
6778 }
62682a34 6779 TyParam(p) => {
1a4d82fc
JJ
6780 byte!(20);
6781 hash!(p.space);
6782 hash!(p.idx);
6783 hash!(token::get_name(p.name));
6784 }
62682a34
SL
6785 TyInfer(_) => unreachable!(),
6786 TyError => byte!(21),
6787 TyClosure(d, _) => {
c34b1796 6788 byte!(22);
1a4d82fc 6789 did(state, d);
1a4d82fc 6790 }
62682a34 6791 TyProjection(ref data) => {
c34b1796 6792 byte!(23);
1a4d82fc
JJ
6793 did(state, data.trait_ref.def_id);
6794 hash!(token::get_name(data.item_name));
6795 }
6796 }
6797 true
6798 });
223e47cc
LB
6799 }
6800}
6801
62682a34
SL
6802impl fmt::Debug for Variance {
6803 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6804 f.write_str(match *self {
1a4d82fc
JJ
6805 Covariant => "+",
6806 Contravariant => "-",
6807 Invariant => "o",
6808 Bivariant => "*",
62682a34 6809 })
223e47cc
LB
6810 }
6811}
6812
1a4d82fc
JJ
6813/// Construct a parameter environment suitable for static contexts or other contexts where there
6814/// are no free type/lifetime parameters in scope.
6815pub fn empty_parameter_environment<'a,'tcx>(cx: &'a ctxt<'tcx>) -> ParameterEnvironment<'a,'tcx> {
6816 ty::ParameterEnvironment { tcx: cx,
6817 free_substs: Substs::empty(),
85aaf69f 6818 caller_bounds: Vec::new(),
1a4d82fc
JJ
6819 implicit_region_bound: ty::ReEmpty,
6820 selection_cache: traits::SelectionCache::new(), }
223e47cc
LB
6821}
6822
85aaf69f
SL
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.
6828pub fn construct_free_substs<'a,'tcx>(
1a4d82fc 6829 tcx: &'a ctxt<'tcx>,
85aaf69f 6830 generics: &Generics<'tcx>,
1a4d82fc 6831 free_id: ast::NodeId)
85aaf69f 6832 -> Substs<'tcx>
1a4d82fc 6833{
1a4d82fc
JJ
6834 // map T => T
6835 let mut types = VecPerParamSpace::empty();
6836 push_types_from_defs(tcx, &mut types, generics.types.as_slice());
223e47cc 6837
85aaf69f
SL
6838 let free_id_outlive = region::DestructionScopeData::new(free_id);
6839
1a4d82fc
JJ
6840 // map bound 'a => free 'a
6841 let mut regions = VecPerParamSpace::empty();
85aaf69f 6842 push_region_params(&mut regions, free_id_outlive, generics.regions.as_slice());
223e47cc 6843
85aaf69f 6844 return Substs {
1a4d82fc
JJ
6845 types: types,
6846 regions: subst::NonerasedRegions(regions)
6847 };
223e47cc 6848
85aaf69f
SL
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={:?}",
62682a34 6863 def);
85aaf69f
SL
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
6871pub 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);
223e47cc 6885
1a4d82fc
JJ
6886 //
6887 // Compute the bounds on Self and the type parameters.
6888 //
6889
85aaf69f
SL
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();
1a4d82fc 6893
85aaf69f 6894 debug!("construct_parameter_environment: free_id={:?} free_subst={:?} predicates={:?}",
1a4d82fc 6895 free_id,
62682a34
SL
6896 free_substs,
6897 predicates);
1a4d82fc 6898
85aaf69f
SL
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 {
1a4d82fc
JJ
6914 tcx: tcx,
6915 free_substs: free_substs,
85aaf69f
SL
6916 implicit_region_bound: ty::ReScope(free_id_outlive.to_code_extent()),
6917 caller_bounds: predicates,
1a4d82fc
JJ
6918 selection_cache: traits::SelectionCache::new(),
6919 };
6920
85aaf69f 6921 let cause = traits::ObligationCause::misc(span, free_id);
bd371182 6922 traits::normalize_param_env_or_error(unnormalized_env, cause)
1a4d82fc 6923}
223e47cc 6924
1a4d82fc
JJ
6925impl BorrowKind {
6926 pub fn from_mutbl(m: ast::Mutability) -> BorrowKind {
6927 match m {
6928 ast::MutMutable => MutBorrow,
6929 ast::MutImmutable => ImmBorrow,
223e47cc 6930 }
1a4d82fc 6931 }
223e47cc 6932
1a4d82fc
JJ
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,
223e47cc 6941
1a4d82fc
JJ
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 }
223e47cc 6948
1a4d82fc
JJ
6949 pub fn to_user_str(&self) -> &'static str {
6950 match *self {
6951 MutBorrow => "mutable",
6952 ImmBorrow => "immutable",
6953 UniqueImmBorrow => "uniquely immutable",
223e47cc
LB
6954 }
6955 }
6956}
6957
1a4d82fc 6958impl<'tcx> ctxt<'tcx> {
1a4d82fc
JJ
6959 pub fn is_method_call(&self, expr_id: ast::NodeId) -> bool {
6960 self.method_map.borrow().contains_key(&MethodCall::expr(expr_id))
6961 }
223e47cc 6962
85aaf69f 6963 pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
c34b1796 6964 Some(self.upvar_capture_map.borrow().get(&upvar_id).unwrap().clone())
1a4d82fc 6965 }
85aaf69f 6966}
1a4d82fc 6967
85aaf69f 6968impl<'a,'tcx> mc::Typer<'tcx> for ParameterEnvironment<'a,'tcx> {
1a4d82fc
JJ
6969 fn node_ty(&self, id: ast::NodeId) -> mc::McResult<Ty<'tcx>> {
6970 Ok(ty::node_id_to_type(self.tcx, id))
223e47cc
LB
6971 }
6972
1a4d82fc
JJ
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
85aaf69f
SL
6999 fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
7000 self.tcx.upvar_capture(upvar_id)
1a4d82fc 7001 }
223e47cc 7002
1a4d82fc
JJ
7003 fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool {
7004 type_moves_by_default(self, span, ty)
223e47cc
LB
7005 }
7006}
7007
85aaf69f 7008impl<'a,'tcx> ClosureTyper<'tcx> for ty::ParameterEnvironment<'a,'tcx> {
1a4d82fc
JJ
7009 fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
7010 self
7011 }
223e47cc 7012
85aaf69f
SL
7013 fn closure_kind(&self,
7014 def_id: ast::DefId)
7015 -> Option<ty::ClosureKind>
1a4d82fc 7016 {
85aaf69f 7017 Some(self.tcx.closure_kind(def_id))
223e47cc
LB
7018 }
7019
85aaf69f
SL
7020 fn closure_type(&self,
7021 def_id: ast::DefId,
7022 substs: &subst::Substs<'tcx>)
7023 -> ty::ClosureTy<'tcx>
1a4d82fc 7024 {
85aaf69f 7025 self.tcx.closure_type(def_id, substs)
1a4d82fc
JJ
7026 }
7027
85aaf69f
SL
7028 fn closure_upvars(&self,
7029 def_id: ast::DefId,
7030 substs: &Substs<'tcx>)
7031 -> Option<Vec<ClosureUpvar<'tcx>>>
1a4d82fc 7032 {
85aaf69f 7033 closure_upvars(self, def_id, substs)
1a4d82fc
JJ
7034 }
7035}
7036
7037
7038/// The category of explicit self.
85aaf69f 7039#[derive(Clone, Copy, Eq, PartialEq, Debug)]
1a4d82fc
JJ
7040pub 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.
7051pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
7052 ty: Ty) {
7053 walk_ty(ty, |ty| {
7054 match ty.sty {
62682a34 7055 TyRef(region, _) => {
1a4d82fc
JJ
7056 accumulator.push(*region)
7057 }
62682a34 7058 TyTrait(ref t) => {
1a4d82fc
JJ
7059 accumulator.push_all(t.principal.0.substs.regions().as_slice());
7060 }
62682a34
SL
7061 TyEnum(_, substs) |
7062 TyStruct(_, substs) => {
1a4d82fc
JJ
7063 accum_substs(accumulator, substs);
7064 }
62682a34 7065 TyClosure(_, substs) => {
1a4d82fc
JJ
7066 accum_substs(accumulator, substs);
7067 }
62682a34
SL
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 => {
970d7e83 7084 }
223e47cc 7085 }
1a4d82fc
JJ
7086 });
7087
7088 fn accum_substs(accumulator: &mut Vec<Region>, substs: &Substs) {
7089 match substs.regions {
7090 subst::ErasedRegions => {}
7091 subst::NonerasedRegions(ref regions) => {
62682a34 7092 for region in regions {
1a4d82fc
JJ
7093 accumulator.push(*region)
7094 }
7095 }
223e47cc
LB
7096 }
7097 }
7098}
7099
1a4d82fc 7100/// A free variable referred to in a function.
85aaf69f 7101#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
1a4d82fc
JJ
7102pub 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
7110pub type FreevarMap = NodeMap<Vec<Freevar>>;
7111
7112pub type CaptureModeMap = NodeMap<ast::CaptureClause>;
7113
7114// Trait method resolution
7115pub 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.
7119pub type GlobMap = HashMap<NodeId, HashSet<Name>>;
7120
7121pub 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(&[]),
85aaf69f 7126 Some(d) => f(&d[..])
1a4d82fc
JJ
7127 }
7128}
7129
7130impl<'tcx> AutoAdjustment<'tcx> {
7131 pub fn is_identity(&self) -> bool {
7132 match *self {
9346a6ac
AL
7133 AdjustReifyFnPointer |
7134 AdjustUnsafeFnPointer => false,
1a4d82fc 7135 AdjustDerefRef(ref r) => r.is_identity(),
223e47cc 7136 }
1a4d82fc
JJ
7137 }
7138}
7139
7140impl<'tcx> AutoDerefRef<'tcx> {
7141 pub fn is_identity(&self) -> bool {
9346a6ac 7142 self.autoderefs == 0 && self.unsize.is_none() && self.autoref.is_none()
1a4d82fc
JJ
7143 }
7144}
7145
7146/// Replace any late-bound regions bound in `value` with free variants attached to scope-id
7147/// `scope_id`.
7148pub fn liberate_late_bound_regions<'tcx, T>(
7149 tcx: &ty::ctxt<'tcx>,
85aaf69f 7150 all_outlive_scope: region::DestructionScopeData,
1a4d82fc
JJ
7151 value: &Binder<T>)
7152 -> T
62682a34 7153 where T : TypeFoldable<'tcx>
1a4d82fc 7154{
62682a34 7155 ty_fold::replace_late_bound_regions(
1a4d82fc 7156 tcx, value,
85aaf69f 7157 |br| ty::ReFree(ty::FreeRegion{scope: all_outlive_scope, bound_region: br})).0
1a4d82fc
JJ
7158}
7159
7160pub fn count_late_bound_regions<'tcx, T>(
7161 tcx: &ty::ctxt<'tcx>,
7162 value: &Binder<T>)
c34b1796 7163 -> usize
62682a34 7164 where T : TypeFoldable<'tcx>
1a4d82fc 7165{
62682a34 7166 let (_, skol_map) = ty_fold::replace_late_bound_regions(tcx, value, |_| ty::ReStatic);
1a4d82fc
JJ
7167 skol_map.len()
7168}
7169
7170pub fn binds_late_bound_regions<'tcx, T>(
7171 tcx: &ty::ctxt<'tcx>,
7172 value: &Binder<T>)
7173 -> bool
62682a34 7174 where T : TypeFoldable<'tcx>
1a4d82fc
JJ
7175{
7176 count_late_bound_regions(tcx, value) > 0
7177}
7178
c34b1796
AL
7179/// Flattens two binding levels into one. So `for<'a> for<'b> Foo`
7180/// becomes `for<'a,'b> Foo`.
7181pub fn flatten_late_bound_regions<'tcx, T>(
7182 tcx: &ty::ctxt<'tcx>,
7183 bound2_value: &Binder<Binder<T>>)
7184 -> Binder<T>
62682a34 7185 where T: TypeFoldable<'tcx>
c34b1796
AL
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
85aaf69f 7203pub fn no_late_bound_regions<'tcx, T>(
1a4d82fc
JJ
7204 tcx: &ty::ctxt<'tcx>,
7205 value: &Binder<T>)
85aaf69f 7206 -> Option<T>
62682a34 7207 where T : TypeFoldable<'tcx>
1a4d82fc 7208{
85aaf69f
SL
7209 if binds_late_bound_regions(tcx, value) {
7210 None
7211 } else {
7212 Some(value.0.clone())
7213 }
1a4d82fc
JJ
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.
7218pub fn erase_late_bound_regions<'tcx, T>(
7219 tcx: &ty::ctxt<'tcx>,
7220 value: &Binder<T>)
7221 -> T
62682a34 7222 where T : TypeFoldable<'tcx>
1a4d82fc 7223{
62682a34 7224 ty_fold::replace_late_bound_regions(tcx, value, |_| ty::ReStatic).0
1a4d82fc
JJ
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
c34b1796
AL
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.
1a4d82fc
JJ
7235pub fn anonymize_late_bound_regions<'tcx, T>(
7236 tcx: &ctxt<'tcx>,
7237 sig: &Binder<T>)
7238 -> Binder<T>
62682a34 7239 where T : TypeFoldable<'tcx>,
1a4d82fc
JJ
7240{
7241 let mut counter = 0;
62682a34 7242 ty::Binder(ty_fold::replace_late_bound_regions(tcx, sig, |_| {
1a4d82fc
JJ
7243 counter += 1;
7244 ReLateBound(ty::DebruijnIndex::new(1), BrAnon(counter))
7245 }).0)
7246}
7247
1a4d82fc
JJ
7248impl 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
62682a34
SL
7259impl<'tcx> fmt::Debug for AutoAdjustment<'tcx> {
7260 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1a4d82fc 7261 match *self {
9346a6ac 7262 AdjustReifyFnPointer => {
62682a34 7263 write!(f, "AdjustReifyFnPointer")
1a4d82fc 7264 }
c34b1796 7265 AdjustUnsafeFnPointer => {
62682a34 7266 write!(f, "AdjustUnsafeFnPointer")
c34b1796 7267 }
1a4d82fc 7268 AdjustDerefRef(ref data) => {
62682a34 7269 write!(f, "{:?}", data)
1a4d82fc 7270 }
223e47cc 7271 }
1a4d82fc
JJ
7272 }
7273}
7274
62682a34
SL
7275impl<'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)
223e47cc
LB
7279 }
7280}
7281
62682a34
SL
7282impl<'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)
223e47cc 7287 }
1a4d82fc 7288}
223e47cc 7289
62682a34
SL
7290impl<'tcx> fmt::Debug for ty::Predicate<'tcx> {
7291 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1a4d82fc 7292 match *self {
62682a34
SL
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),
1a4d82fc
JJ
7298 }
7299 }
970d7e83
LB
7300}
7301
1a4d82fc
JJ
7302pub 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>
970d7e83
LB
7306{
7307 /*!
1a4d82fc
JJ
7308 * Substitutes the values for the receiver's type parameters
7309 * that are found in method, leaving the method's type parameters
7310 * intact.
970d7e83
LB
7311 */
7312
1a4d82fc
JJ
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()
9346a6ac 7321 .map(|def| def.to_early_bound_region())
1a4d82fc
JJ
7322 .collect();
7323 trait_ref.substs.clone().with_method(meth_tps, meth_regions)
7324}
7325
c34b1796 7326#[derive(Copy, Clone)]
1a4d82fc
JJ
7327pub enum CopyImplementationError {
7328 FieldDoesNotImplementCopy(ast::Name),
7329 VariantDoesNotImplementCopy(ast::Name),
7330 TypeIsStructural,
7331 TypeHasDestructor,
7332}
7333
7334pub 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 {
62682a34 7342 ty::TyStruct(struct_did, substs) => {
1a4d82fc 7343 let fields = ty::struct_fields(tcx, struct_did, substs);
85aaf69f 7344 for field in &fields {
1a4d82fc
JJ
7345 if type_moves_by_default(param_env, span, field.mt.ty) {
7346 return Err(FieldDoesNotImplementCopy(field.name))
7347 }
7348 }
7349 struct_did
7350 }
62682a34 7351 ty::TyEnum(enum_did, substs) => {
1a4d82fc 7352 let enum_variants = ty::enum_variants(tcx, enum_did);
62682a34 7353 for variant in enum_variants.iter() {
85aaf69f 7354 for variant_arg_type in &variant.args {
1a4d82fc
JJ
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 };
223e47cc 7366
1a4d82fc
JJ
7367 if ty::has_dtor(tcx, did) {
7368 return Err(TypeHasDestructor)
970d7e83 7369 }
223e47cc 7370
1a4d82fc 7371 Ok(())
970d7e83 7372}
223e47cc 7373
1a4d82fc
JJ
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.
970d7e83 7378
1a4d82fc
JJ
7379pub trait RegionEscape {
7380 fn has_escaping_regions(&self) -> bool {
7381 self.has_regions_escaping_depth(0)
223e47cc 7382 }
1a4d82fc
JJ
7383
7384 fn has_regions_escaping_depth(&self, depth: u32) -> bool;
223e47cc
LB
7385}
7386
1a4d82fc
JJ
7387impl<'tcx> RegionEscape for Ty<'tcx> {
7388 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7389 ty::type_escapes_depth(*self, depth)
223e47cc 7390 }
970d7e83 7391}
223e47cc 7392
1a4d82fc
JJ
7393impl<'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 }
970d7e83
LB
7398}
7399
1a4d82fc
JJ
7400impl<'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)
970d7e83 7407 }
1a4d82fc 7408 })
223e47cc
LB
7409 }
7410}
7411
1a4d82fc
JJ
7412impl<'tcx> RegionEscape for TypeScheme<'tcx> {
7413 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
85aaf69f 7414 self.ty.has_regions_escaping_depth(depth)
223e47cc
LB
7415 }
7416}
7417
1a4d82fc
JJ
7418impl RegionEscape for Region {
7419 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7420 self.escapes_depth(depth)
223e47cc
LB
7421 }
7422}
7423
85aaf69f 7424impl<'tcx> RegionEscape for GenericPredicates<'tcx> {
1a4d82fc
JJ
7425 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7426 self.predicates.has_regions_escaping_depth(depth)
7427 }
223e47cc
LB
7428}
7429
1a4d82fc
JJ
7430impl<'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 }
223e47cc
LB
7440}
7441
c34b1796
AL
7442impl<'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
1a4d82fc
JJ
7448impl<'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 }
223e47cc
LB
7453}
7454
1a4d82fc
JJ
7455impl<'tcx> RegionEscape for subst::RegionSubsts {
7456 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
223e47cc 7457 match *self {
1a4d82fc
JJ
7458 subst::ErasedRegions => false,
7459 subst::NonerasedRegions(ref r) => {
7460 r.iter().any(|t| t.has_regions_escaping_depth(depth))
7461 }
223e47cc
LB
7462 }
7463 }
1a4d82fc 7464}
970d7e83 7465
1a4d82fc
JJ
7466impl<'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)
223e47cc 7469 }
1a4d82fc 7470}
970d7e83 7471
1a4d82fc
JJ
7472impl<'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)
970d7e83 7475 }
223e47cc
LB
7476}
7477
1a4d82fc
JJ
7478impl<'tcx> RegionEscape for TraitPredicate<'tcx> {
7479 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7480 self.trait_ref.has_regions_escaping_depth(depth)
223e47cc
LB
7481 }
7482}
7483
1a4d82fc
JJ
7484impl<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 }
223e47cc
LB
7488}
7489
1a4d82fc
JJ
7490impl<'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}
223e47cc 7496
1a4d82fc
JJ
7497impl<'tcx> RegionEscape for ProjectionTy<'tcx> {
7498 fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7499 self.trait_ref.has_regions_escaping_depth(depth)
223e47cc
LB
7500 }
7501}
7502
1a4d82fc
JJ
7503pub trait HasProjectionTypes {
7504 fn has_projection_types(&self) -> bool;
223e47cc
LB
7505}
7506
1a4d82fc
JJ
7507impl<'tcx,T:HasProjectionTypes> HasProjectionTypes for Vec<T> {
7508 fn has_projection_types(&self) -> bool {
7509 self.iter().any(|p| p.has_projection_types())
223e47cc 7510 }
223e47cc
LB
7511}
7512
1a4d82fc
JJ
7513impl<'tcx,T:HasProjectionTypes> HasProjectionTypes for VecPerParamSpace<T> {
7514 fn has_projection_types(&self) -> bool {
7515 self.iter().any(|p| p.has_projection_types())
223e47cc 7516 }
223e47cc
LB
7517}
7518
1a4d82fc
JJ
7519impl<'tcx> HasProjectionTypes for ClosureTy<'tcx> {
7520 fn has_projection_types(&self) -> bool {
7521 self.sig.has_projection_types()
7522 }
7523}
223e47cc 7524
85aaf69f 7525impl<'tcx> HasProjectionTypes for ClosureUpvar<'tcx> {
1a4d82fc
JJ
7526 fn has_projection_types(&self) -> bool {
7527 self.ty.has_projection_types()
7528 }
970d7e83
LB
7529}
7530
85aaf69f 7531impl<'tcx> HasProjectionTypes for ty::InstantiatedPredicates<'tcx> {
1a4d82fc
JJ
7532 fn has_projection_types(&self) -> bool {
7533 self.predicates.has_projection_types()
970d7e83
LB
7534 }
7535}
7536
1a4d82fc
JJ
7537impl<'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(),
970d7e83 7545 }
223e47cc
LB
7546 }
7547}
7548
1a4d82fc
JJ
7549impl<'tcx> HasProjectionTypes for TraitPredicate<'tcx> {
7550 fn has_projection_types(&self) -> bool {
7551 self.trait_ref.has_projection_types()
7552 }
970d7e83
LB
7553}
7554
1a4d82fc
JJ
7555impl<'tcx> HasProjectionTypes for EquatePredicate<'tcx> {
7556 fn has_projection_types(&self) -> bool {
7557 self.0.has_projection_types() || self.1.has_projection_types()
7558 }
970d7e83
LB
7559}
7560
1a4d82fc
JJ
7561impl HasProjectionTypes for Region {
7562 fn has_projection_types(&self) -> bool {
7563 false
223e47cc
LB
7564 }
7565}
7566
1a4d82fc
JJ
7567impl<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()
223e47cc
LB
7570 }
7571}
7572
1a4d82fc
JJ
7573impl<'tcx> HasProjectionTypes for ProjectionPredicate<'tcx> {
7574 fn has_projection_types(&self) -> bool {
7575 self.projection_ty.has_projection_types() || self.ty.has_projection_types()
223e47cc
LB
7576 }
7577}
7578
1a4d82fc
JJ
7579impl<'tcx> HasProjectionTypes for ProjectionTy<'tcx> {
7580 fn has_projection_types(&self) -> bool {
7581 self.trait_ref.has_projection_types()
223e47cc
LB
7582 }
7583}
7584
1a4d82fc
JJ
7585impl<'tcx> HasProjectionTypes for Ty<'tcx> {
7586 fn has_projection_types(&self) -> bool {
7587 ty::type_has_projection(*self)
7588 }
7589}
223e47cc 7590
1a4d82fc
JJ
7591impl<'tcx> HasProjectionTypes for TraitRef<'tcx> {
7592 fn has_projection_types(&self) -> bool {
7593 self.substs.has_projection_types()
223e47cc 7594 }
1a4d82fc 7595}
223e47cc 7596
1a4d82fc
JJ
7597impl<'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}
223e47cc 7602
1a4d82fc
JJ
7603impl<'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}
223e47cc 7610
1a4d82fc
JJ
7611impl<'tcx,T> HasProjectionTypes for Rc<T>
7612 where T : HasProjectionTypes
7613{
7614 fn has_projection_types(&self) -> bool {
7615 (**self).has_projection_types()
7616 }
223e47cc
LB
7617}
7618
1a4d82fc
JJ
7619impl<'tcx,T> HasProjectionTypes for Box<T>
7620 where T : HasProjectionTypes
7621{
7622 fn has_projection_types(&self) -> bool {
7623 (**self).has_projection_types()
7624 }
223e47cc
LB
7625}
7626
1a4d82fc
JJ
7627impl<T> HasProjectionTypes for Binder<T>
7628 where T : HasProjectionTypes
7629{
7630 fn has_projection_types(&self) -> bool {
7631 self.0.has_projection_types()
223e47cc 7632 }
1a4d82fc
JJ
7633}
7634
7635impl<'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,
223e47cc
LB
7640 }
7641 }
1a4d82fc 7642}
223e47cc 7643
1a4d82fc
JJ
7644impl<'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()
223e47cc 7648 }
1a4d82fc 7649}
223e47cc 7650
1a4d82fc
JJ
7651impl<'tcx> HasProjectionTypes for field<'tcx> {
7652 fn has_projection_types(&self) -> bool {
7653 self.mt.ty.has_projection_types()
7654 }
7655}
223e47cc 7656
1a4d82fc
JJ
7657impl<'tcx> HasProjectionTypes for BareFnTy<'tcx> {
7658 fn has_projection_types(&self) -> bool {
7659 self.sig.has_projection_types()
7660 }
7661}
223e47cc 7662
1a4d82fc
JJ
7663pub trait ReferencesError {
7664 fn references_error(&self) -> bool;
7665}
223e47cc 7666
1a4d82fc
JJ
7667impl<T:ReferencesError> ReferencesError for Binder<T> {
7668 fn references_error(&self) -> bool {
7669 self.0.references_error()
7670 }
7671}
223e47cc 7672
1a4d82fc
JJ
7673impl<T:ReferencesError> ReferencesError for Rc<T> {
7674 fn references_error(&self) -> bool {
7675 (&**self).references_error()
7676 }
223e47cc
LB
7677}
7678
1a4d82fc
JJ
7679impl<'tcx> ReferencesError for TraitPredicate<'tcx> {
7680 fn references_error(&self) -> bool {
7681 self.trait_ref.references_error()
223e47cc
LB
7682 }
7683}
7684
1a4d82fc
JJ
7685impl<'tcx> ReferencesError for ProjectionPredicate<'tcx> {
7686 fn references_error(&self) -> bool {
7687 self.projection_ty.trait_ref.references_error() || self.ty.references_error()
223e47cc
LB
7688 }
7689}
7690
1a4d82fc
JJ
7691impl<'tcx> ReferencesError for TraitRef<'tcx> {
7692 fn references_error(&self) -> bool {
7693 self.input_types().iter().any(|t| t.references_error())
7694 }
7695}
223e47cc 7696
1a4d82fc
JJ
7697impl<'tcx> ReferencesError for Ty<'tcx> {
7698 fn references_error(&self) -> bool {
7699 type_is_error(*self)
7700 }
7701}
970d7e83 7702
1a4d82fc
JJ
7703impl<'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(),
970d7e83 7711 }
223e47cc
LB
7712 }
7713}
7714
1a4d82fc
JJ
7715impl<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()
223e47cc 7720 }
223e47cc
LB
7721}
7722
1a4d82fc
JJ
7723impl<'tcx> ReferencesError for EquatePredicate<'tcx>
7724{
7725 fn references_error(&self) -> bool {
7726 self.0.references_error() || self.1.references_error()
223e47cc
LB
7727 }
7728}
7729
1a4d82fc
JJ
7730impl ReferencesError for Region
7731{
7732 fn references_error(&self) -> bool {
7733 false
7734 }
970d7e83
LB
7735}
7736
62682a34
SL
7737impl<'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)
1a4d82fc 7743 }
970d7e83
LB
7744}
7745
62682a34
SL
7746impl<'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)
1a4d82fc
JJ
7751 }
7752}
7753
62682a34
SL
7754impl<'tcx> fmt::Debug for field<'tcx> {
7755 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7756 write!(f, "field({},{})", self.name, self.mt)
1a4d82fc 7757 }
970d7e83 7758}
85aaf69f 7759
62682a34
SL
7760impl<'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)
85aaf69f
SL
7769 }
7770}
7771
62682a34
SL
7772impl<'tcx> fmt::Debug for ObjectLifetimeDefault {
7773 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
85aaf69f 7774 match *self {
62682a34
SL
7775 ObjectLifetimeDefault::Ambiguous => write!(f, "Ambiguous"),
7776 ObjectLifetimeDefault::BaseDefault => write!(f, "BaseDefault"),
7777 ObjectLifetimeDefault::Specific(ref r) => write!(f, "{:?}", r),
85aaf69f
SL
7778 }
7779 }
7780}