]> git.proxmox.com Git - rustc.git/blame - src/librustc/ty/sty.rs
New upstream version 1.28.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
ea8adc8c 15use middle::const_val::ConstVal;
e9174d1e 16use middle::region;
94b46f34 17use polonius_engine::Atom;
abe05a73 18use rustc_data_structures::indexed_vec::Idx;
0531ce1d 19use ty::subst::{Substs, Subst, Kind, UnpackedKind};
476ff2be 20use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable};
94b46f34 21use ty::{Slice, TyS, ParamEnvAnd, ParamEnv};
0531ce1d 22use util::captures::Captures;
94b46f34 23use mir::interpret::{Scalar, Pointer, Value, ConstValue};
e9174d1e 24
476ff2be
SL
25use std::iter;
26use std::cmp::Ordering;
83c7162d 27use rustc_target::spec::abi;
32a655c1 28use syntax::ast::{self, Name};
0531ce1d 29use syntax::symbol::{keywords, InternedString};
e9174d1e 30
9e0c209e 31use serialize;
9cc50fc6 32
54a0048b 33use hir;
e9174d1e 34
e9174d1e
SL
35use self::InferTy::*;
36use self::TypeVariants::*;
37
94b46f34 38#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
e9174d1e
SL
39pub struct TypeAndMut<'tcx> {
40 pub ty: Ty<'tcx>,
41 pub mutbl: hir::Mutability,
42}
43
44#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash,
45 RustcEncodable, RustcDecodable, Copy)]
46/// A "free" region `fr` can be interpreted as "some region
47/// at least as big as the scope `fr.scope`".
48pub struct FreeRegion {
7cac9316 49 pub scope: DefId,
cc61c64b 50 pub bound_region: BoundRegion,
e9174d1e
SL
51}
52
53#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash,
54 RustcEncodable, RustcDecodable, Copy)]
55pub enum BoundRegion {
56 /// An anonymous region parameter for a given fn (&T)
57 BrAnon(u32),
58
59 /// Named region parameters for functions (a in &'a T)
60 ///
61 /// The def-id is needed to distinguish free regions in
62 /// the event of shadowing.
83c7162d 63 BrNamed(DefId, InternedString),
e9174d1e
SL
64
65 /// Fresh bound identifiers created during GLB computations.
66 BrFresh(u32),
67
7cac9316
XL
68 /// Anonymous region for the implicit env pointer parameter
69 /// to a closure
cc61c64b 70 BrEnv,
e9174d1e
SL
71}
72
7cac9316
XL
73impl BoundRegion {
74 pub fn is_named(&self) -> bool {
75 match *self {
76 BoundRegion::BrNamed(..) => true,
77 _ => false,
78 }
79 }
80}
81
7cac9316
XL
82/// NB: If you change this, you'll probably want to change the corresponding
83/// AST structure in libsyntax/ast.rs as well.
94b46f34 84#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
e9174d1e
SL
85pub enum TypeVariants<'tcx> {
86 /// The primitive boolean type. Written as `bool`.
87 TyBool,
88
89 /// The primitive character type; holds a Unicode scalar value
90 /// (a non-surrogate code point). Written as `char`.
91 TyChar,
92
93 /// A primitive signed integer type. For example, `i32`.
b039eaaf 94 TyInt(ast::IntTy),
e9174d1e
SL
95
96 /// A primitive unsigned integer type. For example, `u32`.
b039eaaf 97 TyUint(ast::UintTy),
e9174d1e
SL
98
99 /// A primitive floating-point type. For example, `f64`.
b039eaaf 100 TyFloat(ast::FloatTy),
e9174d1e 101
9e0c209e 102 /// Structures, enumerations and unions.
e9174d1e
SL
103 ///
104 /// Substs here, possibly against intuition, *may* contain `TyParam`s.
105 /// That is, even after substitution it is possible that there are type
9e0c209e
SL
106 /// variables. This happens when the `TyAdt` corresponds to an ADT
107 /// definition and not a concrete use of it.
476ff2be 108 TyAdt(&'tcx AdtDef, &'tcx Substs<'tcx>),
e9174d1e 109
abe05a73
XL
110 TyForeign(DefId),
111
e9174d1e
SL
112 /// The pointee of a string slice. Written as `str`.
113 TyStr,
114
115 /// An array with the given length. Written as `[T; n]`.
ea8adc8c 116 TyArray(Ty<'tcx>, &'tcx ty::Const<'tcx>),
e9174d1e
SL
117
118 /// The pointee of an array slice. Written as `[T]`.
119 TySlice(Ty<'tcx>),
120
121 /// A raw pointer. Written as `*mut T` or `*const T`
122 TyRawPtr(TypeAndMut<'tcx>),
123
124 /// A reference; a pointer with an associated lifetime. Written as
32a655c1 125 /// `&'a mut T` or `&'a T`.
94b46f34 126 TyRef(Region<'tcx>, Ty<'tcx>, hir::Mutability),
e9174d1e 127
54a0048b
SL
128 /// The anonymous type of a function declaration/definition. Each
129 /// function has a unique type.
041b39d2 130 TyFnDef(DefId, &'tcx Substs<'tcx>),
54a0048b
SL
131
132 /// A pointer to a function. Written as `fn() -> i32`.
8bb4bdeb 133 TyFnPtr(PolyFnSig<'tcx>),
e9174d1e
SL
134
135 /// A trait, defined with `trait`.
7cac9316 136 TyDynamic(Binder<&'tcx Slice<ExistentialPredicate<'tcx>>>, ty::Region<'tcx>),
e9174d1e
SL
137
138 /// The anonymous type of a closure. Used to represent the type of
139 /// `|a| a`.
a7813a04 140 TyClosure(DefId, ClosureSubsts<'tcx>),
e9174d1e 141
ea8adc8c
XL
142 /// The anonymous type of a generator. Used to represent the type of
143 /// `|a| yield a`.
94b46f34 144 TyGenerator(DefId, GeneratorSubsts<'tcx>, hir::GeneratorMovability),
ea8adc8c 145
2c00a5a8
XL
146 /// A type representin the types stored inside a generator.
147 /// This should only appear in GeneratorInteriors.
148 TyGeneratorWitness(Binder<&'tcx Slice<Ty<'tcx>>>),
149
5bcae85e
SL
150 /// The never type `!`
151 TyNever,
152
e9174d1e 153 /// A tuple type. For example, `(i32, bool)`.
0531ce1d 154 TyTuple(&'tcx Slice<Ty<'tcx>>),
e9174d1e
SL
155
156 /// The projection of an associated type. For example,
157 /// `<T as Trait<..>>::N`.
158 TyProjection(ProjectionTy<'tcx>),
159
5bcae85e
SL
160 /// Anonymized (`impl Trait`) type found in a return type.
161 /// The DefId comes from the `impl Trait` ast::Ty node, and the
162 /// substitutions are for the generics of the function in question.
476ff2be 163 /// After typeck, the concrete type can be found in the `types` map.
5bcae85e
SL
164 TyAnon(DefId, &'tcx Substs<'tcx>),
165
e9174d1e
SL
166 /// A type parameter; for example, `T` in `fn f<T>(x: T) {}
167 TyParam(ParamTy),
168
169 /// A type variable used during type-checking.
170 TyInfer(InferTy),
171
172 /// A placeholder for a type which could not be computed; this is
173 /// propagated to avoid useless error messages.
174 TyError,
175}
176
177/// A closure can be modeled as a struct that looks like:
178///
ff7c6d11 179/// struct Closure<'l0...'li, T0...Tj, CK, CS, U0...Uk> {
e9174d1e
SL
180/// upvar0: U0,
181/// ...
182/// upvark: Uk
183/// }
184///
ff7c6d11
XL
185/// where:
186///
187/// - 'l0...'li and T0...Tj are the lifetime and type parameters
188/// in scope on the function that defined the closure,
189/// - CK represents the *closure kind* (Fn vs FnMut vs FnOnce). This
190/// is rather hackily encoded via a scalar type. See
191/// `TyS::to_opt_closure_kind` for details.
192/// - CS represents the *closure signature*, representing as a `fn()`
193/// type. For example, `fn(u32, u32) -> u32` would mean that the closure
194/// implements `CK<(u32, u32), Output = u32>`, where `CK` is the trait
195/// specified above.
196/// - U0...Uk are type parameters representing the types of its upvars
197/// (borrowed, if appropriate; that is, if Ui represents a by-ref upvar,
198/// and the up-var has the type `Foo`, then `Ui = &Foo`).
e9174d1e
SL
199///
200/// So, for example, given this function:
201///
202/// fn foo<'a, T>(data: &'a mut T) {
203/// do(|| data.count += 1)
204/// }
205///
206/// the type of the closure would be something like:
207///
208/// struct Closure<'a, T, U0> {
209/// data: U0
210/// }
211///
212/// Note that the type of the upvar is not specified in the struct.
213/// You may wonder how the impl would then be able to use the upvar,
214/// if it doesn't know it's type? The answer is that the impl is
215/// (conceptually) not fully generic over Closure but rather tied to
216/// instances with the expected upvar types:
217///
218/// impl<'b, 'a, T> FnMut() for Closure<'a, T, &'b mut &'a mut T> {
219/// ...
220/// }
221///
222/// You can see that the *impl* fully specified the type of the upvar
223/// and thus knows full well that `data` has type `&'b mut &'a mut T`.
224/// (Here, I am assuming that `data` is mut-borrowed.)
225///
226/// Now, the last question you may ask is: Why include the upvar types
227/// as extra type parameters? The reason for this design is that the
228/// upvar types can reference lifetimes that are internal to the
229/// creating function. In my example above, for example, the lifetime
ea8adc8c
XL
230/// `'b` represents the scope of the closure itself; this is some
231/// subset of `foo`, probably just the scope of the call to the to
e9174d1e
SL
232/// `do()`. If we just had the lifetime/type parameters from the
233/// enclosing function, we couldn't name this lifetime `'b`. Note that
234/// there can also be lifetimes in the types of the upvars themselves,
235/// if one of them happens to be a reference to something that the
236/// creating fn owns.
237///
238/// OK, you say, so why not create a more minimal set of parameters
239/// that just includes the extra lifetime parameters? The answer is
240/// primarily that it would be hard --- we don't know at the time when
241/// we create the closure type what the full types of the upvars are,
242/// nor do we know which are borrowed and which are not. In this
243/// design, we can just supply a fresh type parameter and figure that
244/// out later.
245///
246/// All right, you say, but why include the type parameters from the
94b46f34 247/// original function then? The answer is that codegen may need them
e9174d1e
SL
248/// when monomorphizing, and they may not appear in the upvars. A
249/// closure could capture no variables but still make use of some
250/// in-scope type parameter with a bound (e.g., if our example above
251/// had an extra `U: Default`, and the closure called `U::default()`).
252///
253/// There is another reason. This design (implicitly) prohibits
254/// closures from capturing themselves (except via a trait
255/// object). This simplifies closure inference considerably, since it
256/// means that when we infer the kind of a closure or its upvars, we
257/// don't have to handle cycles where the decisions we make for
258/// closure C wind up influencing the decisions we ought to make for
259/// closure C (which would then require fixed point iteration to
260/// handle). Plus it fixes an ICE. :P
ff7c6d11
XL
261///
262/// ## Generators
263///
264/// Perhaps surprisingly, `ClosureSubsts` are also used for
265/// generators. In that case, what is written above is only half-true
266/// -- the set of type parameters is similar, but the role of CK and
267/// CS are different. CK represents the "yield type" and CS
268/// represents the "return type" of the generator.
269///
270/// It'd be nice to split this struct into ClosureSubsts and
271/// GeneratorSubsts, I believe. -nmatsakis
94b46f34 272#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
e9174d1e 273pub struct ClosureSubsts<'tcx> {
476ff2be
SL
274 /// Lifetime and type parameters from the enclosing function,
275 /// concatenated with the types of the upvars.
276 ///
94b46f34 277 /// These are separated out because codegen wants to pass them around
e9174d1e 278 /// when monomorphizing.
476ff2be
SL
279 pub substs: &'tcx Substs<'tcx>,
280}
e9174d1e 281
ff7c6d11
XL
282/// Struct returned by `split()`. Note that these are subslices of the
283/// parent slice and not canonical substs themselves.
284struct SplitClosureSubsts<'tcx> {
285 closure_kind_ty: Ty<'tcx>,
286 closure_sig_ty: Ty<'tcx>,
287 upvar_kinds: &'tcx [Kind<'tcx>],
288}
289
290impl<'tcx> ClosureSubsts<'tcx> {
291 /// Divides the closure substs into their respective
292 /// components. Single source of truth with respect to the
293 /// ordering.
294 fn split(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> SplitClosureSubsts<'tcx> {
295 let generics = tcx.generics_of(def_id);
94b46f34 296 let parent_len = generics.parent_count;
ff7c6d11 297 SplitClosureSubsts {
0531ce1d
XL
298 closure_kind_ty: self.substs.type_at(parent_len),
299 closure_sig_ty: self.substs.type_at(parent_len + 1),
ff7c6d11
XL
300 upvar_kinds: &self.substs[parent_len + 2..],
301 }
302 }
303
476ff2be 304 #[inline]
ff7c6d11 305 pub fn upvar_tys(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) ->
476ff2be
SL
306 impl Iterator<Item=Ty<'tcx>> + 'tcx
307 {
ff7c6d11 308 let SplitClosureSubsts { upvar_kinds, .. } = self.split(def_id, tcx);
0531ce1d
XL
309 upvar_kinds.iter().map(|t| {
310 if let UnpackedKind::Type(ty) = t.unpack() {
311 ty
312 } else {
313 bug!("upvar should be type")
314 }
315 })
ff7c6d11
XL
316 }
317
318 /// Returns the closure kind for this closure; may return a type
319 /// variable during inference. To get the closure kind during
320 /// inference, use `infcx.closure_kind(def_id, substs)`.
321 pub fn closure_kind_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> {
322 self.split(def_id, tcx).closure_kind_ty
323 }
324
325 /// Returns the type representing the closure signature for this
326 /// closure; may contain type variables during inference. To get
327 /// the closure signature during inference, use
328 /// `infcx.fn_sig(def_id)`.
329 pub fn closure_sig_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> {
330 self.split(def_id, tcx).closure_sig_ty
331 }
332
ff7c6d11
XL
333 /// Returns the closure kind for this closure; only usable outside
334 /// of an inference context, because in that context we know that
335 /// there are no type variables.
336 ///
337 /// If you have an inference context, use `infcx.closure_kind()`.
338 pub fn closure_kind(self, def_id: DefId, tcx: TyCtxt<'_, 'tcx, 'tcx>) -> ty::ClosureKind {
339 self.split(def_id, tcx).closure_kind_ty.to_opt_closure_kind().unwrap()
340 }
341
342 /// Extracts the signature from the closure; only usable outside
343 /// of an inference context, because in that context we know that
344 /// there are no type variables.
345 ///
346 /// If you have an inference context, use `infcx.closure_sig()`.
347 pub fn closure_sig(self, def_id: DefId, tcx: TyCtxt<'_, 'tcx, 'tcx>) -> ty::PolyFnSig<'tcx> {
348 match self.closure_sig_ty(def_id, tcx).sty {
349 ty::TyFnPtr(sig) => sig,
350 ref t => bug!("closure_sig_ty is not a fn-ptr: {:?}", t),
351 }
476ff2be 352 }
a7813a04 353}
9cc50fc6 354
94b46f34
XL
355#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
356pub struct GeneratorSubsts<'tcx> {
357 pub substs: &'tcx Substs<'tcx>,
358}
359
360struct SplitGeneratorSubsts<'tcx> {
361 yield_ty: Ty<'tcx>,
362 return_ty: Ty<'tcx>,
363 witness: Ty<'tcx>,
364 upvar_kinds: &'tcx [Kind<'tcx>],
365}
366
367impl<'tcx> GeneratorSubsts<'tcx> {
368 fn split(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> SplitGeneratorSubsts<'tcx> {
369 let generics = tcx.generics_of(def_id);
370 let parent_len = generics.parent_count;
371 SplitGeneratorSubsts {
372 yield_ty: self.substs.type_at(parent_len),
373 return_ty: self.substs.type_at(parent_len + 1),
374 witness: self.substs.type_at(parent_len + 2),
375 upvar_kinds: &self.substs[parent_len + 3..],
376 }
377 }
378
379 /// This describes the types that can be contained in a generator.
380 /// It will be a type variable initially and unified in the last stages of typeck of a body.
381 /// It contains a tuple of all the types that could end up on a generator frame.
382 /// The state transformation MIR pass may only produce layouts which mention types
383 /// in this tuple. Upvars are not counted here.
384 pub fn witness(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> {
385 self.split(def_id, tcx).witness
386 }
387
388 #[inline]
389 pub fn upvar_tys(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) ->
390 impl Iterator<Item=Ty<'tcx>> + 'tcx
391 {
392 let SplitGeneratorSubsts { upvar_kinds, .. } = self.split(def_id, tcx);
393 upvar_kinds.iter().map(|t| {
394 if let UnpackedKind::Type(ty) = t.unpack() {
395 ty
396 } else {
397 bug!("upvar should be type")
398 }
399 })
400 }
401
402 /// Returns the type representing the yield type of the generator.
403 pub fn yield_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> {
404 self.split(def_id, tcx).yield_ty
405 }
406
407 /// Returns the type representing the return type of the generator.
408 pub fn return_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> {
409 self.split(def_id, tcx).return_ty
410 }
411
412 /// Return the "generator signature", which consists of its yield
413 /// and return types.
414 ///
415 /// NB. Some bits of the code prefers to see this wrapped in a
416 /// binder, but it never contains bound regions. Probably this
417 /// function should be removed.
418 pub fn poly_sig(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> PolyGenSig<'tcx> {
419 ty::Binder::dummy(self.sig(def_id, tcx))
420 }
421
422 /// Return the "generator signature", which consists of its yield
423 /// and return types.
424 pub fn sig(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> GenSig<'tcx> {
425 ty::GenSig {
426 yield_ty: self.yield_ty(def_id, tcx),
427 return_ty: self.return_ty(def_id, tcx),
428 }
429 }
430}
431
432impl<'a, 'gcx, 'tcx> GeneratorSubsts<'tcx> {
ea8adc8c
XL
433 /// This returns the types of the MIR locals which had to be stored across suspension points.
434 /// It is calculated in rustc_mir::transform::generator::StateTransform.
435 /// All the types here must be in the tuple in GeneratorInterior.
0531ce1d
XL
436 pub fn state_tys(
437 self,
438 def_id: DefId,
439 tcx: TyCtxt<'a, 'gcx, 'tcx>,
440 ) -> impl Iterator<Item=Ty<'tcx>> + Captures<'gcx> + 'a {
ea8adc8c
XL
441 let state = tcx.generator_layout(def_id).fields.iter();
442 state.map(move |d| d.ty.subst(tcx, self.substs))
443 }
444
2c00a5a8
XL
445 /// This is the types of the fields of a generate which
446 /// is available before the generator transformation.
447 /// It includes the upvars and the state discriminant which is u32.
448 pub fn pre_transforms_tys(self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) ->
449 impl Iterator<Item=Ty<'tcx>> + 'a
450 {
451 self.upvar_tys(def_id, tcx).chain(iter::once(tcx.types.u32))
452 }
453
ea8adc8c
XL
454 /// This is the types of all the fields stored in a generator.
455 /// It includes the upvars, state types and the state discriminant which is u32.
456 pub fn field_tys(self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) ->
0531ce1d 457 impl Iterator<Item=Ty<'tcx>> + Captures<'gcx> + 'a
ea8adc8c 458 {
2c00a5a8 459 self.pre_transforms_tys(def_id, tcx).chain(self.state_tys(def_id, tcx))
ea8adc8c
XL
460 }
461}
462
94b46f34
XL
463#[derive(Debug, Copy, Clone)]
464pub enum UpvarSubsts<'tcx> {
465 Closure(ClosureSubsts<'tcx>),
466 Generator(GeneratorSubsts<'tcx>),
467}
468
469impl<'tcx> UpvarSubsts<'tcx> {
470 #[inline]
471 pub fn upvar_tys(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) ->
472 impl Iterator<Item=Ty<'tcx>> + 'tcx
473 {
474 let upvar_kinds = match self {
475 UpvarSubsts::Closure(substs) => substs.split(def_id, tcx).upvar_kinds,
476 UpvarSubsts::Generator(substs) => substs.split(def_id, tcx).upvar_kinds,
477 };
478 upvar_kinds.iter().map(|t| {
479 if let UnpackedKind::Type(ty) = t.unpack() {
480 ty
481 } else {
482 bug!("upvar should be type")
483 }
484 })
485 }
ea8adc8c
XL
486}
487
94b46f34 488#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, RustcEncodable, RustcDecodable)]
476ff2be 489pub enum ExistentialPredicate<'tcx> {
7cac9316 490 /// e.g. Iterator
476ff2be 491 Trait(ExistentialTraitRef<'tcx>),
7cac9316 492 /// e.g. Iterator::Item = T
476ff2be 493 Projection(ExistentialProjection<'tcx>),
7cac9316 494 /// e.g. Send
476ff2be
SL
495 AutoTrait(DefId),
496}
497
498impl<'a, 'gcx, 'tcx> ExistentialPredicate<'tcx> {
94b46f34
XL
499 /// Compares via an ordering that will not change if modules are reordered or other changes are
500 /// made to the tree. In particular, this ordering is preserved across incremental compilations.
501 pub fn stable_cmp(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, other: &Self) -> Ordering {
476ff2be
SL
502 use self::ExistentialPredicate::*;
503 match (*self, *other) {
504 (Trait(_), Trait(_)) => Ordering::Equal,
041b39d2
XL
505 (Projection(ref a), Projection(ref b)) =>
506 tcx.def_path_hash(a.item_def_id).cmp(&tcx.def_path_hash(b.item_def_id)),
476ff2be 507 (AutoTrait(ref a), AutoTrait(ref b)) =>
7cac9316 508 tcx.trait_def(*a).def_path_hash.cmp(&tcx.trait_def(*b).def_path_hash),
476ff2be
SL
509 (Trait(_), _) => Ordering::Less,
510 (Projection(_), Trait(_)) => Ordering::Greater,
511 (Projection(_), _) => Ordering::Less,
512 (AutoTrait(_), _) => Ordering::Greater,
513 }
514 }
515
516}
517
518impl<'a, 'gcx, 'tcx> Binder<ExistentialPredicate<'tcx>> {
519 pub fn with_self_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, self_ty: Ty<'tcx>)
520 -> ty::Predicate<'tcx> {
521 use ty::ToPredicate;
522 match *self.skip_binder() {
523 ExistentialPredicate::Trait(tr) => Binder(tr).with_self_ty(tcx, self_ty).to_predicate(),
524 ExistentialPredicate::Projection(p) =>
525 ty::Predicate::Projection(Binder(p.with_self_ty(tcx, self_ty))),
526 ExistentialPredicate::AutoTrait(did) => {
527 let trait_ref = Binder(ty::TraitRef {
528 def_id: did,
529 substs: tcx.mk_substs_trait(self_ty, &[]),
530 });
531 trait_ref.to_predicate()
532 }
533 }
534 }
535}
536
537impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Slice<ExistentialPredicate<'tcx>> {}
538
539impl<'tcx> Slice<ExistentialPredicate<'tcx>> {
540 pub fn principal(&self) -> Option<ExistentialTraitRef<'tcx>> {
541 match self.get(0) {
542 Some(&ExistentialPredicate::Trait(tr)) => Some(tr),
cc61c64b 543 _ => None,
476ff2be
SL
544 }
545 }
546
547 #[inline]
548 pub fn projection_bounds<'a>(&'a self) ->
549 impl Iterator<Item=ExistentialProjection<'tcx>> + 'a {
550 self.iter().filter_map(|predicate| {
551 match *predicate {
552 ExistentialPredicate::Projection(p) => Some(p),
553 _ => None,
554 }
555 })
556 }
557
558 #[inline]
559 pub fn auto_traits<'a>(&'a self) -> impl Iterator<Item=DefId> + 'a {
560 self.iter().filter_map(|predicate| {
561 match *predicate {
562 ExistentialPredicate::AutoTrait(d) => Some(d),
563 _ => None
564 }
565 })
566 }
567}
568
569impl<'tcx> Binder<&'tcx Slice<ExistentialPredicate<'tcx>>> {
570 pub fn principal(&self) -> Option<PolyExistentialTraitRef<'tcx>> {
83c7162d 571 self.skip_binder().principal().map(Binder::bind)
476ff2be
SL
572 }
573
574 #[inline]
575 pub fn projection_bounds<'a>(&'a self) ->
576 impl Iterator<Item=PolyExistentialProjection<'tcx>> + 'a {
83c7162d 577 self.skip_binder().projection_bounds().map(Binder::bind)
476ff2be
SL
578 }
579
580 #[inline]
581 pub fn auto_traits<'a>(&'a self) -> impl Iterator<Item=DefId> + 'a {
582 self.skip_binder().auto_traits()
583 }
584
585 pub fn iter<'a>(&'a self)
586 -> impl DoubleEndedIterator<Item=Binder<ExistentialPredicate<'tcx>>> + 'tcx {
83c7162d 587 self.skip_binder().iter().cloned().map(Binder::bind)
476ff2be 588 }
e9174d1e
SL
589}
590
591/// A complete reference to a trait. These take numerous guises in syntax,
592/// but perhaps the most recognizable form is in a where clause:
593///
594/// T : Foo<U>
595///
596/// This would be represented by a trait-reference where the def-id is the
9e0c209e
SL
597/// def-id for the trait `Foo` and the substs define `T` as parameter 0,
598/// and `U` as parameter 1.
e9174d1e
SL
599///
600/// Trait references also appear in object types like `Foo<U>`, but in
601/// that case the `Self` parameter is absent from the substitutions.
602///
603/// Note that a `TraitRef` introduces a level of region binding, to
604/// account for higher-ranked trait bounds like `T : for<'a> Foo<&'a
605/// U>` or higher-ranked object types.
9e0c209e 606#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
e9174d1e
SL
607pub struct TraitRef<'tcx> {
608 pub def_id: DefId,
609 pub substs: &'tcx Substs<'tcx>,
610}
611
8bb4bdeb
XL
612impl<'tcx> TraitRef<'tcx> {
613 pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>) -> TraitRef<'tcx> {
614 TraitRef { def_id: def_id, substs: substs }
615 }
616
617 pub fn self_ty(&self) -> Ty<'tcx> {
618 self.substs.type_at(0)
619 }
620
621 pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
622 // Select only the "input types" from a trait-reference. For
623 // now this is all the types that appear in the
624 // trait-reference, but it should eventually exclude
625 // associated types.
626 self.substs.types()
627 }
94b46f34
XL
628
629 pub fn from_method(tcx: TyCtxt<'_, '_, 'tcx>,
630 trait_id: DefId,
631 substs: &Substs<'tcx>)
632 -> ty::TraitRef<'tcx> {
633 let defs = tcx.generics_of(trait_id);
634
635 ty::TraitRef {
636 def_id: trait_id,
637 substs: tcx.intern_substs(&substs[..defs.params.len()])
638 }
639 }
8bb4bdeb
XL
640}
641
e9174d1e
SL
642pub type PolyTraitRef<'tcx> = Binder<TraitRef<'tcx>>;
643
644impl<'tcx> PolyTraitRef<'tcx> {
645 pub fn self_ty(&self) -> Ty<'tcx> {
83c7162d 646 self.skip_binder().self_ty()
e9174d1e
SL
647 }
648
649 pub fn def_id(&self) -> DefId {
83c7162d 650 self.skip_binder().def_id
e9174d1e
SL
651 }
652
653 pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> {
654 // Note that we preserve binding levels
83c7162d 655 Binder(ty::TraitPredicate { trait_ref: self.skip_binder().clone() })
e9174d1e
SL
656 }
657}
658
9e0c209e
SL
659/// An existential reference to a trait, where `Self` is erased.
660/// For example, the trait object `Trait<'a, 'b, X, Y>` is:
661///
662/// exists T. T: Trait<'a, 'b, X, Y>
663///
664/// The substitutions don't include the erased `Self`, only trait
665/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
94b46f34 666#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
9e0c209e
SL
667pub struct ExistentialTraitRef<'tcx> {
668 pub def_id: DefId,
669 pub substs: &'tcx Substs<'tcx>,
670}
671
476ff2be
SL
672impl<'a, 'gcx, 'tcx> ExistentialTraitRef<'tcx> {
673 pub fn input_types<'b>(&'b self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'b {
9e0c209e
SL
674 // Select only the "input types" from a trait-reference. For
675 // now this is all the types that appear in the
676 // trait-reference, but it should eventually exclude
677 // associated types.
678 self.substs.types()
679 }
476ff2be 680
94b46f34
XL
681 pub fn erase_self_ty(tcx: TyCtxt<'a, 'gcx, 'tcx>,
682 trait_ref: ty::TraitRef<'tcx>)
683 -> ty::ExistentialTraitRef<'tcx> {
684 // Assert there is a Self.
685 trait_ref.substs.type_at(0);
686
687 ty::ExistentialTraitRef {
688 def_id: trait_ref.def_id,
689 substs: tcx.intern_substs(&trait_ref.substs[1..])
690 }
691 }
692
476ff2be
SL
693 /// Object types don't have a self-type specified. Therefore, when
694 /// we convert the principal trait-ref into a normal trait-ref,
695 /// you must give *some* self-type. A common choice is `mk_err()`
696 /// or some skolemized type.
697 pub fn with_self_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, self_ty: Ty<'tcx>)
698 -> ty::TraitRef<'tcx> {
699 // otherwise the escaping regions would be captured by the binder
700 assert!(!self_ty.has_escaping_regions());
701
702 ty::TraitRef {
703 def_id: self.def_id,
94b46f34 704 substs: tcx.mk_substs_trait(self_ty, self.substs)
476ff2be
SL
705 }
706 }
9e0c209e
SL
707}
708
709pub type PolyExistentialTraitRef<'tcx> = Binder<ExistentialTraitRef<'tcx>>;
710
711impl<'tcx> PolyExistentialTraitRef<'tcx> {
712 pub fn def_id(&self) -> DefId {
83c7162d 713 self.skip_binder().def_id
9e0c209e 714 }
94b46f34
XL
715
716 /// Object types don't have a self-type specified. Therefore, when
717 /// we convert the principal trait-ref into a normal trait-ref,
718 /// you must give *some* self-type. A common choice is `mk_err()`
719 /// or some skolemized type.
720 pub fn with_self_ty(&self, tcx: TyCtxt<'_, '_, 'tcx>,
721 self_ty: Ty<'tcx>)
722 -> ty::PolyTraitRef<'tcx> {
723 self.map_bound(|trait_ref| trait_ref.with_self_ty(tcx, self_ty))
724 }
9e0c209e
SL
725}
726
e9174d1e
SL
727/// Binder is a binder for higher-ranked lifetimes. It is part of the
728/// compiler's representation for things like `for<'a> Fn(&'a isize)`
729/// (which would be represented by the type `PolyTraitRef ==
730/// Binder<TraitRef>`). Note that when we skolemize, instantiate,
731/// erase, or otherwise "discharge" these bound regions, we change the
732/// type from `Binder<T>` to just `T` (see
733/// e.g. `liberate_late_bound_regions`).
94b46f34 734#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
83c7162d 735pub struct Binder<T>(T);
e9174d1e
SL
736
737impl<T> Binder<T> {
ff7c6d11
XL
738 /// Wraps `value` in a binder, asserting that `value` does not
739 /// contain any bound regions that would be bound by the
740 /// binder. This is commonly used to 'inject' a value T into a
741 /// different binding level.
742 pub fn dummy<'tcx>(value: T) -> Binder<T>
743 where T: TypeFoldable<'tcx>
744 {
745 assert!(!value.has_escaping_regions());
746 Binder(value)
747 }
748
83c7162d
XL
749 /// Wraps `value` in a binder, binding late-bound regions (if any).
750 pub fn bind<'tcx>(value: T) -> Binder<T>
751 {
752 Binder(value)
753 }
754
e9174d1e
SL
755 /// Skips the binder and returns the "bound" value. This is a
756 /// risky thing to do because it's easy to get confused about
757 /// debruijn indices and the like. It is usually better to
758 /// discharge the binder using `no_late_bound_regions` or
759 /// `replace_late_bound_regions` or something like
760 /// that. `skip_binder` is only valid when you are either
761 /// extracting data that has nothing to do with bound regions, you
762 /// are doing some sort of test that does not involve bound
763 /// regions, or you are being very careful about your depth
764 /// accounting.
765 ///
766 /// Some examples where `skip_binder` is reasonable:
ff7c6d11 767 ///
e9174d1e
SL
768 /// - extracting the def-id from a PolyTraitRef;
769 /// - comparing the self type of a PolyTraitRef to see if it is equal to
770 /// a type parameter `X`, since the type `X` does not reference any regions
771 pub fn skip_binder(&self) -> &T {
772 &self.0
773 }
774
775 pub fn as_ref(&self) -> Binder<&T> {
83c7162d 776 Binder(&self.0)
e9174d1e
SL
777 }
778
cc61c64b 779 pub fn map_bound_ref<F, U>(&self, f: F) -> Binder<U>
e9174d1e
SL
780 where F: FnOnce(&T) -> U
781 {
782 self.as_ref().map_bound(f)
783 }
784
cc61c64b 785 pub fn map_bound<F, U>(self, f: F) -> Binder<U>
e9174d1e
SL
786 where F: FnOnce(T) -> U
787 {
83c7162d 788 Binder(f(self.0))
e9174d1e 789 }
ff7c6d11
XL
790
791 /// Unwraps and returns the value within, but only if it contains
792 /// no bound regions at all. (In other words, if this binder --
793 /// and indeed any enclosing binder -- doesn't bind anything at
794 /// all.) Otherwise, returns `None`.
795 ///
796 /// (One could imagine having a method that just unwraps a single
797 /// binder, but permits late-bound regions bound by enclosing
798 /// binders, but that would require adjusting the debruijn
799 /// indices, and given the shallow binding structure we often use,
800 /// would not be that useful.)
801 pub fn no_late_bound_regions<'tcx>(self) -> Option<T>
802 where T : TypeFoldable<'tcx>
803 {
804 if self.skip_binder().has_escaping_regions() {
805 None
806 } else {
807 Some(self.skip_binder().clone())
808 }
809 }
810
811 /// Given two things that have the same binder level,
812 /// and an operation that wraps on their contents, execute the operation
813 /// and then wrap its result.
814 ///
815 /// `f` should consider bound regions at depth 1 to be free, and
816 /// anything it produces with bound regions at depth 1 will be
817 /// bound in the resulting return value.
818 pub fn fuse<U,F,R>(self, u: Binder<U>, f: F) -> Binder<R>
819 where F: FnOnce(T, U) -> R
820 {
83c7162d 821 Binder(f(self.0, u.0))
ff7c6d11
XL
822 }
823
824 /// Split the contents into two things that share the same binder
825 /// level as the original, returning two distinct binders.
826 ///
827 /// `f` should consider bound regions at depth 1 to be free, and
828 /// anything it produces with bound regions at depth 1 will be
829 /// bound in the resulting return values.
830 pub fn split<U,V,F>(self, f: F) -> (Binder<U>, Binder<V>)
831 where F: FnOnce(T) -> (U, V)
832 {
833 let (u, v) = f(self.0);
83c7162d 834 (Binder(u), Binder(v))
ff7c6d11 835 }
e9174d1e
SL
836}
837
e9174d1e
SL
838/// Represents the projection of an associated type. In explicit UFCS
839/// form this would be written `<T as Trait<..>>::N`.
94b46f34 840#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
e9174d1e 841pub struct ProjectionTy<'tcx> {
041b39d2
XL
842 /// The parameters of the associated item.
843 pub substs: &'tcx Substs<'tcx>,
e9174d1e 844
7cac9316
XL
845 /// The DefId of the TraitItem for the associated type N.
846 ///
847 /// Note that this is not the DefId of the TraitRef containing this
848 /// associated type, which is in tcx.associated_item(item_def_id).container.
849 pub item_def_id: DefId,
e9174d1e 850}
7cac9316
XL
851
852impl<'a, 'tcx> ProjectionTy<'tcx> {
853 /// Construct a ProjectionTy by searching the trait from trait_ref for the
854 /// associated item named item_name.
855 pub fn from_ref_and_name(
856 tcx: TyCtxt, trait_ref: ty::TraitRef<'tcx>, item_name: Name
857 ) -> ProjectionTy<'tcx> {
ea8adc8c
XL
858 let item_def_id = tcx.associated_items(trait_ref.def_id).find(|item| {
859 item.kind == ty::AssociatedKind::Type &&
860 tcx.hygienic_eq(item_name, item.name, trait_ref.def_id)
861 }).unwrap().def_id;
7cac9316
XL
862
863 ProjectionTy {
041b39d2
XL
864 substs: trait_ref.substs,
865 item_def_id,
7cac9316
XL
866 }
867 }
868
041b39d2
XL
869 /// Extracts the underlying trait reference from this projection.
870 /// For example, if this is a projection of `<T as Iterator>::Item`,
871 /// then this function would return a `T: Iterator` trait reference.
872 pub fn trait_ref(&self, tcx: TyCtxt) -> ty::TraitRef<'tcx> {
873 let def_id = tcx.associated_item(self.item_def_id).container.id();
874 ty::TraitRef {
3b2f2976 875 def_id,
041b39d2
XL
876 substs: self.substs,
877 }
878 }
879
880 pub fn self_ty(&self) -> Ty<'tcx> {
881 self.substs.type_at(0)
7cac9316
XL
882 }
883}
884
ea8adc8c
XL
885#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
886pub struct GenSig<'tcx> {
887 pub yield_ty: Ty<'tcx>,
888 pub return_ty: Ty<'tcx>,
889}
890
891pub type PolyGenSig<'tcx> = Binder<GenSig<'tcx>>;
892
893impl<'tcx> PolyGenSig<'tcx> {
894 pub fn yield_ty(&self) -> ty::Binder<Ty<'tcx>> {
895 self.map_bound_ref(|sig| sig.yield_ty)
896 }
897 pub fn return_ty(&self) -> ty::Binder<Ty<'tcx>> {
898 self.map_bound_ref(|sig| sig.return_ty)
899 }
900}
7cac9316 901
e9174d1e
SL
902/// Signature of a function type, which I have arbitrarily
903/// decided to use to refer to the input/output types.
904///
905/// - `inputs` is the list of arguments and their modes.
906/// - `output` is the return type.
907/// - `variadic` indicates whether this is a variadic function. (only true for foreign fns)
94b46f34 908#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
e9174d1e 909pub struct FnSig<'tcx> {
476ff2be 910 pub inputs_and_output: &'tcx Slice<Ty<'tcx>>,
8bb4bdeb
XL
911 pub variadic: bool,
912 pub unsafety: hir::Unsafety,
913 pub abi: abi::Abi,
e9174d1e
SL
914}
915
476ff2be 916impl<'tcx> FnSig<'tcx> {
8bb4bdeb 917 pub fn inputs(&self) -> &'tcx [Ty<'tcx>] {
476ff2be
SL
918 &self.inputs_and_output[..self.inputs_and_output.len() - 1]
919 }
920
921 pub fn output(&self) -> Ty<'tcx> {
922 self.inputs_and_output[self.inputs_and_output.len() - 1]
923 }
924}
925
e9174d1e
SL
926pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;
927
928impl<'tcx> PolyFnSig<'tcx> {
8bb4bdeb 929 pub fn inputs(&self) -> Binder<&'tcx [Ty<'tcx>]> {
83c7162d 930 self.map_bound_ref(|fn_sig| fn_sig.inputs())
e9174d1e
SL
931 }
932 pub fn input(&self, index: usize) -> ty::Binder<Ty<'tcx>> {
476ff2be 933 self.map_bound_ref(|fn_sig| fn_sig.inputs()[index])
e9174d1e 934 }
ff7c6d11
XL
935 pub fn inputs_and_output(&self) -> ty::Binder<&'tcx Slice<Ty<'tcx>>> {
936 self.map_bound_ref(|fn_sig| fn_sig.inputs_and_output)
937 }
5bcae85e 938 pub fn output(&self) -> ty::Binder<Ty<'tcx>> {
476ff2be 939 self.map_bound_ref(|fn_sig| fn_sig.output().clone())
e9174d1e
SL
940 }
941 pub fn variadic(&self) -> bool {
942 self.skip_binder().variadic
943 }
8bb4bdeb
XL
944 pub fn unsafety(&self) -> hir::Unsafety {
945 self.skip_binder().unsafety
946 }
947 pub fn abi(&self) -> abi::Abi {
948 self.skip_binder().abi
949 }
e9174d1e
SL
950}
951
94b46f34 952#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
e9174d1e 953pub struct ParamTy {
e9174d1e 954 pub idx: u32,
0531ce1d 955 pub name: InternedString,
e9174d1e
SL
956}
957
a7813a04 958impl<'a, 'gcx, 'tcx> ParamTy {
0531ce1d 959 pub fn new(index: u32, name: InternedString) -> ParamTy {
9e0c209e 960 ParamTy { idx: index, name: name }
e9174d1e
SL
961 }
962
963 pub fn for_self() -> ParamTy {
83c7162d 964 ParamTy::new(0, keywords::SelfType.name().as_interned_str())
e9174d1e
SL
965 }
966
94b46f34 967 pub fn for_def(def: &ty::GenericParamDef) -> ParamTy {
9e0c209e 968 ParamTy::new(def.index, def.name)
e9174d1e
SL
969 }
970
a7813a04 971 pub fn to_ty(self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
94b46f34 972 tcx.mk_ty_param(self.idx, self.name)
e9174d1e
SL
973 }
974
975 pub fn is_self(&self) -> bool {
0531ce1d
XL
976 // FIXME(#50125): Ignoring `Self` with `idx != 0` might lead to weird behavior elsewhere,
977 // but this should only be possible when using `-Z continue-parse-after-error` like
978 // `compile-fail/issue-36638.rs`.
979 if self.name == keywords::SelfType.name().as_str() && self.idx == 0 {
9e0c209e
SL
980 true
981 } else {
982 false
983 }
e9174d1e
SL
984 }
985}
986
987/// A [De Bruijn index][dbi] is a standard means of representing
988/// regions (and perhaps later types) in a higher-ranked setting. In
989/// particular, imagine a type like this:
990///
991/// for<'a> fn(for<'b> fn(&'b isize, &'a isize), &'a char)
992/// ^ ^ | | |
993/// | | | | |
94b46f34 994/// | +------------+ 0 | |
e9174d1e 995/// | | |
94b46f34 996/// +--------------------------------+ 1 |
e9174d1e 997/// | |
94b46f34 998/// +------------------------------------------+ 0
e9174d1e
SL
999///
1000/// In this type, there are two binders (the outer fn and the inner
1001/// fn). We need to be able to determine, for any given region, which
1002/// fn type it is bound by, the inner or the outer one. There are
1003/// various ways you can do this, but a De Bruijn index is one of the
1004/// more convenient and has some nice properties. The basic idea is to
1005/// count the number of binders, inside out. Some examples should help
1006/// clarify what I mean.
1007///
1008/// Let's start with the reference type `&'b isize` that is the first
1009/// argument to the inner function. This region `'b` is assigned a De
94b46f34 1010/// Bruijn index of 0, meaning "the innermost binder" (in this case, a
e9174d1e 1011/// fn). The region `'a` that appears in the second argument type (`&'a
94b46f34 1012/// isize`) would then be assigned a De Bruijn index of 1, meaning "the
e9174d1e
SL
1013/// second-innermost binder". (These indices are written on the arrays
1014/// in the diagram).
1015///
1016/// What is interesting is that De Bruijn index attached to a particular
1017/// variable will vary depending on where it appears. For example,
1018/// the final type `&'a char` also refers to the region `'a` declared on
1019/// the outermost fn. But this time, this reference is not nested within
1020/// any other binders (i.e., it is not an argument to the inner fn, but
1021/// rather the outer one). Therefore, in this case, it is assigned a
94b46f34 1022/// De Bruijn index of 0, because the innermost binder in that location
e9174d1e
SL
1023/// is the outer fn.
1024///
1025/// [dbi]: http://en.wikipedia.org/wiki/De_Bruijn_index
94b46f34
XL
1026newtype_index!(DebruijnIndex
1027 {
1028 DEBUG_FORMAT = "DebruijnIndex({})",
1029 const INNERMOST = 0,
1030 });
e9174d1e 1031
7cac9316
XL
1032pub type Region<'tcx> = &'tcx RegionKind;
1033
e9174d1e
SL
1034/// Representation of regions.
1035///
1036/// Unlike types, most region variants are "fictitious", not concrete,
1037/// regions. Among these, `ReStatic`, `ReEmpty` and `ReScope` are the only
1038/// ones representing concrete regions.
1039///
1040/// ## Bound Regions
1041///
1042/// These are regions that are stored behind a binder and must be substituted
1043/// with some concrete region before being used. There are 2 kind of
476ff2be 1044/// bound regions: early-bound, which are bound in an item's Generics,
e9174d1e
SL
1045/// and are substituted by a Substs, and late-bound, which are part of
1046/// higher-ranked types (e.g. `for<'a> fn(&'a ())`) and are substituted by
1047/// the likes of `liberate_late_bound_regions`. The distinction exists
1048/// because higher-ranked lifetimes aren't supported in all places. See [1][2].
1049///
1050/// Unlike TyParam-s, bound regions are not supposed to exist "in the wild"
1051/// outside their binder, e.g. in types passed to type inference, and
1052/// should first be substituted (by skolemized regions, free regions,
1053/// or region variables).
1054///
1055/// ## Skolemized and Free Regions
1056///
1057/// One often wants to work with bound regions without knowing their precise
1058/// identity. For example, when checking a function, the lifetime of a borrow
1059/// can end up being assigned to some region parameter. In these cases,
1060/// it must be ensured that bounds on the region can't be accidentally
1061/// assumed without being checked.
1062///
1063/// The process of doing that is called "skolemization". The bound regions
1064/// are replaced by skolemized markers, which don't satisfy any relation
3b2f2976 1065/// not explicitly provided.
e9174d1e
SL
1066///
1067/// There are 2 kinds of skolemized regions in rustc: `ReFree` and
1068/// `ReSkolemized`. When checking an item's body, `ReFree` is supposed
1069/// to be used. These also support explicit bounds: both the internally-stored
1070/// *scope*, which the region is assumed to outlive, as well as other
1071/// relations stored in the `FreeRegionMap`. Note that these relations
a7813a04 1072/// aren't checked when you `make_subregion` (or `eq_types`), only by
e9174d1e
SL
1073/// `resolve_regions_and_report_errors`.
1074///
1075/// When working with higher-ranked types, some region relations aren't
1076/// yet known, so you can't just call `resolve_regions_and_report_errors`.
1077/// `ReSkolemized` is designed for this purpose. In these contexts,
1078/// there's also the risk that some inference variable laying around will
1079/// get unified with your skolemized region: if you want to check whether
1080/// `for<'a> Foo<'_>: 'a`, and you substitute your bound region `'a`
1081/// with a skolemized region `'%a`, the variable `'_` would just be
1082/// instantiated to the skolemized region `'%a`, which is wrong because
1083/// the inference variable is supposed to satisfy the relation
1084/// *for every value of the skolemized region*. To ensure that doesn't
1085/// happen, you can use `leak_check`. This is more clearly explained
0531ce1d 1086/// by the [rustc guide].
e9174d1e 1087///
ff7c6d11
XL
1088/// [1]: http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
1089/// [2]: http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
0531ce1d 1090/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html
abe05a73 1091#[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable, PartialOrd, Ord)]
7cac9316 1092pub enum RegionKind {
e9174d1e
SL
1093 // Region bound in a type or fn declaration which will be
1094 // substituted 'early' -- that is, at the same time when type
1095 // parameters are substituted.
1096 ReEarlyBound(EarlyBoundRegion),
1097
1098 // Region bound in a function scope, which will be substituted when the
1099 // function is called.
1100 ReLateBound(DebruijnIndex, BoundRegion),
1101
1102 /// When checking a function body, the types of all arguments and so forth
1103 /// that refer to bound region parameters are modified to refer to free
1104 /// region parameters.
1105 ReFree(FreeRegion),
1106
ea8adc8c 1107 /// A concrete region naming some statically determined scope
e9174d1e
SL
1108 /// (e.g. an expression or sequence of statements) within the
1109 /// current function.
ea8adc8c 1110 ReScope(region::Scope),
e9174d1e
SL
1111
1112 /// Static data that has an "infinite" lifetime. Top in the region lattice.
1113 ReStatic,
1114
1115 /// A region variable. Should not exist after typeck.
1116 ReVar(RegionVid),
1117
1118 /// A skolemized region - basically the higher-ranked version of ReFree.
1119 /// Should not exist after typeck.
83c7162d 1120 ReSkolemized(ty::UniverseIndex, BoundRegion),
e9174d1e
SL
1121
1122 /// Empty lifetime is for data that is never accessed.
1123 /// Bottom in the region lattice. We treat ReEmpty somewhat
1124 /// specially; at least right now, we do not generate instances of
1125 /// it during the GLB computations, but rather
1126 /// generate an error instead. This is to improve error messages.
1127 /// The only way to get an instance of ReEmpty is to have a region
1128 /// variable with no constraints.
1129 ReEmpty,
3157f602 1130
94b46f34 1131 /// Erased region, used by trait selection, in MIR and during codegen.
3157f602 1132 ReErased,
ff7c6d11
XL
1133
1134 /// These are regions bound in the "defining type" for a
1135 /// closure. They are used ONLY as part of the
1136 /// `ClosureRegionRequirements` that are produced by MIR borrowck.
1137 /// See `ClosureRegionRequirements` for more details.
1138 ReClosureBound(RegionVid),
0531ce1d
XL
1139
1140 /// Canonicalized region, used only when preparing a trait query.
1141 ReCanonical(CanonicalVar),
e9174d1e
SL
1142}
1143
7cac9316 1144impl<'tcx> serialize::UseSpecializedDecodable for Region<'tcx> {}
9e0c209e 1145
abe05a73 1146#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, PartialOrd, Ord)]
e9174d1e 1147pub struct EarlyBoundRegion {
7cac9316 1148 pub def_id: DefId,
e9174d1e 1149 pub index: u32,
83c7162d 1150 pub name: InternedString,
e9174d1e
SL
1151}
1152
94b46f34 1153#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
e9174d1e 1154pub struct TyVid {
3157f602 1155 pub index: u32,
e9174d1e
SL
1156}
1157
94b46f34 1158#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
e9174d1e 1159pub struct IntVid {
cc61c64b 1160 pub index: u32,
e9174d1e
SL
1161}
1162
94b46f34 1163#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
e9174d1e 1164pub struct FloatVid {
cc61c64b 1165 pub index: u32,
e9174d1e
SL
1166}
1167
ff7c6d11
XL
1168newtype_index!(RegionVid
1169 {
1170 pub idx
1171 DEBUG_FORMAT = custom,
1172 });
abe05a73 1173
94b46f34
XL
1174impl Atom for RegionVid {
1175 fn index(self) -> usize {
1176 Idx::index(self)
1177 }
1178}
1179
1180impl From<usize> for RegionVid {
1181 fn from(i: usize) -> RegionVid {
1182 RegionVid::new(i)
1183 }
1184}
1185
1186impl From<RegionVid> for usize {
1187 fn from(vid: RegionVid) -> usize {
1188 Idx::index(vid)
1189 }
1190}
1191
1192#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
e9174d1e
SL
1193pub enum InferTy {
1194 TyVar(TyVid),
1195 IntVar(IntVid),
1196 FloatVar(FloatVid),
1197
1198 /// A `FreshTy` is one that is generated as a replacement for an
1199 /// unbound type variable. This is convenient for caching etc. See
54a0048b 1200 /// `infer::freshen` for more details.
e9174d1e
SL
1201 FreshTy(u32),
1202 FreshIntTy(u32),
cc61c64b 1203 FreshFloatTy(u32),
0531ce1d
XL
1204
1205 /// Canonicalized type variable, used only when preparing a trait query.
1206 CanonicalTy(CanonicalVar),
e9174d1e
SL
1207}
1208
0531ce1d
XL
1209newtype_index!(CanonicalVar);
1210
9e0c209e 1211/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
94b46f34 1212#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
9e0c209e 1213pub struct ExistentialProjection<'tcx> {
041b39d2
XL
1214 pub item_def_id: DefId,
1215 pub substs: &'tcx Substs<'tcx>,
cc61c64b 1216 pub ty: Ty<'tcx>,
e9174d1e
SL
1217}
1218
9e0c209e
SL
1219pub type PolyExistentialProjection<'tcx> = Binder<ExistentialProjection<'tcx>>;
1220
476ff2be 1221impl<'a, 'tcx, 'gcx> ExistentialProjection<'tcx> {
041b39d2
XL
1222 /// Extracts the underlying existential trait reference from this projection.
1223 /// For example, if this is a projection of `exists T. <T as Iterator>::Item == X`,
1224 /// then this function would return a `exists T. T: Iterator` existential trait
1225 /// reference.
1226 pub fn trait_ref(&self, tcx: TyCtxt) -> ty::ExistentialTraitRef<'tcx> {
1227 let def_id = tcx.associated_item(self.item_def_id).container.id();
1228 ty::ExistentialTraitRef{
3b2f2976 1229 def_id,
041b39d2
XL
1230 substs: self.substs,
1231 }
9e0c209e
SL
1232 }
1233
1234 pub fn with_self_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
1235 self_ty: Ty<'tcx>)
476ff2be 1236 -> ty::ProjectionPredicate<'tcx>
9e0c209e
SL
1237 {
1238 // otherwise the escaping regions would be captured by the binders
1239 assert!(!self_ty.has_escaping_regions());
1240
476ff2be 1241 ty::ProjectionPredicate {
041b39d2
XL
1242 projection_ty: ty::ProjectionTy {
1243 item_def_id: self.item_def_id,
94b46f34 1244 substs: tcx.mk_substs_trait(self_ty, self.substs),
041b39d2 1245 },
cc61c64b 1246 ty: self.ty,
476ff2be 1247 }
e9174d1e
SL
1248 }
1249}
1250
476ff2be 1251impl<'a, 'tcx, 'gcx> PolyExistentialProjection<'tcx> {
476ff2be
SL
1252 pub fn with_self_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, self_ty: Ty<'tcx>)
1253 -> ty::PolyProjectionPredicate<'tcx> {
1254 self.map_bound(|p| p.with_self_ty(tcx, self_ty))
e9174d1e 1255 }
83c7162d
XL
1256
1257 pub fn item_def_id(&self) -> DefId {
1258 return self.skip_binder().item_def_id;
1259 }
e9174d1e
SL
1260}
1261
1262impl DebruijnIndex {
94b46f34
XL
1263 /// Returns the resulting index when this value is moved into
1264 /// `amount` number of new binders. So e.g. if you had
1265 ///
1266 /// for<'a> fn(&'a x)
1267 ///
1268 /// and you wanted to change to
1269 ///
1270 /// for<'a> fn(for<'b> fn(&'a x))
1271 ///
1272 /// you would need to shift the index for `'a` into 1 new binder.
1273 #[must_use]
1274 pub const fn shifted_in(self, amount: u32) -> DebruijnIndex {
1275 DebruijnIndex(self.0 + amount)
1276 }
1277
1278 /// Update this index in place by shifting it "in" through
1279 /// `amount` number of binders.
1280 pub fn shift_in(&mut self, amount: u32) {
1281 *self = self.shifted_in(amount);
e9174d1e
SL
1282 }
1283
94b46f34
XL
1284 /// Returns the resulting index when this value is moved out from
1285 /// `amount` number of new binders.
1286 #[must_use]
1287 pub const fn shifted_out(self, amount: u32) -> DebruijnIndex {
1288 DebruijnIndex(self.0 - amount)
1289 }
1290
1291 /// Update in place by shifting out from `amount` binders.
1292 pub fn shift_out(&mut self, amount: u32) {
1293 *self = self.shifted_out(amount);
1294 }
1295
1296 /// Adjusts any Debruijn Indices so as to make `to_binder` the
1297 /// innermost binder. That is, if we have something bound at `to_binder`,
1298 /// it will now be bound at INNERMOST. This is an appropriate thing to do
1299 /// when moving a region out from inside binders:
1300 ///
1301 /// ```
1302 /// for<'a> fn(for<'b> for<'c> fn(&'a u32), _)
1303 /// // Binder: D3 D2 D1 ^^
1304 /// ```
1305 ///
1306 /// Here, the region `'a` would have the debruijn index D3,
1307 /// because it is the bound 3 binders out. However, if we wanted
1308 /// to refer to that region `'a` in the second argument (the `_`),
1309 /// those two binders would not be in scope. In that case, we
1310 /// might invoke `shift_out_to_binder(D3)`. This would adjust the
1311 /// debruijn index of `'a` to D1 (the innermost binder).
1312 ///
1313 /// If we invoke `shift_out_to_binder` and the region is in fact
1314 /// bound by one of the binders we are shifting out of, that is an
1315 /// error (and should fail an assertion failure).
1316 pub fn shifted_out_to_binder(self, to_binder: DebruijnIndex) -> Self {
1317 self.shifted_out((to_binder.0 - INNERMOST.0) as u32)
e9174d1e
SL
1318 }
1319}
1320
94b46f34
XL
1321impl_stable_hash_for!(tuple_struct DebruijnIndex { index });
1322
7cac9316
XL
1323/// Region utilities
1324impl RegionKind {
1325 pub fn is_late_bound(&self) -> bool {
e9174d1e 1326 match *self {
e9174d1e 1327 ty::ReLateBound(..) => true,
cc61c64b 1328 _ => false,
e9174d1e
SL
1329 }
1330 }
1331
94b46f34 1332 pub fn bound_at_or_above_binder(&self, index: DebruijnIndex) -> bool {
e9174d1e 1333 match *self {
94b46f34 1334 ty::ReLateBound(debruijn, _) => debruijn >= index,
e9174d1e
SL
1335 _ => false,
1336 }
1337 }
1338
94b46f34
XL
1339 /// Adjusts any Debruijn Indices so as to make `to_binder` the
1340 /// innermost binder. That is, if we have something bound at `to_binder`,
1341 /// it will now be bound at INNERMOST. This is an appropriate thing to do
1342 /// when moving a region out from inside binders:
1343 ///
1344 /// ```
1345 /// for<'a> fn(for<'b> for<'c> fn(&'a u32), _)
1346 /// // Binder: D3 D2 D1 ^^
1347 /// ```
1348 ///
1349 /// Here, the region `'a` would have the debruijn index D3,
1350 /// because it is the bound 3 binders out. However, if we wanted
1351 /// to refer to that region `'a` in the second argument (the `_`),
1352 /// those two binders would not be in scope. In that case, we
1353 /// might invoke `shift_out_to_binder(D3)`. This would adjust the
1354 /// debruijn index of `'a` to D1 (the innermost binder).
1355 ///
1356 /// If we invoke `shift_out_to_binder` and the region is in fact
1357 /// bound by one of the binders we are shifting out of, that is an
1358 /// error (and should fail an assertion failure).
1359 pub fn shifted_out_to_binder(&self, to_binder: ty::DebruijnIndex) -> RegionKind {
e9174d1e 1360 match *self {
94b46f34
XL
1361 ty::ReLateBound(debruijn, r) => ty::ReLateBound(
1362 debruijn.shifted_out_to_binder(to_binder),
1363 r,
1364 ),
e9174d1e
SL
1365 r => r
1366 }
1367 }
c30ab7b3 1368
83c7162d
XL
1369 pub fn keep_in_local_tcx(&self) -> bool {
1370 if let ty::ReVar(..) = self {
1371 true
1372 } else {
1373 false
1374 }
1375 }
1376
c30ab7b3
SL
1377 pub fn type_flags(&self) -> TypeFlags {
1378 let mut flags = TypeFlags::empty();
1379
83c7162d
XL
1380 if self.keep_in_local_tcx() {
1381 flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
1382 }
1383
c30ab7b3
SL
1384 match *self {
1385 ty::ReVar(..) => {
ff7c6d11 1386 flags = flags | TypeFlags::HAS_FREE_REGIONS;
c30ab7b3 1387 flags = flags | TypeFlags::HAS_RE_INFER;
c30ab7b3
SL
1388 }
1389 ty::ReSkolemized(..) => {
ff7c6d11 1390 flags = flags | TypeFlags::HAS_FREE_REGIONS;
c30ab7b3 1391 flags = flags | TypeFlags::HAS_RE_SKOL;
c30ab7b3 1392 }
94b46f34
XL
1393 ty::ReLateBound(..) => {
1394 flags = flags | TypeFlags::HAS_RE_LATE_BOUND;
1395 }
ff7c6d11
XL
1396 ty::ReEarlyBound(..) => {
1397 flags = flags | TypeFlags::HAS_FREE_REGIONS;
1398 flags = flags | TypeFlags::HAS_RE_EARLY_BOUND;
1399 }
1400 ty::ReEmpty |
1401 ty::ReStatic |
1402 ty::ReFree { .. } |
1403 ty::ReScope { .. } => {
1404 flags = flags | TypeFlags::HAS_FREE_REGIONS;
1405 }
1406 ty::ReErased => {
1407 }
0531ce1d
XL
1408 ty::ReCanonical(..) => {
1409 flags = flags | TypeFlags::HAS_FREE_REGIONS;
1410 flags = flags | TypeFlags::HAS_CANONICAL_VARS;
1411 }
ff7c6d11
XL
1412 ty::ReClosureBound(..) => {
1413 flags = flags | TypeFlags::HAS_FREE_REGIONS;
1414 }
c30ab7b3
SL
1415 }
1416
1417 match *self {
94b46f34
XL
1418 ty::ReStatic | ty::ReEmpty | ty::ReErased | ty::ReLateBound(..) => (),
1419 _ => flags = flags | TypeFlags::HAS_FREE_LOCAL_NAMES,
c30ab7b3
SL
1420 }
1421
1422 debug!("type_flags({:?}) = {:?}", self, flags);
1423
1424 flags
1425 }
abe05a73
XL
1426
1427 /// Given an early-bound or free region, returns the def-id where it was bound.
1428 /// For example, consider the regions in this snippet of code:
1429 ///
1430 /// ```
1431 /// impl<'a> Foo {
1432 /// ^^ -- early bound, declared on an impl
1433 ///
1434 /// fn bar<'b, 'c>(x: &self, y: &'b u32, z: &'c u64) where 'static: 'c
1435 /// ^^ ^^ ^ anonymous, late-bound
1436 /// | early-bound, appears in where-clauses
1437 /// late-bound, appears only in fn args
1438 /// {..}
1439 /// }
1440 /// ```
1441 ///
1442 /// Here, `free_region_binding_scope('a)` would return the def-id
1443 /// of the impl, and for all the other highlighted regions, it
1444 /// would return the def-id of the function. In other cases (not shown), this
1445 /// function might return the def-id of a closure.
1446 pub fn free_region_binding_scope(&self, tcx: TyCtxt<'_, '_, '_>) -> DefId {
1447 match self {
1448 ty::ReEarlyBound(br) => {
1449 tcx.parent_def_id(br.def_id).unwrap()
1450 }
1451 ty::ReFree(fr) => fr.scope,
1452 _ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self),
1453 }
1454 }
e9174d1e
SL
1455}
1456
7cac9316 1457/// Type utilities
a7813a04 1458impl<'a, 'gcx, 'tcx> TyS<'tcx> {
e9174d1e
SL
1459 pub fn is_nil(&self) -> bool {
1460 match self.sty {
0531ce1d 1461 TyTuple(ref tys) => tys.is_empty(),
cc61c64b 1462 _ => false,
e9174d1e
SL
1463 }
1464 }
1465
5bcae85e
SL
1466 pub fn is_never(&self) -> bool {
1467 match self.sty {
1468 TyNever => true,
1469 _ => false,
1470 }
1471 }
1472
0531ce1d 1473 pub fn is_primitive(&self) -> bool {
8bb4bdeb 1474 match self.sty {
0531ce1d 1475 TyBool | TyChar | TyInt(_) | TyUint(_) | TyFloat(_) => true,
8bb4bdeb
XL
1476 _ => false,
1477 }
1478 }
1479
0531ce1d 1480 pub fn is_ty_var(&self) -> bool {
9cc50fc6 1481 match self.sty {
0531ce1d 1482 TyInfer(TyVar(_)) => true,
9cc50fc6
SL
1483 _ => false,
1484 }
1485 }
1486
0531ce1d 1487 pub fn is_ty_infer(&self) -> bool {
e9174d1e 1488 match self.sty {
0531ce1d 1489 TyInfer(_) => true,
cc61c64b 1490 _ => false,
e9174d1e
SL
1491 }
1492 }
1493
b039eaaf 1494 pub fn is_phantom_data(&self) -> bool {
9e0c209e 1495 if let TyAdt(def, _) = self.sty {
b039eaaf
SL
1496 def.is_phantom_data()
1497 } else {
1498 false
1499 }
1500 }
1501
e9174d1e
SL
1502 pub fn is_bool(&self) -> bool { self.sty == TyBool }
1503
9e0c209e 1504 pub fn is_param(&self, index: u32) -> bool {
e9174d1e 1505 match self.sty {
9e0c209e 1506 ty::TyParam(ref data) => data.idx == index,
e9174d1e
SL
1507 _ => false,
1508 }
1509 }
1510
1511 pub fn is_self(&self) -> bool {
1512 match self.sty {
9e0c209e 1513 TyParam(ref p) => p.is_self(),
cc61c64b 1514 _ => false,
e9174d1e
SL
1515 }
1516 }
1517
54a0048b 1518 pub fn is_slice(&self) -> bool {
e9174d1e 1519 match self.sty {
94b46f34 1520 TyRawPtr(TypeAndMut { ty, .. }) | TyRef(_, ty, _) => match ty.sty {
e9174d1e
SL
1521 TySlice(_) | TyStr => true,
1522 _ => false,
1523 },
1524 _ => false
1525 }
1526 }
1527
e9174d1e
SL
1528 #[inline]
1529 pub fn is_simd(&self) -> bool {
1530 match self.sty {
cc61c64b
XL
1531 TyAdt(def, _) => def.repr.simd(),
1532 _ => false,
e9174d1e
SL
1533 }
1534 }
1535
a7813a04 1536 pub fn sequence_element_type(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
e9174d1e
SL
1537 match self.sty {
1538 TyArray(ty, _) | TySlice(ty) => ty,
a7813a04 1539 TyStr => tcx.mk_mach_uint(ast::UintTy::U8),
54a0048b 1540 _ => bug!("sequence_element_type called on non-sequence value: {}", self),
e9174d1e
SL
1541 }
1542 }
1543
a7813a04 1544 pub fn simd_type(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
e9174d1e 1545 match self.sty {
9e0c209e 1546 TyAdt(def, substs) => {
2c00a5a8 1547 def.non_enum_variant().fields[0].ty(tcx, substs)
e9174d1e 1548 }
54a0048b 1549 _ => bug!("simd_type called on invalid type")
e9174d1e
SL
1550 }
1551 }
1552
a7813a04 1553 pub fn simd_size(&self, _cx: TyCtxt) -> usize {
e9174d1e 1554 match self.sty {
2c00a5a8 1555 TyAdt(def, _) => def.non_enum_variant().fields.len(),
54a0048b 1556 _ => bug!("simd_size called on invalid type")
e9174d1e
SL
1557 }
1558 }
1559
1560 pub fn is_region_ptr(&self) -> bool {
1561 match self.sty {
1562 TyRef(..) => true,
cc61c64b 1563 _ => false,
e9174d1e
SL
1564 }
1565 }
1566
32a655c1
SL
1567 pub fn is_mutable_pointer(&self) -> bool {
1568 match self.sty {
94b46f34
XL
1569 TyRawPtr(TypeAndMut { mutbl: hir::Mutability::MutMutable, .. }) |
1570 TyRef(_, _, hir::Mutability::MutMutable) => true,
32a655c1
SL
1571 _ => false
1572 }
1573 }
1574
e9174d1e
SL
1575 pub fn is_unsafe_ptr(&self) -> bool {
1576 match self.sty {
1577 TyRawPtr(_) => return true,
cc61c64b 1578 _ => return false,
e9174d1e
SL
1579 }
1580 }
1581
32a655c1 1582 pub fn is_box(&self) -> bool {
e9174d1e 1583 match self.sty {
32a655c1
SL
1584 TyAdt(def, _) => def.is_box(),
1585 _ => false,
1586 }
1587 }
1588
7cac9316 1589 /// panics if called on any type other than `Box<T>`
32a655c1
SL
1590 pub fn boxed_ty(&self) -> Ty<'tcx> {
1591 match self.sty {
1592 TyAdt(def, substs) if def.is_box() => substs.type_at(0),
1593 _ => bug!("`boxed_ty` is called on non-box type {:?}", self),
e9174d1e
SL
1594 }
1595 }
1596
7cac9316
XL
1597 /// A scalar type is one that denotes an atomic datum, with no sub-components.
1598 /// (A TyRawPtr is scalar because it represents a non-managed pointer, so its
1599 /// contents are abstract to rustc.)
e9174d1e
SL
1600 pub fn is_scalar(&self) -> bool {
1601 match self.sty {
1602 TyBool | TyChar | TyInt(_) | TyFloat(_) | TyUint(_) |
1603 TyInfer(IntVar(_)) | TyInfer(FloatVar(_)) |
54a0048b 1604 TyFnDef(..) | TyFnPtr(_) | TyRawPtr(_) => true,
e9174d1e
SL
1605 _ => false
1606 }
1607 }
1608
1609 /// Returns true if this type is a floating point type and false otherwise.
1610 pub fn is_floating_point(&self) -> bool {
1611 match self.sty {
1612 TyFloat(_) |
1613 TyInfer(FloatVar(_)) => true,
1614 _ => false,
1615 }
1616 }
1617
1618 pub fn is_trait(&self) -> bool {
1619 match self.sty {
476ff2be 1620 TyDynamic(..) => true,
cc61c64b 1621 _ => false,
e9174d1e
SL
1622 }
1623 }
1624
ff7c6d11
XL
1625 pub fn is_enum(&self) -> bool {
1626 match self.sty {
1627 TyAdt(adt_def, _) => {
1628 adt_def.is_enum()
1629 }
1630 _ => false,
1631 }
1632 }
1633
7cac9316
XL
1634 pub fn is_closure(&self) -> bool {
1635 match self.sty {
1636 TyClosure(..) => true,
1637 _ => false,
1638 }
1639 }
1640
ff7c6d11
XL
1641 pub fn is_generator(&self) -> bool {
1642 match self.sty {
1643 TyGenerator(..) => true,
1644 _ => false,
1645 }
1646 }
1647
e9174d1e
SL
1648 pub fn is_integral(&self) -> bool {
1649 match self.sty {
1650 TyInfer(IntVar(_)) | TyInt(_) | TyUint(_) => true,
1651 _ => false
1652 }
1653 }
1654
ff7c6d11
XL
1655 pub fn is_fresh_ty(&self) -> bool {
1656 match self.sty {
1657 TyInfer(FreshTy(_)) => true,
1658 _ => false,
1659 }
1660 }
1661
e9174d1e
SL
1662 pub fn is_fresh(&self) -> bool {
1663 match self.sty {
1664 TyInfer(FreshTy(_)) => true,
1665 TyInfer(FreshIntTy(_)) => true,
1666 TyInfer(FreshFloatTy(_)) => true,
cc61c64b 1667 _ => false,
e9174d1e
SL
1668 }
1669 }
1670
e9174d1e
SL
1671 pub fn is_char(&self) -> bool {
1672 match self.sty {
1673 TyChar => true,
cc61c64b 1674 _ => false,
e9174d1e
SL
1675 }
1676 }
1677
e9174d1e
SL
1678 pub fn is_fp(&self) -> bool {
1679 match self.sty {
1680 TyInfer(FloatVar(_)) | TyFloat(_) => true,
1681 _ => false
1682 }
1683 }
1684
1685 pub fn is_numeric(&self) -> bool {
1686 self.is_integral() || self.is_fp()
1687 }
1688
1689 pub fn is_signed(&self) -> bool {
1690 match self.sty {
1691 TyInt(_) => true,
cc61c64b 1692 _ => false,
e9174d1e
SL
1693 }
1694 }
1695
1696 pub fn is_machine(&self) -> bool {
1697 match self.sty {
2c00a5a8 1698 TyInt(ast::IntTy::Isize) | TyUint(ast::UintTy::Usize) => false,
e9174d1e 1699 TyInt(..) | TyUint(..) | TyFloat(..) => true,
cc61c64b 1700 _ => false,
e9174d1e
SL
1701 }
1702 }
1703
54a0048b
SL
1704 pub fn has_concrete_skeleton(&self) -> bool {
1705 match self.sty {
1706 TyParam(_) | TyInfer(_) | TyError => false,
1707 _ => true,
1708 }
1709 }
1710
7cac9316
XL
1711 /// Returns the type and mutability of *ty.
1712 ///
1713 /// The parameter `explicit` indicates if this is an *explicit* dereference.
1714 /// Some types---notably unsafe ptrs---can only be dereferenced explicitly.
2c00a5a8 1715 pub fn builtin_deref(&self, explicit: bool) -> Option<TypeAndMut<'tcx>> {
e9174d1e 1716 match self.sty {
32a655c1 1717 TyAdt(def, _) if def.is_box() => {
e9174d1e 1718 Some(TypeAndMut {
32a655c1 1719 ty: self.boxed_ty(),
2c00a5a8 1720 mutbl: hir::MutImmutable,
e9174d1e
SL
1721 })
1722 },
94b46f34 1723 TyRef(_, ty, mutbl) => Some(TypeAndMut { ty, mutbl }),
e9174d1e 1724 TyRawPtr(mt) if explicit => Some(mt),
cc61c64b 1725 _ => None,
e9174d1e
SL
1726 }
1727 }
1728
83c7162d 1729 /// Returns the type of `ty[i]`.
e9174d1e
SL
1730 pub fn builtin_index(&self) -> Option<Ty<'tcx>> {
1731 match self.sty {
1732 TyArray(ty, _) | TySlice(ty) => Some(ty),
cc61c64b 1733 _ => None,
e9174d1e
SL
1734 }
1735 }
1736
041b39d2 1737 pub fn fn_sig(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> PolyFnSig<'tcx> {
e9174d1e 1738 match self.sty {
041b39d2
XL
1739 TyFnDef(def_id, substs) => {
1740 tcx.fn_sig(def_id).subst(tcx, substs)
1741 }
1742 TyFnPtr(f) => f,
54a0048b 1743 _ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self)
e9174d1e
SL
1744 }
1745 }
1746
e9174d1e
SL
1747 pub fn is_fn(&self) -> bool {
1748 match self.sty {
54a0048b 1749 TyFnDef(..) | TyFnPtr(_) => true,
cc61c64b 1750 _ => false,
e9174d1e
SL
1751 }
1752 }
1753
1754 pub fn ty_to_def_id(&self) -> Option<DefId> {
1755 match self.sty {
476ff2be 1756 TyDynamic(ref tt, ..) => tt.principal().map(|p| p.def_id()),
9e0c209e 1757 TyAdt(def, _) => Some(def.did),
abe05a73 1758 TyForeign(did) => Some(did),
e9174d1e 1759 TyClosure(id, _) => Some(id),
ff7c6d11 1760 TyFnDef(id, _) => Some(id),
cc61c64b 1761 _ => None,
e9174d1e
SL
1762 }
1763 }
1764
476ff2be 1765 pub fn ty_adt_def(&self) -> Option<&'tcx AdtDef> {
e9174d1e 1766 match self.sty {
9e0c209e 1767 TyAdt(adt, _) => Some(adt),
cc61c64b 1768 _ => None,
e9174d1e
SL
1769 }
1770 }
1771
1772 /// Returns the regions directly referenced from this type (but
1773 /// not types reachable from this type via `walk_tys`). This
1774 /// ignores late-bound regions binders.
7cac9316 1775 pub fn regions(&self) -> Vec<ty::Region<'tcx>> {
e9174d1e 1776 match self.sty {
94b46f34 1777 TyRef(region, _, _) => {
9e0c209e 1778 vec![region]
e9174d1e 1779 }
476ff2be
SL
1780 TyDynamic(ref obj, region) => {
1781 let mut v = vec![region];
1782 if let Some(p) = obj.principal() {
1783 v.extend(p.skip_binder().substs.regions());
1784 }
e9174d1e
SL
1785 v
1786 }
9e0c209e
SL
1787 TyAdt(_, substs) | TyAnon(_, substs) => {
1788 substs.regions().collect()
e9174d1e 1789 }
94b46f34
XL
1790 TyClosure(_, ClosureSubsts { ref substs }) |
1791 TyGenerator(_, GeneratorSubsts { ref substs }, _) => {
1792 substs.regions().collect()
e9174d1e
SL
1793 }
1794 TyProjection(ref data) => {
041b39d2 1795 data.substs.regions().collect()
e9174d1e 1796 }
54a0048b
SL
1797 TyFnDef(..) |
1798 TyFnPtr(_) |
2c00a5a8 1799 TyGeneratorWitness(..) |
e9174d1e
SL
1800 TyBool |
1801 TyChar |
1802 TyInt(_) |
1803 TyUint(_) |
1804 TyFloat(_) |
e9174d1e 1805 TyStr |
9e0c209e 1806 TyArray(..) |
e9174d1e
SL
1807 TySlice(_) |
1808 TyRawPtr(_) |
5bcae85e 1809 TyNever |
8bb4bdeb 1810 TyTuple(..) |
abe05a73 1811 TyForeign(..) |
e9174d1e
SL
1812 TyParam(_) |
1813 TyInfer(_) |
1814 TyError => {
1815 vec![]
1816 }
1817 }
1818 }
ff7c6d11
XL
1819
1820 /// When we create a closure, we record its kind (i.e., what trait
1821 /// it implements) into its `ClosureSubsts` using a type
1822 /// parameter. This is kind of a phantom type, except that the
1823 /// most convenient thing for us to are the integral types. This
1824 /// function converts such a special type into the closure
1825 /// kind. To go the other way, use
1826 /// `tcx.closure_kind_ty(closure_kind)`.
1827 ///
1828 /// Note that during type checking, we use an inference variable
1829 /// to represent the closure kind, because it has not yet been
1830 /// inferred. Once upvar inference (in `src/librustc_typeck/check/upvar.rs`)
1831 /// is complete, that type variable will be unified.
1832 pub fn to_opt_closure_kind(&self) -> Option<ty::ClosureKind> {
1833 match self.sty {
1834 TyInt(int_ty) => match int_ty {
1835 ast::IntTy::I8 => Some(ty::ClosureKind::Fn),
1836 ast::IntTy::I16 => Some(ty::ClosureKind::FnMut),
1837 ast::IntTy::I32 => Some(ty::ClosureKind::FnOnce),
1838 _ => bug!("cannot convert type `{:?}` to a closure kind", self),
1839 },
1840
1841 TyInfer(_) => None,
1842
1843 TyError => Some(ty::ClosureKind::Fn),
1844
1845 _ => bug!("cannot convert type `{:?}` to a closure kind", self),
1846 }
1847 }
e9174d1e 1848}
ea8adc8c
XL
1849
1850/// Typed constant value.
94b46f34 1851#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)]
ea8adc8c
XL
1852pub struct Const<'tcx> {
1853 pub ty: Ty<'tcx>,
1854
ea8adc8c
XL
1855 pub val: ConstVal<'tcx>,
1856}
1857
94b46f34
XL
1858impl<'tcx> Const<'tcx> {
1859 pub fn unevaluated(
1860 tcx: TyCtxt<'_, '_, 'tcx>,
1861 def_id: DefId,
1862 substs: &'tcx Substs<'tcx>,
1863 ty: Ty<'tcx>,
1864 ) -> &'tcx Self {
1865 tcx.mk_const(Const {
1866 val: ConstVal::Unevaluated(def_id, substs),
1867 ty,
1868 })
1869 }
1870
1871 #[inline]
1872 pub fn from_const_val(
1873 tcx: TyCtxt<'_, '_, 'tcx>,
1874 val: ConstVal<'tcx>,
1875 ty: Ty<'tcx>,
1876 ) -> &'tcx Self {
1877 tcx.mk_const(Const {
1878 val,
1879 ty,
1880 })
1881 }
1882
1883 #[inline]
1884 pub fn from_const_value(
1885 tcx: TyCtxt<'_, '_, 'tcx>,
1886 val: ConstValue<'tcx>,
1887 ty: Ty<'tcx>,
1888 ) -> &'tcx Self {
1889 Self::from_const_val(tcx, ConstVal::Value(val), ty)
1890 }
1891
1892 #[inline]
1893 pub fn from_byval_value(
1894 tcx: TyCtxt<'_, '_, 'tcx>,
1895 val: Value,
1896 ty: Ty<'tcx>,
1897 ) -> &'tcx Self {
1898 Self::from_const_value(tcx, ConstValue::from_byval_value(val), ty)
1899 }
1900
1901 #[inline]
1902 pub fn from_scalar(
1903 tcx: TyCtxt<'_, '_, 'tcx>,
1904 val: Scalar,
1905 ty: Ty<'tcx>,
1906 ) -> &'tcx Self {
1907 Self::from_const_value(tcx, ConstValue::from_scalar(val), ty)
1908 }
1909
1910 #[inline]
1911 pub fn from_bits(
1912 tcx: TyCtxt<'_, '_, 'tcx>,
1913 bits: u128,
1914 ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
1915 ) -> &'tcx Self {
1916 let ty = tcx.lift_to_global(&ty).unwrap();
1917 let size = tcx.layout_of(ty).unwrap_or_else(|e| {
1918 panic!("could not compute layout for {:?}: {:?}", ty, e)
1919 }).size;
1920 let shift = 128 - size.bits();
1921 let truncated = (bits << shift) >> shift;
1922 assert_eq!(truncated, bits, "from_bits called with untruncated value");
1923 Self::from_scalar(tcx, Scalar::Bits { bits, defined: size.bits() as u8 }, ty.value)
1924 }
1925
1926 #[inline]
1927 pub fn zero_sized(tcx: TyCtxt<'_, '_, 'tcx>, ty: Ty<'tcx>) -> &'tcx Self {
1928 Self::from_scalar(tcx, Scalar::undef(), ty)
1929 }
1930
1931 #[inline]
1932 pub fn from_bool(tcx: TyCtxt<'_, '_, 'tcx>, v: bool) -> &'tcx Self {
1933 Self::from_bits(tcx, v as u128, ParamEnv::empty().and(tcx.types.bool))
1934 }
1935
1936 #[inline]
1937 pub fn from_usize(tcx: TyCtxt<'_, '_, 'tcx>, n: u64) -> &'tcx Self {
1938 Self::from_bits(tcx, n as u128, ParamEnv::empty().and(tcx.types.usize))
1939 }
1940
1941 #[inline]
1942 pub fn to_bits(
1943 &self,
1944 tcx: TyCtxt<'_, '_, 'tcx>,
1945 ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
1946 ) -> Option<u128> {
1947 if self.ty != ty.value {
1948 return None;
1949 }
1950 let ty = tcx.lift_to_global(&ty).unwrap();
1951 let size = tcx.layout_of(ty).ok()?.size;
1952 match self.val {
1953 ConstVal::Value(val) => val.to_bits(size),
1954 _ => None,
1955 }
1956 }
1957
1958 #[inline]
1959 pub fn to_ptr(&self) -> Option<Pointer> {
1960 match self.val {
1961 ConstVal::Value(val) => val.to_ptr(),
1962 _ => None,
1963 }
1964 }
1965
1966 #[inline]
1967 pub fn to_byval_value(&self) -> Option<Value> {
1968 match self.val {
1969 ConstVal::Value(val) => val.to_byval_value(),
1970 _ => None,
1971 }
1972 }
1973
1974 #[inline]
1975 pub fn to_scalar(&self) -> Option<Scalar> {
1976 match self.val {
1977 ConstVal::Value(val) => val.to_scalar(),
1978 _ => None,
1979 }
1980 }
1981
1982 #[inline]
1983 pub fn assert_bits(
1984 &self,
1985 tcx: TyCtxt<'_, '_, '_>,
1986 ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
1987 ) -> Option<u128> {
1988 assert_eq!(self.ty, ty.value);
1989 let ty = tcx.lift_to_global(&ty).unwrap();
1990 let size = tcx.layout_of(ty).ok()?.size;
1991 match self.val {
1992 ConstVal::Value(val) => val.to_bits(size),
1993 _ => None,
1994 }
1995 }
1996
1997 #[inline]
1998 pub fn assert_bool(&self, tcx: TyCtxt<'_, '_, '_>) -> Option<bool> {
1999 self.assert_bits(tcx, ParamEnv::empty().and(tcx.types.bool)).and_then(|v| match v {
2000 0 => Some(false),
2001 1 => Some(true),
2002 _ => None,
2003 })
2004 }
2005
2006 #[inline]
2007 pub fn assert_usize(&self, tcx: TyCtxt<'_, '_, '_>) -> Option<u64> {
2008 self.assert_bits(tcx, ParamEnv::empty().and(tcx.types.usize)).map(|v| v as u64)
2009 }
2010
2011 #[inline]
2012 pub fn unwrap_bits(
2013 &self,
2014 tcx: TyCtxt<'_, '_, '_>,
2015 ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
2016 ) -> u128 {
2017 match self.assert_bits(tcx, ty) {
2018 Some(val) => val,
2019 None => bug!("expected bits of {}, got {:#?}", ty.value, self),
2020 }
2021 }
2022
2023 #[inline]
2024 pub fn unwrap_usize(&self, tcx: TyCtxt<'_, '_, '_>) -> u64 {
2025 match self.assert_usize(tcx) {
2026 Some(val) => val,
2027 None => bug!("expected constant usize, got {:#?}", self),
2028 }
2029 }
2030}
2031
ea8adc8c 2032impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Const<'tcx> {}