Skip to content

[MIR] Phantom unit write after return #31472

Closed

Description

@arielb1

EDIT: I was confused about the issue

pub fn foo(mut value: u64) -> usize {
    return 0;
}
fn(arg0: u64) -> usize {
    let mut var0: u64; // value
    let mut tmp0: ();
    let mut tmp1: ();

    bb0: {
        var0 = arg0;
        return = const 0;
        goto -> bb1;
    }

    bb1: {
        return;
    }

    bb2: {
        drop(tmp0) -> bb3;
    }

    bb3: {
        return = ();
        goto -> bb1;
    }
}

Activity

  1. changed the title [-][MIR] Phantom unit write with loop [/-] [+][MIR] Phantom unit write after return[/+] on Feb 7, 2016
  2. arielb1 commented on Feb 7, 2016

    @arielb1
    ContributorAuthor

    The write here is the empty write at the end of a block - which should not exist if the block is diverging.

    Unclear whether we should not create the (ill-formed) write when building or remove it in post-processing.

  3. nagisa commented on Feb 7, 2016

    @nagisa
    Member

    NB: This write gets removed by simplifycfg (you need to comment the pass out to reproduce the issue).

  4. added
    A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html
    on Feb 7, 2016
  5. arielb1 commented on Feb 7, 2016

    @arielb1
    ContributorAuthor

    This would still pose a problem to analysis passes that want to run before SimplifyCfg. I am adding an early pass for my MIR typeck PR to ameliorate this problem.

  6. nagisa commented on Feb 7, 2016

    @nagisa
    Member

    Likely caused by this

  7. arielb1 commented on Feb 7, 2016

    @arielb1
    ContributorAuthor

    The root cause of the problem is that typeck allows "diverging" blocks to have any kind of return value instead of requiring it to be MIR. I think that clearing the diverging blocks in a post-pass is a better strategy than detecting diverging blocks in HAIR.

  8. solson commented on Feb 19, 2016

    @solson
    Contributor

    Maybe we should only emit what @nagisa linked to when the actual type of the block is unit?

    Generally, a missing final expression doesn't necessarily mean () could be inserted, e.g.:

    fn foo() -> i32 { panic!(); } // OK
    fn foo() -> i32 { panic!(); () } // expected `i32`, found `()` - http://is.gd/qVOTyf

    EDIT: Do we want to omit the unit write even for a block of type unit if the block is diverging? Then what I said wouldn't help.

  9. varkor commented on Apr 12, 2018

    @varkor
    Contributor

    As far as I can tell, this was fixed by #47746, where the trailing unit is only added if the return type of the function is the unit type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlC-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions