sty.rs 78.1 KB
Newer Older
1
//! This module contains `TyKind` and its major components.
2

M
Mark Rousskov 已提交
3
#![allow(rustc::usage_of_ty_tykind)]
F
flip1995 已提交
4

5 6
use self::TyKind::*;

M
Mark Mansi 已提交
7
use crate::infer::canonical::Canonical;
8
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
9
use crate::ty::InferTy::{self, *};
10 11 12
use crate::ty::{
    self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable, WithConstness,
};
M
mark 已提交
13
use crate::ty::{DelaySpanBugEmitted, List, ParamEnv, TyS};
14 15
use polonius_engine::Atom;
use rustc_data_structures::captures::Captures;
16
use rustc_hir as hir;
17
use rustc_hir::def_id::DefId;
18 19
use rustc_index::vec::Idx;
use rustc_macros::HashStable;
20
use rustc_span::symbol::{kw, Symbol};
21
use rustc_target::abi::VariantIdx;
22
use rustc_target::spec::abi;
T
Tyler Mandry 已提交
23
use std::borrow::Cow;
24
use std::cmp::Ordering;
V
varkor 已提交
25
use std::marker::PhantomData;
26
use std::ops::Range;
27
use ty::util::IntTypeExt;
28

M
Matthew Jasper 已提交
29
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
30
#[derive(HashStable, TypeFoldable, Lift)]
31 32 33 34 35
pub struct TypeAndMut<'tcx> {
    pub ty: Ty<'tcx>,
    pub mutbl: hir::Mutability,
}

M
Matthew Jasper 已提交
36
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)]
37
#[derive(HashStable)]
38 39
/// A "free" region `fr` can be interpreted as "some region
/// at least as big as the scope `fr.scope`".
40 41
pub struct FreeRegion {
    pub scope: DefId,
42
    pub bound_region: BoundRegionKind,
43 44
}

M
Matthew Jasper 已提交
45
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)]
46
#[derive(HashStable)]
47
pub enum BoundRegionKind {
48 49 50 51 52
    /// An anonymous region parameter for a given fn (&T)
    BrAnon(u32),

    /// Named region parameters for functions (a in &'a T)
    ///
A
Alexander Regueiro 已提交
53
    /// The `DefId` is needed to distinguish free regions in
54
    /// the event of shadowing.
55
    BrNamed(DefId, Symbol),
56

57 58
    /// Anonymous region for the implicit env pointer parameter
    /// to a closure
T
Tshepang Lekhonkhobe 已提交
59
    BrEnv,
60 61
}

62 63 64 65 66
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, PartialOrd, Ord)]
#[derive(HashStable)]
pub struct BoundRegion {
    pub kind: BoundRegionKind,
}
67

68
impl BoundRegion {
69 70 71 72
    /// When canonicalizing, we replace unbound inference variables and free
    /// regions with anonymous late bound regions. This method asserts that
    /// we have an anonymous late bound region, which hence may refer to
    /// a canonical variable.
73
    pub fn assert_bound_var(&self) -> BoundVar {
74 75
        match self.kind {
            BoundRegionKind::BrAnon(var) => BoundVar::from_u32(var),
76 77 78
            _ => bug!("bound region is not anonymous"),
        }
    }
79 80
}

81 82 83 84 85 86 87 88 89
impl BoundRegionKind {
    pub fn is_named(&self) -> bool {
        match *self {
            BoundRegionKind::BrNamed(_, name) => name != kw::UnderscoreLifetime,
            _ => false,
        }
    }
}

P
pierwill 已提交
90 91
/// Defines the kinds of types.
///
92
/// N.B., if you change this, you'll probably want to change the corresponding
V
Vadim Petrochenkov 已提交
93
/// AST structure in `librustc_ast/ast.rs` as well.
M
Matthew Jasper 已提交
94
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable, Debug)]
95
#[derive(HashStable)]
M
Mark Rousskov 已提交
96
#[rustc_diagnostic_item = "TyKind"]
V
varkor 已提交
97
pub enum TyKind<'tcx> {
98
    /// The primitive boolean type. Written as `bool`.
99
    Bool,
100 101

    /// The primitive character type; holds a Unicode scalar value
A
Alexander Regueiro 已提交
102
    /// (a non-surrogate code point). Written as `char`.
103
    Char,
104 105

    /// A primitive signed integer type. For example, `i32`.
106
    Int(ty::IntTy),
107 108

    /// A primitive unsigned integer type. For example, `u32`.
109
    Uint(ty::UintTy),
110 111

    /// A primitive floating-point type. For example, `f64`.
112
    Float(ty::FloatTy),
113

P
pierwill 已提交
114
    /// Algebraic data types (ADT). For example: structures, enumerations and unions.
115
    ///
C
csmoe 已提交
116
    /// InternalSubsts here, possibly against intuition, *may* contain `Param`s.
117
    /// That is, even after substitution it is possible that there are type
V
varkor 已提交
118
    /// variables. This happens when the `Adt` corresponds to an ADT
119
    /// definition and not a concrete use of it.
C
csmoe 已提交
120
    Adt(&'tcx AdtDef, SubstsRef<'tcx>),
V
Vadim Petrochenkov 已提交
121

122
    /// An unsized FFI type that is opaque to Rust. Written as `extern type T`.
V
varkor 已提交
123
    Foreign(DefId),
P
Paul Lietar 已提交
124

125
    /// The pointee of a string slice. Written as `str`.
126
    Str,
127 128

    /// An array with the given length. Written as `[T; n]`.
O
Oliver Scherer 已提交
129
    Array(Ty<'tcx>, &'tcx ty::Const<'tcx>),
130

A
Alexander Regueiro 已提交
131
    /// The pointee of an array slice. Written as `[T]`.
V
varkor 已提交
132
    Slice(Ty<'tcx>),
133 134

    /// A raw pointer. Written as `*mut T` or `*const T`
V
varkor 已提交
135
    RawPtr(TypeAndMut<'tcx>),
136 137

    /// A reference; a pointer with an associated lifetime. Written as
138
    /// `&'a mut T` or `&'a T`.
V
varkor 已提交
139
    Ref(Region<'tcx>, Ty<'tcx>, hir::Mutability),
140

141
    /// The anonymous type of a function declaration/definition. Each
142 143
    /// function has a unique type, which is output (for a function
    /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
144
    ///
145
    /// For example the type of `bar` here:
146 147 148
    ///
    /// ```rust
    /// fn foo() -> i32 { 1 }
149
    /// let bar = foo; // bar: fn() -> i32 {foo}
150
    /// ```
C
csmoe 已提交
151
    FnDef(DefId, SubstsRef<'tcx>),
152

A
Alexander Regueiro 已提交
153
    /// A pointer to a function. Written as `fn() -> i32`.
154
    ///
155
    /// For example the type of `bar` here:
156 157 158
    ///
    /// ```rust
    /// fn foo() -> i32 { 1 }
159
    /// let bar: fn() -> i32 = foo;
160
    /// ```
V
varkor 已提交
161
    FnPtr(PolyFnSig<'tcx>),
162

L
lcnr 已提交
163
    /// A trait object. Written as `dyn for<'b> Trait<'b, Assoc = u32> + Send + 'a`.
J
Jack Huey 已提交
164
    Dynamic(&'tcx List<Binder<ExistentialPredicate<'tcx>>>, ty::Region<'tcx>),
165 166 167

    /// The anonymous type of a closure. Used to represent the type of
    /// `|a| a`.
168
    Closure(DefId, SubstsRef<'tcx>),
169

J
John Kåre Alsaker 已提交
170 171
    /// The anonymous type of a generator. Used to represent the type of
    /// `|a| yield a`.
172
    Generator(DefId, SubstsRef<'tcx>, hir::Movability),
J
John Kåre Alsaker 已提交
173

P
pierwill 已提交
174
    /// A type representing the types stored inside a generator.
175
    /// This should only appear in GeneratorInteriors.
V
varkor 已提交
176
    GeneratorWitness(Binder<&'tcx List<Ty<'tcx>>>),
177

P
pierwill 已提交
178
    /// The never type `!`.
V
varkor 已提交
179
    Never,
180

A
Alexander Regueiro 已提交
181
    /// A tuple type. For example, `(i32, bool)`.
182
    /// Use `TyS::tuple_fields` to iterate over the field types.
183
    Tuple(SubstsRef<'tcx>),
184

A
Alexander Regueiro 已提交
185
    /// The projection of an associated type. For example,
186
    /// `<T as Trait<..>>::N`.
V
varkor 已提交
187
    Projection(ProjectionTy<'tcx>),
188

189
    /// Opaque (`impl Trait`) type found in a return type.
190
    /// The `DefId` comes either from
O
Oliver Schneider 已提交
191
    /// * the `impl Trait` ast::Ty node,
V
varkor 已提交
192
    /// * or the `type Foo = impl Trait` declaration
O
Oliver Schneider 已提交
193
    /// The substitutions are for the generics of the function in question.
194
    /// After typeck, the concrete type can be found in the `types` map.
C
csmoe 已提交
195
    Opaque(DefId, SubstsRef<'tcx>),
196

L
Lzu Tao 已提交
197
    /// A type parameter; for example, `T` in `fn f<T>(x: T) {}`.
V
varkor 已提交
198
    Param(ParamTy),
199

S
scalexm 已提交
200
    /// Bound type variable, used only when preparing a trait query.
201
    Bound(ty::DebruijnIndex, BoundTy),
S
scalexm 已提交
202

S
scalexm 已提交
203 204 205
    /// A placeholder type - universally quantified higher-ranked type.
    Placeholder(ty::PlaceholderType),

206
    /// A type variable used during type checking.
V
varkor 已提交
207
    Infer(InferTy),
208 209 210

    /// A placeholder for a type which could not be computed; this is
    /// propagated to avoid useless error messages.
211
    Error(DelaySpanBugEmitted),
212 213
}

J
jumbatm 已提交
214 215 216
impl TyKind<'tcx> {
    #[inline]
    pub fn is_primitive(&self) -> bool {
217
        matches!(self, Bool | Char | Int(_) | Uint(_) | Float(_))
J
jumbatm 已提交
218
    }
219 220 221 222 223 224

    /// Get the article ("a" or "an") to use with this type.
    pub fn article(&self) -> &'static str {
        match self {
            Int(_) | Float(_) | Array(_, _) => "an",
            Adt(def, _) if def.is_enum() => "an",
225 226 227
            // This should never happen, but ICEing and causing the user's code
            // to not compile felt too harsh.
            Error(_) => "a",
228 229 230
            _ => "a",
        }
    }
J
jumbatm 已提交
231 232
}

233
// `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger.
234
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
235
static_assert_size!(TyKind<'_>, 24);
236

237 238
/// A closure can be modeled as a struct that looks like:
///
239
///     struct Closure<'l0...'li, T0...Tj, CK, CS, U>(...U);
240
///
241 242
/// where:
///
243
/// - 'l0...'li and T0...Tj are the generic parameters
244 245 246 247
///   in scope on the function that defined the closure,
/// - CK represents the *closure kind* (Fn vs FnMut vs FnOnce). This
///   is rather hackily encoded via a scalar type. See
///   `TyS::to_opt_closure_kind` for details.
248 249 250 251
/// - CS represents the *closure signature*, representing as a `fn()`
///   type. For example, `fn(u32, u32) -> u32` would mean that the closure
///   implements `CK<(u32, u32), Output = u32>`, where `CK` is the trait
///   specified above.
252 253 254
/// - U is a type parameter representing the types of its upvars, tupled up
///   (borrowed, if appropriate; that is, if an U field represents a by-ref upvar,
///    and the up-var has the type `Foo`, then that field of U will be `&Foo`).
255 256 257 258 259 260 261 262 263
///
/// So, for example, given this function:
///
///     fn foo<'a, T>(data: &'a mut T) {
///          do(|| data.count += 1)
///     }
///
/// the type of the closure would be something like:
///
264
///     struct Closure<'a, T, U>(...U);
265 266 267 268 269 270 271
///
/// Note that the type of the upvar is not specified in the struct.
/// You may wonder how the impl would then be able to use the upvar,
/// if it doesn't know it's type? The answer is that the impl is
/// (conceptually) not fully generic over Closure but rather tied to
/// instances with the expected upvar types:
///
272
///     impl<'b, 'a, T> FnMut() for Closure<'a, T, (&'b mut &'a mut T,)> {
273 274 275 276 277 278 279 280
///         ...
///     }
///
/// You can see that the *impl* fully specified the type of the upvar
/// and thus knows full well that `data` has type `&'b mut &'a mut T`.
/// (Here, I am assuming that `data` is mut-borrowed.)
///
/// Now, the last question you may ask is: Why include the upvar types
281
/// in an extra type parameter? The reason for this design is that the
282 283
/// upvar types can reference lifetimes that are internal to the
/// creating function. In my example above, for example, the lifetime
284 285
/// `'b` represents the scope of the closure itself; this is some
/// subset of `foo`, probably just the scope of the call to the to
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
/// `do()`. If we just had the lifetime/type parameters from the
/// enclosing function, we couldn't name this lifetime `'b`. Note that
/// there can also be lifetimes in the types of the upvars themselves,
/// if one of them happens to be a reference to something that the
/// creating fn owns.
///
/// OK, you say, so why not create a more minimal set of parameters
/// that just includes the extra lifetime parameters? The answer is
/// primarily that it would be hard --- we don't know at the time when
/// we create the closure type what the full types of the upvars are,
/// nor do we know which are borrowed and which are not. In this
/// design, we can just supply a fresh type parameter and figure that
/// out later.
///
/// All right, you say, but why include the type parameters from the
I
Irina Popa 已提交
301
/// original function then? The answer is that codegen may need them
A
Alexander Regueiro 已提交
302
/// when monomorphizing, and they may not appear in the upvars. A
303 304 305 306 307 308 309 310 311 312 313 314
/// closure could capture no variables but still make use of some
/// in-scope type parameter with a bound (e.g., if our example above
/// had an extra `U: Default`, and the closure called `U::default()`).
///
/// There is another reason. This design (implicitly) prohibits
/// closures from capturing themselves (except via a trait
/// object). This simplifies closure inference considerably, since it
/// means that when we infer the kind of a closure or its upvars, we
/// don't have to handle cycles where the decisions we make for
/// closure C wind up influencing the decisions we ought to make for
/// closure C (which would then require fixed point iteration to
/// handle). Plus it fixes an ICE. :P
315 316 317
///
/// ## Generators
///
318
/// Generators are handled similarly in `GeneratorSubsts`.  The set of
319 320 321 322 323 324 325 326 327 328 329
/// type parameters is similar, but `CK` and `CS` are replaced by the
/// following type parameters:
///
/// * `GS`: The generator's "resume type", which is the type of the
///   argument passed to `resume`, and the type of `yield` expressions
///   inside the generator.
/// * `GY`: The "yield type", which is the type of values passed to
///   `yield` inside the generator.
/// * `GR`: The "return type", which is the type of value returned upon
///   completion of the generator.
/// * `GW`: The "generator witness".
C
Camille GILLOT 已提交
330
#[derive(Copy, Clone, Debug, TypeFoldable)]
331
pub struct ClosureSubsts<'tcx> {
332
    /// Lifetime and type parameters from the enclosing function,
333
    /// concatenated with a tuple containing the types of the upvars.
334
    ///
I
Irina Popa 已提交
335
    /// These are separated out because codegen wants to pass them around
336
    /// when monomorphizing.
C
csmoe 已提交
337
    pub substs: SubstsRef<'tcx>,
338
}
339

340 341 342 343 344 345
/// Struct returned by `split()`.
pub struct ClosureSubstsParts<'tcx, T> {
    pub parent_substs: &'tcx [GenericArg<'tcx>],
    pub closure_kind_ty: T,
    pub closure_sig_as_fn_ptr_ty: T,
    pub tupled_upvars_ty: T,
346 347 348
}

impl<'tcx> ClosureSubsts<'tcx> {
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
    /// Construct `ClosureSubsts` from `ClosureSubstsParts`, containing `Substs`
    /// for the closure parent, alongside additional closure-specific components.
    pub fn new(
        tcx: TyCtxt<'tcx>,
        parts: ClosureSubstsParts<'tcx, Ty<'tcx>>,
    ) -> ClosureSubsts<'tcx> {
        ClosureSubsts {
            substs: tcx.mk_substs(
                parts.parent_substs.iter().copied().chain(
                    [parts.closure_kind_ty, parts.closure_sig_as_fn_ptr_ty, parts.tupled_upvars_ty]
                        .iter()
                        .map(|&ty| ty.into()),
                ),
            ),
        }
    }

    /// Divides the closure substs into their respective components.
    /// The ordering assumed here must match that used by `ClosureSubsts::new` above.
    fn split(self) -> ClosureSubstsParts<'tcx, GenericArg<'tcx>> {
369
        match self.substs[..] {
370 371 372
            [ref parent_substs @ .., closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty] => {
                ClosureSubstsParts {
                    parent_substs,
373 374 375 376
                    closure_kind_ty,
                    closure_sig_as_fn_ptr_ty,
                    tupled_upvars_ty,
                }
377 378
            }
            _ => bug!("closure substs missing synthetics"),
379 380 381
        }
    }

382 383 384 385 386 387
    /// Returns `true` only if enough of the synthetic types are known to
    /// allow using all of the methods on `ClosureSubsts` without panicking.
    ///
    /// Used primarily by `ty::print::pretty` to be able to handle closure
    /// types that haven't had their synthetic types substituted in.
    pub fn is_valid(self) -> bool {
L
LeSeulArtichaut 已提交
388 389
        self.substs.len() >= 3
            && matches!(self.split().tupled_upvars_ty.expect_ty().kind(), Tuple(_))
390 391
    }

392 393
    /// Returns the substitutions of the closure's parent.
    pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] {
394
        self.split().parent_substs
395 396
    }

397 398 399
    /// Returns an iterator over the list of types of captured paths by the closure.
    /// In case there was a type error in figuring out the types of the captured path, an
    /// empty iterator is returned.
400
    #[inline]
401
    pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
402
        match self.tupled_upvars_ty().kind() {
R
Roxane 已提交
403 404
            TyKind::Error(_) => None,
            TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()),
405 406 407
            TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
            ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
        }
R
Roxane 已提交
408 409
        .into_iter()
        .flatten()
410 411 412 413 414 415
    }

    /// Returns the tuple type representing the upvars for this closure.
    #[inline]
    pub fn tupled_upvars_ty(self) -> Ty<'tcx> {
        self.split().tupled_upvars_ty.expect_ty()
416 417
    }

418
    /// Returns the closure kind for this closure; may return a type
419
    /// variable during inference. To get the closure kind during
420 421
    /// inference, use `infcx.closure_kind(substs)`.
    pub fn kind_ty(self) -> Ty<'tcx> {
422
        self.split().closure_kind_ty.expect_ty()
423
    }
424

425 426
    /// Returns the `fn` pointer type representing the closure signature for this
    /// closure.
427 428 429 430
    // FIXME(eddyb) this should be unnecessary, as the shallowly resolved
    // type is known at the time of the creation of `ClosureSubsts`,
    // see `rustc_typeck::check::closure`.
    pub fn sig_as_fn_ptr_ty(self) -> Ty<'tcx> {
431
        self.split().closure_sig_as_fn_ptr_ty.expect_ty()
432
    }
