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

Match expressions should sometimes have type ! #3231

Open
1 task
powerboat9 opened this issue Oct 28, 2024 · 3 comments
Open
1 task

Match expressions should sometimes have type ! #3231

powerboat9 opened this issue Oct 28, 2024 · 3 comments
Assignees

Comments

@powerboat9
Copy link
Contributor

powerboat9 commented Oct 28, 2024

Summary

Match expressions with no arms should give a value of type !

Reproducer

I tried this code:

pub enum X {}

pub fn foo(x: X) {
    let _a: i32 = match x {};
}

pub fn main() {}

Does the code make use of any (1.49) nightly feature ?

  • Nightly

Godbolt link

link

Actual behavior

<source>:4:5: error: mismatched types, expected 'i32' but got '()' [E0308]
    4 |     let _a: i32 = match x {};
      |     ^~~     ~~~   ~~~~~

Expected behavior

No error

GCC Version

GCCRS master on godbolt

@powerboat9 powerboat9 changed the title Match expressions should sometimes have type '!' Match expressions should sometimes have type ! Oct 28, 2024
@CohenArthur CohenArthur added this to the Remaining typecheck issues milestone Nov 5, 2024
@philberty
Copy link
Member

Whats the logic for never type here ? @flip1995

@CohenArthur
Copy link
Member

@philberty https://github.com/rust-lang/rust/blob/3d1dba830a564d1118361345d7ada47a05241f45/compiler/rustc_hir_typeck/src/_match.rs#L32-L36 I believe

so it should be pretty simple - if there are no arms, then it returns !. if there are no arms when there should be arms, then it's up to the exhaustiveness checker to report an error

@flip1995
Copy link
Member

flip1995 commented Nov 8, 2024

The best documentation I could find was a blog post by Niko. Also take a look at the linked RFC. I think this is something missing in the reference.

I think this paragraph from the RFC explains it best:

let foo: &'static str = match x {};

Reading this, it may be tempting to ask the question "what is the value of foo then?". Remember that this depends on the value of x. As there are no possible values of x it's a meaningless question and besides, the fact that x has type Never gives us a static guarantee that the match block will never be executed.

Because the scrutinee is an uninhabited type (which the never type is), it can never be created. So this match can never be executed. So the type of the expression is ! = never.

@philberty philberty self-assigned this Nov 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants