Skip to content

Code no longer compiles after -Zdrop-tracking-mir was enabled by default #116242

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
tmandry opened this issue Sep 28, 2023 · 16 comments · Fixed by #117134
Closed

Code no longer compiles after -Zdrop-tracking-mir was enabled by default #116242

tmandry opened this issue Sep 28, 2023 · 16 comments · Fixed by #117134
Assignees
Labels
A-async-await Area: Async & Await AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. C-bug Category: This is a bug. P-critical Critical priority regression-from-stable-to-beta Performance or correctness regression from stable to beta. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@tmandry
Copy link
Member

tmandry commented Sep 28, 2023

Some code that used to compile no longer does after #107421. We don't think was ever supposed to compile. Don't have an MCVE yet.

Snippet:

let selecting_fut = selecting
    .do_selecting(
        &client_config,
        &test_socket_provider,
        &mut rng,
        &time,
        &mut stop_receiver,
    )
    .fuse();

let time = &time;

let wait_fut = async {
    // Wait some arbitrary amount of time to ensure `do_selecting` is waiting on a reply.
    // Note that this is fake time, not 30 actual seconds.
    time.wait_until(std::time::Duration::from_secs(30)).await;
}
.fuse();

pin_mut!(selecting_fut, wait_fut);

let main_future = async {
    select! {
        _ = selecting_fut => unreachable!("should keep retransmitting DHCPDISCOVER forever"),
        () = wait_fut => (),
    }
};
pin_mut!(main_future);

run_with_accelerated_time(&mut executor, time, &mut main_future);

stop_sender.unbounded_send(()).expect("sending stop signal should succeed");

let selecting_result = selecting_fut.now_or_never().expect(
    "selecting_fut should complete after single poll after stop signal has been sent",
);

assert_matches!(selecting_result, Ok(SelectingOutcome::GracefulShutdown));

Full code is here: https://cs.opensource.google/fuchsia/fuchsia/+/main:src/connectivity/network/dhcpv4/client/core/src/client.rs;l=1521-1576;drc=4a7d2eb6793e61c0021f8dd7dab35804590d36b6

I expected to see this happen: compiles as before

Instead, this happened:

error[E0505]: cannot move out of `selecting_fut` because it is borrowed
    --> ../../src/connectivity/network/dhcpv4/client/core/src/client.rs:1571:32
     |
1559 |           let main_future = async {
     |  ___________________________-
1560 | |             select! {
1561 | |                 _ = selecting_fut => unreachable!("should keep retransmitting DHCPDISCOVER forever"),
     | |                     ------------- borrow occurs due to use in generator
1562 | |                 () = wait_fut => (),
1563 | |             }
1564 | |         };
     | |_________- borrow of `selecting_fut` occurs here
...
1571 |           let selecting_result = selecting_fut.now_or_never().expect(
     |                                  ^^^^^^^^^^^^^ move out of `selecting_fut` occurs here
...
1576 |       }
     |       - borrow might be used here, when `main_future` is dropped and runs the destructor for generator

error: aborting due to previous error

For more information about this error, try `rustc --explain E0505`.

Version it worked on

It most recently worked on: Nightly 2023-09-22

@rustbot modify labels: +regression-from-stable-to-nightly -regression-untriaged

@tmandry tmandry added C-bug Category: This is a bug. regression-untriaged Untriaged performance or correctness regression. labels Sep 28, 2023
@rustbot rustbot added needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. I-prioritize Issue: Indicates that prioritization has been requested for this issue. regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. and removed regression-untriaged Untriaged performance or correctness regression. labels Sep 28, 2023
@Noratrieb Noratrieb removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Sep 28, 2023
@Noratrieb
Copy link
Member

@cjgillot

@Noratrieb Noratrieb added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-async-await Area: Async & Await labels Sep 28, 2023
@jamuraa
Copy link

jamuraa commented Sep 28, 2023

I've made a minimized version of this using tokio which confirmed the behavior of passing on the stable compiler and failing to compile on nightly in the playground:

use futures::pin_mut;
use futures::select;
use futures::FutureExt;

fn main() {
    let rt = tokio::runtime::Runtime::new().unwrap();
   
    let (send, recv) = futures::channel::oneshot::channel::<()>();
    let ready_fut = futures::future::ready(());
    
    pin_mut!(ready_fut, recv);
    let combined_fut = async {
        select! {
            _ = recv => unreachable!("should not send"),
            () = ready_fut => (),
        }
    };
    pin_mut!(combined_fut);
    let _ = rt.block_on(combined_fut);
   
    send.send(()).unwrap(); 
    assert_eq!(Some(Ok(())), recv.now_or_never());
}

@cjgillot
Copy link
Contributor

Thanks for the repro @jamuraa.

What changed is the the dropping of combined_fut. Stable is able to determine that combined_fut does not need dropping, as it only contains a PollFn<some closure>. Nightly supposes that all generators need dropping to avoid cycles when building MIR.

I'm not sure how this can be fixed.