433

434
    /// Returns the closure kind for this closure; only usable outside
435 436
    /// of an inference context, because in that context we know that
    /// there are no type variables.
437 438
    ///
    /// If you have an inference context, use `infcx.closure_kind()`.
439
    pub fn kind(self) -> ty::ClosureKind {
440
        self.kind_ty().to_opt_closure_kind().unwrap()
441
    }
442

443
    /// Extracts the signature from the closure.
444 445
    pub fn sig(self) -> ty::PolyFnSig<'tcx> {
        let ty = self.sig_as_fn_ptr_ty();
L
LeSeulArtichaut 已提交
446 447 448
        match ty.kind() {
            ty::FnPtr(sig) => *sig,
            _ => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {:?}", ty.kind()),
449 450
        }
    }
451 452
}

453
/// Similar to `ClosureSubsts`; see the above documentation for more.
C
Camille GILLOT 已提交
454
#[derive(Copy, Clone, Debug, TypeFoldable)]
455
pub struct GeneratorSubsts<'tcx> {
C
csmoe 已提交
456
    pub substs: SubstsRef<'tcx>,
457 458
}

459 460 461 462 463 464 465
pub struct GeneratorSubstsParts<'tcx, T> {
    pub parent_substs: &'tcx [GenericArg<'tcx>],
    pub resume_ty: T,
    pub yield_ty: T,
    pub return_ty: T,
    pub witness: T,
    pub tupled_upvars_ty: T,
466 467 468
}

impl<'tcx> GeneratorSubsts<'tcx> {
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494
    /// Construct `GeneratorSubsts` from `GeneratorSubstsParts`, containing `Substs`
    /// for the generator parent, alongside additional generator-specific components.
    pub fn new(
        tcx: TyCtxt<'tcx>,
        parts: GeneratorSubstsParts<'tcx, Ty<'tcx>>,
    ) -> GeneratorSubsts<'tcx> {
        GeneratorSubsts {
            substs: tcx.mk_substs(
                parts.parent_substs.iter().copied().chain(
                    [
                        parts.resume_ty,
                        parts.yield_ty,
                        parts.return_ty,
                        parts.witness,
                        parts.tupled_upvars_ty,
                    ]
                    .iter()
                    .map(|&ty| ty.into()),
                ),
            ),
        }
    }

    /// Divides the generator substs into their respective components.
    /// The ordering assumed here must match that used by `GeneratorSubsts::new` above.
    fn split(self) -> GeneratorSubstsParts<'tcx, GenericArg<'tcx>> {
495
        match self.substs[..] {
496 497 498
            [ref parent_substs @ .., resume_ty, yield_ty, return_ty, witness, tupled_upvars_ty] => {
                GeneratorSubstsParts {
                    parent_substs,
499 500 501 502 503 504
                    resume_ty,
                    yield_ty,
                    return_ty,
                    witness,
                    tupled_upvars_ty,
                }
505 506
            }
            _ => bug!("generator substs missing synthetics"),
507 508 509
        }
    }

510 511 512 513 514 515
    /// Returns `true` only if enough of the synthetic types are known to
    /// allow using all of the methods on `GeneratorSubsts` without panicking.
    ///
    /// Used primarily by `ty::print::pretty` to be able to handle generator
    /// types that haven't had their synthetic types substituted in.
    pub fn is_valid(self) -> bool {
L
LeSeulArtichaut 已提交
516 517
        self.substs.len() >= 5
            && matches!(self.split().tupled_upvars_ty.expect_ty().kind(), Tuple(_))
518 519
    }

520 521
    /// Returns the substitutions of the generator's parent.
    pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] {
522
        self.split().parent_substs
523 524
    }

525 526 527 528 529
    /// This describes the types that can be contained in a generator.
    /// It will be a type variable initially and unified in the last stages of typeck of a body.
    /// It contains a tuple of all the types that could end up on a generator frame.
    /// The state transformation MIR pass may only produce layouts which mention types
    /// in this tuple. Upvars are not counted here.
530
    pub fn witness(self) -> Ty<'tcx> {
531
        self.split().witness.expect_ty()
532 533
    }

534 535 536
    /// Returns an iterator over the list of types of captured paths by the generator.
    /// In case there was a type error in figuring out the types of the captured path, an
    /// empty iterator is returned.
537
    #[inline]
538
    pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
539
        match self.tupled_upvars_ty().kind() {
R
Roxane 已提交
540 541
            TyKind::Error(_) => None,
            TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()),
542 543 544
            TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
            ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
        }
R
Roxane 已提交
545 546
        .into_iter()
        .flatten()
547 548 549 550 551 552
    }

    /// Returns the tuple type representing the upvars for this generator.
    #[inline]
    pub fn tupled_upvars_ty(self) -> Ty<'tcx> {
        self.split().tupled_upvars_ty.expect_ty()
553 554
    }

555
    /// Returns the type representing the resume type of the generator.
556
    pub fn resume_ty(self) -> Ty<'tcx> {
557
        self.split().resume_ty.expect_ty()
558 559
    }

560
    /// Returns the type representing the yield type of the generator.
561
    pub fn yield_ty(self) -> Ty<'tcx> {
562
        self.split().yield_ty.expect_ty()
563 564 565
    }

    /// Returns the type representing the return type of the generator.
566
    pub fn return_ty(self) -> Ty<'tcx> {
567
        self.split().return_ty.expect_ty()
568 569
    }

A
Alexander Regueiro 已提交
570
    /// Returns the "generator signature", which consists of its yield
571 572
    /// and return types.
    ///
A
Alexander Regueiro 已提交
573
    /// N.B., some bits of the code prefers to see this wrapped in a
574 575
    /// binder, but it never contains bound regions. Probably this
    /// function should be removed.
