Fix elided lifetimes shown as '_ on async functions
This commit is contained in:
parent
50a90975c0
commit
530c33cd5f
2 changed files with 52 additions and 2 deletions
|
|
@ -635,6 +635,18 @@ impl Clean<Generics> for hir::Generics<'_> {
|
|||
_ => false,
|
||||
}
|
||||
}
|
||||
/// This can happen for `async fn`, e.g. `async fn f<'_>(&'_ self)`.
|
||||
///
|
||||
/// See [`lifetime_to_generic_param`] in [`rustc_ast_lowering`] for more information.
|
||||
///
|
||||
/// [`lifetime_to_generic_param`]: rustc_ast_lowering::LoweringContext::lifetime_to_generic_param
|
||||
fn is_elided_lifetime(param: &hir::GenericParam<'_>) -> bool {
|
||||
match param.kind {
|
||||
hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Elided } => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
let impl_trait_params = self
|
||||
.params
|
||||
.iter()
|
||||
|
|
@ -653,7 +665,7 @@ impl Clean<Generics> for hir::Generics<'_> {
|
|||
.collect::<Vec<_>>();
|
||||
|
||||
let mut params = Vec::with_capacity(self.params.len());
|
||||
for p in self.params.iter().filter(|p| !is_impl_trait(p)) {
|
||||
for p in self.params.iter().filter(|p| !is_impl_trait(p) && !is_elided_lifetime(p)) {
|
||||
let p = p.clean(cx);
|
||||
params.push(p);
|
||||
}
|
||||
|
|
@ -1433,7 +1445,16 @@ impl Clean<Type> for hir::Ty<'_> {
|
|||
TyKind::Never => Never,
|
||||
TyKind::Ptr(ref m) => RawPointer(m.mutbl, box m.ty.clean(cx)),
|
||||
TyKind::Rptr(ref l, ref m) => {
|
||||
let lifetime = if l.is_elided() { None } else { Some(l.clean(cx)) };
|
||||
// There are two times a `Fresh` lifetime can be created:
|
||||
// 1. For `&'_ x`, written by the user. This corresponds to `lower_lifetime` in `rustc_ast_lowering`.
|
||||
// 2. For `&x` as a parameter to an `async fn`. This corresponds to `elided_ref_lifetime in `rustc_ast_lowering`.
|
||||
// See commit 749349fc9f7b12f212bca9ba2297e463328cb701 for more information.
|
||||
// Ideally we would only hide the `'_` for case 2., but I don't know a way to distinguish it.
|
||||
// Turning `fn f(&'_ self)` into `fn f(&self)` isn't the worst thing in the world, though;
|
||||
// there's no case where it could cause the function to fail to compile.
|
||||
let elided =
|
||||
l.is_elided() || matches!(l.name, LifetimeName::Param(ParamName::Fresh(_)));
|
||||
let lifetime = if elided { None } else { Some(l.clean(cx)) };
|
||||
BorrowedRef { lifetime, mutability: m.mutbl, type_: box m.ty.clean(cx) }
|
||||
}
|
||||
TyKind::Slice(ref ty) => Slice(box ty.clean(cx)),
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
// ignore-tidy-linelength
|
||||
// edition:2018
|
||||
#![feature(min_const_generics)]
|
||||
|
||||
|
|
@ -52,3 +53,31 @@ pub trait Trait<const N: usize> {}
|
|||
// @has async_fn/fn.const_generics.html
|
||||
// @has - '//pre[@class="rust fn"]' 'pub async fn const_generics<const N: usize>(_: impl Trait<N>)'
|
||||
pub async fn const_generics<const N: usize>(_: impl Trait<N>) {}
|
||||
|
||||
// test that elided lifetimes are properly elided and not displayed as `'_`
|
||||
// regression test for #63037
|
||||
// @has async_fn/fn.elided.html
|
||||
// @has - '//pre[@class="rust fn"]' 'pub async fn elided(foo: &str) -> &str'
|
||||
pub async fn elided(foo: &str) -> &str {}
|
||||
// This should really be shown as written, but for implementation reasons it's difficult.
|
||||
// See `impl Clean for TyKind::Rptr`.
|
||||
// @has async_fn/fn.user_elided.html
|
||||
// @has - '//pre[@class="rust fn"]' 'pub async fn user_elided(foo: &str) -> &str'
|
||||
pub async fn user_elided(foo: &'_ str) -> &str {}
|
||||
// @has async_fn/fn.static_trait.html
|
||||
// @has - '//pre[@class="rust fn"]' 'pub async fn static_trait(foo: &str) -> Box<dyn Bar>'
|
||||
pub async fn static_trait(foo: &str) -> Box<dyn Bar> {}
|
||||
// @has async_fn/fn.lifetime_for_trait.html
|
||||
// @has - '//pre[@class="rust fn"]' "pub async fn lifetime_for_trait(foo: &str) -> Box<dyn Bar + '_>"
|
||||
pub async fn lifetime_for_trait(foo: &str) -> Box<dyn Bar + '_> {}
|
||||
|
||||
struct AsyncFdReadyGuard<'a, T> { x: &'a T }
|
||||
|
||||
impl Foo {
|
||||
// @has async_fn/struct.Foo.html
|
||||
// @has - '//h4[@class="method"]' 'pub async fn complicated_lifetimes( &self, context: &impl Bar) -> impl Iterator<Item = &usize>'
|
||||
pub async fn complicated_lifetimes(&self, context: &impl Bar) -> impl Iterator<Item = &usize> {}
|
||||
// taken from `tokio` as an example of a method that was particularly bad before
|
||||
// @has - '//h4[@class="method"]' "pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()>"
|
||||
pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()> {}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue