Change:
cc
cc
I'm hitting this a lot at the moment-- any idea what the cause might be? I'd love to help get this resolved.
I'm sometimes able to fix it by moving conditions that out of the body of an expression.
It also seems to have regressed between and -- updating the compiler caused this to happen in more places.
Possibly related to ? cc
Trying to fix in more places and it looks like it's always related to temporaries-- if I make it and then use in the place I was using it usually solves the issue.
Smaller example: ()
cc this is blocking roll out of async/await in Fuchsia
Looked at this and pointed out that it looks like typechecking thinks that isn't live at the point (which is correct) but that MIR thinks it is live (which is incorrect). I tried searching through the diff to see if there were any related PRs, but so far the only thing I've found that touches MIR is , which seems like it shouldn't be related.
Is working on bisecting this.
I think the problem is that is borrowed by and because of this the generator transformation only uses and statements to calculate liveness. However we generate a statement for before its initialiser which contains the statement. So appears live during the statement, even though its storage isn't used for anything.
Bisection pointed to as the PR that made this worse (more code ICEs now), although the minimal test case still fails before and after. cc
minimal repro: This ICE only surfaces after
using instead of makes the ICE "go away"
Ah you need at the very least to use and initializations, not . AFAIK the type of a variable could be dead at a (lifetimes not ready yet). Arguably you could also have the time before moving out and a reinitialization also count as dead, e.g. doesn't really need to keep alive.

Discussion:
use dataflow::BitDenotation; /// This calculates if any part of a MIR local could have previously been borrowed. <del> /// This means that once a local has been borrowed, its bit will always be set /// from that point and onwards, even if the borrow ends. You could also think of this /// as computing the lifetimes of infinite borrows. </del> <ins> /// This means that once a local has been borrowed, its bit will be set /// from that point and onwards, until we see a StorageDead statement for the local, /// at which points there is no memory associated with the local, so it cannot be borrowed. </ins> /// This is used to compute which locals are live during a yield expression for /// immovable generators. #[derive(Copy, Clone)]

fn statement_effect(&self, sets: &mut BlockSets<Local>, loc: Location) { <ins> let stmt = &self.mir[loc.block].statements[loc.statement_index]; </ins> BorrowedLocalsVisitor { sets, <del> }.visit_statement(loc.block, &self.mir[loc.block].statements[loc.statement_index], loc); </del> <ins> }.visit_statement(loc.block, stmt, loc); // StorageDead invalidates all borrows and raw pointers to a local match stmt.kind { StatementKind::StorageDead(l) => sets.kill(&l), _ => (), } </ins> } fn terminator_effect(&self,

// The `liveness` variable contains the liveness of MIR locals ignoring borrows. // This is correct for movable generators since borrows cannot live across // suspension points. However for immovable generators we need to account for <del> // borrows, so we conseratively assume that all borrowed locals live forever. </del> <ins> // borrows, so we conseratively assume that all borrowed locals are live until // we find a StorageDead statement referencing the locals. </ins> // To do this we just union our `liveness` result with `borrowed_locals`, which // contains all the locals which has been borrowed before this suspension point. // If a borrow is converted to a raw reference, we must also assume that it lives

<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![feature(generators)] fn main() { static || { loop { // Test that `opt` is not live across the yield, even when borrowed in a loop // See https://github.com/rust-lang/rust/issues/52792 let opt = { yield; true }; &opt; } }; } </ins>