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

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

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 extent of the closure itself; this is some subset of foo, probably just the extent 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)

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]

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

Trait Implementations

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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]

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

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

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

This method tests for !=.

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

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

Feeds this value into the state given, updating the hasher as necessary.

Feeds a slice of this type into the state provided.

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

Formats the value using the given formatter.

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

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

deprecated in favor of rustc-serialize on crates.io

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

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

deprecated in favor of rustc-serialize on crates.io