Skip to content

E0623 highlights wrong parameter in async fn #74256

Closed

Description

@SNCPlay42
struct Struct { }

impl Struct {
    async fn async_fn(self: &Struct, f: &u32) -> &u32 {
        f
    }
    
    fn sync_fn(self: &Struct, f: &u32) -> &u32 {
        f
    }
}

Output (playground)

   Compiling playground v0.0.1 (/playground)
error[E0623]: lifetime mismatch
 --> src/main.rs:5:9
  |
4 |     async fn async_fn(self: &Struct, f: &u32) -> &u32 {
  |                             -------              ----
  |                             |
  |                             this parameter and the return type are declared with different lifetimes...
5 |         f
  |         ^ ...but data from `f` is returned here

error[E0623]: lifetime mismatch
 --> src/main.rs:9:9
  |
8 |     fn sync_fn(self: &Struct, f: &u32) -> &u32 {
  |                                  ----     ----
  |                                  |
  |                                  this parameter and the return type are declared with different lifetimes...
9 |         f
  |         ^ ...but data from `f` is returned here

error: aborting due to 2 previous errors

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

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

The error in sync_fn is correct, but the one for async_fn incorrectly claims the return type lifetime is different from self's lifetime, when they are in fact the same per the elision rules.

Activity

  1. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    C-bugCategory: This is a bug.
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Jul 11, 2020
  2. ayazhafiz commented on Jul 12, 2020

    @ayazhafiz
    Contributor

    related: #63499

  3. tmandry commented on Jul 14, 2020

    @tmandry
    Member

    Seems related to #74072. Triaging as On Deck since this is an incorrect diagnostic which can cause confusion.

  4. added
    AsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.
    D-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.
    on Jul 14, 2020
  5. SNCPlay42 commented on Jul 22, 2020

    @SNCPlay42
    ContributorAuthor

    Another case:

    async fn async_fn(x: &i32, y: &mut &i32) {
        *y = x;
    }
    
    fn sync_fn(x: &i32, y: &mut &i32) {
        *y = x;
    }

    Output (playground)

    error[E0623]: lifetime mismatch
     --> src/main.rs:2:10
      |
    1 | async fn async_fn(x: &i32, y: &mut &i32) {
      |                                    ----  -
      |                                    |
      |                                    this parameter and the return type are declared with different lifetimes...
    2 |     *y = x;
      |          ^ ...but data from `x` is returned here
    
    error[E0623]: lifetime mismatch
     --> src/main.rs:6:10
      |
    5 | fn sync_fn(x: &i32, y: &mut &i32) {
      |               ----          ----
      |               |
      |               these two types are declared with different lifetimes...
    6 |     *y = x;
      |          ^ ...but data from `x` flows into `y` here
    

    The error message for async_fn refers to returning when no returning is involved!

  6. SNCPlay42 commented on Jul 22, 2020

    @SNCPlay42
    ContributorAuthor

    Output for the async functions in both cases with #![feature(nll)]: (playground)

    error: lifetime may not live long enough
     --> src/main.rs:4:5
      |
    3 | async fn async_fn(x: &i32, y: &mut &i32) {
      |                      -             - let's call the lifetime of this reference `'2`
      |                      |
      |                      let's call the lifetime of this reference `'1`
    4 |     *y = x;
      |     ^^^^^^ assignment requires that `'1` must outlive `'2`
    
    error: lifetime may not live long enough
      --> src/main.rs:11:9
       |
    10 |     async fn async_fn(self: &Struct, f: &u32) -> &u32 {
       |                             -           - let's call the lifetime of this reference `'1`
       |                             |
       |                             let's call the lifetime of this reference `'2`
    11 |         f
       |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    

    Looks like this can be tagged as fixed by NLL.

  7. eholk commented on Sep 8, 2021

    @eholk
    Contributor

    @SNCPlay42 - since this is tagged as fixed by NLL, do you think we can go ahead and close the whole issue?

  8. tmandry commented on Sep 9, 2021

    @tmandry
    Member

    This still reproduces for me. Adding #![feature(nll)] does fix the issue, I'm not sure what we're using that feature for nowadays.

  9. eholk commented on Sep 16, 2021

    @eholk
    Contributor

    @rustbot claim

  10. 6 remaining items

  11. eholk commented on Oct 18, 2021

    @eholk
    Contributor

    @rustbot label +AsyncAwait-Polish

  12. added 2 commits that reference this issue on Jan 15, 2022
  13. tmandry commented on Apr 14, 2022

    @tmandry
    Member

    There is a remaining issue not fixed by #92183 which I'll attempt to elucidate here.

    In try_report_anon_anon_conflict, we are reporting an error with two anonymous lifetimes. We rely on the fact that anonymous lifetimes can only be introduced in parameters, and the only other place they can appear is the return type. To check if the conflict occurs in the return type, we check to see if either lifetime appears in the return type. If it does, we highlight the return type and the parameter corresponding to the other lifetime.

    This is a little broken. Just because a lifetime appears in the return type does not necessarily mean the return type had anything to do with the current error. We want to know what types the failing lifetime obligation came from, and the span of those types. For example, for each lifetime it could be

    • The return type
    • The type of the parameter that introduced the lifetime
    • An associated type embedded in either of the above (e.g., impl Future<Output = &'a i32>)
  14. moved this to In progress (current sprint) in wg-async workon Dec 8, 2022
  15. estebank commented on Aug 3, 2023

    @estebank
    Contributor

    Current output:

    error: lifetime may not live long enough
     --> src/main.rs:5:9
      |
    4 |     async fn async_fn(self: &Struct, f: &u32) -> &u32 {
      |                             -           - let's call the lifetime of this reference `'1`
      |                             |
      |                             let's call the lifetime of this reference `'2`
    5 |         f
      |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
      |
    help: consider introducing a named lifetime parameter and update trait if needed
      |
    4 |     async fn async_fn<'a>(self: &'a Struct, f: &'a u32) -> &u32 {
      |                      ++++        ++             ++
    
    error: lifetime may not live long enough
     --> src/main.rs:9:9
      |
    8 |     fn sync_fn(self: &Struct, f: &u32) -> &u32 {
      |                      -           - let's call the lifetime of this reference `'1`
      |                      |
      |                      let's call the lifetime of this reference `'2`
    9 |         f
      |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
      |
    help: consider introducing a named lifetime parameter and update trait if needed
      |
    8 |     fn sync_fn<'a>(self: &'a Struct, f: &'a u32) -> &u32 {
      |               ++++        ++             ++
    
  16. removed
    D-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.
    on Aug 3, 2023
  17. moved this from In progress (current sprint) to On deck in wg-async workon Aug 22, 2023
  18. removed their assignment
    on Aug 22, 2023
  19. compiler-errors commented on Dec 31, 2024

    @compiler-errors
    Contributor

    this works now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitA-diagnosticsArea: Messages for errors, warnings, and lintsAsyncAwait-PolishAsync-await issues that are part of the "polish" areaAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.fixed-by-NLLBugs fixed, but only when NLL is enabled.

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions