Skip to content

Show the location of a type usage for trait bound failures #66444

Closed as not planned
@oli-cosmian

Description

@oli-cosmian

cc @estebank

The following diagnostic doesn't tell the user anything about where the type that causes the failure is coming from. I understand that we can't report a correct source site, but we could create a heuristic:

Instead of having a note: without an associated span, we could check where (if at all) the type is used in the function and report those spans as potential sources of the error. Though I'm not sure what would be needed to fiddle this information through to the diagnostic reporting site.

fn foo(i: i32) -> impl std::future::Future<Output = ()> + Send {
    async move {
        boo(format!("{}", i).as_str()).await;
    }
}

async fn boo(_: &str) {
    
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
 --> src/lib.rs:1:19
  |
1 | fn foo(i: i32) -> impl std::future::Future<Output = ()> + Send {
  |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
  |
  = help: within `core::fmt::Void`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)`
  = note: required because it appears within the type `std::marker::PhantomData<*mut (dyn std::ops::Fn() + 'static)>`
  = note: required because it appears within the type `core::fmt::Void`
  = note: required because of the requirements on the impl of `std::marker::Send` for `&core::fmt::Void`
  = note: required because it appears within the type `std::fmt::ArgumentV1<'_>`
  = note: required because it appears within the type `[std::fmt::ArgumentV1<'_>; 1]`
  = note: required because it appears within the type `for<'r, 's, 't0, 't1, 't2, 't3, 't4, 't5, 't6, 't7, 't8, 't9, 't10, 't11, 't12, 't13, 't14, 't15, 't16, 't17, 't18> {for<'_> fn(&str) -> impl std::future::Future {boo}, for<'t19> fn(std::fmt::Arguments<'t19>) -> std::string::String {std::fmt::format}, fn(&'r [&'r str], &'r [std::fmt::ArgumentV1<'r>]) -> std::fmt::Arguments<'r> {std::fmt::Arguments::<'r>::new_v1}, &'s str, &'t0 str, [&'t1 str; 1], &'t2 [&'t3 str], &'t4 [&'t5 str; 1], i32, &'t6 i32, (&'t7 i32,), [std::fmt::ArgumentV1<'t8>; 1], &'t9 [std::fmt::ArgumentV1<'t10>], &'t11 [std::fmt::ArgumentV1<'t12>; 1], std::fmt::Arguments<'t13>, &'t14 std::string::String, std::string::String, &'t15 str, &'t16 str, impl std::future::Future, impl std::future::Future, ()}`
  = note: required because it appears within the type `[static generator@src/lib.rs:2:16: 4:6 i:i32 for<'r, 's, 't0, 't1, 't2, 't3, 't4, 't5, 't6, 't7, 't8, 't9, 't10, 't11, 't12, 't13, 't14, 't15, 't16, 't17, 't18> {for<'_> fn(&str) -> impl std::future::Future {boo}, for<'t19> fn(std::fmt::Arguments<'t19>) -> std::string::String {std::fmt::format}, fn(&'r [&'r str], &'r [std::fmt::ArgumentV1<'r>]) -> std::fmt::Arguments<'r> {std::fmt::Arguments::<'r>::new_v1}, &'s str, &'t0 str, [&'t1 str; 1], &'t2 [&'t3 str], &'t4 [&'t5 str; 1], i32, &'t6 i32, (&'t7 i32,), [std::fmt::ArgumentV1<'t8>; 1], &'t9 [std::fmt::ArgumentV1<'t10>], &'t11 [std::fmt::ArgumentV1<'t12>; 1], std::fmt::Arguments<'t13>, &'t14 std::string::String, std::string::String, &'t15 str, &'t16 str, impl std::future::Future, impl std::future::Future, ()}]`
  = note: required because it appears within the type `std::future::GenFuture<[static generator@src/lib.rs:2:16: 4:6 i:i32 for<'r, 's, 't0, 't1, 't2, 't3, 't4, 't5, 't6, 't7, 't8, 't9, 't10, 't11, 't12, 't13, 't14, 't15, 't16, 't17, 't18> {for<'_> fn(&str) -> impl std::future::Future {boo}, for<'t19> fn(std::fmt::Arguments<'t19>) -> std::string::String {std::fmt::format}, fn(&'r [&'r str], &'r [std::fmt::ArgumentV1<'r>]) -> std::fmt::Arguments<'r> {std::fmt::Arguments::<'r>::new_v1}, &'s str, &'t0 str, [&'t1 str; 1], &'t2 [&'t3 str], &'t4 [&'t5 str; 1], i32, &'t6 i32, (&'t7 i32,), [std::fmt::ArgumentV1<'t8>; 1], &'t9 [std::fmt::ArgumentV1<'t10>], &'t11 [std::fmt::ArgumentV1<'t12>; 1], std::fmt::Arguments<'t13>, &'t14 std::string::String, std::string::String, &'t15 str, &'t16 str, impl std::future::Future, impl std::future::Future, ()}]>`
  = note: required because it appears within the type `impl std::future::Future`
  = note: the return type of a function must have a statically known size

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.

Metadata

Metadata

Assignees

Labels

A-async-awaitArea: Async & AwaitA-diagnosticsArea: Messages for errors, warnings, and lintsAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-enhancementCategory: An issue proposing an enhancement or a PR with one.D-confusingDiagnostics: Confusing error or lint that should be reworked.D-papercutDiagnostics: An error or lint that needs small tweaks.S-needs-reproStatus: This issue has no reproduction and needs a reproduction to make progress.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