576 577
    pub fn poly_sig(self) -> PolyGenSig<'tcx> {
        ty::Binder::dummy(self.sig())
578 579
    }

580
    /// Returns the "generator signature", which consists of its resume, yield
581
    /// and return types.
582
    pub fn sig(self) -> GenSig<'tcx> {
583
        ty::GenSig {
584 585 586
            resume_ty: self.resume_ty(),
            yield_ty: self.yield_ty(),
            return_ty: self.return_ty(),
587
        }
588 589 590
    }
}

591
impl<'tcx> GeneratorSubsts<'tcx> {
592
    /// Generator has not been resumed yet.
593
    pub const UNRESUMED: usize = 0;
594
    /// Generator has returned or is completed.
595
    pub const RETURNED: usize = 1;
596
    /// Generator has been poisoned.
597 598 599 600 601 602
    pub const POISONED: usize = 2;

    const UNRESUMED_NAME: &'static str = "Unresumed";
    const RETURNED_NAME: &'static str = "Returned";
    const POISONED_NAME: &'static str = "Panicked";

603
    /// The valid variant indices of this generator.
604
    #[inline]
605
    pub fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range<VariantIdx> {
606
        // FIXME requires optimized MIR
607
        let num_variants = tcx.generator_layout(def_id).unwrap().variant_fields.len();
608
        VariantIdx::new(0)..VariantIdx::new(num_variants)
609 610
    }

611
    /// The discriminant for the given variant. Panics if the `variant_index` is
612 613 614
    /// out of range.
    #[inline]
    pub fn discriminant_for_variant(
615 616
        &self,
        def_id: DefId,
617
        tcx: TyCtxt<'tcx>,
618
        variant_index: VariantIdx,
619 620 621 622 623 624 625
    ) -> Discr<'tcx> {
        // Generators don't support explicit discriminant values, so they are
        // the same as the variant index.
        assert!(self.variant_range(def_id, tcx).contains(&variant_index));
        Discr { val: variant_index.as_usize() as u128, ty: self.discr_ty(tcx) }
    }

626
    /// The set of all discriminants for the generator, enumerated with their
627 628 629
    /// variant indices.
    #[inline]
    pub fn discriminants(
C
csmoe 已提交
630
        self,
631
        def_id: DefId,
632 633
        tcx: TyCtxt<'tcx>,
    ) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'tcx> {
634 635 636
        self.variant_range(def_id, tcx).map(move |index| {
            (index, Discr { val: index.as_usize() as u128, ty: self.discr_ty(tcx) })
        })
637 638 639 640
    }

    /// Calls `f` with a reference to the name of the enumerator for the given
    /// variant `v`.
641
    pub fn variant_name(v: VariantIdx) -> Cow<'static, str> {
T
Tyler Mandry 已提交
642 643 644 645
        match v.as_usize() {
            Self::UNRESUMED => Cow::from(Self::UNRESUMED_NAME),
            Self::RETURNED => Cow::from(Self::RETURNED_NAME),
            Self::POISONED => Cow::from(Self::POISONED_NAME),
M
Mark Rousskov 已提交
646
            _ => Cow::from(format!("Suspend{}", v.as_usize() - 3)),
T
Tyler Mandry 已提交
647
        }
648 649
    }

650
    /// The type of the state discriminant used in the generator type.
651
    #[inline]
652
    pub fn discr_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
653 654 655
        tcx.types.u32
    }

J
John Kåre Alsaker 已提交
656 657 658
    /// This returns the types of the MIR locals which had to be stored across suspension points.
    /// It is calculated in rustc_mir::transform::generator::StateTransform.
    /// All the types here must be in the tuple in GeneratorInterior.
T
Tyler Mandry 已提交
659 660 661
    ///
    /// The locals are grouped by their variant number. Note that some locals may
    /// be repeated in multiple variants.
662
    #[inline]
663 664 665
    pub fn state_tys(
        self,
        def_id: DefId,
666 667
        tcx: TyCtxt<'tcx>,
    ) -> impl Iterator<Item = impl Iterator<Item = Ty<'tcx>> + Captures<'tcx>> {
668
        let layout = tcx.generator_layout(def_id).unwrap();
669
        layout.variant_fields.iter().map(move |variant| {
M
Mark Rousskov 已提交
670
            variant.iter().map(move |field| layout.field_tys[*field].subst(tcx, self.substs))
671
        })
672 673
    }

T
Tyler Mandry 已提交
674 675
    /// This is the types of the fields of a generator which are not stored in a
    /// variant.
676
    #[inline]
677 678
    pub fn prefix_tys(self) -> impl Iterator<Item = Ty<'tcx>> {
        self.upvar_tys()
J
John Kåre Alsaker 已提交
679 680 681
    }
}

682 683
#[derive(Debug, Copy, Clone)]
pub enum UpvarSubsts<'tcx> {
C
csmoe 已提交
684
    Closure(SubstsRef<'tcx>),
C
csmoe 已提交
685
    Generator(SubstsRef<'tcx>),
686 687 688
}

impl<'tcx> UpvarSubsts<'tcx> {
689 690 691
    /// Returns an iterator over the list of types of captured paths by the closure/generator.
    /// In case there was a type error in figuring out the types of the captured path, an
    /// empty iterator is returned.
692
    #[inline]
693
    pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
R
Roxane 已提交
694 695 696
        let tupled_tys = match self {
            UpvarSubsts::Closure(substs) => substs.as_closure().tupled_upvars_ty(),
            UpvarSubsts::Generator(substs) => substs.as_generator().tupled_upvars_ty(),
697
        };
R
Roxane 已提交
698 699 700 701 702 703

        match tupled_tys.kind() {
            TyKind::Error(_) => None,
            TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()),
            TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
            ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
704
        }
R
Roxane 已提交
705 706
        .into_iter()
        .flatten()
707
    }
708 709 710 711 712 713 714 715

    #[inline]
    pub fn tupled_upvars_ty(self) -> Ty<'tcx> {
        match self {
            UpvarSubsts::Closure(substs) => substs.as_closure().tupled_upvars_ty(),
            UpvarSubsts::Generator(substs) => substs.as_generator().tupled_upvars_ty(),
        }
    }
J
John Kåre Alsaker 已提交
716 717
}

M
Matthew Jasper 已提交
718
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, TyEncodable, TyDecodable)]
C
Camille GILLOT 已提交
719
#[derive(HashStable, TypeFoldable)]
720
pub enum ExistentialPredicate<'tcx> {
A
Alexander Regueiro 已提交
721
    /// E.g., `Iterator`.
722
    Trait(ExistentialTraitRef<'tcx>),
A
Alexander Regueiro 已提交
723
    /// E.g., `Iterator::Item = T`.
724
    Projection(ExistentialProjection<'tcx>),
A
Alexander Regueiro 已提交
725
    /// E.g., `Send`.
726
    AutoTrait(DefId),
727 728
}

729
impl<'tcx> ExistentialPredicate<'tcx> {
730 731
    /// Compares via an ordering that will not change if modules are reordered or other changes are
    /// made to the tree. In particular, this ordering is preserved across incremental compilations.
732
    pub fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering {
733 734 735
        use self::ExistentialPredicate::*;
        match (*self, *other) {
            (Trait(_), Trait(_)) => Ordering::Equal,
M
Mark Rousskov 已提交
736 737 738 739 740 741
            (Projection(ref a), Projection(ref b)) => {
                tcx.def_path_hash(a.item_def_id).cmp(&tcx.def_path_hash(b.item_def_id))
            }
            (AutoTrait(ref a), AutoTrait(ref b)) => {
                tcx.trait_def(*a).def_path_hash.cmp(&tcx.trait_def(*b).def_path_hash)
            }
742 743 744 745 746 747 748 749
            (Trait(_), _) => Ordering::Less,
            (Projection(_), Trait(_)) => Ordering::Greater,
            (Projection(_), _) => Ordering::Less,
            (AutoTrait(_), _) => Ordering::Greater,
        }
    }
}

750 751
impl<'tcx> Binder<ExistentialPredicate<'tcx>> {
    pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> {
M
Mark Mansi 已提交
752
        use crate::ty::ToPredicate;
753
        match self.skip_binder() {
J
Jack Huey 已提交
754 755 756
            ExistentialPredicate::Trait(tr) => {
                self.rebind(tr).with_self_ty(tcx, self_ty).without_const().to_predicate(tcx)
            }
M
Mark Rousskov 已提交
757
            ExistentialPredicate::Projection(p) => {
J
Jack Huey 已提交
758
                self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx)
M
Mark Rousskov 已提交
759
            }
760
            ExistentialPredicate::AutoTrait(did) => {
J
Jack Huey 已提交
761
                let trait_ref = self.rebind(ty::TraitRef {
762 763 764
                    def_id: did,
                    substs: tcx.mk_substs_trait(self_ty, &[]),
                });
765
                trait_ref.without_const().to_predicate(tcx)
766 767 768 769 770
            }
        }
    }
}

J
Jack Huey 已提交
771
impl<'tcx> List<ty::Binder<ExistentialPredicate<'tcx>>> {
772
    /// Returns the "principal `DefId`" of this set of existential predicates.
773 774 775
    ///
    /// A Rust trait object type consists (in addition to a lifetime bound)
    /// of a set of trait bounds, which are separated into any number
776
    /// of auto-trait bounds, and at most one non-auto-trait bound. The
777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796
    /// non-auto-trait bound is called the "principal" of the trait
    /// object.
    ///
    /// Only the principal can have methods or type parameters (because
    /// auto traits can have neither of them). This is important, because
    /// it means the auto traits can be treated as an unordered set (methods
    /// would force an order for the vtable, while relating traits with
    /// type parameters without knowing the order to relate them in is
    /// a rather non-trivial task).
    ///
    /// For example, in the trait object `dyn fmt::Debug + Sync`, the
    /// principal bound is `Some(fmt::Debug)`, while the auto-trait bounds
    /// are the set `{Sync}`.
    ///
    /// It is also possible to have a "trivial" trait object that
    /// consists only of auto traits, with no principal - for example,
    /// `dyn Send + Sync`. In that case, the set of auto-trait bounds
    /// is `{Send, Sync}`, while there is no principal. These trait objects
    /// have a "trivial" vtable consisting of just the size, alignment,
    /// and destructor.
J
Jack Huey 已提交
797 798 799 800 801 802 803
    pub fn principal(&self) -> Option<ty::Binder<ExistentialTraitRef<'tcx>>> {
        self[0]
            .map_bound(|this| match this {
                ExistentialPredicate::Trait(tr) => Some(tr),
                _ => None,
            })
            .transpose()
804 805
    }

806
    pub fn principal_def_id(&self) -> Option<DefId> {
J
Jack Huey 已提交
807
        self.principal().map(|trait_ref| trait_ref.skip_binder().def_id)
808 809
    }

810
    #[inline]
M
Mark Rousskov 已提交
811 812
    pub fn projection_bounds<'a>(
        &'a self,
J
Jack Huey 已提交
813 814 815 816 817 818 819 820
    ) -> impl Iterator<Item = ty::Binder<ExistentialProjection<'tcx>>> + 'a {
        self.iter().filter_map(|predicate| {
            predicate
                .map_bound(|pred| match pred {
                    ExistentialPredicate::Projection(projection) => Some(projection),
                    _ => None,
                })
                .transpose()
821 822 823 824
        })
    }

    #[inline]
825
    pub fn auto_traits<'a>(&'a self) -> impl Iterator<Item = DefId> + 'a {
J
Jack Huey 已提交
826
        self.iter().filter_map(|predicate| match predicate.skip_binder() {
M
Mark Rousskov 已提交
827 828
            ExistentialPredicate::AutoTrait(did) => Some(did),
            _ => None,
829 830 831 832
        })
    }
}

833
/// A complete reference to a trait. These take numerous guises in syntax,
A
Alexander Regueiro 已提交
834
/// but perhaps the most recognizable form is in a where-clause:
835
///
836
///     T: Foo<U>
837
///
A
Alexander Regueiro 已提交
838 839
/// This would be represented by a trait-reference where the `DefId` is the
/// `DefId` for the trait `Foo` and the substs define `T` as parameter 0,
840
/// and `U` as parameter 1.
841 842 843
///
/// Trait references also appear in object types like `Foo<U>`, but in
/// that case the `Self` parameter is absent from the substitutions.
M
Matthew Jasper 已提交
844
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
C
Camille GILLOT 已提交
845
#[derive(HashStable, TypeFoldable)]
846 847
pub struct TraitRef<'tcx> {
    pub def_id: DefId,
