Skip to content

Diagnostic does not fire on marker trait that requires static #131683

Open
@jamesmunns

Description

@jamesmunns

Code

#[diagnostic::on_unimplemented(
    message = "Arguments to embassy tasks must be 'static",
    label = "Not 'static",
    note = "See https://embassy.dev/... for more details on sharing",
)]
trait SecretStatic {
}

// // Option A
impl<T: 'static> SecretStatic for T {
    
}
// //

// Option B
// impl SecretStatic for i8
// {
// }

// impl SecretStatic for u16
// {
// }

// impl SecretStatic for u32
// {
// }
//

fn expanded_func<T, U, V>(t: T, u: U, v: V)
where
    T: SecretStatic,
    U: SecretStatic,
    V: SecretStatic,
{
    todo!()
}

struct Example {
    x: u32,
}

fn main() {
    expanded_func(1i8, 2u16, 3u32);
    let x = Example { x: 123 };
    expanded_func::<&Example, u16, u32>(&x, 2u16, 3u32);
}

Current output

error[E0597]: `x` does not live long enough
  --> src/main.rs:45:41
   |
44 |     let x = Example { x: 123 };
   |         - binding `x` declared here
45 |     expanded_func::<&Example, u16, u32>(&x, 2u16, 3u32);
   |     ------------------------------------^^-------------
   |     |                                   |
   |     |                                   borrowed value does not live long enough
   |     argument requires that `x` is borrowed for `'static`
46 | }
   | - `x` dropped here while still borrowed

For more information about this error, try `rustc --explain E0597`.

Desired output

error[E0277]: Arguments to embassy tasks must be 'static
  --> src/main.rs:45:21
   |
45 |     expanded_func::<&Example, u16, u32>(&x, 2u16, 3u32);
   |                     ^^^^^^^^ Not 'static
   |
   = help: the trait `SecretStatic` is not implemented for `&Example`
   = note: See https://embassy.dev/... for more details on sharing
   = help: the following other types implement trait `SecretStatic`:
             i8
             u16
             u32
note: required by a bound in `expanded_func`
  --> src/main.rs:31:8
   |
29 | fn expanded_func<T, U, V>(t: T, u: U, v: V)
   |    ------------- required by a bound in this function
30 | where
31 |     T: SecretStatic,
   |        ^^^^^^^^^^^^ required by this bound in `expanded_func`

Rationale and extra context

We want to use a marker trait in macro expanded code for the embassy executor so that all arguments to tasks are 'static. This is a limitation of the executor, and is a common stumbling block for users.

We wanted to use diagnostics for this to reduce the amount of work required in a proc macro to get good spans and errors, but noticed that diagnostics did not fire at all. They DO fire when we manually add impls for the type instead of using a blanket impl (this is not practical to support for arbitrary user types

Other cases

No response

Rust Version

Tested with 1.81.0 stable and 1.82.0-beta.6, same output

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsD-diagnostic-infraDiagnostics: Issues that affect all diagnostics, or relate to the diagnostic machinery itself.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions