Struct rustc::ty::ClosureSubsts [] [src]

pub struct ClosureSubsts<'tcx> {
    pub substs: &'tcx Substs<'tcx>,
}
🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

A closure can be modeled as a struct that looks like:

struct Closure<'l0...'li, T0...Tj, U0...Uk> {
    upvar0: U0,
    ...
    upvark: Uk
}

where 'l0...'li and T0...Tj are the lifetime and type parameters in scope on the function that defined the closure, and U0...Uk are type parameters representing the types of its upvars (borrowed, if appropriate).

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:

struct Closure<'a, T, U0> {
    data: U0
}

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:

impl<'b, 'a, T> FnMut() for Closure<'a, T, &'b mut &'a mut T> {
    ...
}

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 as extra type parameters? The reason for this design is that the upvar types can reference lifetimes that are internal to the creating function. In my example above, for example, the lifetime 'b represents the scope of the closure itself; this is some subset of foo, probably just the scope of the call to the to 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 original function then? The answer is that trans may need them when monomorphizing, and they may not appear in the upvars. A 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

Fields

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

Lifetime and type parameters from the enclosing function, concatenated with the types of the upvars.

These are separated out because trans wants to pass them around when monomorphizing.

Methods

impl<'a, 'gcx, 'acx, 'tcx> ClosureSubsts<'tcx>
[src]

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

impl<'a, 'gcx, 'tcx> ClosureSubsts<'tcx>
[src]

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

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.

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

This is the types of all the fields stored in a generator. It includes the upvars, state types and the state discriminant which is u32.

Trait Implementations

impl<'tcx> HashStable<StableHashingContext<'tcx>> for ClosureSubsts<'tcx>
[src]

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

impl<'gcx> TransNormalize<'gcx> for ClosureSubsts<'gcx>
[src]

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

impl<'tcx> Relate<'tcx> for ClosureSubsts<'tcx>
[src]

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

impl<'a, 'tcx> Lift<'tcx> for ClosureSubsts<'a>
[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

impl<'tcx> TypeFoldable<'tcx> for ClosureSubsts<'tcx>
[src]

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

Indicates whether this value references only 'global' types/lifetimes that are the same regardless of what fn we are in. This is used for caching. Errs on the side of returning false. Read more

impl<'tcx> Copy for ClosureSubsts<'tcx>
[src]

impl<'tcx> Clone for ClosureSubsts<'tcx>
[src]

[src]

Returns a copy of the value. Read more

1.0.0
[src]

Performs copy-assignment from source. Read more

impl<'tcx> PartialEq for ClosureSubsts<'tcx>
[src]

[src]

This method tests for self and other values to be equal, and is used by ==. Read more

[src]

This method tests for !=.

impl<'tcx> Eq for ClosureSubsts<'tcx>
[src]

impl<'tcx> Hash for ClosureSubsts<'tcx>
[src]

[src]

Feeds this value into the given [Hasher]. Read more

1.3.0
[src]

Feeds a slice of this type into the given [Hasher]. Read more

impl<'tcx> Debug for ClosureSubsts<'tcx>
[src]

[src]

Formats the value using the given formatter.

impl<'tcx> Encodable for ClosureSubsts<'tcx>
[src]

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?

impl<'tcx> Decodable for ClosureSubsts<'tcx>
[src]

[src]

🔬 This is a nightly-only experimental API. (rustc_private)

this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml instead?