C
csmoe 已提交
848
    pub substs: SubstsRef<'tcx>,
849 850
}

851
impl<'tcx> TraitRef<'tcx> {
C
csmoe 已提交
852
    pub fn new(def_id: DefId, substs: SubstsRef<'tcx>) -> TraitRef<'tcx> {
853
        TraitRef { def_id, substs }
854 855
    }

A
Alexander Regueiro 已提交
856
    /// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
857
    /// are the parameters defined on trait.
858
    pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> TraitRef<'tcx> {
M
Mark Rousskov 已提交
859
        TraitRef { def_id, substs: InternalSubsts::identity_for_item(tcx, def_id) }
860 861
    }

862
    #[inline]
863 864 865 866
    pub fn self_ty(&self) -> Ty<'tcx> {
        self.substs.type_at(0)
    }

867
    pub fn from_method(
868
        tcx: TyCtxt<'tcx>,
869 870 871
        trait_id: DefId,
        substs: SubstsRef<'tcx>,
    ) -> ty::TraitRef<'tcx> {
872 873
        let defs = tcx.generics_of(trait_id);

M
Mark Rousskov 已提交
874
        ty::TraitRef { def_id: trait_id, substs: tcx.intern_substs(&substs[..defs.params.len()]) }
875
    }
876 877
}

878 879 880
pub type PolyTraitRef<'tcx> = Binder<TraitRef<'tcx>>;

impl<'tcx> PolyTraitRef<'tcx> {
881 882
    pub fn self_ty(&self) -> Binder<Ty<'tcx>> {
        self.map_bound_ref(|tr| tr.self_ty())
883 884 885
    }

    pub fn def_id(&self) -> DefId {
886
        self.skip_binder().def_id
887 888 889
    }

    pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> {
890
        self.map_bound(|trait_ref| ty::TraitPredicate { trait_ref })
891 892 893
    }
}

894 895 896 897 898 899 900
/// An existential reference to a trait, where `Self` is erased.
/// For example, the trait object `Trait<'a, 'b, X, Y>` is:
///
///     exists T. T: Trait<'a, 'b, X, Y>
///
/// The substitutions don't include the erased `Self`, only trait
/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
M
Matthew Jasper 已提交
901
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
C
Camille GILLOT 已提交
902
#[derive(HashStable, TypeFoldable)]
903 904
pub struct ExistentialTraitRef<'tcx> {
    pub def_id: DefId,
C
csmoe 已提交
905
    pub substs: SubstsRef<'tcx>,
906 907
}

908
impl<'tcx> ExistentialTraitRef<'tcx> {
909
    pub fn erase_self_ty(
910
        tcx: TyCtxt<'tcx>,
911 912
        trait_ref: ty::TraitRef<'tcx>,
    ) -> ty::ExistentialTraitRef<'tcx> {
913 914 915 916 917
        // Assert there is a Self.
        trait_ref.substs.type_at(0);

        ty::ExistentialTraitRef {
            def_id: trait_ref.def_id,
M
Mark Rousskov 已提交
918
            substs: tcx.intern_substs(&trait_ref.substs[1..]),
919 920 921
        }
    }

A
Alexander Regueiro 已提交
922
    /// Object types don't have a self type specified. Therefore, when
923
    /// we convert the principal trait-ref into a normal trait-ref,
A
Alexander Regueiro 已提交
924
    /// you must give *some* self type. A common choice is `mk_err()`
N
Niko Matsakis 已提交
925
    /// or some placeholder type.
926
    pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::TraitRef<'tcx> {
927 928
        // otherwise the escaping vars would be captured by the binder
        // debug_assert!(!self_ty.has_escaping_bound_vars());
929

M
Mark Rousskov 已提交
930
        ty::TraitRef { def_id: self.def_id, substs: tcx.mk_substs_trait(self_ty, self.substs) }
931
    }
932 933 934 935
}

pub type PolyExistentialTraitRef<'tcx> = Binder<ExistentialTraitRef<'tcx>>;

936
impl<'tcx> PolyExistentialTraitRef<'tcx> {
937
    pub fn def_id(&self) -> DefId {
938
        self.skip_binder().def_id
939
    }
940

A
Alexander Regueiro 已提交
941
    /// Object types don't have a self type specified. Therefore, when
942
    /// we convert the principal trait-ref into a normal trait-ref,
A
Alexander Regueiro 已提交
943
    /// you must give *some* self type. A common choice is `mk_err()`
N
Niko Matsakis 已提交
944
    /// or some placeholder type.
945
    pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::PolyTraitRef<'tcx> {
946 947
        self.map_bound(|trait_ref| trait_ref.with_self_ty(tcx, self_ty))
    }
948 949
}

950
/// Binder is a binder for higher-ranked lifetimes or types. It is part of the
951 952
/// compiler's representation for things like `for<'a> Fn(&'a isize)`
/// (which would be represented by the type `PolyTraitRef ==
953
/// Binder<TraitRef>`). Note that when we instantiate,
954
/// erase, or otherwise "discharge" these bound vars, we change the
955
/// type from `Binder<T>` to just `T` (see
956
/// e.g., `liberate_late_bound_regions`).
957
///
J
Jack Huey 已提交
958
/// `Decodable` and `Encodable` are implemented for `Binder<T>` using the `impl_binder_encode_decode!` macro.
959
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
960
pub struct Binder<T>(T);
961 962

impl<T> Binder<T> {
963
    /// Wraps `value` in a binder, asserting that `value` does not
964
    /// contain any bound vars that would be bound by the
965 966
    /// binder. This is commonly used to 'inject' a value T into a
    /// different binding level.
967
    pub fn dummy<'tcx>(value: T) -> Binder<T>
M
Mark Rousskov 已提交
968 969
    where
        T: TypeFoldable<'tcx>,
970
    {
971
        debug_assert!(!value.has_escaping_bound_vars());
972 973 974
        Binder(value)
    }

975
    /// Wraps `value` in a binder, binding higher-ranked vars (if any).
976
    pub fn bind(value: T) -> Binder<T> {
977 978 979
        Binder(value)
    }

980 981
    /// Wraps `value` in a binder without actually binding any currently
    /// unbound variables.
B
Bastian Kauschke 已提交
982 983 984
    ///
    /// Note that this will shift all debrujin indices of escaping bound variables
    /// by 1 to avoid accidential captures.
985 986 987 988 989
    pub fn wrap_nonbinding(tcx: TyCtxt<'tcx>, value: T) -> Binder<T>
    where
        T: TypeFoldable<'tcx>,
    {
        if value.has_escaping_bound_vars() {
B
Bastian Kauschke 已提交
990
            Binder::bind(super::fold::shift_vars(tcx, value, 1))
991 992 993 994 995
        } else {
            Binder::dummy(value)
        }
    }

996 997
    /// Skips the binder and returns the "bound" value. This is a
    /// risky thing to do because it's easy to get confused about
A
Alexander Regueiro 已提交
998
    /// De Bruijn indices and the like. It is usually better to
999
    /// discharge the binder using `no_bound_vars` or
1000 1001
    /// `replace_late_bound_regions` or something like
    /// that. `skip_binder` is only valid when you are either
1002
    /// extracting data that has nothing to do with bound vars, you
1003 1004 1005 1006 1007
    /// are doing some sort of test that does not involve bound
    /// regions, or you are being very careful about your depth
    /// accounting.
    ///
    /// Some examples where `skip_binder` is reasonable:
1008
    ///
A
Alexander Regueiro 已提交
1009
    /// - extracting the `DefId` from a PolyTraitRef;
1010
    /// - comparing the self type of a PolyTraitRef to see if it is equal to
1011
    ///   a type parameter `X`, since the type `X` does not reference any regions
1012 1013
    pub fn skip_binder(self) -> T {
        self.0
1014 1015 1016
    }

    pub fn as_ref(&self) -> Binder<&T> {
1017
        Binder(&self.0)
1018 1019
    }

T
Tshepang Lekhonkhobe 已提交
1020
    pub fn map_bound_ref<F, U>(&self, f: F) -> Binder<U>
M
Mark Rousskov 已提交
1021 1022
    where
        F: FnOnce(&T) -> U,
1023 1024 1025 1026
    {
        self.as_ref().map_bound(f)
    }

T
Tshepang Lekhonkhobe 已提交
1027
    pub fn map_bound<F, U>(self, f: F) -> Binder<U>
M
Mark Rousskov 已提交
1028 1029
    where
        F: FnOnce(T) -> U,
1030
    {
1031
        Binder(f(self.0))
1032
    }
1033

J
Jack Huey 已提交
1034 1035 1036 1037
    /// Wraps a `value` in a binder, using the same bound variables as the
    /// current `Binder`. This should not be used if the new value *changes*
    /// the bound variables. Note: the (old or new) value itself does not
    /// necessarily need to *name* all the bound variables.
J
Jack Huey 已提交
1038 1039 1040 1041 1042
    ///
    /// This currently doesn't do anything different than `bind`, because we
    /// don't actually track bound vars. However, semantically, it is different
    /// because bound vars aren't allowed to change here, whereas they are
    /// in `bind`. This may be (debug) asserted in the future.
J
Jack Huey 已提交
1043 1044 1045 1046
    pub fn rebind<U>(&self, value: U) -> Binder<U> {
        Binder(value)
    }

1047
    /// Unwraps and returns the value within, but only if it contains
1048
    /// no bound vars at all. (In other words, if this binder --
1049 1050 1051 1052
    /// and indeed any enclosing binder -- doesn't bind anything at
    /// all.) Otherwise, returns `None`.
    ///
    /// (One could imagine having a method that just unwraps a single
1053
    /// binder, but permits late-bound vars bound by enclosing
1054 1055 1056
    /// binders, but that would require adjusting the debruijn
    /// indices, and given the shallow binding structure we often use,
    /// would not be that useful.)
1057
    pub fn no_bound_vars<'tcx>(self) -> Option<T>
M
Mark Rousskov 已提交
1058 1059
    where
        T: TypeFoldable<'tcx>,
1060
    {
1061
        if self.0.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
1062
    }
1063 1064

    /// Given two things that have the same binder level,
A
Alexander Regueiro 已提交
1065 1066
    /// and an operation that wraps on their contents, executes the operation
    /// and then wraps its result.
1067 1068 1069 1070
    ///
    /// `f` should consider bound regions at depth 1 to be free, and
    /// anything it produces with bound regions at depth 1 will be
    /// bound in the resulting return value.
M
Mark Rousskov 已提交
1071 1072 1073
    pub fn fuse<U, F, R>(self, u: Binder<U>, f: F) -> Binder<R>
    where
        F: FnOnce(T, U) -> R,
1074
    {
1075
        Binder(f(self.0, u.0))
1076 1077
    }

A
Alexander Regueiro 已提交
1078
    /// Splits the contents into two things that share the same binder
1079 1080 1081 1082 1083
    /// level as the original, returning two distinct binders.
    ///
    /// `f` should consider bound regions at depth 1 to be free, and
    /// anything it produces with bound regions at depth 1 will be
    /// bound in the resulting return values.
M
Mark Rousskov 已提交
1084 1085 1086
    pub fn split<U, V, F>(self, f: F) -> (Binder<U>, Binder<V>)
    where
        F: FnOnce(T) -> (U, V),
1087 1088
    {
        let (u, v) = f(self.0);
1089
        (Binder(u), Binder(v))
1090
    }
1091 1092
}

1093 1094
impl<T> Binder<Option<T>> {
    pub fn transpose(self) -> Option<Binder<T>> {
1095
        self.0.map(Binder)
1096 1097 1098
    }
}

1099 1100
/// Represents the projection of an associated type. In explicit UFCS
/// form this would be written `<T as Trait<..>>::N`.
M
Matthew Jasper 已提交
1101
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
C
Camille GILLOT 已提交
1102
#[derive(HashStable, TypeFoldable)]
1103
pub struct ProjectionTy<'tcx> {
1104
    /// The parameters of the associated item.
C
csmoe 已提交
1105
    pub substs: SubstsRef<'tcx>,
1106

1107
    /// The `DefId` of the `TraitItem` for the associated type `N`.
1108
    ///
1109 1110
    /// Note that this is not the `DefId` of the `TraitRef` containing this
    /// associated type, which is in `tcx.associated_item(item_def_id).container`.
1111 1112 1113
    pub item_def_id: DefId,
}

