rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.12k stars 12.69k forks source link

Non exhaustive match error presents incompletely with tuples and .unwrap() #100097

Open Jeremiah-Griffin opened 2 years ago

Jeremiah-Griffin commented 2 years ago

When matching against a tuple, if one of the values is an Option<char>, unwrapping it in the match statement itself provides a garbled error message from the compiler.

previous_chr is of type Option<char> current_chr if of type char

match ( (previous_chr.unwrap(), current_chr) ){
    ('\\', '"') => {
        self.is_within_literal = true; 
        self.previous_chr = Some(current_chr)
    }
} 

I would expect a typical error message stating that the None case for the optional value is not covered. Instead, this message is returned by the compiler:

   --> src\interpreter\helpers\mod.rs:147:23
    |
147 |                 match ((self.previous_chr.unwrap(),current_chr)){
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ patterns `('\0'..='[', _)`, `(']'..='\u{d
7ff}', _)` and `('\u{e000}'..='\u{10ffff}', _)` not covered
    |
    = note: the matched value is of type `(char, char)`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match ar
m with multiple or-patterns as shown, or multiple match arms
152 +                     ('\0'..='[', _) | (']'..='\u{d7ff}', _) | ('\u{e000}'..='\u{10ffff}', _) => todo!()   
    |

Changing the code to the following...

match ( (previous_chr, current_chr) ){
    (Some('\\'), '"') => {
        self.is_within_literal = true; 
        self.previous_chr = Some(current_chr)
    }
} 

...produces the expected message:

   --> src\interpreter\helpers\mod.rs:147:23
    |
147 |                 match ((self.previous_chr,current_chr)){
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `(None, _)` not covered
    |
    = note: the matched value is of type `(std::option::Option<char>, char)`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an expli
cit pattern as shown
    |
151 ~                     }
152 +                     (None, _) => todo!()
    |

rust version:

rustc 1.64.0-nightly (4493a0f47 2022-08-02) binary: rustc commit-hash: 4493a0f4724c0bae1436242d76cccc9c0a287b80 commit-date: 2022-08-02 host: x86_64-pc-windows-msvc release: 1.64.0-nightly LLVM version: 14.0.6

There is no panic and no backtrace is emitted.

hdelc commented 2 years ago

The errors emitted look correct, but your second example's diagnostic output is incomplete.

I could see addressing all possibilities for every combination of types and nested types becoming very unwieldy and difficult to read, though.

@rustbot label A-diagnostics