Skip to content

Commit

Permalink
Rollup merge of rust-lang#110965 - compiler-errors:anon-lt-dupe-oops,…
Browse files Browse the repository at this point in the history
… 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) rust-lang#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).
  • Loading branch information
matthiaskrgr committed Apr 29, 2023
2 parents 862d50c + 4e05cfb commit e8a3d8c
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 8 deletions.
6 changes: 1 addition & 5 deletions compiler/rustc_resolve/src/late.rs
Expand Up @@ -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(..) => {
Expand Down
4 changes: 1 addition & 3 deletions tests/ui/async-await/in-trait/nested-rpit.rs
@@ -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)]
Expand Down
48 changes: 48 additions & 0 deletions tests/ui/async-await/return-type-notation/issue-110963-early.rs
@@ -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 {}
}
}
@@ -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

50 changes: 50 additions & 0 deletions tests/ui/async-await/return-type-notation/issue-110963-late.rs
@@ -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 {}
}
}
19 changes: 19 additions & 0 deletions tests/ui/async-await/return-type-notation/issue-110963-late.stderr
@@ -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

0 comments on commit e8a3d8c

Please sign in to comment.