1114
impl<'tcx> ProjectionTy<'tcx> {
1115 1116 1117
    pub fn trait_def_id(&self, tcx: TyCtxt<'tcx>) -> DefId {
        tcx.associated_item(self.item_def_id).container.id()
    }
1118

1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131
    /// Extracts the underlying trait reference and own substs from this projection.
    /// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
    /// then this function would return a `T: Iterator` trait reference and `['a]` as the own substs
    pub fn trait_ref_and_own_substs(
        &self,
        tcx: TyCtxt<'tcx>,
    ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
        let def_id = tcx.associated_item(self.item_def_id).container.id();
        let trait_generics = tcx.generics_of(def_id);
        (
            ty::TraitRef { def_id, substs: self.substs.truncate_to(tcx, trait_generics) },
            &self.substs[trait_generics.count()..],
        )
1132 1133
    }

1134 1135 1136
    /// Extracts the underlying trait reference from this projection.
    /// For example, if this is a projection of `<T as Iterator>::Item`,
    /// then this function would return a `T: Iterator` trait reference.
1137 1138 1139 1140
    ///
    /// WARNING: This will drop the substs for generic associated types
    /// consider calling [Self::trait_ref_and_own_substs] to get those
    /// as well.
1141
    pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> {
1142 1143
        let def_id = self.trait_def_id(tcx);
        ty::TraitRef { def_id, substs: self.substs.truncate_to(tcx, tcx.generics_of(def_id)) }
1144 1145 1146 1147
    }

    pub fn self_ty(&self) -> Ty<'tcx> {
        self.substs.type_at(0)
1148
    }
1149
}
1150

1151
#[derive(Copy, Clone, Debug, TypeFoldable)]
J
John Kåre Alsaker 已提交
1152
pub struct GenSig<'tcx> {
1153
    pub resume_ty: Ty<'tcx>,
J
John Kåre Alsaker 已提交
1154
    pub yield_ty: Ty<'tcx>,
J
John Kåre Alsaker 已提交
1155 1156 1157 1158 1159 1160
    pub return_ty: Ty<'tcx>,
}

pub type PolyGenSig<'tcx> = Binder<GenSig<'tcx>>;

impl<'tcx> PolyGenSig<'tcx> {
1161 1162 1163
    pub fn resume_ty(&self) -> ty::Binder<Ty<'tcx>> {
        self.map_bound_ref(|sig| sig.resume_ty)
    }
J
John Kåre Alsaker 已提交
1164 1165
    pub fn yield_ty(&self) -> ty::Binder<Ty<'tcx>> {
        self.map_bound_ref(|sig| sig.yield_ty)
J
John Kåre Alsaker 已提交
1166 1167 1168 1169 1170
    }
    pub fn return_ty(&self) -> ty::Binder<Ty<'tcx>> {
        self.map_bound_ref(|sig| sig.return_ty)
    }
}
1171

1172
/// Signature of a function type, which we have arbitrarily
1173 1174
/// decided to use to refer to the input/output types.
///
1175 1176
/// - `inputs`: is the list of arguments and their modes.
/// - `output`: is the return type.
D
Dan Robertson 已提交
1177
/// - `c_variadic`: indicates whether this is a C-variadic function.
M
Matthew Jasper 已提交
1178
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
C
Camille GILLOT 已提交
1179
#[derive(HashStable, TypeFoldable)]
1180
pub struct FnSig<'tcx> {
V
varkor 已提交
1181
    pub inputs_and_output: &'tcx List<Ty<'tcx>>,
D
Dan Robertson 已提交
1182
    pub c_variadic: bool,
1183 1184
    pub unsafety: hir::Unsafety,
    pub abi: abi::Abi,
1185 1186 1187
}

impl<'tcx> FnSig<'tcx> {
1188
    pub fn inputs(&self) -> &'tcx [Ty<'tcx>] {
1189
        &self.inputs_and_output[..self.inputs_and_output.len() - 1]
1190 1191 1192
    }

    pub fn output(&self) -> Ty<'tcx> {
1193
        self.inputs_and_output[self.inputs_and_output.len() - 1]
1194
    }
1195

1196 1197
    // Creates a minimal `FnSig` to be used when encountering a `TyKind::Error` in a fallible
    // method.
1198 1199 1200 1201 1202 1203 1204 1205
    fn fake() -> FnSig<'tcx> {
        FnSig {
            inputs_and_output: List::empty(),
            c_variadic: false,
            unsafety: hir::Unsafety::Normal,
            abi: abi::Abi::Rust,
        }
    }
1206 1207 1208 1209 1210
}

pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;

impl<'tcx> PolyFnSig<'tcx> {
1211
    #[inline]
1212
    pub fn inputs(&self) -> Binder<&'tcx [Ty<'tcx>]> {
1213
        self.map_bound_ref(|fn_sig| fn_sig.inputs())
1214
    }
1215
    #[inline]
1216
    pub fn input(&self, index: usize) -> ty::Binder<Ty<'tcx>> {
1217
        self.map_bound_ref(|fn_sig| fn_sig.inputs()[index])
1218
    }
V
varkor 已提交
1219
    pub fn inputs_and_output(&self) -> ty::Binder<&'tcx List<Ty<'tcx>>> {
1220 1221
        self.map_bound_ref(|fn_sig| fn_sig.inputs_and_output)
    }
1222
    #[inline]
1223
    pub fn output(&self) -> ty::Binder<Ty<'tcx>> {
S
Shotaro Yamada 已提交
1224
        self.map_bound_ref(|fn_sig| fn_sig.output())
1225
    }
D
Dan Robertson 已提交
1226 1227
    pub fn c_variadic(&self) -> bool {
        self.skip_binder().c_variadic
1228
    }
1229 1230 1231 1232 1233 1234
    pub fn unsafety(&self) -> hir::Unsafety {
        self.skip_binder().unsafety
    }
    pub fn abi(&self) -> abi::Abi {
        self.skip_binder().abi
    }
1235 1236
}

1237 1238
pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<FnSig<'tcx>>>;

M
Matthew Jasper 已提交
1239
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
1240
#[derive(HashStable)]
1241
pub struct ParamTy {
1242
    pub index: u32,
1243
    pub name: Symbol,
1244 1245
}

1246
impl<'tcx> ParamTy {
1247
    pub fn new(index: u32, name: Symbol) -> ParamTy {
1248
        ParamTy { index, name }
1249 1250 1251
    }

    pub fn for_self() -> ParamTy {
1252
        ParamTy::new(0, kw::SelfUpper)
1253 1254
    }

1255
    pub fn for_def(def: &ty::GenericParamDef) -> ParamTy {
1256
        ParamTy::new(def.index, def.name)
1257 1258
    }

1259
    #[inline]
1260
    pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
1261
        tcx.mk_ty_param(self.index, self.name)
1262 1263 1264
    }
}

M
Matthew Jasper 已提交
1265
#[derive(Copy, Clone, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)]
1266
#[derive(HashStable)]
V
varkor 已提交
1267 1268
pub struct ParamConst {
    pub index: u32,
1269
    pub name: Symbol,
V
varkor 已提交
1270 1271
}

1272
impl<'tcx> ParamConst {
1273
    pub fn new(index: u32, name: Symbol) -> ParamConst {
V
varkor 已提交
1274 1275 1276 1277 1278 1279 1280
        ParamConst { index, name }
    }

    pub fn for_def(def: &ty::GenericParamDef) -> ParamConst {
        ParamConst::new(def.index, def.name)
    }

1281
    pub fn to_const(self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
V
varkor 已提交
1282 1283 1284 1285
        tcx.mk_const_param(self.index, self.name, ty)
    }
}

1286
pub type Region<'tcx> = &'tcx RegionKind;
N
Niko Matsakis 已提交
1287

M
Matthew Jasper 已提交
1288 1289 1290 1291 1292
/// Representation of regions. Note that the NLL checker uses a distinct
/// representation of regions. For this reason, it internally replaces all the
/// regions with inference variables -- the index of the variable is then used
/// to index into internal NLL data structures. See `rustc_mir::borrow_check`
/// module for more information.
1293
///
N
Niko Matsakis 已提交
1294 1295
/// ## The Region lattice within a given function
///
M
Matthew Jasper 已提交
1296
/// In general, the region lattice looks like
N
Niko Matsakis 已提交
1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317
///
/// ```
/// static ----------+-----...------+       (greatest)
/// |                |              |
/// early-bound and  |              |
/// free regions     |              |
/// |                |              |
/// |                |              |
/// empty(root)   placeholder(U1)   |
/// |            /                  |
/// |           /         placeholder(Un)
/// empty(U1) --         /
/// |                   /
/// ...                /
/// |                 /
/// empty(Un) --------                      (smallest)
/// ```
///
/// Early-bound/free regions are the named lifetimes in scope from the
/// function declaration. They have relationships to one another
/// determined based on the declared relationships from the
M
Matthew Jasper 已提交
1318
/// function.
N
Niko Matsakis 已提交
1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339
///
/// Note that inference variables and bound regions are not included
/// in this diagram. In the case of inference variables, they should
/// be inferred to some other region from the diagram.  In the case of
/// bound regions, they are excluded because they don't make sense to
/// include -- the diagram indicates the relationship between free
/// regions.
///
/// ## Inference variables
///
/// During region inference, we sometimes create inference variables,
/// represented as `ReVar`. These will be inferred by the code in
/// `infer::lexical_region_resolve` to some free region from the
/// lattice above (the minimal region that meets the
/// constraints).
///
/// During NLL checking, where regions are defined differently, we
/// also use `ReVar` -- in that case, the index is used to index into
/// the NLL region checker's data structures. The variable may in fact
/// represent either a free region or an inference variable, in that
/// case.
1340 1341 1342 1343
///
/// ## Bound Regions
///
/// These are regions that are stored behind a binder and must be substituted
A
Alexander Regueiro 已提交
1344 1345
/// with some concrete region before being used. There are two kind of
/// bound regions: early-bound, which are bound in an item's `Generics`,
C
csmoe 已提交
1346
/// and are substituted by a `InternalSubsts`, and late-bound, which are part of
A
Alexander Regueiro 已提交
1347
/// higher-ranked types (e.g., `for<'a> fn(&'a ())`), and are substituted by
1348 1349 1350
/// the likes of `liberate_late_bound_regions`. The distinction exists
/// because higher-ranked lifetimes aren't supported in all places. See [1][2].
///
A
Alexander Regueiro 已提交
1351
/// Unlike `Param`s, bound regions are not supposed to exist "in the wild"
1352
/// outside their binder, e.g., in types passed to type inference, and
N
Niko Matsakis 已提交
1353
/// should first be substituted (by placeholder regions, free regions,
1354 1355
/// or region variables).
///
N
Niko Matsakis 已提交
1356
/// ## Placeholder and Free Regions
1357 1358 1359 1360 1361 1362 1363
///
/// One often wants to work with bound regions without knowing their precise
/// identity. For example, when checking a function, the lifetime of a borrow
/// can end up being assigned to some region parameter. In these cases,
/// it must be ensured that bounds on the region can't be accidentally
/// assumed without being checked.
///
1364 1365
/// To do this, we replace the bound regions with placeholder markers,
/// which don't satisfy any relation not explicitly provided.
1366
///
A
Alexander Regueiro 已提交
1367
/// There are two kinds of placeholder regions in rustc: `ReFree` and
N
Niko Matsakis 已提交
1368
/// `RePlaceholder`. When checking an item's body, `ReFree` is supposed
1369 1370 1371
/// to be used. These also support explicit bounds: both the internally-stored
/// *scope*, which the region is assumed to outlive, as well as other
/// relations stored in the `FreeRegionMap`. Note that these relations
1372
/// aren't checked when you `make_subregion` (or `eq_types`), only by
1373 1374 1375 1376
/// `resolve_regions_and_report_errors`.
///
/// When working with higher-ranked types, some region relations aren't
/// yet known, so you can't just call `resolve_regions_and_report_errors`.
N
Niko Matsakis 已提交
1377
/// `RePlaceholder` is designed for this purpose. In these contexts,
1378
/// there's also the risk that some inference variable laying around will
N
Niko Matsakis 已提交
1379
/// get unified with your placeholder region: if you want to check whether
1380
/// `for<'a> Foo<'_>: 'a`, and you substitute your bound region `'a`
N
Niko Matsakis 已提交
1381 1382
/// with a placeholder region `'%a`, the variable `'_` would just be
/// instantiated to the placeholder region `'%a`, which is wrong because
1383
/// the inference variable is supposed to satisfy the relation
N
Niko Matsakis 已提交
1384
/// *for every value of the placeholder region*. To ensure that doesn't
1385
/// happen, you can use `leak_check`. This is more clearly explained
1386
/// by the [rustc dev guide].
1387
///
1388 1389
/// [1]: http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
/// [2]: http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
1390
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
M
Matthew Jasper 已提交
1391
#[derive(Clone, PartialEq, Eq, Hash, Copy, TyEncodable, TyDecodable, PartialOrd, Ord)]
1392
pub enum RegionKind {
D
Dan Robertson 已提交
1393 1394 1395
    /// Region bound in a type or fn declaration which will be
    /// substituted 'early' -- that is, at the same time when type
    /// parameters are substituted.
1396 1397
    ReEarlyBound(EarlyBoundRegion),

D
Dan Robertson 已提交
1398 1399
    /// Region bound in a function scope, which will be substituted when the
    /// function is called.
L
LeSeulArtichaut 已提交
1400
    ReLateBound(ty::DebruijnIndex, BoundRegion),
1401 1402 1403 1404

