Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support #[track_caller] on closures and generators #87064

Merged
merged 1 commit into from
Sep 23, 2021

Commits on Sep 22, 2021

  1. Support #[track_caller] on closures and generators

    This PR allows applying a `#[track_caller]` attribute to a
    closure/generator expression. The attribute as interpreted as applying
    to the compiler-generated implementation of the corresponding trait
    method (`FnOnce::call_once`, `FnMut::call_mut`, `Fn::call`, or
    `Generator::resume`).
    
    This feature does not have its own feature gate - however, it requires
    `#![feature(stmt_expr_attributes)]` in order to actually apply
    an attribute to a closure or generator.
    
    This is implemented in the same way as for functions - an extra
    location argument is appended to the end of the ABI. For closures,
    this argument is *not* part of the 'tupled' argument storing the
    parameters - the final closure argument for `#[track_caller]` closures
    is no longer a tuple.
    
    For direct (monomorphized) calls, the necessary support was already
    implemented - we just needeed to adjust some assertions around checking
    the ABI and argument count to take closures into account.
    
    For calls through a trait object, more work was needed.
    When creating a `ReifyShim`, we need to create a shim
    for the trait method (e.g. `FnOnce::call_mut`) - unlike normal
    functions, closures are never invoked directly, and always go through a
    trait method.
    
    Additional handling was needed for `InstanceDef::ClosureOnceShim`. In
    order to pass location information throgh a direct (monomorphized) call
    to `FnOnce::call_once` on an `FnMut` closure, we need to make
    `ClosureOnceShim` aware of `#[tracked_caller]`. A new field
    `track_caller` is added to `ClosureOnceShim` - this is used by
    `InstanceDef::requires_caller` location, allowing codegen to
    pass through the extra location argument.
    
    Since `ClosureOnceShim.track_caller` is only used by codegen,
    we end up generating two identical MIR shims - one for
    `track_caller == true`, and one for `track_caller == false`. However,
    these two shims are used by the entire crate (i.e. it's two shims total,
    not two shims per unique closure), so this shouldn't a big deal.
    Aaron1011 committed Sep 22, 2021
    Configuration menu
    Copy the full SHA
    94b19fa View commit details
    Browse the repository at this point in the history