Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apparent unused variable in match statement

Tags:

enums

match

rust

I am implementing a simple library system to keep track of my pdfs.

I have a Subject enum and a Entry struct defined as follows:

pub enum Subject {

    Math,
    Programming,
    CompSci,
    Language,
    Misc,
    None
}

pub struct Entry {

    pub subject: Subject

}

I am trying to implement a function that will operate on a vector of Entry's and return a Vec<&Entry> whose entries match a given Subject.

I have a simple Library struct that is a wrapper around a Vec<Entry>:

pub struct Library {

    pub entries: Vec<Entry>

}

In order to do so, I need to iterate through entries and filter only the elements whose .subject field correspond to the desired subject. To accomplish this I have created a function that will return a predicate function.

Here is the get_subject function:

impl Library {
    
    pub fn get_subject(&self, subject: Subject) -> Vec<&Entry> {

        let pred = subject_pred(subject);
        self.entries.iter().filter(pred).collect::<Vec<&Entry>>()
    }
}

which calls the function subject_pred to create the correct predicate function:

// Return a PREDICATE that returns true when
// the passed ENTRY matches the desired SUBJECT
fn subject_pred(subject_UNUSED: Subject) -> impl FnMut(&&Entry) -> bool {
    |e: &&Entry| if matches!(&e.subject, subject_UNUSED) {
        true
    } else {
        false
    }
}

Here's the problem. This syntax compiles just fine but apparently the subject_UNUSED local variable in subject_pred is "unused". I am flabbergasted as my syntax clearly shows intent to match with the passed subject_UNUSED. When I test out this function on a vector of entries, the predicate always returns true (hence why I am receiving the "unused" warning) but I have literally no idea why.

If anyone could explain why the match statement is always matched, that would be greatly appreciated. I tried using a regular match statement but the same warning is popping up, and this is not the behavior that I am trying to code. If I don't include the subject_UNUSED in a traditional match statement, the compiler tells me that I have to cover the Math, Programming, CompSci, Language, Misc and None variants of my enum, which indicates to me that everything up until that point is good.

like image 515
ejovo13 Avatar asked Dec 02 '25 17:12

ejovo13


1 Answers

You cannot match against a variable. What you've done is equivalent to

matches!(&e.subject, some_subject)

That matches any Subject, just like a wildcard (_), except it also captures it in the some_subject variable (can be used in a guard like matches!(&e.subject, subject_UNUSED if subject_UNUSED == ...)). Neither the captured variable nor the parameter (which is shadowed by it) are used.

What you need to do is to #[derive(PartialEq)] then use ==:

if e.subject == subject_UNUSED { ... }

By the way, your code also has other problems: you don't move into the closure and you're taking owned entries but produce borrowed.

like image 164
Chayim Friedman Avatar answered Dec 05 '25 15:12

Chayim Friedman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!