    /// When checking a function body, the types of all arguments and so forth
    /// that refer to bound region parameters are modified to refer to free
    /// region parameters.
1405
    ReFree(FreeRegion),
1406 1407 1408 1409

    /// Static data that has an "infinite" lifetime. Top in the region lattice.
    ReStatic,

A
Alexander Regueiro 已提交
1410
    /// A region variable. Should not exist after typeck.
1411 1412
    ReVar(RegionVid),

1413
    /// A placeholder region -- basically, the higher-ranked version of `ReFree`.
1414
    /// Should not exist after typeck.
S
scalexm 已提交
1415
    RePlaceholder(ty::PlaceholderRegion),
1416

N
Niko Matsakis 已提交
1417 1418 1419
    /// Empty lifetime is for data that is never accessed.  We tag the
    /// empty lifetime with a universe -- the idea is that we don't
    /// want `exists<'a> { forall<'b> { 'b: 'a } }` to be satisfiable.
N
Niko Matsakis 已提交
1420 1421 1422
    /// Therefore, the `'empty` in a universe `U` is less than all
    /// regions visible from `U`, but not less than regions not visible
    /// from `U`.
N
Niko Matsakis 已提交
1423
    ReEmpty(ty::UniverseIndex),
1424

I
Irina Popa 已提交
1425
    /// Erased region, used by trait selection, in MIR and during codegen.
1426
    ReErased,
1427 1428
}

M
Matthew Jasper 已提交
1429
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, PartialOrd, Ord)]
1430
pub struct EarlyBoundRegion {
1431
    pub def_id: DefId,
1432
    pub index: u32,
1433
    pub name: Symbol,
1434 1435
}

C
Camelid 已提交
1436
/// A **`const`** **v**ariable **ID**.
M
Matthew Jasper 已提交
1437
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
V
varkor 已提交
1438 1439 1440 1441 1442
pub struct ConstVid<'tcx> {
    pub index: u32,
    pub phantom: PhantomData<&'tcx ()>,
}

1443
rustc_index::newtype_index! {
C
Camelid 已提交
1444
    /// A **region** (lifetime) **v**ariable **ID**.
1445
    pub struct RegionVid {
1446
        DEBUG_FORMAT = custom,
1447 1448
    }
}
1449

1450 1451 1452 1453 1454 1455
impl Atom for RegionVid {
    fn index(self) -> usize {
        Idx::index(self)
    }
}

1456
rustc_index::newtype_index! {
S
scalexm 已提交
1457
    pub struct BoundVar { .. }
1458
}
1459

M
Matthew Jasper 已提交
1460
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
1461
#[derive(HashStable)]
1462
pub struct BoundTy {
S
scalexm 已提交
1463
    pub var: BoundVar,
S
scalexm 已提交
1464
    pub kind: BoundTyKind,
1465 1466
}

M
Matthew Jasper 已提交
1467
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
1468
#[derive(HashStable)]
S
scalexm 已提交
1469 1470
pub enum BoundTyKind {
    Anon,
1471
    Param(Symbol),
S
scalexm 已提交
1472 1473
}

1474 1475
impl From<BoundVar> for BoundTy {
    fn from(var: BoundVar) -> Self {
M
Mark Rousskov 已提交
1476
        BoundTy { var, kind: BoundTyKind::Anon }
S
scalexm 已提交
1477 1478
    }
}
1479

1480
/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
M
Matthew Jasper 已提交
1481
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
C
Camille GILLOT 已提交
1482
#[derive(HashStable, TypeFoldable)]
1483
pub struct ExistentialProjection<'tcx> {
1484
    pub item_def_id: DefId,
C
csmoe 已提交
1485
    pub substs: SubstsRef<'tcx>,
T
Tshepang Lekhonkhobe 已提交
1486
    pub ty: Ty<'tcx>,
1487 1488
}

1489 1490
pub type PolyExistentialProjection<'tcx> = Binder<ExistentialProjection<'tcx>>;

1491
impl<'tcx> ExistentialProjection<'tcx> {
1492 1493 1494 1495
    /// Extracts the underlying existential trait reference from this projection.
    /// For example, if this is a projection of `exists T. <T as Iterator>::Item == X`,
    /// then this function would return a `exists T. T: Iterator` existential trait
    /// reference.
1496
    pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::ExistentialTraitRef<'tcx> {
1497
        let def_id = tcx.associated_item(self.item_def_id).container.id();
1498 1499 1500
        let subst_count = tcx.generics_of(def_id).count() - 1;
        let substs = tcx.intern_substs(&self.substs[..subst_count]);
        ty::ExistentialTraitRef { def_id, substs }
1501 1502
    }

1503 1504
    pub fn with_self_ty(
        &self,
1505
        tcx: TyCtxt<'tcx>,
1506 1507
        self_ty: Ty<'tcx>,
    ) -> ty::ProjectionPredicate<'tcx> {
1508
        // otherwise the escaping regions would be captured by the binders
1509
        debug_assert!(!self_ty.has_escaping_bound_vars());
1510

1511
        ty::ProjectionPredicate {
1512 1513
            projection_ty: ty::ProjectionTy {
                item_def_id: self.item_def_id,
1514
                substs: tcx.mk_substs_trait(self_ty, self.substs),
1515
            },
T
Tshepang Lekhonkhobe 已提交
1516
            ty: self.ty,
1517
        }
1518
    }
1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532

    pub fn erase_self_ty(
        tcx: TyCtxt<'tcx>,
        projection_predicate: ty::ProjectionPredicate<'tcx>,
    ) -> Self {
        // Assert there is a Self.
        projection_predicate.projection_ty.substs.type_at(0);

        Self {
            item_def_id: projection_predicate.projection_ty.item_def_id,
            substs: tcx.intern_substs(&projection_predicate.projection_ty.substs[1..]),
            ty: projection_predicate.ty,
        }
    }
1533 1534
}

1535
impl<'tcx> PolyExistentialProjection<'tcx> {
1536 1537
    pub fn with_self_ty(
        &self,
1538
        tcx: TyCtxt<'tcx>,
1539 1540
        self_ty: Ty<'tcx>,
    ) -> ty::PolyProjectionPredicate<'tcx> {
1541
        self.map_bound(|p| p.with_self_ty(tcx, self_ty))
1542
    }
1543 1544

    pub fn item_def_id(&self) -> DefId {
1545
        self.skip_binder().item_def_id
1546
    }
1547 1548
}

1549
/// Region utilities
1550
impl RegionKind {
D
David Wood 已提交
1551 1552 1553 1554
    /// Is this region named by the user?
    pub fn has_name(&self) -> bool {
        match *self {
            RegionKind::ReEarlyBound(ebr) => ebr.has_name(),
1555
            RegionKind::ReLateBound(_, br) => br.kind.is_named(),
D
David Wood 已提交
1556 1557 1558
            RegionKind::ReFree(fr) => fr.bound_region.is_named(),
            RegionKind::ReStatic => true,
            RegionKind::ReVar(..) => false,
1559
            RegionKind::RePlaceholder(placeholder) => placeholder.name.is_named(),
N
Niko Matsakis 已提交
1560
            RegionKind::ReEmpty(_) => false,
D
David Wood 已提交
1561 1562 1563 1564
            RegionKind::ReErased => false,
        }
    }

1565
    #[inline]
1566
    pub fn is_late_bound(&self) -> bool {
1567
        matches!(*self, ty::ReLateBound(..))
1568 1569
    }

1570
    #[inline]
N
Niko Matsakis 已提交
1571
    pub fn is_placeholder(&self) -> bool {
1572
        matches!(*self, ty::RePlaceholder(..))
N
Niko Matsakis 已提交
1573 1574
    }

1575
    #[inline]
L
LeSeulArtichaut 已提交
1576
    pub fn bound_at_or_above_binder(&self, index: ty::DebruijnIndex) -> bool {
1577
        match *self {
1578
            ty::ReLateBound(debruijn, _) => debruijn >= index,
1579 1580 1581 1582
            _ => false,
        }
    }

A
Alexander Regueiro 已提交
1583
    /// Adjusts any De Bruijn indices so as to make `to_binder` the
1584 1585 1586 1587 1588 1589 1590 1591 1592
    /// innermost binder. That is, if we have something bound at `to_binder`,
    /// it will now be bound at INNERMOST. This is an appropriate thing to do
    /// when moving a region out from inside binders:
    ///
    /// ```
    ///             for<'a>   fn(for<'b>   for<'c>   fn(&'a u32), _)
    /// // Binder:  D3           D2        D1            ^^
    /// ```
    ///
A
Alexander Regueiro 已提交
1593
    /// Here, the region `'a` would have the De Bruijn index D3,
1594 1595 1596 1597
    /// because it is the bound 3 binders out. However, if we wanted
    /// to refer to that region `'a` in the second argument (the `_`),
    /// those two binders would not be in scope. In that case, we
    /// might invoke `shift_out_to_binder(D3)`. This would adjust the
A
Alexander Regueiro 已提交
1598
    /// De Bruijn index of `'a` to D1 (the innermost binder).
1599 1600 1601 1602 1603
    ///
    /// If we invoke `shift_out_to_binder` and the region is in fact
    /// bound by one of the binders we are shifting out of, that is an
    /// error (and should fail an assertion failure).
    pub fn shifted_out_to_binder(&self, to_binder: ty::DebruijnIndex) -> RegionKind {
1604
        match *self {
M
Mark Rousskov 已提交
1605 1606 1607 1608
            ty::ReLateBound(debruijn, r) => {
                ty::ReLateBound(debruijn.shifted_out_to_binder(to_binder), r)
            }
            r => r,
1609 1610
        }
    }
1611 1612 1613 1614 1615 1616

    pub fn type_flags(&self) -> TypeFlags {
        let mut flags = TypeFlags::empty();

        match *self {
            ty::ReVar(..) => {
1617
                flags = flags | TypeFlags::HAS_FREE_REGIONS;
1618
                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
1619 1620
                flags = flags | TypeFlags::HAS_RE_INFER;
            }
N
Niko Matsakis 已提交
1621
            ty::RePlaceholder(..) => {
1622
                flags = flags | TypeFlags::HAS_FREE_REGIONS;
1623
                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
1624
                flags = flags | TypeFlags::HAS_RE_PLACEHOLDER;
1625
            }
1626 1627
            ty::ReEarlyBound(..) => {
                flags = flags | TypeFlags::HAS_FREE_REGIONS;
1628
                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
M
Matthew Jasper 已提交
1629
                flags = flags | TypeFlags::HAS_RE_PARAM;
1630
            }
M
Matthew Jasper 已提交
1631
            ty::ReFree { .. } => {
1632
                flags = flags | TypeFlags::HAS_FREE_REGIONS;
1633
                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
1634
            }
1635 1636
            ty::ReEmpty(_) | ty::ReStatic => {
                flags = flags | TypeFlags::HAS_FREE_REGIONS;
1637
            }
1638 1639 1640 1641 1642 1643
            ty::ReLateBound(..) => {
                flags = flags | TypeFlags::HAS_RE_LATE_BOUND;
            }
            ty::ReErased => {
                flags = flags | TypeFlags::HAS_RE_ERASED;
            }
1644 1645 1646 1647 1648 1649
        }

        debug!("type_flags({:?}) = {:?}", self, flags);

        flags
    }
1650

A
Alexander Regueiro 已提交
1651
    /// Given an early-bound or free region, returns the `DefId` where it was bound.
1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665
    /// For example, consider the regions in this snippet of code:
    ///
    /// ```
    /// impl<'a> Foo {
    ///      ^^ -- early bound, declared on an impl
    ///
    ///     fn bar<'b, 'c>(x: &self, y: &'b u32, z: &'c u64) where 'static: 'c
    ///            ^^  ^^     ^ anonymous, late-bound
    ///            |   early-bound, appears in where-clauses
    ///            late-bound, appears only in fn args
    ///     {..}
    /// }
    /// ```
    ///
A
Alexander Regueiro 已提交
1666
    /// Here, `free_region_binding_scope('a)` would return the `DefId`
1667
    /// of the impl, and for all the other highlighted regions, it
A
Alexander Regueiro 已提交
1668 1669
    /// would return the `DefId` of the function. In other cases (not shown), this
    /// function might return the `DefId` of a closure.
1670
    pub fn free_region_binding_scope(&self, tcx: TyCtxt<'_>) -> DefId {
1671
        match self {
M
Mark Rousskov 已提交
1672
            ty::ReEarlyBound(br) => tcx.parent(br.def_id).unwrap(),
1673 1674 1675 1676
            ty::ReFree(fr) => fr.scope,
            _ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self),
        }
    }
