Skip to content

unreachable_code lint doesn't work with unboxed closures #20574

New issue

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

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

Already on GitHub? # to your account

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-lints 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-lints 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
}

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

No branches or pull requests

7 participants