Skip to content

Uninhabited function parameter/match pattern #12073

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

Open
Fuzzyzilla opened this issue Jan 2, 2024 · 3 comments
Open

Uninhabited function parameter/match pattern #12073

Fuzzyzilla opened this issue Jan 2, 2024 · 3 comments
Labels
A-lint Area: New lints

Comments

@Fuzzyzilla
Copy link

Fuzzyzilla commented Jan 2, 2024

What it does

Mark functions with uninhabited parameters and match arms on uninhabited patterns as dead code.

Advantage

Uninhabited types can never be constructed and thus the function can never be called - If the function/arm body is non-trivial, this hints at a mistake.

This can come up as a result of implementing a generic trait Trait<Bar: OtherTrait> where the parameter type comes from the OtherTrait. Users may populate the function without noticing Bar's impl of OtherTrait has uninhabited associated types.

Drawbacks

Detecting what function bodies are allowable may be difficult. When the return type is (), an empty block suffices, however any other type may require the match uninhabited {} trick and thus such a body should be allowable without triggering the lint.

Example

fn make_int(_: !) -> i32 {
    my_important_fn();
    0
}
fn my_match(val: Option<!>) -> i32 {
    match val {
        None => none_important_fn(),    // ok
        Some(_) => some_important_fn(), // dead code!
    }
}

Could be written as:

fn make_int(val: !) -> i32 {
    val
}
fn my_match(val: Option<!>) -> i32 {
    match val {
        None => none_important_fn(), 
        Some(val) => val,
    }
}

Edit: change examples to !

@Fuzzyzilla Fuzzyzilla added the A-lint Area: New lints label Jan 2, 2024
@asquared31415
Copy link
Contributor

These functions are useful for being generic or for using traits, #11984 has some more context about when this pattern is useful. I suppose that taking an uninhabited type by value is less useful, but it could still be useful for use in a generic API.

@Fuzzyzilla
Copy link
Author

I am aware the existence of trait functions with uninhabited parameters have uses, this suggestion is about accidentally writing a non-trivial body for these implementations, as the implementation code is actually unreachable. I encountered this when working with the wayland_client crate, where an event handler trait must be implemented. Some of these event handlers take an uninhabited enum to describe the event, and I made the mistake of writing important logic in such a function and it was silently accepted!

@asquared31415
Copy link
Contributor

Ah my bad, I didn't notice the "body is non-trivial" qualifier. In that case I agree with this lint being useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint Area: New lints
Projects
None yet
Development

No branches or pull requests

2 participants