1677 1678
}

1679
/// Type utilities
1680
impl<'tcx> TyS<'tcx> {
L
LeSeulArtichaut 已提交
1681 1682 1683 1684 1685
    #[inline(always)]
    pub fn kind(&self) -> &TyKind<'tcx> {
        &self.kind
    }

L
LeSeulArtichaut 已提交
1686 1687 1688 1689 1690
    #[inline(always)]
    pub fn flags(&self) -> TypeFlags {
        self.flags
    }

1691
    #[inline]
K
kenta7777 已提交
1692
    pub fn is_unit(&self) -> bool {
L
LeSeulArtichaut 已提交
1693
        match self.kind() {
V
varkor 已提交
1694
            Tuple(ref tys) => tys.is_empty(),
T
Tshepang Lekhonkhobe 已提交
1695
            _ => false,
1696 1697 1698
        }
    }

1699
    #[inline]
A
Andrew Cann 已提交
1700
    pub fn is_never(&self) -> bool {
1701
        matches!(self.kind(), Never)
A
Andrew Cann 已提交
1702 1703
    }

1704
    #[inline]
1705
    pub fn is_primitive(&self) -> bool {
L
LeSeulArtichaut 已提交
1706 1707 1708 1709 1710
        self.kind().is_primitive()
    }

    #[inline]
    pub fn is_adt(&self) -> bool {
1711
        matches!(self.kind(), Adt(..))
L
LeSeulArtichaut 已提交
1712 1713 1714 1715
    }

    #[inline]
    pub fn is_ref(&self) -> bool {
1716
        matches!(self.kind(), Ref(..))
1717 1718
    }

1719
    #[inline]
1720
    pub fn is_ty_var(&self) -> bool {
1721
        matches!(self.kind(), Infer(TyVar(_)))
1722 1723
    }

1724
    #[inline]
L
leonardo.yvens 已提交
1725
    pub fn is_ty_infer(&self) -> bool {
1726
        matches!(self.kind(), Infer(_))
L
leonardo.yvens 已提交
1727 1728
    }

1729
    #[inline]
1730
    pub fn is_phantom_data(&self) -> bool {
L
LeSeulArtichaut 已提交
1731
        if let Adt(def, _) = self.kind() { def.is_phantom_data() } else { false }
1732 1733
    }

1734
    #[inline]
M
Mark Rousskov 已提交
1735
    pub fn is_bool(&self) -> bool {
L
LeSeulArtichaut 已提交
1736
        *self.kind() == Bool
M
Mark Rousskov 已提交
1737
    }
1738

G
Guanqun Lu 已提交
1739 1740
    /// Returns `true` if this type is a `str`.
    #[inline]
M
Mark Rousskov 已提交
1741
    pub fn is_str(&self) -> bool {
L
LeSeulArtichaut 已提交
1742
        *self.kind() == Str
M
Mark Rousskov 已提交
1743
    }
G
Guanqun Lu 已提交
1744

1745
    #[inline]
1746
    pub fn is_param(&self, index: u32) -> bool {
L
LeSeulArtichaut 已提交
1747
        match self.kind() {
1748
            ty::Param(ref data) => data.index == index,
1749 1750 1751 1752
            _ => false,
        }
    }

1753
    #[inline]
1754
    pub fn is_slice(&self) -> bool {
L
LeSeulArtichaut 已提交
1755
        match self.kind() {
1756
            RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => matches!(ty.kind(), Slice(_) | Str),
M
Mark Rousskov 已提交
1757
            _ => false,
1758 1759 1760
        }
    }

L
LeSeulArtichaut 已提交
1761 1762
    #[inline]
    pub fn is_array(&self) -> bool {
1763
        matches!(self.kind(), Array(..))
L
LeSeulArtichaut 已提交
1764 1765
    }

1766 1767
    #[inline]
    pub fn is_simd(&self) -> bool {
L
LeSeulArtichaut 已提交
1768
        match self.kind() {
V
varkor 已提交
1769
            Adt(def, _) => def.repr.simd(),
T
Tshepang Lekhonkhobe 已提交
1770
            _ => false,
1771 1772 1773
        }
    }

1774
    pub fn sequence_element_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
L
LeSeulArtichaut 已提交
1775
        match self.kind() {
V
varkor 已提交
1776
            Array(ty, _) | Slice(ty) => ty,
1777
            Str => tcx.mk_mach_uint(ty::UintTy::U8),
1778
            _ => bug!("`sequence_element_type` called on non-sequence value: {}", self),
1779 1780 1781
        }
    }

R
Ralf Jung 已提交
1782
    pub fn simd_size_and_type(&self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) {
L
LeSeulArtichaut 已提交
1783
        match self.kind() {
R
Ralf Jung 已提交
1784 1785
            Adt(def, substs) => {
                let variant = def.non_enum_variant();
1786 1787 1788
                let f0_ty = variant.fields[0].ty(tcx, substs);

                match f0_ty.kind() {
1789 1790 1791 1792 1793 1794 1795
                    Array(f0_elem_ty, f0_len) => {
                        // FIXME(repr_simd): https://github.com/rust-lang/rust/pull/78863#discussion_r522784112
                        // The way we evaluate the `N` in `[T; N]` here only works since we use
                        // `simd_size_and_type` post-monomorphization. It will probably start to ICE
                        // if we use it in generic code. See the `simd-array-trait` ui test.
                        (f0_len.eval_usize(tcx, ParamEnv::empty()) as u64, f0_elem_ty)
                    }
1796 1797
                    _ => (variant.fields.len() as u64, f0_ty),
                }
R
Ralf Jung 已提交
1798
            }
1799
            _ => bug!("`simd_size_and_type` called on invalid type"),
R
Ralf Jung 已提交
1800 1801 1802
        }
    }

1803
    #[inline]
1804
    pub fn is_region_ptr(&self) -> bool {
1805
        matches!(self.kind(), Ref(..))
1806 1807
    }

1808
    #[inline]
1809
    pub fn is_mutable_ptr(&self) -> bool {
1810 1811
        matches!(
            self.kind(),
M
Mark Rousskov 已提交
1812
            RawPtr(TypeAndMut { mutbl: hir::Mutability::Mut, .. })
1813 1814
                | Ref(_, _, hir::Mutability::Mut)
        )
1815 1816
    }

1817 1818 1819 1820 1821 1822 1823 1824 1825
    /// Get the mutability of the reference or `None` when not a reference
    #[inline]
    pub fn ref_mutability(&self) -> Option<hir::Mutability> {
        match self.kind() {
            Ref(_, _, mutability) => Some(*mutability),
            _ => None,
        }
    }

1826
    #[inline]
1827
    pub fn is_unsafe_ptr(&self) -> bool {
1828
        matches!(self.kind(), RawPtr(_))
1829 1830
    }

1831 1832 1833 1834 1835 1836
    /// Tests if this is any kind of primitive pointer type (reference, raw pointer, fn pointer).
    #[inline]
    pub fn is_any_ptr(&self) -> bool {
        self.is_region_ptr() || self.is_unsafe_ptr() || self.is_fn_ptr()
    }

1837
    #[inline]
1838
    pub fn is_box(&self) -> bool {
L
LeSeulArtichaut 已提交
1839
        match self.kind() {
V
varkor 已提交
1840
            Adt(def, _) => def.is_box(),
1841 1842 1843 1844
            _ => false,
        }
    }

1845
    /// Panics if called on any type other than `Box<T>`.
1846
    pub fn boxed_ty(&self) -> Ty<'tcx> {
L
LeSeulArtichaut 已提交
1847
        match self.kind() {
V
varkor 已提交
1848
            Adt(def, substs) if def.is_box() => substs.type_at(0),
1849
            _ => bug!("`boxed_ty` is called on non-box type {:?}", self),
1850 1851 1852
        }
    }

1853
    /// A scalar type is one that denotes an atomic datum, with no sub-components.
V
varkor 已提交
1854
    /// (A RawPtr is scalar because it represents a non-managed pointer, so its
1855
    /// contents are abstract to rustc.)
1856
    #[inline]
1857
    pub fn is_scalar(&self) -> bool {
1858 1859
        matches!(
            self.kind(),
M
Mark Rousskov 已提交
1860 1861 1862 1863 1864 1865 1866 1867
            Bool | Char
                | Int(_)
                | Float(_)
                | Uint(_)
                | FnDef(..)
                | FnPtr(_)
                | RawPtr(_)
                | Infer(IntVar(_) | FloatVar(_))
1868
        )
1869 1870
    }

A
Alexander Regueiro 已提交
1871
    /// Returns `true` if this type is a floating point type.
1872
    #[inline]
1873
    pub fn is_floating_point(&self) -> bool {
1874
        matches!(self.kind(), Float(_) | Infer(FloatVar(_)))
1875 1876
    }

1877
    #[inline]
1878
    pub fn is_trait(&self) -> bool {
1879
        matches!(self.kind(), Dynamic(..))
1880 1881
    }

1882
    #[inline]
1883
    pub fn is_enum(&self) -> bool {
L
LeSeulArtichaut 已提交
1884
        match self.kind() {
M
Mark Rousskov 已提交
1885
            Adt(adt_def, _) => adt_def.is_enum(),
1886 1887 1888 1889
            _ => false,
        }
    }

1890
    #[inline]
1891
    pub fn is_closure(&self) -> bool {
1892
        matches!(self.kind(), Closure(..))
1893 1894
    }

1895
    #[inline]
1896
    pub fn is_generator(&self) -> bool {
1897
        matches!(self.kind(), Generator(..))
1898 1899
    }

1900
    #[inline]
1901
    pub fn is_integral(&self) -> bool {
1902
        matches!(self.kind(), Infer(IntVar(_)) | Int(_) | Uint(_))
1903 1904
    }

1905
    #[inline]
1906
    pub fn is_fresh_ty(&self) -> bool {
1907
        matches!(self.kind(), Infer(FreshTy(_)))
1908 1909
    }

1910
    #[inline]
1911
    pub fn is_fresh(&self) -> bool {
1912
        matches!(self.kind(), Infer(FreshTy(_) | FreshIntTy(_) | FreshFloatTy(_)))
1913 1914
    }

1915
    #[inline]
1916
    pub fn is_char(&self) -> bool {
1917
        matches!(self.kind(), Char)
1918 1919
    }

1920
    #[inline]
1921
    pub fn is_numeric(&self) -> bool {
1922
        self.is_integral() || self.is_floating_point()
1923 1924
    }

1925
    #[inline]
1926
    pub fn is_signed(&self) -> bool {
1927
        matches!(self.kind(), Int(_))
1928 1929
    }

1930
    #[inline]
1931
    pub fn is_ptr_sized_integral(&self) -> bool {
1932
        matches!(self.kind(), Int(ty::IntTy::Isize) | Uint(ty::UintTy::Usize))
V
varkor 已提交
1933 1934
    }

1935
    #[inline]
1936
    pub fn is_machine(&self) -> bool {
1937
        matches!(self.kind(), Int(..) | Uint(..) | Float(..))
1938 1939
    }

1940
    #[inline]
1941
    pub fn has_concrete_skeleton(&self) -> bool {
1942
        !matches!(self.kind(), Param(_) | Infer(_) | Error(_))
1943 1944
    }

1945
    /// Returns the type and mutability of `*ty`.
1946 1947
    ///
    /// The parameter `explicit` indicates if this is an *explicit* dereference.
1948
    /// Some types -- notably unsafe ptrs -- can only be dereferenced explicitly.
1949
    pub fn builtin_deref(&self, explicit: bool) -> Option<TypeAndMut<'tcx>> {
