]> git.proxmox.com Git - rustc.git/blame - src/librustc/ty/sty.rs
New upstream version 1.20.0+dfsg1
[rustc.git] / src / librustc / ty / sty.rs
CommitLineData
e9174d1e
SL
1// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11//! This module contains TypeVariants and its major components
12
54a0048b 13use hir::def_id::DefId;
476ff2be 14
e9174d1e 15use middle::region;
041b39d2 16use ty::subst::{Substs, Subst};
476ff2be 17use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable};
9e0c209e 18use ty::{Slice, TyS};
476ff2be 19use ty::subst::Kind;
e9174d1e 20
e9174d1e 21use std::fmt;
476ff2be
SL
22use std::iter;
23use std::cmp::Ordering;
e9174d1e 24use syntax::abi;
32a655c1 25use syntax::ast::{self, Name};
041b39d2 26use syntax::symbol::keywords;
8bb4bdeb 27use util::nodemap::FxHashMap;
e9174d1e 28
9e0c209e 29use serialize;
9cc50fc6 30
54a0048b 31use hir;
e9174d1e 32
e9174d1e
SL
33use self::InferTy::*;
34use self::TypeVariants::*;
35
9e0c209e 36#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
e9174d1e
SL
37pub struct TypeAndMut<'tcx> {
38 pub ty: Ty<'tcx>,
39 pub mutbl: hir::Mutability,
40}
41
42#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash,
43 RustcEncodable, RustcDecodable, Copy)]
44/// A "free" region `fr` can be interpreted as "some region
45/// at least as big as the scope `fr.scope`".
46pub struct FreeRegion {
7cac9316 47 pub scope: DefId,
cc61c64b 48 pub bound_region: BoundRegion,
e9174d1e
SL
49}
50
51#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash,
52 RustcEncodable, RustcDecodable, Copy)]
53pub enum BoundRegion {
54 /// An anonymous region parameter for a given fn (&T)
55 BrAnon(u32),
56
57 /// Named region parameters for functions (a in &'a T)
58 ///
59 /// The def-id is needed to distinguish free regions in
60 /// the event of shadowing.
8bb4bdeb 61 BrNamed(DefId, Name),
e9174d1e
SL
62
63 /// Fresh bound identifiers created during GLB computations.
64 BrFresh(u32),
65
7cac9316
XL
66 /// Anonymous region for the implicit env pointer parameter
67 /// to a closure
cc61c64b 68 BrEnv,
e9174d1e
SL
69}
70
7cac9316
XL
71impl BoundRegion {
72 pub fn is_named(&self) -> bool {
73 match *self {
74 BoundRegion::BrNamed(..) => true,
75 _ => false,
76 }
77 }
78}
79
8bb4bdeb
XL
80/// When a region changed from late-bound to early-bound when #32330
81/// was fixed, its `RegionParameterDef` will have one of these
82/// structures that we can use to give nicer errors.
3157f602
XL
83#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash,
84 RustcEncodable, RustcDecodable)]
8bb4bdeb
XL
85pub struct Issue32330 {
86 /// fn where is region declared
87 pub fn_def_id: DefId,
3157f602 88
8bb4bdeb
XL
89 /// name of region; duplicates the info in BrNamed but convenient
90 /// to have it here, and this code is only temporary
91 pub region_name: ast::Name,
3157f602
XL
92}
93
7cac9316
XL
94/// NB: If you change this, you'll probably want to change the corresponding
95/// AST structure in libsyntax/ast.rs as well.
9e0c209e 96#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
e9174d1e
SL
97pub enum TypeVariants<'tcx> {
98 /// The primitive boolean type. Written as `bool`.
99 TyBool,
100
101 /// The primitive character type; holds a Unicode scalar value
102 /// (a non-surrogate code point). Written as `char`.
103 TyChar,
104
105 /// A primitive signed integer type. For example, `i32`.
b039eaaf 106 TyInt(ast::IntTy),
e9174d1e
SL
107
108 /// A primitive unsigned integer type. For example, `u32`.
b039eaaf 109 TyUint(ast::UintTy),
e9174d1e
SL
110
111 /// A primitive floating-point type. For example, `f64`.
b039eaaf 112 TyFloat(ast::FloatTy),
e9174d1e 113
9e0c209e 114 /// Structures, enumerations and unions.
e9174d1e
SL
115 ///
116 /// Substs here, possibly against intuition, *may* contain `TyParam`s.
117 /// That is, even after substitution it is possible that there are type
9e0c209e
SL
118 /// variables. This happens when the `TyAdt` corresponds to an ADT
119 /// definition and not a concrete use of it.
476ff2be 120 TyAdt(&'tcx AdtDef, &'tcx Substs<'tcx>),
e9174d1e 121
e9174d1e
SL
122 /// The pointee of a string slice. Written as `str`.
123 TyStr,
124
125 /// An array with the given length. Written as `[T; n]`.
126 TyArray(Ty<'tcx>, usize),
127
128 /// The pointee of an array slice. Written as `[T]`.
129 TySlice(Ty<'tcx>),
130
131 /// A raw pointer. Written as `*mut T` or `*const T`
132 TyRawPtr(TypeAndMut<'tcx>),
133
134 /// A reference; a pointer with an associated lifetime. Written as
32a655c1 135 /// `&'a mut T` or `&'a T`.
7cac9316 136 TyRef(Region<'tcx>, TypeAndMut<'tcx>),
e9174d1e 137
54a0048b
SL
138 /// The anonymous type of a function declaration/definition. Each
139 /// function has a unique type.
041b39d2 140 TyFnDef(DefId, &'tcx Substs<'tcx>),
54a0048b
SL
141
142 /// A pointer to a function. Written as `fn() -> i32`.
8bb4bdeb 143 TyFnPtr(PolyFnSig<'tcx>),
e9174d1e
SL
144
145 /// A trait, defined with `trait`.
7cac9316 146 TyDynamic(Binder<&'tcx Slice<ExistentialPredicate<'tcx>>>, ty::Region<'tcx>),
e9174d1e
SL
147
148 /// The anonymous type of a closure. Used to represent the type of
149 /// `|a| a`.
a7813a04 150 TyClosure(DefId, ClosureSubsts<'tcx>),
e9174d1e 151
5bcae85e
SL
152 /// The never type `!`
153 TyNever,
154
e9174d1e 155 /// A tuple type. For example, `(i32, bool)`.
8bb4bdeb
XL
156 /// The bool indicates whether this is a unit tuple and was created by
157 /// defaulting a diverging type variable with feature(never_type) disabled.
158 /// It's only purpose is for raising future-compatibility warnings for when
159 /// diverging type variables start defaulting to ! instead of ().
160 TyTuple(&'tcx Slice<Ty<'tcx>>, bool),
e9174d1e
SL
161
162 /// The projection of an associated type. For example,
163 /// `<T as Trait<..>>::N`.
164 TyProjection(ProjectionTy<'tcx>),
165
5bcae85e
SL
166 /// Anonymized (`impl Trait`) type found in a return type.
167 /// The DefId comes from the `impl Trait` ast::Ty node, and the
168 /// substitutions are for the generics of the function in question.
476ff2be 169 /// After typeck, the concrete type can be found in the `types` map.
5bcae85e
SL
170 TyAnon(DefId, &'tcx Substs<'tcx>),
171
e9174d1e
SL
172 /// A type parameter; for example, `T` in `fn f<T>(x: T) {}
173 TyParam(ParamTy),
174
175 /// A type variable used during type-checking.
176 TyInfer(InferTy),
177
178 /// A placeholder for a type which could not be computed; this is
179 /// propagated to avoid useless error messages.
180 TyError,
181}
182
183/// A closure can be modeled as a struct that looks like:
184///
185/// struct Closure<'l0...'li, T0...Tj, U0...Uk> {
186/// upvar0: U0,
187/// ...
188/// upvark: Uk
189/// }
190///
191/// where 'l0...'li and T0...Tj are the lifetime and type parameters
192/// in scope on the function that defined the closure, and U0...Uk are
193/// type parameters representing the types of its upvars (borrowed, if
194/// appropriate).
195///
196/// So, for example, given this function:
197///
198/// fn foo<'a, T>(data: &'a mut T) {
199/// do(|| data.count += 1)
200/// }
201///
202/// the type of the closure would be something like:
203///
204/// struct Closure<'a, T, U0> {
205/// data: U0
206/// }
207///
208/// Note that the type of the upvar is not specified in the struct.
209/// You may wonder how the impl would then be able to use the upvar,
210/// if it doesn't know it's type? The answer is that the impl is
211/// (conceptually) not fully generic over Closure but rather tied to
212/// instances with the expected upvar types:
213///
214/// impl<'b, 'a, T> FnMut() for Closure<'a, T, &'b mut &'a mut T> {
215/// ...
216/// }
217///
218/// You can see that the *impl* fully specified the type of the upvar
219/// and thus knows full well that `data` has type `&'b mut &'a mut T`.
220/// (Here, I am assuming that `data` is mut-borrowed.)
221///
222/// Now, the last question you may ask is: Why include the upvar types
223/// as extra type parameters? The reason for this design is that the
224/// upvar types can reference lifetimes that are internal to the
225/// creating function. In my example above, for example, the lifetime
226/// `'b` represents the extent of the closure itself; this is some
227/// subset of `foo`, probably just the extent of the call to the to
228/// `do()`. If we just had the lifetime/type parameters from the
229/// enclosing function, we couldn't name this lifetime `'b`. Note that
230/// there can also be lifetimes in the types of the upvars themselves,
231/// if one of them happens to be a reference to something that the
232/// creating fn owns.
233///
234/// OK, you say, so why not create a more minimal set of parameters
235/// that just includes the extra lifetime parameters? The answer is
236/// primarily that it would be hard --- we don't know at the time when
237/// we create the closure type what the full types of the upvars are,
238/// nor do we know which are borrowed and which are not. In this
239/// design, we can just supply a fresh type parameter and figure that
240/// out later.
241///
242/// All right, you say, but why include the type parameters from the
243/// original function then? The answer is that trans may need them
244/// when monomorphizing, and they may not appear in the upvars. A
245/// closure could capture no variables but still make use of some
246/// in-scope type parameter with a bound (e.g., if our example above
247/// had an extra `U: Default`, and the closure called `U::default()`).
248///
249/// There is another reason. This design (implicitly) prohibits
250/// closures from capturing themselves (except via a trait
251/// object). This simplifies closure inference considerably, since it
252/// means that when we infer the kind of a closure or its upvars, we
253/// don't have to handle cycles where the decisions we make for
254/// closure C wind up influencing the decisions we ought to make for
255/// closure C (which would then require fixed point iteration to
256/// handle). Plus it fixes an ICE. :P
9e0c209e 257#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
e9174d1e 258pub struct ClosureSubsts<'tcx> {
476ff2be
SL
259 /// Lifetime and type parameters from the enclosing function,
260 /// concatenated with the types of the upvars.
261 ///
e9174d1e
SL
262 /// These are separated out because trans wants to pass them around
263 /// when monomorphizing.
476ff2be
SL
264 pub substs: &'tcx Substs<'tcx>,
265}
e9174d1e 266
476ff2be
SL
267impl<'a, 'gcx, 'acx, 'tcx> ClosureSubsts<'tcx> {
268 #[inline]
269 pub fn upvar_tys(self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'acx>) ->
270 impl Iterator<Item=Ty<'tcx>> + 'tcx
271 {
7cac9316 272 let generics = tcx.generics_of(def_id);
476ff2be
SL
273 self.substs[self.substs.len()-generics.own_count()..].iter().map(
274 |t| t.as_type().expect("unexpected region in upvars"))
275 }
a7813a04 276}
9cc50fc6 277
476ff2be
SL
278#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
279pub enum ExistentialPredicate<'tcx> {
7cac9316 280 /// e.g. Iterator
476ff2be 281 Trait(ExistentialTraitRef<'tcx>),
7cac9316 282 /// e.g. Iterator::Item = T
476ff2be 283 Projection(ExistentialProjection<'tcx>),
7cac9316 284 /// e.g. Send
476ff2be
SL
285 AutoTrait(DefId),
286}
287
288impl<'a, 'gcx, 'tcx> ExistentialPredicate<'tcx> {
289 pub fn cmp(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, other: &Self) -> Ordering {
290 use self::ExistentialPredicate::*;
291 match (*self, *other) {
292 (Trait(_), Trait(_)) => Ordering::Equal,
041b39d2
XL
293 (Projection(ref a), Projection(ref b)) =>
294 tcx.def_path_hash(a.item_def_id).cmp(&tcx.def_path_hash(b.item_def_id)),
476ff2be 295 (AutoTrait(ref a), AutoTrait(ref b)) =>
7cac9316 296 tcx.trait_def(*a).def_path_hash.cmp(&tcx.trait_def(*b).def_path_hash),
476ff2be
SL
297 (Trait(_), _) => Ordering::Less,
298 (Projection(_), Trait(_)) => Ordering::Greater,
299 (Projection(_), _) => Ordering::Less,
300 (AutoTrait(_), _) => Ordering::Greater,
301 }
302 }
303
304}
305
306impl<'a, 'gcx, 'tcx> Binder<ExistentialPredicate<'tcx>> {
307 pub fn with_self_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, self_ty: Ty<'tcx>)
308 -> ty::Predicate<'tcx> {
309 use ty::ToPredicate;
310 match *self.skip_binder() {
311 ExistentialPredicate::Trait(tr) => Binder(tr).with_self_ty(tcx, self_ty).to_predicate(),
312 ExistentialPredicate::Projection(p) =>
313 ty::Predicate::Projection(Binder(p.with_self_ty(tcx, self_ty))),
314 ExistentialPredicate::AutoTrait(did) => {
315 let trait_ref = Binder(ty::TraitRef {
316 def_id: did,
317 substs: tcx.mk_substs_trait(self_ty, &[]),
318 });
319 trait_ref.to_predicate()
320 }
321 }
322 }
323}
324
325impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Slice<ExistentialPredicate<'tcx>> {}
326
327impl<'tcx> Slice<ExistentialPredicate<'tcx>> {
328 pub fn principal(&self) -> Option<ExistentialTraitRef<'tcx>> {
329 match self.get(0) {
330 Some(&ExistentialPredicate::Trait(tr)) => Some(tr),
cc61c64b 331 _ => None,
476ff2be
SL
332 }
333 }
334
335 #[inline]
336 pub fn projection_bounds<'a>(&'a self) ->
337 impl Iterator<Item=ExistentialProjection<'tcx>> + 'a {
338 self.iter().filter_map(|predicate| {
339 match *predicate {
340 ExistentialPredicate::Projection(p) => Some(p),
341 _ => None,
342 }
343 })
344 }
345
346 #[inline]
347 pub fn auto_traits<'a>(&'a self) -> impl Iterator<Item=DefId> + 'a {
348 self.iter().filter_map(|predicate| {
349 match *predicate {
350 ExistentialPredicate::AutoTrait(d) => Some(d),
351 _ => None
352 }
353 })
354 }
355}
356
357impl<'tcx> Binder<&'tcx Slice<ExistentialPredicate<'tcx>>> {
358 pub fn principal(&self) -> Option<PolyExistentialTraitRef<'tcx>> {
359 self.skip_binder().principal().map(Binder)
360 }
361
362 #[inline]
363 pub fn projection_bounds<'a>(&'a self) ->
364 impl Iterator<Item=PolyExistentialProjection<'tcx>> + 'a {
365 self.skip_binder().projection_bounds().map(Binder)
366 }
367
368 #[inline]
369 pub fn auto_traits<'a>(&'a self) -> impl Iterator<Item=DefId> + 'a {
370 self.skip_binder().auto_traits()
371 }
372
373 pub fn iter<'a>(&'a self)
374 -> impl DoubleEndedIterator<Item=Binder<ExistentialPredicate<'tcx>>> + 'tcx {
375 self.skip_binder().iter().cloned().map(Binder)
376 }
e9174d1e
SL
377}
378
379/// A complete reference to a trait. These take numerous guises in syntax,
380/// but perhaps the most recognizable form is in a where clause:
381///
382/// T : Foo<U>
383///
384/// This would be represented by a trait-reference where the def-id is the
9e0c209e
SL
385/// def-id for the trait `Foo` and the substs define `T` as parameter 0,
386/// and `U` as parameter 1.
e9174d1e
SL
387///
388/// Trait references also appear in object types like `Foo<U>`, but in
389/// that case the `Self` parameter is absent from the substitutions.
390///
391/// Note that a `TraitRef` introduces a level of region binding, to
392/// account for higher-ranked trait bounds like `T : for<'a> Foo<&'a
393/// U>` or higher-ranked object types.
9e0c209e 394#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
e9174d1e
SL
395pub struct TraitRef<'tcx> {
396 pub def_id: DefId,
397 pub substs: &'tcx Substs<'tcx>,
398}
399
8bb4bdeb
XL
400impl<'tcx> TraitRef<'tcx> {
401 pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>) -> TraitRef<'tcx> {
402 TraitRef { def_id: def_id, substs: substs }
403 }
404
405 pub fn self_ty(&self) -> Ty<'tcx> {
406 self.substs.type_at(0)
407 }
408
409 pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
410 // Select only the "input types" from a trait-reference. For
411 // now this is all the types that appear in the
412 // trait-reference, but it should eventually exclude
413 // associated types.
414 self.substs.types()
415 }
416}
417
e9174d1e
SL
418pub type PolyTraitRef<'tcx> = Binder<TraitRef<'tcx>>;
419
420impl<'tcx> PolyTraitRef<'tcx> {
421 pub fn self_ty(&self) -> Ty<'tcx> {
422 self.0.self_ty()
423 }
424
425 pub fn def_id(&self) -> DefId {
426 self.0.def_id
427 }
428
429 pub fn substs(&self) -> &'tcx Substs<'tcx> {
430 // FIXME(#20664) every use of this fn is probably a bug, it should yield Binder<>
431 self.0.substs
432 }
433
9e0c209e 434 pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
e9174d1e
SL
435 // FIXME(#20664) every use of this fn is probably a bug, it should yield Binder<>
436 self.0.input_types()
437 }
438
439 pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> {
440 // Note that we preserve binding levels
441 Binder(ty::TraitPredicate { trait_ref: self.0.clone() })
442 }
443}
444
9e0c209e
SL
445/// An existential reference to a trait, where `Self` is erased.
446/// For example, the trait object `Trait<'a, 'b, X, Y>` is:
447///
448/// exists T. T: Trait<'a, 'b, X, Y>
449///
450/// The substitutions don't include the erased `Self`, only trait
451/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
452#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
453pub struct ExistentialTraitRef<'tcx> {
454 pub def_id: DefId,
455 pub substs: &'tcx Substs<'tcx>,
456}
457
476ff2be
SL
458impl<'a, 'gcx, 'tcx> ExistentialTraitRef<'tcx> {
459 pub fn input_types<'b>(&'b self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'b {
9e0c209e
SL
460 // Select only the "input types" from a trait-reference. For
461 // now this is all the types that appear in the
462 // trait-reference, but it should eventually exclude
463 // associated types.
464 self.substs.types()
465 }
476ff2be
SL
466
467 /// Object types don't have a self-type specified. Therefore, when
468 /// we convert the principal trait-ref into a normal trait-ref,
469 /// you must give *some* self-type. A common choice is `mk_err()`
470 /// or some skolemized type.
471 pub fn with_self_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, self_ty: Ty<'tcx>)
472 -> ty::TraitRef<'tcx> {
473 // otherwise the escaping regions would be captured by the binder
474 assert!(!self_ty.has_escaping_regions());
475
476 ty::TraitRef {
477 def_id: self.def_id,
478 substs: tcx.mk_substs(
479 iter::once(Kind::from(self_ty)).chain(self.substs.iter().cloned()))
480 }
481 }
9e0c209e
SL
482}
483
484pub type PolyExistentialTraitRef<'tcx> = Binder<ExistentialTraitRef<'tcx>>;
485
486impl<'tcx> PolyExistentialTraitRef<'tcx> {
487 pub fn def_id(&self) -> DefId {
488 self.0.def_id
489 }
490
491 pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
492 // FIXME(#20664) every use of this fn is probably a bug, it should yield Binder<>
493 self.0.input_types()
494 }
495}
496
e9174d1e
SL
497/// Binder is a binder for higher-ranked lifetimes. It is part of the
498/// compiler's representation for things like `for<'a> Fn(&'a isize)`
499/// (which would be represented by the type `PolyTraitRef ==
500/// Binder<TraitRef>`). Note that when we skolemize, instantiate,
501/// erase, or otherwise "discharge" these bound regions, we change the
502/// type from `Binder<T>` to just `T` (see
503/// e.g. `liberate_late_bound_regions`).
9e0c209e 504#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
e9174d1e
SL
505pub struct Binder<T>(pub T);
506
507impl<T> Binder<T> {
508 /// Skips the binder and returns the "bound" value. This is a
509 /// risky thing to do because it's easy to get confused about
510 /// debruijn indices and the like. It is usually better to
511 /// discharge the binder using `no_late_bound_regions` or
512 /// `replace_late_bound_regions` or something like
513 /// that. `skip_binder` is only valid when you are either
514 /// extracting data that has nothing to do with bound regions, you
515 /// are doing some sort of test that does not involve bound
516 /// regions, or you are being very careful about your depth
517 /// accounting.
518 ///
519 /// Some examples where `skip_binder` is reasonable:
520 /// - extracting the def-id from a PolyTraitRef;
521 /// - comparing the self type of a PolyTraitRef to see if it is equal to
522 /// a type parameter `X`, since the type `X` does not reference any regions
523 pub fn skip_binder(&self) -> &T {
524 &self.0
525 }
526
527 pub fn as_ref(&self) -> Binder<&T> {
528 ty::Binder(&self.0)
529 }
530
cc61c64b 531 pub fn map_bound_ref<F, U>(&self, f: F) -> Binder<U>
e9174d1e
SL
532 where F: FnOnce(&T) -> U
533 {
534 self.as_ref().map_bound(f)
535 }
536
cc61c64b 537 pub fn map_bound<F, U>(self, f: F) -> Binder<U>
e9174d1e
SL
538 where F: FnOnce(T) -> U
539 {
540 ty::Binder(f(self.0))
541 }
542}
543
544impl fmt::Debug for TypeFlags {
545 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
c30ab7b3 546 write!(f, "{:x}", self.bits)
e9174d1e
SL
547 }
548}
549
550/// Represents the projection of an associated type. In explicit UFCS
551/// form this would be written `<T as Trait<..>>::N`.
9e0c209e 552#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
e9174d1e 553pub struct ProjectionTy<'tcx> {
041b39d2
XL
554 /// The parameters of the associated item.
555 pub substs: &'tcx Substs<'tcx>,
e9174d1e 556
7cac9316
XL
557 /// The DefId of the TraitItem for the associated type N.
558 ///
559 /// Note that this is not the DefId of the TraitRef containing this
560 /// associated type, which is in tcx.associated_item(item_def_id).container.
561 pub item_def_id: DefId,
e9174d1e 562}
7cac9316
XL
563
564impl<'a, 'tcx> ProjectionTy<'tcx> {
565 /// Construct a ProjectionTy by searching the trait from trait_ref for the
566 /// associated item named item_name.
567 pub fn from_ref_and_name(
568 tcx: TyCtxt, trait_ref: ty::TraitRef<'tcx>, item_name: Name
569 ) -> ProjectionTy<'tcx> {
570 let item_def_id = tcx.associated_items(trait_ref.def_id).find(
041b39d2
XL
571 |item| item.name == item_name && item.kind == ty::AssociatedKind::Type
572 ).unwrap().def_id;
7cac9316
XL
573
574 ProjectionTy {
041b39d2
XL
575 substs: trait_ref.substs,
576 item_def_id,
7cac9316
XL
577 }
578 }
579
041b39d2
XL
580 /// Extracts the underlying trait reference from this projection.
581 /// For example, if this is a projection of `<T as Iterator>::Item`,
582 /// then this function would return a `T: Iterator` trait reference.
583 pub fn trait_ref(&self, tcx: TyCtxt) -> ty::TraitRef<'tcx> {
584 let def_id = tcx.associated_item(self.item_def_id).container.id();
585 ty::TraitRef {
586 def_id: def_id,
587 substs: self.substs,
588 }
589 }
590
591 pub fn self_ty(&self) -> Ty<'tcx> {
592 self.substs.type_at(0)
7cac9316
XL
593 }
594}
595
596
e9174d1e
SL
597/// Signature of a function type, which I have arbitrarily
598/// decided to use to refer to the input/output types.
599///
600/// - `inputs` is the list of arguments and their modes.
601/// - `output` is the return type.
602/// - `variadic` indicates whether this is a variadic function. (only true for foreign fns)
8bb4bdeb 603#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
e9174d1e 604pub struct FnSig<'tcx> {
476ff2be 605 pub inputs_and_output: &'tcx Slice<Ty<'tcx>>,
8bb4bdeb
XL
606 pub variadic: bool,
607 pub unsafety: hir::Unsafety,
608 pub abi: abi::Abi,
e9174d1e
SL
609}
610
476ff2be 611impl<'tcx> FnSig<'tcx> {
8bb4bdeb 612 pub fn inputs(&self) -> &'tcx [Ty<'tcx>] {
476ff2be
SL
613 &self.inputs_and_output[..self.inputs_and_output.len() - 1]
614 }
615
616 pub fn output(&self) -> Ty<'tcx> {
617 self.inputs_and_output[self.inputs_and_output.len() - 1]
618 }
619}
620
e9174d1e
SL
621pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;
622
623impl<'tcx> PolyFnSig<'tcx> {
8bb4bdeb 624 pub fn inputs(&self) -> Binder<&'tcx [Ty<'tcx>]> {
476ff2be 625 Binder(self.skip_binder().inputs())
e9174d1e
SL
626 }
627 pub fn input(&self, index: usize) -> ty::Binder<Ty<'tcx>> {
476ff2be 628 self.map_bound_ref(|fn_sig| fn_sig.inputs()[index])
e9174d1e 629 }
5bcae85e 630 pub fn output(&self) -> ty::Binder<Ty<'tcx>> {
476ff2be 631 self.map_bound_ref(|fn_sig| fn_sig.output().clone())
e9174d1e
SL
632 }
633 pub fn variadic(&self) -> bool {
634 self.skip_binder().variadic
635 }
8bb4bdeb
XL
636 pub fn unsafety(&self) -> hir::Unsafety {
637 self.skip_binder().unsafety
638 }
639 pub fn abi(&self) -> abi::Abi {
640 self.skip_binder().abi
641 }
e9174d1e
SL
642}
643
9e0c209e 644#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
e9174d1e 645pub struct ParamTy {
e9174d1e
SL
646 pub idx: u32,
647 pub name: Name,
648}
649
a7813a04 650impl<'a, 'gcx, 'tcx> ParamTy {
9e0c209e
SL
651 pub fn new(index: u32, name: Name) -> ParamTy {
652 ParamTy { idx: index, name: name }
e9174d1e
SL
653 }
654
655 pub fn for_self() -> ParamTy {
9e0c209e 656 ParamTy::new(0, keywords::SelfType.name())
e9174d1e
SL
657 }
658
659 pub fn for_def(def: &ty::TypeParameterDef) -> ParamTy {
9e0c209e 660 ParamTy::new(def.index, def.name)
e9174d1e
SL
661 }
662
a7813a04 663 pub fn to_ty(self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
9e0c209e 664 tcx.mk_param(self.idx, self.name)
e9174d1e
SL
665 }
666
667 pub fn is_self(&self) -> bool {
9e0c209e
SL
668 if self.name == keywords::SelfType.name() {
669 assert_eq!(self.idx, 0);
670 true
671 } else {
672 false
673 }
e9174d1e
SL
674 }
675}
676
677/// A [De Bruijn index][dbi] is a standard means of representing
678/// regions (and perhaps later types) in a higher-ranked setting. In
679/// particular, imagine a type like this:
680///
681/// for<'a> fn(for<'b> fn(&'b isize, &'a isize), &'a char)
682/// ^ ^ | | |
683/// | | | | |
684/// | +------------+ 1 | |
685/// | | |
686/// +--------------------------------+ 2 |
687/// | |
688/// +------------------------------------------+ 1
689///
690/// In this type, there are two binders (the outer fn and the inner
691/// fn). We need to be able to determine, for any given region, which
692/// fn type it is bound by, the inner or the outer one. There are
693/// various ways you can do this, but a De Bruijn index is one of the
694/// more convenient and has some nice properties. The basic idea is to
695/// count the number of binders, inside out. Some examples should help
696/// clarify what I mean.
697///
698/// Let's start with the reference type `&'b isize` that is the first
699/// argument to the inner function. This region `'b` is assigned a De
700/// Bruijn index of 1, meaning "the innermost binder" (in this case, a
701/// fn). The region `'a` that appears in the second argument type (`&'a
702/// isize`) would then be assigned a De Bruijn index of 2, meaning "the
703/// second-innermost binder". (These indices are written on the arrays
704/// in the diagram).
705///
706/// What is interesting is that De Bruijn index attached to a particular
707/// variable will vary depending on where it appears. For example,
708/// the final type `&'a char` also refers to the region `'a` declared on
709/// the outermost fn. But this time, this reference is not nested within
710/// any other binders (i.e., it is not an argument to the inner fn, but
711/// rather the outer one). Therefore, in this case, it is assigned a
712/// De Bruijn index of 1, because the innermost binder in that location
713/// is the outer fn.
714///
715/// [dbi]: http://en.wikipedia.org/wiki/De_Bruijn_index
716#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, Copy)]
717pub struct DebruijnIndex {
7cac9316
XL
718 /// We maintain the invariant that this is never 0. So 1 indicates
719 /// the innermost binder. To ensure this, create with `DebruijnIndex::new`.
e9174d1e
SL
720 pub depth: u32,
721}
722
7cac9316
XL
723pub type Region<'tcx> = &'tcx RegionKind;
724
e9174d1e
SL
725/// Representation of regions.
726///
727/// Unlike types, most region variants are "fictitious", not concrete,
728/// regions. Among these, `ReStatic`, `ReEmpty` and `ReScope` are the only
729/// ones representing concrete regions.
730///
731/// ## Bound Regions
732///
733/// These are regions that are stored behind a binder and must be substituted
734/// with some concrete region before being used. There are 2 kind of
476ff2be 735/// bound regions: early-bound, which are bound in an item's Generics,
e9174d1e
SL
736/// and are substituted by a Substs, and late-bound, which are part of
737/// higher-ranked types (e.g. `for<'a> fn(&'a ())`) and are substituted by
738/// the likes of `liberate_late_bound_regions`. The distinction exists
739/// because higher-ranked lifetimes aren't supported in all places. See [1][2].
740///
741/// Unlike TyParam-s, bound regions are not supposed to exist "in the wild"
742/// outside their binder, e.g. in types passed to type inference, and
743/// should first be substituted (by skolemized regions, free regions,
744/// or region variables).
745///
746/// ## Skolemized and Free Regions
747///
748/// One often wants to work with bound regions without knowing their precise
749/// identity. For example, when checking a function, the lifetime of a borrow
750/// can end up being assigned to some region parameter. In these cases,
751/// it must be ensured that bounds on the region can't be accidentally
752/// assumed without being checked.
753///
754/// The process of doing that is called "skolemization". The bound regions
755/// are replaced by skolemized markers, which don't satisfy any relation
756/// not explicity provided.
757///
758/// There are 2 kinds of skolemized regions in rustc: `ReFree` and
759/// `ReSkolemized`. When checking an item's body, `ReFree` is supposed
760/// to be used. These also support explicit bounds: both the internally-stored
761/// *scope*, which the region is assumed to outlive, as well as other
762/// relations stored in the `FreeRegionMap`. Note that these relations
a7813a04 763/// aren't checked when you `make_subregion` (or `eq_types`), only by
e9174d1e
SL
764/// `resolve_regions_and_report_errors`.
765///
766/// When working with higher-ranked types, some region relations aren't
767/// yet known, so you can't just call `resolve_regions_and_report_errors`.
768/// `ReSkolemized` is designed for this purpose. In these contexts,
769/// there's also the risk that some inference variable laying around will
770/// get unified with your skolemized region: if you want to check whether
771/// `for<'a> Foo<'_>: 'a`, and you substitute your bound region `'a`
772/// with a skolemized region `'%a`, the variable `'_` would just be
773/// instantiated to the skolemized region `'%a`, which is wrong because
774/// the inference variable is supposed to satisfy the relation
775/// *for every value of the skolemized region*. To ensure that doesn't
776/// happen, you can use `leak_check`. This is more clearly explained
777/// by infer/higher_ranked/README.md.
778///
779/// [1] http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
780/// [2] http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
9cc50fc6 781#[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable)]
7cac9316 782pub enum RegionKind {
e9174d1e
SL
783 // Region bound in a type or fn declaration which will be
784 // substituted 'early' -- that is, at the same time when type
785 // parameters are substituted.
786 ReEarlyBound(EarlyBoundRegion),
787
788 // Region bound in a function scope, which will be substituted when the
789 // function is called.
790 ReLateBound(DebruijnIndex, BoundRegion),
791
792 /// When checking a function body, the types of all arguments and so forth
793 /// that refer to bound region parameters are modified to refer to free
794 /// region parameters.
795 ReFree(FreeRegion),
796
797 /// A concrete region naming some statically determined extent
798 /// (e.g. an expression or sequence of statements) within the
799 /// current function.
800 ReScope(region::CodeExtent),
801
802 /// Static data that has an "infinite" lifetime. Top in the region lattice.
803 ReStatic,
804
805 /// A region variable. Should not exist after typeck.
806 ReVar(RegionVid),
807
808 /// A skolemized region - basically the higher-ranked version of ReFree.
809 /// Should not exist after typeck.
810 ReSkolemized(SkolemizedRegionVid, BoundRegion),
811
812 /// Empty lifetime is for data that is never accessed.
813 /// Bottom in the region lattice. We treat ReEmpty somewhat
814 /// specially; at least right now, we do not generate instances of
815 /// it during the GLB computations, but rather
816 /// generate an error instead. This is to improve error messages.
817 /// The only way to get an instance of ReEmpty is to have a region
818 /// variable with no constraints.
819 ReEmpty,
3157f602
XL
820
821 /// Erased region, used by trait selection, in MIR and during trans.
822 ReErased,
e9174d1e
SL
823}
824
7cac9316 825impl<'tcx> serialize::UseSpecializedDecodable for Region<'tcx> {}
9e0c209e 826
e9174d1e
SL
827#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
828pub struct EarlyBoundRegion {
7cac9316 829 pub def_id: DefId,
e9174d1e
SL
830 pub index: u32,
831 pub name: Name,
832}
833
9e0c209e 834#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
e9174d1e 835pub struct TyVid {
3157f602 836 pub index: u32,
e9174d1e
SL
837}
838
9e0c209e 839#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
e9174d1e 840pub struct IntVid {
cc61c64b 841 pub index: u32,
e9174d1e
SL
842}
843
9e0c209e 844#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
e9174d1e 845pub struct FloatVid {
cc61c64b 846 pub index: u32,
e9174d1e
SL
847}
848
849#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
850pub struct RegionVid {
cc61c64b 851 pub index: u32,
e9174d1e
SL
852}
853
9cc50fc6 854#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
e9174d1e 855pub struct SkolemizedRegionVid {
cc61c64b 856 pub index: u32,
e9174d1e
SL
857}
858
9e0c209e 859#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
e9174d1e
SL
860pub enum InferTy {
861 TyVar(TyVid),
862 IntVar(IntVid),
863 FloatVar(FloatVid),
864
865 /// A `FreshTy` is one that is generated as a replacement for an
866 /// unbound type variable. This is convenient for caching etc. See
54a0048b 867 /// `infer::freshen` for more details.
e9174d1e
SL
868 FreshTy(u32),
869 FreshIntTy(u32),
cc61c64b 870 FreshFloatTy(u32),
e9174d1e
SL
871}
872
9e0c209e
SL
873/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
874#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
875pub struct ExistentialProjection<'tcx> {
041b39d2
XL
876 pub item_def_id: DefId,
877 pub substs: &'tcx Substs<'tcx>,
cc61c64b 878 pub ty: Ty<'tcx>,
e9174d1e
SL
879}
880
9e0c209e
SL
881pub type PolyExistentialProjection<'tcx> = Binder<ExistentialProjection<'tcx>>;
882
476ff2be 883impl<'a, 'tcx, 'gcx> ExistentialProjection<'tcx> {
041b39d2
XL
884 /// Extracts the underlying existential trait reference from this projection.
885 /// For example, if this is a projection of `exists T. <T as Iterator>::Item == X`,
886 /// then this function would return a `exists T. T: Iterator` existential trait
887 /// reference.
888 pub fn trait_ref(&self, tcx: TyCtxt) -> ty::ExistentialTraitRef<'tcx> {
889 let def_id = tcx.associated_item(self.item_def_id).container.id();
890 ty::ExistentialTraitRef{
891 def_id: def_id,
892 substs: self.substs,
893 }
9e0c209e
SL
894 }
895
896 pub fn with_self_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
897 self_ty: Ty<'tcx>)
476ff2be 898 -> ty::ProjectionPredicate<'tcx>
9e0c209e
SL
899 {
900 // otherwise the escaping regions would be captured by the binders
901 assert!(!self_ty.has_escaping_regions());
902
476ff2be 903 ty::ProjectionPredicate {
041b39d2
XL
904 projection_ty: ty::ProjectionTy {
905 item_def_id: self.item_def_id,
906 substs: tcx.mk_substs(
907 iter::once(Kind::from(self_ty)).chain(self.substs.iter().cloned())),
908 },
cc61c64b 909 ty: self.ty,
476ff2be 910 }
e9174d1e
SL
911 }
912}
913
476ff2be 914impl<'a, 'tcx, 'gcx> PolyExistentialProjection<'tcx> {
476ff2be
SL
915 pub fn with_self_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, self_ty: Ty<'tcx>)
916 -> ty::PolyProjectionPredicate<'tcx> {
917 self.map_bound(|p| p.with_self_ty(tcx, self_ty))
e9174d1e
SL
918 }
919}
920
921impl DebruijnIndex {
922 pub fn new(depth: u32) -> DebruijnIndex {
923 assert!(depth > 0);
924 DebruijnIndex { depth: depth }
925 }
926
927 pub fn shifted(&self, amount: u32) -> DebruijnIndex {
928 DebruijnIndex { depth: self.depth + amount }
929 }
930}
931
7cac9316
XL
932/// Region utilities
933impl RegionKind {
934 pub fn is_late_bound(&self) -> bool {
e9174d1e 935 match *self {
e9174d1e 936 ty::ReLateBound(..) => true,
cc61c64b 937 _ => false,
e9174d1e
SL
938 }
939 }
940
941 pub fn needs_infer(&self) -> bool {
942 match *self {
943 ty::ReVar(..) | ty::ReSkolemized(..) => true,
944 _ => false
945 }
946 }
947
948 pub fn escapes_depth(&self, depth: u32) -> bool {
949 match *self {
950 ty::ReLateBound(debruijn, _) => debruijn.depth > depth,
951 _ => false,
952 }
953 }
954
955 /// Returns the depth of `self` from the (1-based) binding level `depth`
7cac9316 956 pub fn from_depth(&self, depth: u32) -> RegionKind {
e9174d1e
SL
957 match *self {
958 ty::ReLateBound(debruijn, r) => ty::ReLateBound(DebruijnIndex {
959 depth: debruijn.depth - (depth - 1)
960 }, r),
961 r => r
962 }
963 }
c30ab7b3
SL
964
965 pub fn type_flags(&self) -> TypeFlags {
966 let mut flags = TypeFlags::empty();
967
968 match *self {
969 ty::ReVar(..) => {
970 flags = flags | TypeFlags::HAS_RE_INFER;
971 flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
972 }
973 ty::ReSkolemized(..) => {
974 flags = flags | TypeFlags::HAS_RE_INFER;
975 flags = flags | TypeFlags::HAS_RE_SKOL;
976 flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
977 }
978 ty::ReLateBound(..) => { }
979 ty::ReEarlyBound(..) => { flags = flags | TypeFlags::HAS_RE_EARLY_BOUND; }
980 ty::ReStatic | ty::ReErased => { }
981 _ => { flags = flags | TypeFlags::HAS_FREE_REGIONS; }
982 }
983
984 match *self {
985 ty::ReStatic | ty::ReEmpty | ty::ReErased => (),
986 _ => flags = flags | TypeFlags::HAS_LOCAL_NAMES,
987 }
988
989 debug!("type_flags({:?}) = {:?}", self, flags);
990
991 flags
992 }
041b39d2
XL
993
994 // This method returns whether the given Region is Named
995 pub fn is_named_region(&self) -> bool {
996 match *self {
997 ty::ReFree(ref free_region) => {
998 match free_region.bound_region {
999 ty::BrNamed(..) => true,
1000 _ => false,
1001 }
1002 }
1003 _ => false,
1004 }
1005 }
e9174d1e
SL
1006}
1007
7cac9316 1008/// Type utilities
a7813a04 1009impl<'a, 'gcx, 'tcx> TyS<'tcx> {
e9174d1e
SL
1010 pub fn as_opt_param_ty(&self) -> Option<ty::ParamTy> {
1011 match self.sty {
1012 ty::TyParam(ref d) => Some(d.clone()),
1013 _ => None,
1014 }
1015 }
1016
1017 pub fn is_nil(&self) -> bool {
1018 match self.sty {
8bb4bdeb 1019 TyTuple(ref tys, _) => tys.is_empty(),
cc61c64b 1020 _ => false,
e9174d1e
SL
1021 }
1022 }
1023
5bcae85e
SL
1024 pub fn is_never(&self) -> bool {
1025 match self.sty {
1026 TyNever => true,
1027 _ => false,
1028 }
1029 }
1030
7cac9316
XL
1031 /// Test whether this is a `()` which was produced by defaulting a
1032 /// diverging type variable with feature(never_type) disabled.
8bb4bdeb
XL
1033 pub fn is_defaulted_unit(&self) -> bool {
1034 match self.sty {
1035 TyTuple(_, true) => true,
1036 _ => false,
1037 }
1038 }
1039
32a655c1
SL
1040 /// Checks whether a type is visibly uninhabited from a particular module.
1041 /// # Example
1042 /// ```rust
1043 /// enum Void {}
1044 /// mod a {
1045 /// pub mod b {
1046 /// pub struct SecretlyUninhabited {
1047 /// _priv: !,
1048 /// }
1049 /// }
1050 /// }
1051 ///
1052 /// mod c {
1053 /// pub struct AlsoSecretlyUninhabited {
1054 /// _priv: Void,
1055 /// }
1056 /// mod d {
1057 /// }
1058 /// }
1059 ///
1060 /// struct Foo {
1061 /// x: a::b::SecretlyUninhabited,
1062 /// y: c::AlsoSecretlyUninhabited,
1063 /// }
1064 /// ```
1065 /// In this code, the type `Foo` will only be visibly uninhabited inside the
1066 /// modules b, c and d. This effects pattern-matching on `Foo` or types that
1067 /// contain `Foo`.
1068 ///
1069 /// # Example
1070 /// ```rust
1071 /// let foo_result: Result<T, Foo> = ... ;
1072 /// let Ok(t) = foo_result;
1073 /// ```
1074 /// This code should only compile in modules where the uninhabitedness of Foo is
1075 /// visible.
1076 pub fn is_uninhabited_from(&self, module: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
8bb4bdeb 1077 let mut visited = FxHashMap::default();
32a655c1 1078 let forest = self.uninhabited_from(&mut visited, tcx);
476ff2be 1079
32a655c1
SL
1080 // To check whether this type is uninhabited at all (not just from the
1081 // given node) you could check whether the forest is empty.
1082 // ```
1083 // forest.is_empty()
1084 // ```
1085 forest.contains(tcx, module)
e9174d1e
SL
1086 }
1087
9cc50fc6
SL
1088 pub fn is_primitive(&self) -> bool {
1089 match self.sty {
1090 TyBool | TyChar | TyInt(_) | TyUint(_) | TyFloat(_) => true,
1091 _ => false,
1092 }
1093 }
1094
e9174d1e
SL
1095 pub fn is_ty_var(&self) -> bool {
1096 match self.sty {
1097 TyInfer(TyVar(_)) => true,
cc61c64b 1098 _ => false,
e9174d1e
SL
1099 }
1100 }
1101
b039eaaf 1102 pub fn is_phantom_data(&self) -> bool {
9e0c209e 1103 if let TyAdt(def, _) = self.sty {
b039eaaf
SL
1104 def.is_phantom_data()
1105 } else {
1106 false
1107 }
1108 }
1109
e9174d1e
SL
1110 pub fn is_bool(&self) -> bool { self.sty == TyBool }
1111
9e0c209e 1112 pub fn is_param(&self, index: u32) -> bool {
e9174d1e 1113 match self.sty {
9e0c209e 1114 ty::TyParam(ref data) => data.idx == index,
e9174d1e
SL
1115 _ => false,
1116 }
1117 }
1118
1119 pub fn is_self(&self) -> bool {
1120 match self.sty {
9e0c209e 1121 TyParam(ref p) => p.is_self(),
cc61c64b 1122 _ => false,
e9174d1e
SL
1123 }
1124 }
1125
54a0048b 1126 pub fn is_slice(&self) -> bool {
e9174d1e
SL
1127 match self.sty {
1128 TyRawPtr(mt) | TyRef(_, mt) => match mt.ty.sty {
1129 TySlice(_) | TyStr => true,
1130 _ => false,
1131 },
1132 _ => false
1133 }
1134 }
1135
1136 pub fn is_structural(&self) -> bool {
1137 match self.sty {
9e0c209e 1138 TyAdt(..) | TyTuple(..) | TyArray(..) | TyClosure(..) => true,
cc61c64b 1139 _ => self.is_slice() | self.is_trait(),
e9174d1e
SL
1140 }
1141 }
1142
1143 #[inline]
1144 pub fn is_simd(&self) -> bool {
1145 match self.sty {
cc61c64b
XL
1146 TyAdt(def, _) => def.repr.simd(),
1147 _ => false,
e9174d1e
SL
1148 }
1149 }
1150
a7813a04 1151 pub fn sequence_element_type(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
e9174d1e
SL
1152 match self.sty {
1153 TyArray(ty, _) | TySlice(ty) => ty,
a7813a04 1154 TyStr => tcx.mk_mach_uint(ast::UintTy::U8),
54a0048b 1155 _ => bug!("sequence_element_type called on non-sequence value: {}", self),
e9174d1e
SL
1156 }
1157 }
1158
a7813a04 1159 pub fn simd_type(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
e9174d1e 1160 match self.sty {
9e0c209e 1161 TyAdt(def, substs) => {
a7813a04 1162 def.struct_variant().fields[0].ty(tcx, substs)
e9174d1e 1163 }
54a0048b 1164 _ => bug!("simd_type called on invalid type")
e9174d1e
SL
1165 }
1166 }
1167
a7813a04 1168 pub fn simd_size(&self, _cx: TyCtxt) -> usize {
e9174d1e 1169 match self.sty {
9e0c209e 1170 TyAdt(def, _) => def.struct_variant().fields.len(),
54a0048b 1171 _ => bug!("simd_size called on invalid type")
e9174d1e
SL
1172 }
1173 }
1174
1175 pub fn is_region_ptr(&self) -> bool {
1176 match self.sty {
1177 TyRef(..) => true,
cc61c64b 1178 _ => false,
e9174d1e
SL
1179 }
1180 }
1181
32a655c1
SL
1182 pub fn is_mutable_pointer(&self) -> bool {
1183 match self.sty {
1184 TyRawPtr(tnm) | TyRef(_, tnm) => if let hir::Mutability::MutMutable = tnm.mutbl {
1185 true
1186 } else {
1187 false
1188 },
1189 _ => false
1190 }
1191 }
1192
e9174d1e
SL
1193 pub fn is_unsafe_ptr(&self) -> bool {
1194 match self.sty {
1195 TyRawPtr(_) => return true,
cc61c64b 1196 _ => return false,
e9174d1e
SL
1197 }
1198 }
1199
32a655c1 1200 pub fn is_box(&self) -> bool {
e9174d1e 1201 match self.sty {
32a655c1
SL
1202 TyAdt(def, _) => def.is_box(),
1203 _ => false,
1204 }
1205 }
1206
7cac9316 1207 /// panics if called on any type other than `Box<T>`
32a655c1
SL
1208 pub fn boxed_ty(&self) -> Ty<'tcx> {
1209 match self.sty {
1210 TyAdt(def, substs) if def.is_box() => substs.type_at(0),
1211 _ => bug!("`boxed_ty` is called on non-box type {:?}", self),
e9174d1e
SL
1212 }
1213 }
1214
7cac9316
XL
1215 /// A scalar type is one that denotes an atomic datum, with no sub-components.
1216 /// (A TyRawPtr is scalar because it represents a non-managed pointer, so its
1217 /// contents are abstract to rustc.)
e9174d1e
SL
1218 pub fn is_scalar(&self) -> bool {
1219 match self.sty {
1220 TyBool | TyChar | TyInt(_) | TyFloat(_) | TyUint(_) |
1221 TyInfer(IntVar(_)) | TyInfer(FloatVar(_)) |
54a0048b 1222 TyFnDef(..) | TyFnPtr(_) | TyRawPtr(_) => true,
e9174d1e
SL
1223 _ => false
1224 }
1225 }
1226
1227 /// Returns true if this type is a floating point type and false otherwise.
1228 pub fn is_floating_point(&self) -> bool {
1229 match self.sty {
1230 TyFloat(_) |
1231 TyInfer(FloatVar(_)) => true,
1232 _ => false,
1233 }
1234 }
1235
1236 pub fn is_trait(&self) -> bool {
1237 match self.sty {
476ff2be 1238 TyDynamic(..) => true,
cc61c64b 1239 _ => false,
e9174d1e
SL
1240 }
1241 }
1242
7cac9316
XL
1243 pub fn is_closure(&self) -> bool {
1244 match self.sty {
1245 TyClosure(..) => true,
1246 _ => false,
1247 }
1248 }
1249
e9174d1e
SL
1250 pub fn is_integral(&self) -> bool {
1251 match self.sty {
1252 TyInfer(IntVar(_)) | TyInt(_) | TyUint(_) => true,
1253 _ => false
1254 }
1255 }
1256
1257 pub fn is_fresh(&self) -> bool {
1258 match self.sty {
1259 TyInfer(FreshTy(_)) => true,
1260 TyInfer(FreshIntTy(_)) => true,
1261 TyInfer(FreshFloatTy(_)) => true,
cc61c64b 1262 _ => false,
e9174d1e
SL
1263 }
1264 }
1265
1266 pub fn is_uint(&self) -> bool {
1267 match self.sty {
7453a54e 1268 TyInfer(IntVar(_)) | TyUint(ast::UintTy::Us) => true,
e9174d1e
SL
1269 _ => false
1270 }
1271 }
1272
1273 pub fn is_char(&self) -> bool {
1274 match self.sty {
1275 TyChar => true,
cc61c64b 1276 _ => false,
e9174d1e
SL
1277 }
1278 }
1279
e9174d1e
SL
1280 pub fn is_fp(&self) -> bool {
1281 match self.sty {
1282 TyInfer(FloatVar(_)) | TyFloat(_) => true,
1283 _ => false
1284 }
1285 }
1286
1287 pub fn is_numeric(&self) -> bool {
1288 self.is_integral() || self.is_fp()
1289 }
1290
1291 pub fn is_signed(&self) -> bool {
1292 match self.sty {
1293 TyInt(_) => true,
cc61c64b 1294 _ => false,
e9174d1e
SL
1295 }
1296 }
1297
1298 pub fn is_machine(&self) -> bool {
1299 match self.sty {
7453a54e 1300 TyInt(ast::IntTy::Is) | TyUint(ast::UintTy::Us) => false,
e9174d1e 1301 TyInt(..) | TyUint(..) | TyFloat(..) => true,
cc61c64b 1302 _ => false,
e9174d1e
SL
1303 }
1304 }
1305
54a0048b
SL
1306 pub fn has_concrete_skeleton(&self) -> bool {
1307 match self.sty {
1308 TyParam(_) | TyInfer(_) | TyError => false,
1309 _ => true,
1310 }
1311 }
1312
7cac9316
XL
1313 /// Returns the type and mutability of *ty.
1314 ///
1315 /// The parameter `explicit` indicates if this is an *explicit* dereference.
1316 /// Some types---notably unsafe ptrs---can only be dereferenced explicitly.
e9174d1e
SL
1317 pub fn builtin_deref(&self, explicit: bool, pref: ty::LvaluePreference)
1318 -> Option<TypeAndMut<'tcx>>
1319 {
1320 match self.sty {
32a655c1 1321 TyAdt(def, _) if def.is_box() => {
e9174d1e 1322 Some(TypeAndMut {
32a655c1 1323 ty: self.boxed_ty(),
e9174d1e
SL
1324 mutbl: if pref == ty::PreferMutLvalue {
1325 hir::MutMutable
1326 } else {
1327 hir::MutImmutable
1328 },
1329 })
1330 },
1331 TyRef(_, mt) => Some(mt),
1332 TyRawPtr(mt) if explicit => Some(mt),
cc61c64b 1333 _ => None,
e9174d1e
SL
1334 }
1335 }
1336
7cac9316 1337 /// Returns the type of ty[i]
e9174d1e
SL
1338 pub fn builtin_index(&self) -> Option<Ty<'tcx>> {
1339 match self.sty {
1340 TyArray(ty, _) | TySlice(ty) => Some(ty),
cc61c64b 1341 _ => None,
e9174d1e
SL
1342 }
1343 }
1344
041b39d2 1345 pub fn fn_sig(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> PolyFnSig<'tcx> {
e9174d1e 1346 match self.sty {
041b39d2
XL
1347 TyFnDef(def_id, substs) => {
1348 tcx.fn_sig(def_id).subst(tcx, substs)
1349 }
1350 TyFnPtr(f) => f,
54a0048b 1351 _ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self)
e9174d1e
SL
1352 }
1353 }
1354
e9174d1e
SL
1355 pub fn is_fn(&self) -> bool {
1356 match self.sty {
54a0048b 1357 TyFnDef(..) | TyFnPtr(_) => true,
cc61c64b 1358 _ => false,
e9174d1e
SL
1359 }
1360 }
1361
1362 pub fn ty_to_def_id(&self) -> Option<DefId> {
1363 match self.sty {
476ff2be 1364 TyDynamic(ref tt, ..) => tt.principal().map(|p| p.def_id()),
9e0c209e 1365 TyAdt(def, _) => Some(def.did),
e9174d1e 1366 TyClosure(id, _) => Some(id),
cc61c64b 1367 _ => None,
e9174d1e
SL
1368 }
1369 }
1370
476ff2be 1371 pub fn ty_adt_def(&self) -> Option<&'tcx AdtDef> {
e9174d1e 1372 match self.sty {
9e0c209e 1373 TyAdt(adt, _) => Some(adt),
cc61c64b 1374 _ => None,
e9174d1e
SL
1375 }
1376 }
1377
1378 /// Returns the regions directly referenced from this type (but
1379 /// not types reachable from this type via `walk_tys`). This
1380 /// ignores late-bound regions binders.
7cac9316 1381 pub fn regions(&self) -> Vec<ty::Region<'tcx>> {
e9174d1e
SL
1382 match self.sty {
1383 TyRef(region, _) => {
9e0c209e 1384 vec![region]
e9174d1e 1385 }
476ff2be
SL
1386 TyDynamic(ref obj, region) => {
1387 let mut v = vec![region];
1388 if let Some(p) = obj.principal() {
1389 v.extend(p.skip_binder().substs.regions());
1390 }
e9174d1e
SL
1391 v
1392 }
9e0c209e
SL
1393 TyAdt(_, substs) | TyAnon(_, substs) => {
1394 substs.regions().collect()
e9174d1e
SL
1395 }
1396 TyClosure(_, ref substs) => {
476ff2be 1397 substs.substs.regions().collect()
e9174d1e
SL
1398 }
1399 TyProjection(ref data) => {
041b39d2 1400 data.substs.regions().collect()
e9174d1e 1401 }
54a0048b
SL
1402 TyFnDef(..) |
1403 TyFnPtr(_) |
e9174d1e
SL
1404 TyBool |
1405 TyChar |
1406 TyInt(_) |
1407 TyUint(_) |
1408 TyFloat(_) |
e9174d1e 1409 TyStr |
9e0c209e 1410 TyArray(..) |
e9174d1e
SL
1411 TySlice(_) |
1412 TyRawPtr(_) |
5bcae85e 1413 TyNever |
8bb4bdeb 1414 TyTuple(..) |
e9174d1e
SL
1415 TyParam(_) |
1416 TyInfer(_) |
1417 TyError => {
1418 vec![]
1419 }
1420 }
1421 }
1422}