Nate Houk
Nate Houk

Reputation: 365

Why does Match compile with invalid Type in Rust?

I don't understand why this compiles with the type value of "typpo" in the Match statement.

I am assuming it is because the variable "typpo" is acting as the "_" catch-all variable.

// This stub file contains items which aren't used yet; feel free to remove this module attribute
// to enable stricter warnings.
#![allow(unused)]

/// various log levels
#[derive(Clone, PartialEq, Debug)]
pub enum LogLevel {
    Info,
    Warning,
    Error,
}
/// primary function for emitting logs
pub fn log(level: LogLevel, message: &str) -> String {
    match level {
        LogLevel::Info => info(&message),
        LogLevel::Warning => warn(&message),
        typpo => error(&message),
    }
}
pub fn info(message: &str) -> String {
    format!("[INFO]: {}", &message)
}
pub fn warn(message: &str) -> String {
    format!("[WARNING]: {}", &message)
}
pub fn error(message: &str) -> String {
    format!("[ERROR]: {}", &message)
}

However, if this is true, then why does this also compile, where we have multiple catch all variables? Why does it not warn of an unused code path at "typpo", since the variable above "typppo" already catches all?

// This stub file contains items which aren't used yet; feel free to remove this module attribute
// to enable stricter warnings.
#![allow(unused)]

/// various log levels
#[derive(Clone, PartialEq, Debug)]
pub enum LogLevel {
    Info,
    Warning,
    Error,
}
/// primary function for emitting logs
pub fn log(level: LogLevel, message: &str) -> String {
    match level {
        LogLevel::Info => info(&message),
        typppo => warn(&message),
        typpo => error(&message),
    }
}
pub fn info(message: &str) -> String {
    format!("[INFO]: {}", &message)
}
pub fn warn(message: &str) -> String {
    format!("[WARNING]: {}", &message)
}
pub fn error(message: &str) -> String {
    format!("[ERROR]: {}", &message)
}

Upvotes: 0

Views: 115

Answers (1)

Thomas
Thomas

Reputation: 181735

typpo is indeed interpreted as a catch-all pattern that binds to the entire expression. And in the second example, typpo is indeed unreachable because match arms are evaluated in order.

The compiler does warn about both of these (playground link), but #![allow(unused)] suppresses both warnings. unused is the name of a lint group that "detect things being declared but not used, or excess syntax".

Use allow(unused_variable) to only suppress the warning about an unused catch-all binding, and allow(unreachable_patterns) to suppress the warning about an unreachable match arm.

Upvotes: 6

Related Questions