L
LeSeulArtichaut 已提交
1950
        match self.kind() {
V
varkor 已提交
1951
            Adt(def, _) if def.is_box() => {
M
Mark Rousskov 已提交
1952 1953
                Some(TypeAndMut { ty: self.boxed_ty(), mutbl: hir::Mutability::Not })
            }
L
LeSeulArtichaut 已提交
1954 1955
            Ref(_, ty, mutbl) => Some(TypeAndMut { ty, mutbl: *mutbl }),
            RawPtr(mt) if explicit => Some(*mt),
T
Tshepang Lekhonkhobe 已提交
1956
            _ => None,
1957 1958 1959
        }
    }

1960
    /// Returns the type of `ty[i]`.
1961
    pub fn builtin_index(&self) -> Option<Ty<'tcx>> {
L
LeSeulArtichaut 已提交
1962
        match self.kind() {
V
varkor 已提交
1963
            Array(ty, _) | Slice(ty) => Some(ty),
T
Tshepang Lekhonkhobe 已提交
1964
            _ => None,
1965 1966 1967
        }
    }

1968
    pub fn fn_sig(&self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> {
L
LeSeulArtichaut 已提交
1969 1970 1971
        match self.kind() {
            FnDef(def_id, substs) => tcx.fn_sig(*def_id).subst(tcx, substs),
            FnPtr(f) => *f,
1972
            Error(_) => {
M
Mark Rousskov 已提交
1973
                // ignore errors (#54954)
1974 1975
                ty::Binder::dummy(FnSig::fake())
            }
1976 1977 1978
            Closure(..) => bug!(
                "to get the signature of a closure, use `substs.as_closure().sig()` not `fn_sig()`",
            ),
M
Mark Rousskov 已提交
1979
            _ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self),
1980 1981 1982
        }
    }

1983
    #[inline]
1984
    pub fn is_fn(&self) -> bool {
1985
        matches!(self.kind(), FnDef(..) | FnPtr(_))
1986 1987
    }

1988 1989
    #[inline]
    pub fn is_fn_ptr(&self) -> bool {
1990
        matches!(self.kind(), FnPtr(_))
1991 1992
    }

1993
    #[inline]
1994
    pub fn is_impl_trait(&self) -> bool {
1995
        matches!(self.kind(), Opaque(..))
1996 1997
    }

1998
    #[inline]
1999
    pub fn ty_adt_def(&self) -> Option<&'tcx AdtDef> {
L
LeSeulArtichaut 已提交
2000
        match self.kind() {
V
varkor 已提交
2001
            Adt(adt, _) => Some(adt),
T
Tshepang Lekhonkhobe 已提交
2002
            _ => None,
2003 2004
        }
    }
2005

2006 2007
    /// Iterates over tuple fields.
    /// Panics when called on anything but a tuple.
M
Mark Rousskov 已提交
2008
    pub fn tuple_fields(&self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> {
L
LeSeulArtichaut 已提交
2009
        match self.kind() {
2010 2011
            Tuple(substs) => substs.iter().map(|field| field.expect_ty()),
            _ => bug!("tuple_fields called on non-tuple"),
A
Aman Arora 已提交
2012 2013 2014 2015 2016 2017 2018 2019 2020
        }
    }

    /// Get the `i`-th element of a tuple.
    /// Panics when called on anything but a tuple.
    pub fn tuple_element_ty(&self, i: usize) -> Option<Ty<'tcx>> {
        match self.kind() {
            Tuple(substs) => substs.iter().nth(i).map(|field| field.expect_ty()),
            _ => bug!("tuple_fields called on non-tuple"),
2021 2022 2023
        }
    }

2024
    /// If the type contains variants, returns the valid range of variant indices.
2025 2026
    //
    // FIXME: This requires the optimized MIR in the case of generators.
2027
    #[inline]
2028
    pub fn variant_range(&self, tcx: TyCtxt<'tcx>) -> Option<Range<VariantIdx>> {
L
LeSeulArtichaut 已提交
2029
        match self.kind() {
2030
            TyKind::Adt(adt, _) => Some(adt.variant_range()),
M
Mark Rousskov 已提交
2031
            TyKind::Generator(def_id, substs, _) => {
L
LeSeulArtichaut 已提交
2032
                Some(substs.as_generator().variant_range(*def_id, tcx))
M
Mark Rousskov 已提交
2033
            }
2034 2035 2036 2037 2038 2039
            _ => None,
        }
    }

    /// If the type contains variants, returns the variant for `variant_index`.
    /// Panics if `variant_index` is out of range.
2040 2041
    //
    // FIXME: This requires the optimized MIR in the case of generators.
2042 2043 2044
    #[inline]
    pub fn discriminant_for_variant(
        &self,
2045
        tcx: TyCtxt<'tcx>,
2046
        variant_index: VariantIdx,
2047
    ) -> Option<Discr<'tcx>> {
L
LeSeulArtichaut 已提交
2048
        match self.kind() {
2049 2050 2051
            TyKind::Adt(adt, _) if adt.variants.is_empty() => {
                bug!("discriminant_for_variant called on zero variant enum");
            }
R
Ralf Jung 已提交
2052 2053 2054
            TyKind::Adt(adt, _) if adt.is_enum() => {
                Some(adt.discriminant_for_variant(tcx, variant_index))
            }
M
Mark Rousskov 已提交
2055
            TyKind::Generator(def_id, substs, _) => {
L
LeSeulArtichaut 已提交
2056
                Some(substs.as_generator().discriminant_for_variant(*def_id, tcx, variant_index))
M
Mark Rousskov 已提交
2057
            }
2058
            _ => None,
2059 2060
        }
    }
2061

2062
    /// Returns the type of the discriminant of this type.
2063
    pub fn discriminant_ty(&'tcx self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
L
LeSeulArtichaut 已提交
2064
        match self.kind() {
R
Ralf Jung 已提交
2065
            ty::Adt(adt, _) if adt.is_enum() => adt.repr.discr_type().to_ty(tcx),
2066
            ty::Generator(_, substs, _) => substs.as_generator().discr_ty(tcx),
2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100

            ty::Param(_) | ty::Projection(_) | ty::Opaque(..) | ty::Infer(ty::TyVar(_)) => {
                let assoc_items =
                    tcx.associated_items(tcx.lang_items().discriminant_kind_trait().unwrap());
                let discriminant_def_id = assoc_items.in_definition_order().next().unwrap().def_id;
                tcx.mk_projection(discriminant_def_id, tcx.mk_substs([self.into()].iter()))
            }

            ty::Bool
            | ty::Char
            | ty::Int(_)
            | ty::Uint(_)
            | ty::Float(_)
            | ty::Adt(..)
            | ty::Foreign(_)
            | ty::Str
            | ty::Array(..)
            | ty::Slice(_)
            | ty::RawPtr(_)
            | ty::Ref(..)
            | ty::FnDef(..)
            | ty::FnPtr(..)
            | ty::Dynamic(..)
            | ty::Closure(..)
            | ty::GeneratorWitness(..)
            | ty::Never
            | ty::Tuple(_)
            | ty::Error(_)
            | ty::Infer(IntVar(_) | FloatVar(_)) => tcx.types.u8,

            ty::Bound(..)
            | ty::Placeholder(_)
            | ty::Infer(FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
                bug!("`discriminant_ty` applied to unexpected type: {:?}", self)
R
Ralf Jung 已提交
2101
            }
2102 2103 2104
        }
    }

2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135
    /// Returns the type of metadata for (potentially fat) pointers to this type.
    pub fn ptr_metadata_ty(&'tcx self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
        // FIXME: should this normalize?
        let tail = tcx.struct_tail_without_normalization(self);
        match tail.kind() {
            // Sized types
            ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
            | ty::Uint(_)
            | ty::Int(_)
            | ty::Bool
            | ty::Float(_)
            | ty::FnDef(..)
            | ty::FnPtr(_)
            | ty::RawPtr(..)
            | ty::Char
            | ty::Ref(..)
            | ty::Generator(..)
            | ty::GeneratorWitness(..)
            | ty::Array(..)
            | ty::Closure(..)
            | ty::Never
            | ty::Error(_)
            | ty::Foreign(..)
            // If returned by `struct_tail_without_normalization` this is a unit struct
            // without any fields, or not a struct, and therefore is Sized.
            | ty::Adt(..)
            // If returned by `struct_tail_without_normalization` this is the empty tuple,
            // a.k.a. unit type, which is Sized
            | ty::Tuple(..) => tcx.types.unit,

            ty::Str | ty::Slice(_) => tcx.types.usize,
2136 2137 2138 2139
            ty::Dynamic(..) => {
                let dyn_metadata = tcx.lang_items().dyn_metadata().unwrap();
                tcx.type_of(dyn_metadata).subst(tcx, &[tail.into()])
            },
2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152

            ty::Projection(_)
            | ty::Param(_)
            | ty::Opaque(..)
            | ty::Infer(ty::TyVar(_))
            | ty::Bound(..)
            | ty::Placeholder(..)
            | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
                bug!("`ptr_metadata_ty` applied to unexpected type: {:?}", tail)
            }
        }
    }

2153 2154 2155 2156 2157 2158 2159 2160 2161 2162
    /// When we create a closure, we record its kind (i.e., what trait
    /// it implements) into its `ClosureSubsts` using a type
    /// parameter. This is kind of a phantom type, except that the
    /// most convenient thing for us to are the integral types. This
    /// function converts such a special type into the closure
    /// kind. To go the other way, use
    /// `tcx.closure_kind_ty(closure_kind)`.
    ///
    /// Note that during type checking, we use an inference variable
    /// to represent the closure kind, because it has not yet been
M
Malo Jaffré 已提交
2163 2164
    /// inferred. Once upvar inference (in `src/librustc_typeck/check/upvar.rs`)
    /// is complete, that type variable will be unified.
2165
    pub fn to_opt_closure_kind(&self) -> Option<ty::ClosureKind> {
L
LeSeulArtichaut 已提交
2166
        match self.kind() {
2167
            Int(int_ty) => match int_ty {
2168 2169 2170
                ty::IntTy::I8 => Some(ty::ClosureKind::Fn),
                ty::IntTy::I16 => Some(ty::ClosureKind::FnMut),
                ty::IntTy::I32 => Some(ty::ClosureKind::FnOnce),
2171 2172 2173
                _ => bug!("cannot convert type `{:?}` to a closure kind", self),
            },

2174 2175 2176
            // "Bound" types appear in canonical queries when the
            // closure type is not yet known
            Bound(..) | Infer(_) => None,
2177

2178
            Error(_) => Some(ty::ClosureKind::Fn),
2179

2180 2181 2182
            _ => bug!("cannot convert type `{:?}` to a closure kind", self),
        }
    }
2183 2184 2185 2186 2187

    /// Fast path helper for testing if a type is `Sized`.
    ///
    /// Returning true means the type is known to be sized. Returning
    /// `false` means nothing -- could be sized, might not be.
2188 2189 2190 2191 2192 2193
    ///
    /// Note that we could never rely on the fact that a type such as `[_]` is
    /// trivially `!Sized` because we could be in a type environment with a
    /// bound such as `[_]: Copy`. A function with such a bound obviously never
    /// can be called, but that doesn't mean it shouldn't typecheck. This is why
    /// this method doesn't return `Option<bool>`.
2194
    pub fn is_trivially_sized(&self, tcx: TyCtxt<'tcx>) -> bool {
L
LeSeulArtichaut 已提交
2195
        match self.kind() {
2196
            ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
M
Mark Rousskov 已提交
2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210
            | ty::Uint(_)
            | ty::Int(_)
            | ty::Bool
            | ty::Float(_)
            | ty::FnDef(..)
            | ty::FnPtr(_)
            | ty::RawPtr(..)
            | ty::Char
            | ty::Ref(..)
            | ty::Generator(..)
            | ty::GeneratorWitness(..)
            | ty::Array(..)
            | ty::Closure(..)
            | ty::Never
2211
            | ty::Error(_) => true,
M
Mark Rousskov 已提交
2212 2213 2214 2215 2216 2217

            ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => false,

            ty::Tuple(tys) => tys.iter().all(|ty| ty.expect_ty().is_trivially_sized(tcx)),

            ty::Adt(def, _substs) => def.sized_constraint(tcx).is_empty(),
2218

2219
            ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => false,
2220

V
varkor 已提交
2221
            ty::Infer(ty::TyVar(_)) => false,
2222

M
Mark Rousskov 已提交
2223 2224
            ty::Bound(..)
            | ty::Placeholder(..)
2225
            | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
M
Mark Rousskov 已提交
2226 2227
                bug!("`is_trivially_sized` applied to unexpected type: {:?}", self)
            }
2228 2229
        }
    }
2230
}