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

unreachable_code lint doesn't work with unboxed closures #20574

Closed
japaric opened this issue Jan 5, 2015 · 10 comments
Closed

unreachable_code lint doesn't work with unboxed closures #20574

japaric opened this issue Jan 5, 2015 · 10 comments
Labels
A-lint Area: Lints (warnings about flaws in source code) such as unused_mut.

Comments

@japaric
Copy link
Member

japaric commented Jan 5, 2015

This compiles, but it shouldn't

#![deny(unreachable_code)]

fn main() {
    let uc = |&:| panic!();
    uc();
    println!("unreachable");
}

This is correctly rejected

#![deny(unreachable_code)]

fn main() {
    let bc = || -> ! panic!();
    bc();
    println!("unreachable");
}

version: rustc 0.13.0-nightly (c6c786671 2015-01-04 00:50:59 +0000)

@huonw huonw added the A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. label Jan 5, 2015
@huonw
Copy link
Member

huonw commented Jan 5, 2015

AFAICT, it seems that the first closure is defaulting to have return type (); since ! isn't a real type, it requires explicit annotation for the compiler to believe that you want it.

(Maybe that's what we should regard as a bug?)

@reem
Copy link
Contributor

reem commented Jan 5, 2015

I think it would be quite interesting for ! to be a "real" type. There are certain patterns that could be made more usable, such as consuming a thread to run an event loop, for instance.

@reem
Copy link
Contributor

reem commented Jan 5, 2015

@japaric what happens if you explicitly annotate the return type of the unboxed closure to be !? Is that even possible?

@japaric
Copy link
Member Author

japaric commented Jan 5, 2015

@reem

let uc = |&:| -> ! panic!();
uc();

ICEs with internal error: entered unreachable code

@reem
Copy link
Contributor

reem commented Jan 5, 2015

Well, that's unfortunate. It's apparently illegal to use ! as a type parameter for traits:

pub trait X<T> {}
pub struct Foo;
impl X<!> for Foo {}

fn main() {}

errors with expected type, found !, which likely explains why the unboxed closure expansion breaks. These all seem to just be symptoms of ! not being a proper type when it should be.

@steveklabnik
Copy link
Member

Triage: updated code:

#![deny(unreachable_code)]

fn main() {
    let uc = || panic!();
    uc();
    println!("unreachable");
}

and

#![deny(unreachable_code)]

fn main() {
    let uc = || -> ! { panic!() };
    uc();
    println!("unreachable");
}

The former still compiles, while the latter doesn't.

AFAICT, it seems that the first closure is defaulting to have return type (); since ! isn't a real type, it requires explicit annotation for the compiler to believe that you want it.

This would seem to be the case. @rust-lang/lang , what are the semantics we want here?

@nikomatsakis
Copy link
Contributor

We no longer support closures with -> ! return type, so I think the lint just can't handle this case anymore (and I'm ok with that).

@pnkfelix
Copy link
Member

pnkfelix commented Jan 4, 2016

(see also #14973 and rust-lang/rfcs#1001 for related discussion of whether one would want ! to be a first-class type of its own, and why/why not)

@steveklabnik
Copy link
Member

Sounds good to me, thanks!

@Phlosioneer
Copy link
Contributor

Should this be re-opened @nikomatsakis ? The type system can now handle ! as a proper type, so the closure should get the ! return type correctly now, and the lint should be able to handle that... We still have an ignored test about it:

#![deny(unreachable_code)]
fn main() {
let x = || panic!();
x();
println!("Foo bar"); //~ ERROR: unreachable statement
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint Area: Lints (warnings about flaws in source code) such as unused_mut.
Projects
None yet
Development

No branches or pull requests

7 participants