Rollup merge of #110965 - compiler-errors:anon-lt-dupe-oops, r=cjgillot

Don't duplicate anonymous lifetimes for async fn in traits

`record_lifetime_params_for_async` needs to be called outside of the scope of the function, or else it'll end up collecting anonymous lifetimes twice (those on the function and those within the `AnonymousCreateParameter` rib). This matches how `record_lifetime_params_for_async` is being used for functions with bodies below.

This fixes (partially) #110963 when the lifetimes are late-bound, but does not do so when the lifetimes are early-bound (as seen from the known-bug that I added).
This commit is contained in:
Dylan DPC 2023-04-29 11:27:56 +05:30 committed by GitHub
commit 81910a1b21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 164 additions and 8 deletions

View File

@ -859,13 +859,9 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
sig.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)),
&sig.decl.output,
);
this.record_lifetime_params_for_async(
fn_id,
sig.header.asyncness.opt_return_id(),
);
},
);
self.record_lifetime_params_for_async(fn_id, sig.header.asyncness.opt_return_id());
return;
}
FnKind::Fn(..) => {

View File

@ -1,7 +1,5 @@
// edition: 2021
// known-bug: #105197
// failure-status:101
// dont-check-compiler-stderr
// check-pass
#![feature(async_fn_in_trait)]
#![feature(return_position_impl_trait_in_trait)]

View File

@ -0,0 +1,48 @@
// edition: 2021
// known-bug: #110963
#![feature(return_type_notation)]
#![feature(async_fn_in_trait)]
trait HealthCheck {
async fn check<'a: 'a>(&'a mut self) -> bool;
}
async fn do_health_check_par<HC>(hc: HC)
where
HC: HealthCheck<check(): Send> + Send + 'static,
{
spawn(async move {
let mut hc = hc;
if !hc.check().await {
log_health_check_failure().await;
}
});
}
async fn log_health_check_failure() {}
fn main() {}
// Fake tokio spawn
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
fn spawn<F>(future: F) -> JoinHandle
where
F: Future + Send + 'static,
F::Output: Send + 'static,
{
loop {}
}
struct JoinHandle;
impl Future for JoinHandle {
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
loop {}
}
}

View File

@ -0,0 +1,45 @@
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-110963-early.rs:4:12
|
LL | #![feature(return_type_notation)]
| ^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
= note: `#[warn(incomplete_features)]` on by default
warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-110963-early.rs:5:12
|
LL | #![feature(async_fn_in_trait)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
error: higher-ranked lifetime error
--> $DIR/issue-110963-early.rs:15:5
|
LL | / spawn(async move {
LL | | let mut hc = hc;
LL | | if !hc.check().await {
LL | | log_health_check_failure().await;
LL | | }
LL | | });
| |______^
|
= note: could not prove `[async block@$DIR/issue-110963-early.rs:15:11: 20:6]: Send`
error: higher-ranked lifetime error
--> $DIR/issue-110963-early.rs:15:5
|
LL | / spawn(async move {
LL | | let mut hc = hc;
LL | | if !hc.check().await {
LL | | log_health_check_failure().await;
LL | | }
LL | | });
| |______^
|
= note: could not prove `[async block@$DIR/issue-110963-early.rs:15:11: 20:6]: Send`
error: aborting due to 2 previous errors; 2 warnings emitted

View File

@ -0,0 +1,50 @@
// edition: 2021
// check-pass
#![feature(return_type_notation)]
//~^ WARN the feature `return_type_notation` is incomplete
#![feature(async_fn_in_trait)]
//~^ WARN the feature `async_fn_in_trait` is incomplete
trait HealthCheck {
async fn check(&mut self) -> bool;
}
async fn do_health_check_par<HC>(hc: HC)
where
HC: HealthCheck<check(): Send> + Send + 'static,
{
spawn(async move {
let mut hc = hc;
if !hc.check().await {
log_health_check_failure().await;
}
});
}
async fn log_health_check_failure() {}
fn main() {}
// Fake tokio spawn
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
fn spawn<F>(future: F) -> JoinHandle
where
F: Future + Send + 'static,
F::Output: Send + 'static,
{
loop {}
}
struct JoinHandle;
impl Future for JoinHandle {
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
loop {}
}
}

View File

@ -0,0 +1,19 @@
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-110963-late.rs:4:12
|
LL | #![feature(return_type_notation)]
| ^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
= note: `#[warn(incomplete_features)]` on by default
warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-110963-late.rs:6:12
|
LL | #![feature(async_fn_in_trait)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
warning: 2 warnings emitted