@apiraino
Copy link
Contributor

Nominating for the next T-compiler meeting. I'd like to get a feeling of the priority and actionables.

@rustbot label +I-compiler-nominated

@rustbot rustbot added the I-compiler-nominated Nominated for discussion during a compiler team meeting. label Oct 11, 2023
@wesleywiser wesleywiser added the I-types-nominated Nominated for discussion during a types team meeting. label Oct 12, 2023
@wesleywiser
Copy link
Member

During the compiler team triage meeting, @jackh726 said:

We should probably just nominate it for T-types ... to get some idea if there is something we can do to mitigate the breakage

so nominating for T-types as well.

@apiraino
Copy link
Contributor

T-compiler discussed the issue: in addition to adding T-types to the discussion, we defer until next week to see the results of the crater run for #114624 that is solved by MIR drop tracking, too. Crater run is in progress at #116567.

(Zulip link)

@nikomatsakis
Copy link
Contributor

nikomatsakis commented Oct 23, 2023

We discussed this in the @rust-lang/types meeting today.

@lcnr is going to mentor @spastorino to prepare a fix by modifying the drop outlives code for generators to be more accurate.

@nikomatsakis
Copy link
Contributor

@rustbot assign @spastorino

@traviscross
Copy link
Contributor

@rustbot labels +AsyncAwait-Triaged

We discussed this in a WG-async meeting and are leaving this in the capable hands of T-types for resolution.

@rustbot rustbot added the AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. label Oct 23, 2023
@lcnr lcnr added P-critical Critical priority regression-from-stable-to-beta Performance or correctness regression from stable to beta. I-types-nominated Nominated for discussion during a types team meeting. and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. I-types-nominated Nominated for discussion during a types team meeting. regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. labels Oct 23, 2023
bors added a commit to rust-lang-ci/rust that referenced this issue Oct 24, 2023
dropck_outlives check whether generator witness needs_drop

see https://rust-lang.zulipchat.com/#narrow/stream/326866-t-types.2Fnominated/topic/.23116242.3A.20Code.20no.20longer.20compiles.20after.20-Zdrop-tracking-mir.20.E2.80.A6/near/398311627 for an explanation.

Fixes rust-lang#116242 (or well, the repro by `@jamuraa` in rust-lang#116242 (comment)). I did not add a regression test as it depends on other crates. We do have 1 test going from fail to pass, showing the intended behavior.

r? types
bors added a commit to rust-lang-ci/rust that referenced this issue Oct 26, 2023
dropck_outlives check whether generator witness needs_drop

see https://rust-lang.zulipchat.com/#narrow/stream/326866-t-types.2Fnominated/topic/.23116242.3A.20Code.20no.20longer.20compiles.20after.20-Zdrop-tracking-mir.20.E2.80.A6/near/398311627 for an explanation.

Fixes rust-lang#116242 (or well, the repro by `@jamuraa` in rust-lang#116242 (comment)). I did not add a regression test as it depends on other crates. We do have 1 test going from fail to pass, showing the intended behavior.

r? types
@lqd
Copy link
Member

lqd commented Oct 26, 2023

Reduced

use std::future;

fn main() {
    let mut recv = future::ready(());
    let _combined_fut = async {
        let _ = || read(&mut recv);
    };

    drop(recv);
}

fn read<F: future::Future>(_: &mut F) -> F::Output {
    todo!()
}

You could likely inline std::future::Ready if you wanted to, but this seems self-contained enough for a test?

@apiraino
Copy link
Contributor

apiraino commented Nov 2, 2023

Briefly mentioned this one during T-compiler meeting (Zulip notes).

Leaving this as I-compiler-nominated and tracking backport of #117134. We would like to see this fixed in the next stable release (on 2023-11-16)

@bors bors closed this as completed in a2f5f96 Nov 3, 2023
@wesleywiser
Copy link
Member

Reopening to track beta-backport.

@wesleywiser wesleywiser reopened this Nov 3, 2023
@lcnr lcnr removed the I-types-nominated Nominated for discussion during a types team meeting. label Nov 6, 2023
@apiraino
Copy link
Contributor

apiraino commented Nov 9, 2023

Removing the T-compiler nomination as the backport of #117134 was approved (Zulip link).

@rustbot label -I-compiler-nominated

@rustbot rustbot removed the I-compiler-nominated Nominated for discussion during a compiler team meeting. label Nov 9, 2023
@apiraino
Copy link
Contributor

@tmandry when you have a chance can you confirm if the issue is solved, now that #117134 has been merged? Feel free to close this issue if it's the case. thanks 👍

@Nashenas88
Copy link
Contributor

I can confirm that the failing code now compiles on a recent rust build (revision d97bb19).

@lqd
Copy link
Member

lqd commented Nov 16, 2023

Great, thank you!

@lqd lqd closed this as completed Nov 16, 2023
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-async-await Area: Async & Await AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. C-bug Category: This is a bug. P-critical Critical priority regression-from-stable-to-beta Performance or correctness regression from stable to beta. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.