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

rustdoc shows anonymous elided lifetimes in async fn signature #63037

Closed
basdebue opened this issue Jul 27, 2019 · 6 comments · Fixed by #80319
Closed

rustdoc shows anonymous elided lifetimes in async fn signature #63037

basdebue opened this issue Jul 27, 2019 · 6 comments · Fixed by #80319
Assignees
Labels
A-lifetimes Area: lifetime related C-bug Category: This is a bug. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.

Comments

@basdebue
Copy link

When run on an async fn with elided lifetimes, rustdoc generates documentation containing the anonymous elided lifetimes in the function's signature. Running rustdoc on the blocking variant of the same function produces a correct signature.

You can reproduce this issue by generating docs for the following code:

#![feature(async_await)]

pub async fn asynchronous(foo: &str, bar: &str) -> String {
    format!("{}{}", foo, bar)
}

pub fn blocking(foo: &str, bar: &str) -> String {
    format!("{}{}", foo, bar)
}

The asynchronous function's docs show the elided lifetimes, the blocking function's docs don't:

pub async fn asynchronous<'_, '_>(foo: &'_ str, bar: &'_ str) -> String
pub fn blocking(foo: &str, bar: &str) -> String

Meta

rustdoc --version --verbose:

rustdoc 1.38.0-nightly (c43753f91 2019-07-26)
binary: rustdoc
commit-hash: c43753f910aae000f8bcb0a502407ea332afc74b
commit-date: 2019-07-26
host: x86_64-unknown-linux-gnu
release: 1.38.0-nightly
LLVM version: 9.0
@jonas-schievink jonas-schievink added C-bug Category: This is a bug. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Jul 27, 2019
@GuillaumeGomez GuillaumeGomez self-assigned this Jul 27, 2019
@elslooo
Copy link

elslooo commented Aug 3, 2020

I agree that this makes some function signatures unnecessarily verbose. For example:

pub async fn identifiers(&self, context: &impl Context) -> impl Iterator<&Identifier>

... becomes ...

pub async fn identifiers<'_, '_, '_>(&'_ self, context: &'_ impl Context) -> impl Iterator<&'_ Identifier>

However, given the nuances of async functions (specifically: the referenced values must survive every state of the FSM), one could argue that showing these lifetimes in the docs might be useful(?).

It's obviously not the worst problem on earth, but could someone at least shed some light on whether this behaviour is intended or not? Is this a feature or a bug? Maybe @GuillaumeGomez?

@GuillaumeGomez
Copy link
Member

I think it's the expected behaviour. However we can discuss about removing the elided lifetimes. In this case it's not really useful...

@elomatreb
Copy link
Contributor

It's especially visually disruptive with a &self parameter, making simple methods look significantly more complex than they actually are. It also feels surprising to special-case async functions like this, if it makes sense to show these lifetimes symmetry with traditional functions would be nice.

@Darksonn
Copy link
Contributor

We have several instances of #[allow(clippy::needless_lifetime)] in the Tokio codebase because the version with explicit lifetimes is simpler than the one with all the elided ones displayed. There are many cases where it would be more useful to just not show lifetimes on the method.

@jyn514 jyn514 self-assigned this Dec 22, 2020
@jyn514
Copy link
Member

jyn514 commented Dec 22, 2020

So I don't forget, I got halfway through debugging this on Zulip and it has something to do with 'in band lifetimes': 749349f. Naively changing this to use the same mechanism as fn runs into borrow check errors.

@jyn514
Copy link
Member

jyn514 commented Dec 22, 2020

Funnily enough, this does work with 1.34 if you add enough #![feature]s:

#![feature(async_await)]
#![feature(futures_api)]

pub async fn asynchronous(foo: &str) -> String {
    format!("{}{}", foo, bar)
}

pub fn not_asynchronous(foo: &str) -> String {
    format!("{}{}", foo, bar)
}

image

So in some sense this is a regression, although you needed nightly to use async at the time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lifetimes Area: lifetime related C-bug Category: This is a bug. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

7 participants