Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[MIR] Phantom unit write after return #31472

Closed
arielb1 opened this issue Feb 7, 2016 · 7 comments
Closed

[MIR] Phantom unit write after return #31472

arielb1 opened this issue Feb 7, 2016 · 7 comments
Labels
A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html C-bug Category: This is a bug.

Comments

@arielb1
Copy link
Contributor

arielb1 commented Feb 7, 2016

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;
    }
}
@arielb1 arielb1 changed the title [MIR] Phantom unit write with loop [MIR] Phantom unit write after return Feb 7, 2016
@arielb1
Copy link
Contributor Author

arielb1 commented Feb 7, 2016

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.

@nagisa
Copy link
Member

nagisa commented Feb 7, 2016

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

@nagisa nagisa added the A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html label Feb 7, 2016
@arielb1
Copy link
Contributor Author

arielb1 commented Feb 7, 2016

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.

@nagisa
Copy link
Member

nagisa commented Feb 7, 2016

Likely caused by this

@arielb1
Copy link
Contributor Author

arielb1 commented Feb 7, 2016

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.

@solson
Copy link
Member

solson commented Feb 19, 2016

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.

@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 24, 2017
@varkor
Copy link
Member

varkor commented Apr 12, 2018

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.

@varkor varkor closed this as completed Apr 12, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

5 participants