Skip to content

Argument-position impl Trait requires a named lifetime #49287

Open

Description

@cramertj

This function produces an "expected lifetime parameter" error:

fn foo(_: impl Iterator<Item = &u8>) {}

This code should instead be accepted and bound the impl Trait parameter by the elided lifetime.

cc #34511

Activity

  1. nikomatsakis commented on Mar 23, 2018

    @nikomatsakis
    Contributor

    In my opinion, we should accept '_, in-band lifetimes, and friends in where clauses as well. I'm not 100% sure whether this was controversial though, have to check.

  2. added
    C-enhancementCategory: An issue proposing an enhancement or a PR with one.
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.
    on Mar 23, 2018
  3. alexreg commented on Jan 28, 2019

    @alexreg
  4. cramertj commented on Jan 29, 2019

    @cramertj
    Author
  5. alexreg commented on Jan 29, 2019

    @alexreg
  6. CAD97 commented on May 8, 2019

    @CAD97
    Contributor

    Ran into this today. Providing the '_ lifetime gives a very fun error:

    fn f(_: impl Iterator<Item = &'_ ()>) {}
    error[E0106]: missing lifetime specifier
     --> src/lib.rs:1:31
      |
    1 | fn f(_: impl Iterator<Item = &'_ ()>) {}
      |                               ^^ expected lifetime parameter
    
  7. added
    D-confusingDiagnostics: Confusing error or lint that should be reworked.
    D-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.
    on Jan 30, 2020
  8. estebank commented on Jan 30, 2020

    @estebank
    Contributor

    It's actually gotten slightly worse:

    error[E0106]: missing lifetime specifier
     --> src/lib.rs:1:31
      |
    1 | fn f(_: impl Iterator<Item = &'_ ()>) {}
      |                               ^^ expected named lifetime parameter
      |
    help: consider introducing a named lifetime parameter
      |
    1 | fn f(_: 'a, impl Iterator<Item = &'a ()>) {}
      |         ^^                       ^^^
    

    #68583 will address that. After it gets merged the output will be

    Screen Shot 2020-01-30 at 11 55 07 AM

    I feel that's going to be as good a diagnostic we're gonna have for this.

  9. added a commit that references this issue on Jan 30, 2020
  10. runiq commented on Jan 31, 2020

    @runiq

    I feel that's going to be as good a diagnostic we're gonna have for this.

    @estebank Does that mean that this will be the "final" state for this feature? As in, anonymous lifetimes will not be usable in the positions mentioned by @nikomatsakis in #49287 (comment)?

  11. estebank commented on Jan 31, 2020

    @estebank
    Contributor

    What I mean that until anonymous lifetimes are accepted in impl Trait we're going to have some diagnostic, and the one I posted is likely the best we can do given our constraints.

  12. added a commit that references this issue on Feb 5, 2020
  13. added a commit that references this issue on Feb 5, 2020
  14. nikomatsakis commented on Feb 5, 2020

    @nikomatsakis
    Contributor

    The reason that lifetimes were not permitted here, as I recall, was some uncertainty about what they should mean (in particular, should impl Foo<'_> mean impl for<'a> Foo<'a> or what). I am actually still a bit unsure as to my opinion here -- I've seen people expect it to mean both things.

  15. estebank commented on Feb 5, 2020

    @estebank
    Contributor

    In this case, impl for<'a> Foo<'a> wouldn't work, but could you show me a case where it would? I feel that the only case where impl for<'a> X is common is for Fn() and in that case unnamed lifetimes usually work, and in the case where a named lifetime that hasn't been introduced is used produces the following now (not yet in the latest nightly):

    error[E0261]: use of undeclared lifetime name `'a`
     --> file4.rs:1:27
      |
    1 | fn foo(_compare: impl Fn(&'a u8)) {
      |                           ^^ undeclared lifetime
      |
      = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
    help: consider introducing lifetime `'a` here
      |
    1 | fn foo<'a>(_compare: impl Fn(&'a u8)) {
      |       ^^^^
    help: consider making the bound lifetime-generic with a new `'a` lifetime
      |
    1 | fn foo(_compare: impl for<'a> Fn(&'a u8)) {
      |                       ^^^^^^^
    
  16. removed
    D-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.
    on Feb 5, 2020
  17. nikomatsakis commented on Feb 5, 2020

    @nikomatsakis
    Contributor

    I'm not sure what you mean by "show you a case where it would work", I guess you mean a realistic example where that is what you would want? I don't really have one off the top of my head, but I agree with you it's probably quite a bit less common -- after all, I almost never write for bounds in practice.

    So yeah, I pretty much agree it'd be the wrong meaning, and I think it'd even be somewhat counter-intuitive. We have a pretty strong precedent right now that '_ binds into the "innermost enclosing parentheses", in a sense, and I would be quite surprising to find impl Foo<'_> create a lifetime bound within the scope of impl keyword.

  18. added a commit that references this issue on Feb 6, 2020
  19. Dylan-DPC commented on Dec 12, 2024

    @Dylan-DPC
    Member

    Current output:

    error[E0658]: anonymous lifetimes in `impl Trait` are unstable
     --> src/lib.rs:1:33
      |
    1 | fn foo(_: impl Iterator<Item = &u8>) {}
      |                                 ^ expected named lifetime parameter
      |
    help: consider introducing a named lifetime parameter
      |
    1 | fn foo<'a>(_: impl Iterator<Item = &'a u8>) {}
      |       ++++                          ++
    
    For more information about this error, try `rustc --explain E0658`.
    
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-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.C-enhancementCategory: An issue proposing an enhancement or a PR with one.D-confusingDiagnostics: Confusing error or lint that should be reworked.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