Skip to content

Out of storage use of local for temporary caused by label break #104736

Closed
@JakobDegen

Description

@JakobDegen

Code

Playground. Needs release

struct A;
struct B;

impl Drop for A {
    fn drop(&mut self) {}
}
impl Drop for B {
    fn drop(&mut self) {}
}

#[inline(always)]
fn no_unwind() {}

fn weird_temporary(a: A, b: B, nothing: ((), (), ()), x: bool) -> ((), (), ()) {
    'scope: {
        (
            {
                let _z = b;
                if x {
                    break 'scope nothing;
                }
            },
            match { a } {
                _ => (),
            },
            no_unwind(),
        )
    }
}

Meta

Version: 0d5573e and all other recent versions

Explanation

This causes an ICE in the MIR validator. The reason is an out of storage use of the local that is the temporary for { a }. This local has a couple interesting properties. The most important of these is that MIR building thinks that it may need to be dropped while unwinding in two scenarios:

  1. If the drop of _z unwinds.
  2. If no_unwind() unwinds.

Neither of these are actually possible.

First, drop elaboration comes along, sees that only the second of these is possible. It reacts to this by inserting a drop flag for the local. Then, inlining comes along and inlines no_unwind(). The potential unwind edge is now gone.

The result is that the cleanup drop is actually completely unreachable, and this ends up causing an ICE.

Curiously, this does not reproduce if one replaces break 'scope nothing; with return nothing;. In the case of the return, MIR building correctly realizes that the temporary has not been created yet and hence does not need to be dropped. The best solution to this is likely to make the break do the same thing - I'm not sure how difficult that is.

Metadata

Metadata

Assignees

Labels

-Zvalidate-mirUnstable option: MIR validationA-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlC-bugCategory: This is a bug.E-hardCall for participation: Hard difficulty. Experience needed to fix: A lot.E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.glacierICE tracked in rust-lang/glacier.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions